Skip to main content
Tools let a model call server-side code. Give each tool a focused description, validate its input, declare its behavioral annotations, and return an official MCP CallToolResult.

Register a tool

inputSchema accepts a Standard Schema implementation that can produce JSON Schema. Zod is one option; ArkType and Valibot are also supported.
Field descriptions become hints for clients and models. The schema validates input before the callback runs and supplies the callback’s inferred TypeScript type.

Add tool icons

Set icons on the tool definition to advertise artwork on tools/list. The field uses the exported MCP Icon type: src, optional mimeType, optional sizes, and optional theme ("light" or "dark"). The SDK preserves icon order and these fields.
Put local files under public/ and use a path relative to that directory. For HTTP requests, the SDK emits an absolute URL under <basePath>/_mcp-use/public/. Absolute HTTP(S) and image data URLs pass through unchanged. Tools mounted with server.proxy() retain their upstream icons. Omit icons to leave the tool without its own artwork; an explicit empty array stays empty. Server constructor icons continues to describe server branding. For ChatGPT launchers, add icons directly to the entrypoint tool and follow the entrypoint icon guide.

Return structured output

Declare outputSchema when clients need a typed structured result. Every successful result from a schema-backed tool must include matching structuredContent. An error result may instead set isError: true.
Prefer raw results:

Bind a View

Export the tool reference from the server entry so mcp-env.d.ts can expose its input and output types to View code. Place the React entry at views/<name>/view.tsx, set view.name to that directory name, and return its data in structuredContent.
A view-bound tool must declare outputSchema, and one View can bind to only one tool. The view reads the structured data while the model reads content.

Tool listing metadata

The server derives UI metadata in tools/list from a tool’s view and visibility fields. Author-supplied _meta is preserved except for these framework-owned keys:
  • If the tool declares a view, the server sets both _meta.ui.resourceUri and the legacy _meta["ui/resourceUri"] to that View’s URI. Without a view, it removes both keys, even if _meta supplied them.
  • If the tool declares visibility: "model" or visibility: "app", the server sets _meta.ui.visibility to a one-item array containing that value. Without top-level visibility, it removes an author-supplied _meta.ui.visibility.
Other _meta keys, including other properties inside _meta.ui, pass through. Set view or top-level visibility when you need these UI fields in the tool listing; setting their wire keys directly in _meta does not preserve them.

Use request context

The second callback argument is scoped to the current request. It includes an abort signal, client-reported capability metadata, progress and logging methods, and the originating Hono request when HTTP context exists.
Client metadata is self-reported and must not be used for authorization. ctx.auth is available only when the server has an OAuth provider; use its verified provider user for access control. On a server with mixedAuth: true, a tool’s securitySchemes field marks it public (noauth), optional (noauth and oauth2), or sign-in with extra scopes; see Mixed Authentication.

Notify tool-list listeners

Publish a tool-list invalidation when the tools clients can discover have changed:
Clients with an active subscription listener can then request tools/list again. This notification does not register or replace tools; register tools while constructing the server, before it starts handling requests.

Test tools

Run mcp-use dev, open the built-in inspector, and test valid inputs, schema failures, error results, and structured output:
For view-bound tools, also verify that the View renders the returned structuredContent.