Skip to main content
The first widget uses one provider and one hook. Add the other hooks as the widget gains features. Create the bindings once in src/mcp.ts. Components import the hooks from that file. Every hook runs inside that factory’s AppProvider.

Display the first result

result is the complete initiating tool result. Its structuredContent contains the typed data you returned on the server. It can be absent while waiting, after cancellation, or when a tool fails. Handle error, result?.isError, and missing data before rendering the result, as shown in the quickstart. With several tools in the map, use useToolResult("weather") to select the expected tool’s type. An unnamed result is a union you can narrow by state.toolName.

Add a refresh button

First, export useToolCall alongside your existing bindings:
src/mcp.ts
In src/App.tsx, import useToolCall from ./mcp.ts. Replace the Weather component with this version; keep it inside the provider:
useToolCall returns call, pending, result, and error. The catch prevents an unhandled rejection; the hook stores the failure in refresh.error, which the component displays. The host must advertise server tool-call support. The initial result and refresh result are separate. refresh.result ?? initial.result displays the latest successful call or the original data. The hook does not overwrite useToolResult() or start calls automatically.

Interactive calls

call(input, options?) returns the full result. Explicit isError: true tool results resolve normally; transport and JSON-RPC failures reject. Concurrent calls each settle their promises, while the latest invocation owns the hook’s displayed state. Options are optional:
The default deadline is 30 seconds. An abort or timeout rejects locally and suppresses late replies. Host cancellation remains cooperative.

Read host context when needed

The provider already applies host fonts and theme variables. CSS such as var(--color-text-primary, #1f2937) is enough for the basic widget. Export useHostContext from src/mcp.ts when you need host information in React logic:
These hints are optional. Supply application defaults, such as locale ?? "en". Use host actions to request a display-mode change or another explicit host operation.

Inferred types

Tool names come from registration keys. Arguments use the input schema’s input type, before defaults/transforms. Structured results use the parsed output schema type. Result _meta retains the type inferred from mcpResult(). structuredContent and _meta remain optional. Toolgrain validates the wire envelopes; application payload types are inferred rather than schema-validated in the browser. See metadata for an example.

Provider lifecycle

Use one provider per widget window. Pass appInfo and either tool for a separate entry or resolveTool for a shared entry. Identity, routing, and declared display modes are fixed for that mount. The factory is safe to import during server rendering. Mounting connects to the host; React Strict Mode reuses the connection during effect replay. Unmount/host teardown removes owned listeners, observers, and timers and rejects pending requests. Remount to reconnect. Host styling and automatic size reporting default to on. Disable them with applyHostStyles={false} or autoResize={false} when your application needs to manage them. See the API reference for the complete provider options and state contracts.