Skip to main content
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

params.arguments
Record<string, unknown>
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
}