Skip to main content
import { App } from "sunpeak";
In sunpeak, register event handlers in the onAppCreated callback of useApp to ensure they’re set before the connection handshake.

Overview

The App class exposes setter properties for handling host notifications and requests. These are convenience wrappers around setNotificationHandler() and setRequestHandler() from the MCP SDK’s Protocol class. For making requests from the View to the host, see Requests.
Register handlers before calling connect() to avoid missing notifications during the initialization handshake.

Notification Handlers

ontoolinput

Called when the host sends complete tool arguments. This arrives after a tool call begins and before the tool result.
app.ontoolinput = (params) => {
  console.log("Tool arguments:", params.arguments);
};
params.arguments
Record<string, unknown>
Complete tool call arguments as key-value pairs.

ontoolinputpartial

Called as the host streams partial tool arguments during tool call initialization. Use for progressive rendering before complete input is available.
const codePreview = document.querySelector<HTMLPreElement>("#code-preview")!;

app.ontoolinputpartial = (params) => {
  codePreview.textContent = (params.arguments?.code as string) ?? "";
};
params.arguments
Record<string, unknown>
Partial tool arguments (healed JSON — incomplete objects may be truncated).
Partial arguments are “healed” JSON — the host closes unclosed brackets/braces to produce valid JSON. The last item in arrays or objects may be truncated. Use partial data only for preview UI, not for critical operations.

ontoolresult

Called when the host sends the result of a tool execution.
app.ontoolresult = (params) => {
  if (params.isError) {
    console.error("Tool failed:", params.content);
  } else {
    console.log("Tool output:", params.content);
    console.log("Structured data:", params.structuredContent);
  }
};
params
CallToolResult
Standard MCP tool execution result. Key fields:
FieldTypeDescription
contentContentBlock[]Text content for model context
structuredContentRecord<string, unknown>Data optimized for UI rendering
isErrorbooleanWhether the tool returned an error
_metaobjectMetadata (e.g., viewUUID for state persistence)

ontoolcancelled

Called when tool execution is cancelled (user action, timeout, classifier intervention).
app.ontoolcancelled = (params) => {
  console.log("Cancelled:", params.reason);
};
params.reason
string
Optional reason for the cancellation.

onhostcontextchanged

Called when the host context changes (theme toggle, resize, locale change, etc.). Params are automatically merged into the internal context before the callback — getHostContext() returns updated values.
app.onhostcontextchanged = (ctx) => {
  if (ctx.theme) {
    document.body.classList.toggle("dark", ctx.theme === "dark");
  }
  if (ctx.displayMode) {
    container.classList.toggle("fullscreen", ctx.displayMode === "fullscreen");
  }
  if (ctx.availableDisplayModes) {
    fullscreenBtn.style.display =
      ctx.availableDisplayModes.includes("fullscreen") ? "block" : "none";
  }
};
params
McpUiHostContext
Partial context update containing only changed fields. See Core Types for the full McpUiHostContext structure.

Request Handlers

onteardown

Called when the host requests graceful shutdown before unmounting the iframe. Return {} (or a promise resolving to {}) when ready.
app.onteardown = async () => {
  await saveState();
  closeConnections();
  return {};
};

oncalltool

Handle tool calls from the host directed at this app. Requires declaring tools capability in the constructor.
const app = new App(
  { name: "MyApp", version: "1.0.0" },
  { tools: { listChanged: true } },
);

app.oncalltool = async (params) => {
  if (params.name === "get-selection") {
    return { content: [{ type: "text", text: selectedText }] };
  }
  throw new Error(`Unknown tool: ${params.name}`);
};
params.name
string
Name of the tool being called.
params.arguments
Record<string, unknown>
Tool arguments.

onlisttools

Return the list of tools this app provides. Requires declaring tools capability.
app.onlisttools = async () => {
  return { tools: ["get-selection", "format-text"] };
};

Using setNotificationHandler / setRequestHandler

The setter properties above are convenience wrappers. You can also use the underlying MCP SDK methods directly:
import { McpUiToolInputNotificationSchema } from "sunpeak";

app.setNotificationHandler(McpUiToolInputNotificationSchema, (notification) => {
  console.log("Tool input:", notification.params.arguments);
});