MCP
defineMcpHandler(options)
Define an H3 event handler that implements the Model Context Protocol (MCP) over HTTP using JSON-RPC 2.0 as the wire format.
Supports MCP methods: initialize, ping, tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get, and notifications/initialized.
Example:
app.all(
"/mcp",
defineMcpHandler({
name: "my-server",
version: "1.0.0",
tools: [echoTool],
resources: [readmeResource],
prompts: [greetPrompt],
}),
);
Example:
// Dynamic options based on request context
app.all(
"/mcp",
defineMcpHandler((event) => ({
name: "my-server",
version: "1.0.0",
tools: getToolsForUser(event),
})),
);
defineMcpPrompt(definition)
Define an MCP prompt with optional arguments and a handler that returns messages.
Example:
// Prompt with arguments
const greetPrompt = defineMcpPrompt({
name: "greet",
description: "Generate a greeting",
args: [{ name: "name", required: true }],
handler: async (args, event) => ({
messages: [
{ role: "user", content: { type: "text", text: `Hello ${args.name}!` } },
],
}),
});
Example:
// Prompt without arguments
const helpPrompt = defineMcpPrompt({
name: "help",
description: "Show help information",
handler: async (event) => ({
messages: [
{ role: "user", content: { type: "text", text: "How can I help?" } },
],
}),
});
defineMcpResource(definition)
Define an MCP resource with a static URI and a handler that returns its contents.
Example:
const readmeResource = defineMcpResource({
name: "readme",
uri: "file:///readme",
description: "Project README",
mimeType: "text/markdown",
handler: async (uri, event) => ({
contents: [{ uri: uri.toString(), text: "# My Project" }],
}),
});
defineMcpTool(definition)
Define an MCP tool with a name, optional JSON Schema input, and a handler function.
Example:
// Tool with input parameters
const echoTool = defineMcpTool({
name: "echo",
description: "Echo back a message",
inputSchema: {
type: "object",
properties: { message: { type: "string" } },
required: ["message"],
},
handler: async (args, event) => ({
content: [{ type: "text", text: args.message as string }],
}),
});
Example:
// Tool without input parameters
const pingTool = defineMcpTool({
name: "ping",
description: "Returns pong",
handler: async (event) => ({
content: [{ type: "text", text: "pong" }],
}),
});
createJsonRpcError(id, code, message, data?)
Creates a JSON-RPC error response object.
createMethodMap(methods)
Build a null-prototype lookup map to prevent prototype pollution. This ensures that method names like "proto", "constructor", "toString", "hasOwnProperty", etc. cannot resolve to inherited Object.prototype properties.
defineJsonRpcHandler()
Creates an H3 event handler that implements the JSON-RPC 2.0 specification.
Example:
app.post(
"/rpc",
defineJsonRpcHandler({
methods: {
echo: ({ params }, event) => {
return `Received \`${params}\` on path \`${event.url.pathname}\``;
},
sum: ({ params }, event) => {
return params.a + params.b;
},
},
}),
);
defineJsonRpcWebSocketHandler()
Creates an H3 event handler that implements JSON-RPC 2.0 over WebSocket.
This is an opt-in feature that allows JSON-RPC communication over WebSocket connections for bi-directional messaging. Each incoming WebSocket text message is processed as a JSON-RPC request, and responses are sent back to the peer.
Example:
app.get(
"/rpc/ws",
defineJsonRpcWebSocketHandler({
methods: {
echo: ({ params }) => {
return `Received: ${Array.isArray(params) ? params[0] : params?.message}`;
},
sum: ({ params }) => {
return params.a + params.b;
},
},
}),
);
Example:
// With additional WebSocket hooks
app.get(
"/rpc/ws",
defineJsonRpcWebSocketHandler({
methods: {
greet: ({ params }) => `Hello, ${params.name}!`,
},
hooks: {
open(peer) {
console.log(`Peer connected: ${peer.id}`);
},
close(peer, details) {
console.log(`Peer disconnected: ${peer.id}`, details);
},
},
}),
);
processJsonRpcBody(body, methodMap, context)
Validates and processes a parsed JSON-RPC body (single or batch).