MCP Apps SDKDocumentation Index
Fetch the complete documentation index at: https://sunpeak.ai/docs/llms.txt
Use this file to discover all available pages before exploring further.
Overview
MCP Apps is bidirectional. In addition to the View calling tools on the originating MCP server (seecallServerTool), the View itself can act like a tiny MCP server — registering tools that the host or model can call.
App-side tools are useful when the answer lives inside the View and can’t be answered by the server:
- DOM and selection state — get the user’s current selection, scroll position, or visible viewport
- Form state — submit values from a multi-step wizard or pending edits
- Local computation — derive values from data the View has already loaded
- User intent — surface explicit UI actions (a “Save” button, a confirm dialog) to the model
tools capability, onlisttools, oncalltool, and (optionally) sendToolListChanged for dynamic tool lists.
Two ways to register tools
The SDK offers two equivalent patterns. Pick the one that matches the shape of your app.Static list — onlisttools + oncalltool
Declare a fixed list once. The host queries onlisttools, then dispatches calls to oncalltool. Good for apps where the tool set never changes.
Dynamic registry — app.registerTool()
Add, update, enable, disable, or remove tools at runtime. Each call returns a handle with enable(), disable(), remove(), and update(). The SDK builds the tool list and dispatches calls for you. Pair with sendToolListChanged to notify the host that the list has changed.
1. Declare the tools capability
The host only routes tools/list and tools/call to the View if the View declared support during initialization. Pass tools in the capabilities argument to the App constructor.
listChanged: true only if you plan to add or remove tools at runtime. The host will re-query onlisttools whenever you send a notifications/tools/list_changed notification.
2. Declare which tools the app exposes
Static — onlisttools
Return an array of MCP Tool definitions. Each must have a name and an inputSchema (with type: "object").
Dynamic — app.registerTool()
Define tools in code with Standard Schema (Zod, ArkType, Valibot) for input validation. The SDK populates onlisttools and dispatches oncalltool automatically.
| Method | Effect |
|---|---|
update(config) | Replace name, description, schemas, or annotations |
enable() | Re-list the tool after disable() |
disable() | Hide the tool from the host (still registered) |
remove() | Permanently remove the tool |
3. Handle tool calls
When the host calls one of the View’s tools, it arrives inoncalltool. Return a CallToolResult with content (for the model) and optional structuredContent (for any UI that reads it).
registerTool, you skip this — each tool’s callback runs automatically. The dispatcher checks the registry first, falling back to oncalltool for any unmatched name.
Returning errors
Throw to fail the request at the transport level. Return{ isError: true, content: [...] } to surface a tool-level error that the model can see and recover from. Prefer the latter for anything the model could act on.
Dynamic tool lists
Notify the host whenever the tool list changes — afterregisterTool, enable(), disable(), or remove(). The host re-runs tools/list and updates the model’s available tools for the next turn.
tools: { listChanged: true } and the host also reported tools.listChanged support in its capabilities.
A typical pattern: register tools eagerly, then enable or disable them as UI state changes.
Tool visibility — model, app, or both
The_meta.ui.visibility array on a tool controls who can call it: "model", "app", or both. App-side tools that are surfaced to the model should remain ["model", "app"] (the default). Set ["app"] for tools that are pure UI plumbing (refresh buttons, pagination) and shouldn’t clutter the model’s tool list. See Tool _meta for the full discussion.
End-to-end example
Related
onlisttools— request handler fortools/listoncalltool— request handler fortools/callregisterTool— dynamic registry on theAppsendToolListChanged— notify the host of changes- Tool
_meta— visibility and resource linkage useAppToolsanduseRegisterTool— sunpeak React wrappers