host.ui
Shipping soon, expanding. The external MCP-apps bridge is implemented and you can use it; the surface is still growing. See What's ready.
host.ui is the App SDK's MCP Apps UI bridge. It mirrors the MCP Apps ui/* interface (SEP-1865) so a bundle authored for an external MCP host (Claude, ChatGPT, MCP-UI) works inside Robutler unchanged. If you write a UI app to the MCP Apps spec, host.ui adapts those ui/* calls onto the Robutler runtime; if you target Robutler directly, you would normally use the dedicated namespaces (host.kv, host.commands, and so on) instead.
API
interface UiNamespace {
bridge: UiBridge;
App: typeof UiApp;
}
interface UiBridge {
initialize(): Promise<{ hostContext: Record<string, unknown> }>;
callTool(name: string, args?: unknown): Promise<unknown>;
onToolResult(cb: (result: unknown) => void): () => void;
requestDisplayMode(mode: 'inline' | 'pip' | 'fullscreen'): Promise<unknown>;
openLink(url: string): Promise<unknown>;
notifySizeChanged(size: { width: number; height: number }): Promise<void>;
message(msg: unknown): Promise<unknown>;
updateModelContext(ctx: Record<string, unknown>): Promise<void>;
on(method: string, cb: (params: unknown) => void): () => void;
}The UiApp class is a small convenience wrapper over bridge:
class UiApp {
connect(): Promise<{ hostContext: Record<string, unknown> }>;
callTool(name: string, args?: unknown): Promise<unknown>;
onToolResult(cb: (result: unknown) => void): void;
requestDisplayMode(mode: 'inline' | 'pip' | 'fullscreen'): Promise<unknown>;
}Use it
const app = new host.ui.App();
const { hostContext } = await app.connect();
app.onToolResult((result) => render(result));
const out = await app.callTool('search', { query: hostContext.query });
await app.requestDisplayMode('fullscreen');Or drive the bridge directly:
const bridge = host.ui.bridge;
await bridge.initialize();
const off = bridge.on('ui/render', (params) => render(params));
await bridge.callTool('lookup', { id });
await bridge.notifySizeChanged({ width: 640, height: 480 });When to reach for it
- You have an existing MCP Apps UI bundle and want it to run in Robutler without a rewrite.
- You are building one app to ship to several MCP hosts and want a single code path.
For an app built only for Robutler, prefer the native namespaces; they expose more of the platform than the ui/* subset.
Related
- Protocols: MCP and how the App SDK relates to it
- App SDK overview: the native namespaces
- What's ready: the status of this bridge