bridge.oninitialized = () => {
console.log("View ready");
bridge.sendToolInput({ arguments: toolArgs });
};
McpUiInitializedNotification for the notification typesendToolInput for sending tool arguments to the ViewUse addEventListener("initialized", handler) instead — it composes with other listeners and supports cleanup via removeEventListener.
Register a handler for logging messages from the view.
The view sends standard MCP notifications/message (logging) notifications
to report debugging information, errors, warnings, and other telemetry to the
host. The host can display these in a console, log them to a file, or send
them to a monitoring service.
This uses the standard MCP logging notification format, not a UI-specific message type.
bridge.onloggingmessage = ({ level, logger, data }) => {
console[level === "error" ? "error" : "log"](
`[${logger ?? "View"}] ${level.toUpperCase()}:`,
data,
);
};
Use addEventListener("loggingmessage", handler) instead — it composes with other listeners and supports cleanup via removeEventListener.
Register a handler for app-initiated teardown request notifications from the view.
The view sends ui/notifications/request-teardown when it wants the host to tear it down.
If the host decides to proceed, it should send
ui/resource-teardown (via teardownResource) to allow
the view to perform gracefull termination, then unmount the iframe after the view responds.
bridge.onrequestteardown = async (params) => {
console.log("App requested teardown");
// Initiate teardown to allow the app to persist unsaved state
// Alternatively, the callback can early return to prevent teardown
await bridge.teardownResource({});
// Now safe to unmount the iframe
iframe.remove();
};
McpUiRequestTeardownNotification for the notification typeteardownResource for initiating teardownUse addEventListener("requestteardown", handler) instead — it composes with other listeners and supports cleanup via removeEventListener.
InternalRegister a handler for sandbox proxy ready notifications.
This is an internal callback used by web-based hosts implementing the
double-iframe sandbox architecture. The sandbox proxy sends
ui/notifications/sandbox-proxy-ready after it loads and is ready to receive
HTML content.
When this fires, the host should call sendSandboxResourceReady with
the HTML content to load into the inner sandboxed iframe.
bridge.onsandboxready = async () => {
const resource = await mcpClient.request(
{ method: "resources/read", params: { uri: "ui://my-app" } },
ReadResourceResultSchema
);
bridge.sendSandboxResourceReady({
html: resource.contents[0].text,
sandbox: "allow-scripts"
});
};
McpUiSandboxProxyReadyNotification for the notification typesendSandboxResourceReady for sending content to the sandboxUse addEventListener("sandboxready", handler) instead — it composes with other listeners and supports cleanup via removeEventListener.
Register a handler for size change notifications from the view.
The view sends ui/notifications/size-changed when its rendered content
size changes, typically via ResizeObserver. Set this callback to dynamically
adjust the iframe container dimensions based on the view's content.
Note: This is for View → Host communication. To notify the View of
host container dimension changes, use setHostContext.
bridge.onsizechange = ({ width, height }) => {
if (width != null) {
iframe.style.width = `${width}px`;
}
if (height != null) {
iframe.style.height = `${height}px`;
}
};
McpUiSizeChangedNotification for the notification typeApp.sendSizeChanged - the View method that sends these notificationsUse addEventListener("sizechange", handler) instead — it composes with other listeners and supports cleanup via removeEventListener.
Create a new AppBridge instance.
MCP client connected to the server, or null. When provided,
connect will automatically set up forwarding of MCP requests/notifications
between the View and the server. When null, you must register handlers
manually using the oncalltool, onlistresources, etc. setters.
Host application identification (name and version)
Features and capabilities the host supports
Optionaloptions: HostOptionsConfiguration options (inherited from Protocol)
Add a listener for a notification event.
Unlike the singular on* handler, calling this multiple times appends
listeners rather than replacing them. All registered listeners fire in
insertion order after the on* handler when the notification arrives.
Registration is lazy: the first call (for a given event, from either
this method or the on* setter) registers a dispatcher with the base
Protocol.
Asserts that a request handler has not already been set for the given method, in preparation for a new one being automatically installed.
InternalVerify that the guest supports the capability required for the given request method.
InternalVerify that the host supports the capability required for the given notification method.
InternalVerify that a request handler is registered and supported for the given method.
ProtectedassertInternalVerify that task creation is supported for the given request method.
ProtectedassertInternalVerify that task handler is supported for the given method.
Call a tool on the view.
Sends a tools/call request to the view and returns the result.
Tool call parameters (name and arguments)
Optionaloptions: RequestOptionsRequest options (timeout, abort signal, etc.)
Promise resolving to the tool call result
ProtectedcancelExperimentalCancels a specific task.
Use client.experimental.tasks.cancelTask() to access this method.
Optionaloptions: RequestOptionsCloses the connection.
Connect to the view via transport and optionally set up message forwarding.
This method establishes the transport connection. If an MCP client was passed to the constructor, it also automatically sets up request/notification forwarding based on the MCP server's capabilities, proxying the following to the view:
If no client was passed to the constructor, no automatic forwarding is set up
and you must register handlers manually using the oncalltool, onlistresources,
etc. setters.
After calling connect, wait for the oninitialized callback before sending
tool input and other data to the View.
Transport layer (typically PostMessageTransport)
Promise resolving when connection is established
If a client was passed but server capabilities are not available.
This occurs when connect() is called before the MCP client has completed its
initialization with the server. Ensure await client.connect() completes
before calling bridge.connect().
const bridge = new AppBridge(mcpClient, hostInfo, capabilities);
const transport = new PostMessageTransport(
iframe.contentWindow!,
iframe.contentWindow!,
);
bridge.oninitialized = () => {
console.log("View ready");
bridge.sendToolInput({ arguments: toolArgs });
};
await bridge.connect(transport);
Get the view's capabilities discovered during initialization.
Returns the capabilities that the view advertised during its
initialization request. Returns undefined if called before
initialization completes.
view capabilities, or undefined if not yet initialized
bridge.oninitialized = () => {
const caps = bridge.getAppCapabilities();
if (caps?.tools) {
console.log("View provides tools");
}
};
McpUiAppCapabilities for the capabilities structure
Get the view's implementation info discovered during initialization.
Returns the view's name and version as provided in its initialization
request. Returns undefined if called before initialization completes.
view implementation info, or undefined if not yet initialized
Get the host capabilities passed to the constructor.
Host capabilities object
McpUiHostCapabilities for the capabilities structure
ProtectedgetProtectedgetExperimentalGets the current status of a task.
Use client.experimental.tasks.getTask() to access this method.
Optionaloptions: RequestOptionsProtectedgetExperimentalRetrieves the result of a completed task.
Use client.experimental.tasks.getTaskResult() to access this method.
Optionaloptions: RequestOptionsProtectedlistExperimentalLists tasks, optionally starting from a pagination cursor.
Use client.experimental.tasks.listTasks() to access this method.
Optionalparams: { cursor?: string }Optionaloptions: RequestOptionsList tools available on the view.
Sends a tools/list request to the view and returns the result.
List tools parameters (may include cursor for pagination)
Optionaloptions: RequestOptionsRequest options (timeout, abort signal, etc.)
Promise resolving to the list of tools
Emits a notification, which is a one-way message that does not expect a response.
Optionaloptions: NotificationOptionsProtectedonRemove a previously registered event listener. The dispatcher stays registered even if the listener array becomes empty; future notifications simply have no listeners to call.
Removes the notification handler for the given method.
Removes the request handler for the given method.
Sends a request and waits for a response.
Do not use this method to emit notifications! Use notification() instead.
Optionaloptions: RequestOptionsProtectedrequestExperimentalSends a request and returns an AsyncGenerator that yields response messages. The generator is guaranteed to end with either a 'result' or 'error' message.
Optionaloptions: RequestOptionsconst stream = protocol.requestStream(request, resultSchema, options);
for await (const message of stream) {
switch (message.type) {
case 'taskCreated':
console.log('Task created:', message.task.taskId);
break;
case 'taskStatus':
console.log('Task status:', message.task.status);
break;
case 'result':
console.log('Final result:', message.result);
break;
case 'error':
console.error('Error:', message.error);
break;
}
}
Use client.experimental.tasks.requestStream() to access this method.
Low-level method to notify the view of host context changes.
Most hosts should use setHostContext instead, which automatically
detects changes and calls this method with only the modified fields.
Use this directly only when you need fine-grained control over change detection.
The context fields that have changed (partial update)
Notify the view that the MCP server's prompt list has changed.
The host sends notifications/prompts/list_changed to the view when it
receives this notification from the MCP server. This allows the view
to refresh its prompt cache or UI accordingly.
Optional notification params (typically empty)
Notify the view that the MCP server's resource list has changed.
The host sends notifications/resources/list_changed to the view when it
receives this notification from the MCP server. This allows the view
to refresh its resource cache or UI accordingly.
Optional notification params (typically empty)
InternalSend HTML resource to the sandbox proxy for secure loading.
This is an internal method used by web-based hosts implementing the
double-iframe sandbox architecture. After the sandbox proxy signals readiness
via ui/notifications/sandbox-proxy-ready, the host sends this notification
with the HTML content to load.
HTML content and sandbox configuration:
html: The HTML content to load into the sandboxed iframesandbox: Optional sandbox attribute value (e.g., "allow-scripts")Optionalcsp?: McpUiResourceCspOptionalpermissions?: McpUiResourcePermissionsOptionalsandbox?: stringonsandboxready for handling the sandbox proxy ready notification
Notify the view that tool execution was cancelled.
The host MUST send this notification if tool execution was cancelled for any reason, including user action, sampling error, classifier intervention, or any other interruption. This allows the view to update its state and display appropriate feedback to the user.
Cancellation details object
reason: Human-readable explanation for why the tool was cancelledOptionalreason?: string// User clicked "Cancel" button
bridge.sendToolCancelled({ reason: "User cancelled the operation" });
// Sampling error or timeout
bridge.sendToolCancelled({ reason: "Request timeout after 30 seconds" });
// Classifier intervention
bridge.sendToolCancelled({ reason: "Content policy violation detected" });
McpUiToolCancelledNotification for the notification typesendToolResult for sending successful resultssendToolInput for sending tool argumentsSend complete tool arguments to the view.
The host MUST send this notification after the View completes initialization
(after oninitialized callback fires) and complete tool arguments become available.
This notification is sent exactly once and is required before sendToolResult.
Complete tool call arguments
Optionalarguments?: Record<string, unknown>bridge.oninitialized = () => {
bridge.sendToolInput({
arguments: { location: "New York", units: "metric" },
});
};
McpUiToolInputNotification for the notification typeoninitialized for the initialization callbacksendToolResult for sending results after executionSend streaming partial tool arguments to the view.
The host MAY send this notification zero or more times while tool arguments
are being streamed, before sendToolInput is called with complete
arguments. This enables progressive rendering of tool arguments in the
view.
The arguments represent best-effort recovery of incomplete JSON. views SHOULD handle missing or changing fields gracefully between notifications.
Partial tool call arguments (may be incomplete)
Optionalarguments?: Record<string, unknown>// As streaming progresses...
bridge.sendToolInputPartial({ arguments: { loc: "N" } });
bridge.sendToolInputPartial({ arguments: { location: "New" } });
bridge.sendToolInputPartial({ arguments: { location: "New York" } });
// When complete, send final input
bridge.sendToolInput({
arguments: { location: "New York", units: "metric" },
});
McpUiToolInputPartialNotification for the notification typesendToolInput for sending complete argumentsNotify the view that the MCP server's tool list has changed.
The host sends notifications/tools/list_changed to the view when it
receives this notification from the MCP server. This allows the view
to refresh its tool cache or UI accordingly.
Optional notification params (typically empty)
Send tool execution result to the view.
The host MUST send this notification when tool execution completes successfully,
provided the view is still displayed. If the view was closed before execution
completes, the host MAY skip this notification. This must be sent after
sendToolInput.
Standard MCP tool execution result
const result = await mcpClient.request(
{ method: "tools/call", params: { name: "get_weather", arguments: args } },
CallToolResultSchema,
);
bridge.sendToolResult(result);
McpUiToolResultNotification for the notification typesendToolInput for sending tool arguments before resultsProtectedsetSet or clear the singular on* handler for an event.
Replace semantics — like the DOM's el.onclick = fn. Assigning
undefined clears the handler without affecting addEventListener
listeners.
Update the host context and notify the view of changes.
Compares fields present in the new context with the current context and sends a
ui/notifications/host-context-changed notification containing only fields
that have been added or modified. If no fields have changed, no notification is sent.
The new context fully replaces the internal state.
Common use cases include notifying the view when:
The complete new host context state
bridge.setHostContext({
theme: "dark",
containerDimensions: { maxHeight: 600, width: 800 },
});
McpUiHostContext for the context structureMcpUiHostContextChangedNotification for the notification typeRequest graceful shutdown of the view.
The host MUST send this request before tearing down the UI resource (before unmounting the iframe). This gives the view an opportunity to save state, cancel pending operations, or show confirmation dialogs.
The host SHOULD wait for the response before unmounting to prevent data loss.
Empty params object
Optionaloptions: RequestOptionsRequest options (timeout, etc.)
Promise resolving when view confirms readiness for teardown
ProtectedwarnWarn if a request handler on* setter is replacing a previously-set
handler. Call from each request setter before updating the backing field.
Protected ReadonlyeventEvent name → notification schema. Subclasses populate this so that the event system can lazily register a dispatcher with the correct schema on first use.
OptionalfallbackA handler to invoke for any notification types that do not have their own handler installed.
OptionalfallbackA handler to invoke for any request types that do not have their own handler installed.
OptionaloncloseCallback for when the connection is closed for any reason.
This is invoked when close() is called as well.
OptionalonerrorCallback for when an error occurs.
Note that errors are not necessarily fatal; they are used for reporting any kind of exceptional condition out of band.
OptionalonpingOptional handler for ping requests from the view.
The View can send standard MCP ping requests to verify the connection
is alive. The AppBridge automatically responds with an empty object, but this
handler allows the host to observe or log ping activity.
Unlike the other handlers which use setters, this is a direct property assignment. It is optional; if not set, pings are still handled automatically.
Empty params object from the ping request
Request metadata (abort signal, session info)
ProtectedreplaceReplace a request handler, bypassing double-set protection. Used by
on* request-handler setters that need replace semantics.
Registers a handler to invoke when this protocol object receives a request with the given method.
Note that this will replace any previous request handler for the same method.
Request graceful shutdown of the view.
The host MUST send this request before tearing down the UI resource (before unmounting the iframe). This gives the view an opportunity to save state, cancel pending operations, or show confirmation dialogs.
The host SHOULD wait for the response before unmounting to prevent data loss.
Empty params object
Optionaloptions: RequestOptionsRequest options (timeout, etc.)
Promise resolving when view confirms readiness for teardown
Use teardownResource instead
Registers a notification handler. Throws if a handler for the same
method has already been registered — use the on* setter (replace
semantics) or addEventListener (multi-listener) for mapped events.
Registers a handler to invoke when this protocol object receives a notification with the given method.
Note that this will replace any previous notification handler for the same method.
Registers a request handler. Throws if a handler for the same method
has already been registered — use the on* setter (replace semantics)
or addEventListener (multi-listener) for notification events.
Registers a handler to invoke when this protocol object receives a request with the given method.
Note that this will replace any previous request handler for the same method.
Called when the view completes initialization.
Set this callback to be notified when the view has finished its initialization handshake and is ready to receive tool input and other data.