MCP Apps SDK
import { App } from "@modelcontextprotocol/ext-apps";
Overview
The ontoolinputpartial notification handler is called as the host streams partial tool arguments during tool call initialization. This enables progressive rendering — your app can display a live preview of content before the complete input is available.
Partial arguments are delivered as “healed” JSON: the host closes any unclosed brackets or braces to produce valid JSON at each step. This means the data is always parseable but may be incomplete.
Like all notification handlers, ontoolinputpartial should be registered before calling connect().
Register handlers before calling connect() to avoid missing notifications during the initialization handshake.
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.
Signature
app.ontoolinputpartial = (params) => void;
Parameters
Partial tool arguments (healed JSON — incomplete objects may be truncated).
Usage
Basic preview rendering
const app = new App({ name: "MyApp", version: "1.0.0" });
const codePreview = document.querySelector<HTMLPreElement>("#code-preview")!;
app.ontoolinputpartial = (params) => {
codePreview.textContent = (params.arguments?.code as string) ?? "";
};
await app.connect();
Progressive rendering with a final state
Combine ontoolinputpartial for live preview with ontoolinput for the finalized result:
const preview = document.querySelector<HTMLElement>("#preview")!;
app.ontoolinputpartial = (params) => {
const markdown = (params.arguments?.content as string) ?? "";
preview.innerHTML = renderMarkdownPreview(markdown);
preview.classList.add("streaming");
};
app.ontoolinput = (params) => {
const markdown = params.arguments.content as string;
preview.innerHTML = renderMarkdownFinal(markdown);
preview.classList.remove("streaming");
};
Using with the sunpeak framework
The sunpeak framework provides the useToolData hook, which manages both partial and complete tool input as a reactive value. This is the recommended approach when building with sunpeak.
import { useToolData } from "sunpeak/hooks";
function MyComponent() {
const toolData = useToolData();
// toolData.input updates progressively as partial arguments stream in
}