mcpPlugin
Install an MCP (Model Context Protocol) endpoint so AI assistants can call your API as tools.
Serve an MCP (Model Context Protocol) endpoint as part of your API. Declare it on new Kizuna(), pass mcpPluginServer() to server.api, and api.mount serves it, on every adapter.
pnpm add @ts-kizuna/mcpbun add @ts-kizuna/mcpnpm install @ts-kizuna/mcpimport { mcpPlugin } from '@ts-kizuna/mcp';
import { mcpPluginServer } from '@ts-kizuna/mcp/server';Parameters
mcpPlugin(props?: McpPluginProps): PluginDeclaration
mcpPluginServer(): PluginImplementation| Parameter | Type | Required | Description |
|---|---|---|---|
props | McpPluginProps | No | Configuration options |
Props
| Option | Default | Description |
|---|---|---|
path | '/mcp' | Path the endpoint is served from |
name | 'MCP Server' | Human-readable name shown to AI assistants |
version | '1.0.0' | Semantic version string |
routeFilter | excludes multipart | Predicate to filter which routes become tools |
Props are pure data, because they reach the contract and the contract reaches your client. The MCP SDK lives in mcpPluginServer(), which takes nothing: declaring the plugin is where it is configured.
Example
import { Kizuna } from '@ts-kizuna/core';
import { mcpPlugin } from '@ts-kizuna/mcp';
export const k = new Kizuna({
tags,
identities,
plugins: {
mcp: mcpPlugin({
name: 'My API',
}),
},
});import { mcpPluginServer } from '@ts-kizuna/mcp/server';
export const api = server.api({
router,
plugins: {
mcp: mcpPluginServer(),
},
});api.mount(app);Two halves
@ts-kizuna/mcp declares the path and the tool settings, as data on your contract. @ts-kizuna/mcp/server holds the endpoint and the MCP SDK. Miss the second half and server.api throws, naming the module to import. See Plugins.
Next.js
The endpoint is served by the catch-all route file that already serves your contract, so path resolves under its basePath:
export const { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS } = api.mount({
basePath: '/api',
});With the default path, the endpoint is at /api/mcp.
Secured routes
Each tool call runs the same guard pipeline as an HTTP request, reading credentials from the MCP transport request's headers. A deny(...) becomes a tool error result. See the MCP guide for configuring clients to send credentials.
Not in your client
The endpoint is a plugin route, so it lives outside contract.routes. Your fetch client, OpenAPI document and generated Swift and Kotlin clients never see it.
See also
- MCP guide
createMcpServerto drive the transport yourself- Create a Plugin