> ## Documentation Index
> Fetch the complete documentation index at: https://sunpeak.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Apps ontoolresult - Tool Execution Result

> Handle the result of a tool execution sent by the host. Use ontoolresult to render output, detect errors, and access structured content for UI display.

<Badge color="green">MCP Apps SDK</Badge>

```ts theme={null}
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()`.

<Warning>
  Register handlers **before** calling `connect()` to avoid missing notifications during the initialization handshake.
</Warning>

## Signature

```ts theme={null}
app.ontoolresult = (params) => void;
```

## Parameters

<ResponseField name="params" type="CallToolResult">
  Standard MCP tool execution result containing the following fields:
</ResponseField>

<ResponseField name="params.content" type="ContentBlock[]">
  Text content blocks intended for model context.
</ResponseField>

<ResponseField name="params.structuredContent" type="Record<string, unknown>">
  Structured data optimized for UI rendering. Use this for displaying rich results in your app.
</ResponseField>

<ResponseField name="params.isError" type="boolean">
  Whether the tool returned an error. When `true`, `content` contains error details.
</ResponseField>

<ResponseField name="params._meta" type="object">
  Optional metadata attached to the result (for example a `progressToken` or a related-task reference). Fields here are protocol-level and host-defined; do not assume application fields unless your server sets them.
</ResponseField>

## Usage

### Handling success and error states

```ts theme={null}
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

```ts theme={null}
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 with the sunpeak framework

The sunpeak framework provides the [`useToolData`](/app-framework/hooks/use-tool-data) hook, which wraps `ontoolresult` (along with related handlers) into a reactive value for React components.

```ts theme={null}
import { useToolData } from "sunpeak";

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

## Related

* [Event Handlers overview](/mcp-apps/app/event-handlers) -- all notification and request handlers
* [ontoolinput](/mcp-apps/app/event-handlers/ontoolinput) -- receive complete tool arguments before the result
