diff --git a/docs/ADVANCED.md b/docs/ADVANCED.md index a51e385..4f59f3d 100644 --- a/docs/ADVANCED.md +++ b/docs/ADVANCED.md @@ -56,40 +56,99 @@ export { handler as GET, handler as POST, handler as DELETE }; ```typescript interface Config { - redisUrl?: string; // Redis connection URL for pub/sub - basePath?: string; // Base path for MCP endpoints + redisUrl?: string; // Redis connection URL for pub/sub + basePath?: string; // Base path for MCP endpoints maxDuration?: number; // Maximum duration for SSE connections (seconds) verboseLogs?: boolean; // Enable debug logging } ``` -## Nuxt Usage +## Elicitation + +Elicitation requires a bidirectional transport so the server can ask the client +for input while a tool is running. Use the SSE transport with Redis enabled and +export all three HTTP methods: ```typescript -// server/api/mcp/[transport].ts +// app/api/[transport]/route.ts import { createMcpHandler } from "mcp-handler"; -import { fromWebHandler } from "h3"; import { z } from "zod"; const handler = createMcpHandler( (server) => { server.registerTool( - "roll_dice", + "quote_product", { - title: "Roll Dice", - description: "Roll a dice with a specified number of sides.", - inputSchema: { sides: z.number().int().min(2) }, + title: "Quote Product", + description: "Ask the user which product should be quoted.", + inputSchema: {}, }, - async ({ sides }) => { - const value = 1 + Math.floor(Math.random() * sides); + async () => { + const result = await server.server.elicitInput({ + message: "Which product should be quoted?", + requestedSchema: { + type: "object", + properties: { + productName: { + type: "string", + title: "Product", + enum: ["starter", "pro", "enterprise"], + }, + }, + required: ["productName"], + }, + }); + + const productName = result.content?.productName; return { - content: [{ type: "text", text: `🎲 You rolled a ${value}!` }], + content: [ + { + type: "text", + text: `Creating a quote for ${productName}.`, + }, + ], }; } ); }, - {} + {}, + { + basePath: "/api", + redisUrl: process.env.REDIS_URL, + } ); +export { handler as GET, handler as POST, handler as DELETE }; +``` + +Clients must support elicitation. If a client only sends Streamable HTTP `POST` +requests and does not keep a server-to-client channel open, the server cannot +deliver the elicitation request. + +## Nuxt Usage + +```typescript +// server/api/mcp/[transport].ts +import { createMcpHandler } from "mcp-handler"; +import { fromWebHandler } from "h3"; +import { z } from "zod"; + +const handler = createMcpHandler((server) => { + server.registerTool( + "roll_dice", + { + title: "Roll Dice", + description: "Roll a dice with a specified number of sides.", + inputSchema: { sides: z.number().int().min(2) }, + }, + async ({ sides }) => { + const value = 1 + Math.floor(Math.random() * sides); + return { + content: [{ type: "text", text: `🎲 You rolled a ${value}!` }], + }; + } + ); +}, {}); + export default fromWebHandler(handler); ```