Skip to main content
MCP Apps SDK
import { App } from "@modelcontextprotocol/ext-apps";

Overview

The ontoolresult notification handler is called when the host sends the result of a tool execution. The result includes text content for model context, optional structured data optimized for UI rendering, and an error flag. Like all notification handlers, ontoolresult should be registered before calling connect().
Register handlers before calling connect() to avoid missing notifications during the initialization handshake.

Signature

app.ontoolresult = (params) => void;

Parameters

params
CallToolResult
Standard MCP tool execution result containing the following fields:
params.content
ContentBlock[]
Text content blocks intended for model context.
params.structuredContent
Record<string, unknown>
Structured data optimized for UI rendering. Use this for displaying rich results in your app.
params.isError
boolean
Whether the tool returned an error. When true, content contains error details.
params._meta
object
Metadata object. Contains viewUUID which can be used for state persistence across tool calls.

Usage

Handling success and error states

const app = new App({ name: "MyApp", version: "1.0.0" });

app.ontoolresult = (params) => {
  if (params.isError) {
    console.error("Tool failed:", params.content);
    showErrorBanner(params.content);
  } else {
    console.log("Tool output:", params.content);
    console.log("Structured data:", params.structuredContent);
  }
};

await app.connect();

Rendering structured content

app.ontoolresult = (params) => {
  if (params.isError) {
    renderError(params.content);
    return;
  }

  const data = params.structuredContent as {
    rows: Array<Record<string, string>>;
    columns: string[];
  };

  if (data) {
    renderTable(data.columns, data.rows);
  } else {
    renderTextContent(params.content);
  }
};

Using viewUUID for state persistence

app.ontoolresult = (params) => {
  const viewUUID = params._meta?.viewUUID as string | undefined;

  if (viewUUID) {
    // Restore previous state for this view
    const savedState = stateStore.get(viewUUID);
    if (savedState) {
      restoreState(savedState);
    }
  }

  renderResult(params);
};

Using with the sunpeak framework

The sunpeak framework provides the useToolData hook, which wraps ontoolresult (along with related handlers) into a reactive value for React components.
import { useToolData } from "sunpeak/hooks";

function MyComponent() {
  const toolData = useToolData();
  // toolData.result contains the tool execution result
  // toolData.isError indicates whether the tool failed
}