### Fastify MCP Server Quick Start (TypeScript) Source: https://github.com/platformatic/mcp/blob/main/README.md Demonstrates how to set up a Fastify server and register the @platformatic/mcp plugin. It includes examples of adding tools, resources, and prompts with their respective handlers and schemas. ```typescript import Fastify from 'fastify' import mcpPlugin from '@platformatic/mcp' // Or use named import: // import { mcpPlugin } from '@platformatic/mcp' const app = Fastify({ logger: true }) // Register the MCP plugin await app.register(mcpPlugin, { serverInfo: { name: 'my-mcp-server', version: '1.0.0' }, capabilities: { tools: { listChanged: true }, resources: { subscribe: true }, prompts: {} }, instructions: 'This server provides custom tools and resources' }) // Add tools, resources, and prompts with handlers app.mcpAddTool({ name: 'calculator', description: 'Performs basic arithmetic operations', inputSchema: { type: 'object', properties: { operation: { type: 'string', enum: ['add', 'subtract', 'multiply', 'divide'] }, a: { type: 'number' }, b: { type: 'number' } }, required: ['operation', 'a', 'b'] } }, async (params) => { const { operation, a, b } = params let result switch (operation) { case 'add': result = a + b; break case 'subtract': result = a - b; break case 'multiply': result = a * b; break case 'divide': result = a / b; break default: throw new Error('Invalid operation') } return { content: [{ type: 'text', text: `Result: ${result}` }] } }) app.mcpAddResource({ uri: 'file://config.json', name: 'Application Config', description: 'Server configuration file', mimeType: 'application/json' }, async (uri, context) => { // Read and return the configuration file const config = { setting1: 'value1', setting2: 'value2' } return { contents: [{ uri, text: JSON.stringify(config, null, 2), mimeType: 'application/json' }] } }) app.mcpAddPrompt({ name: 'code-review', description: 'Generates code review comments', arguments: [{ name: 'language', description: 'Programming language', required: true }] }, async (name, args, context) => { const language = args?.language || 'javascript' return { messages: [{ role: 'user', content: { type: 'text', text: `Please review this ${language} code for best practices, potential bugs, and improvements.` } }] } }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Run Stdio Server API Function Source: https://github.com/platformatic/mcp/blob/main/examples/README-stdio.md Starts a Fastify MCP server in stdio mode. It takes a Fastify instance and optional options for input, output, error streams, and debug logging. Dependencies include a Fastify instance with the MCP plugin registered. ```javascript // Function signature for documentation purposes // async function runStdioServer(app, options) // Parameters: // - app: Fastify instance with MCP plugin registered // - options: Optional stdio transport options // - debug: Enable debug logging to stderr (default: false) // - input: Custom input stream (default: process.stdin) // - output: Custom output stream (default: process.stdout) // - error: Custom error stream (default: process.stderr) ``` -------------------------------- ### Run Stdio Server Example Source: https://github.com/platformatic/mcp/blob/main/examples/README-stdio.md Executes the example Fastify MCP server over stdio transport using Node.js. Requires experimental flags and disables warnings. No specific inputs or outputs are defined for this execution command. ```bash node --experimental-strip-types --no-warnings examples/stdio-server.ts ``` -------------------------------- ### Stdio Transport for CLI Integration Source: https://context7.com/platformatic/mcp/llms.txt This section details how to run the MCP server over stdio, enabling integration with command-line clients. It includes a TypeScript example demonstrating the setup and how to add a simple 'echo' tool. ```APIDOC ## Stdio Transport for CLI Integration ### Description Run MCP server over stdio for command-line clients. ### Method N/A (This describes a server setup, not a specific HTTP request) ### Endpoint N/A (stdio communication) ### Parameters N/A ### Request Example ```bash echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}},"id":1}' | node server.js ``` ### Response N/A (Output is streamed via stdio) ``` -------------------------------- ### Create Custom Stdio Server with Fastify MCP Source: https://github.com/platformatic/mcp/blob/main/examples/README-stdio.md Creates a custom Fastify MCP server that runs over stdio transport. It registers the MCP plugin, adds a custom tool, and then starts the stdio server. Dependencies include 'fastify' and '@platformatic/mcp'. ```typescript import fastify from 'fastify' import mcpPlugin from '../src/index.ts' import { runStdioServer } from '../src/stdio.ts' // Create a Fastify server const app = fastify({ logger: false // Disable HTTP logging to avoid interference with stdio }) // Register the MCP plugin await app.register(mcpPlugin, { serverInfo: { name: 'my-mcp-server', version: '1.0.0' }, capabilities: { tools: {}, resources: {}, prompts: {} } }) // Register your tools, resources, and prompts app.mcpAddTool({ name: 'my-tool', description: 'My custom tool', inputSchema: { type: 'object', properties: { input: { type: 'string' } } } }, async (args) => { return { content: [{ type: 'text', text: `Processed: ${args.input}` }] } }) // Wait for the server to be ready await app.ready() // Start the stdio transport await runStdioServer(app, { debug: process.env.DEBUG === 'true' }) ``` -------------------------------- ### Create Stdio Transport API Function Source: https://github.com/platformatic/mcp/blob/main/examples/README-stdio.md Creates a stdio transport instance for Fastify MCP without starting it immediately. It returns an object with `start()` and `stop()` methods. Dependencies include a Fastify instance with the MCP plugin registered. ```javascript // Function signature for documentation purposes // function createStdioTransport(app, options) // Parameters: // - app: Fastify instance with MCP plugin registered // - options: Optional stdio transport options // Returns: StdioTransport instance with start() and stop() methods ``` -------------------------------- ### MCP Stdio Transport Initialization Example (Bash) Source: https://github.com/platformatic/mcp/blob/main/README.md Example of how to initialize an MCP server running with stdio transport from the command line. It sends an 'initialize' JSON-RPC request to the server process via stdin. ```bash # Initialize the server echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0.0"}}}' | node server.js ``` -------------------------------- ### Example HTTP GET Request with Access Token Source: https://github.com/platformatic/mcp/blob/main/spec/authorization.md An example HTTP GET request to an MCP server, demonstrating the correct placement of the 'Authorization: Bearer' header. This follows OAuth 2.1 Section 5.1.1 requirements. ```http GET /mcp HTTP/1.1 Host: mcp.example.com Authorization: Bearer eyJhbGciOiJIUzI1NiIs... ``` -------------------------------- ### OAuth 2.1 Authorization Setup and Usage (TypeScript) Source: https://context7.com/platformatic/mcp/llms.txt Demonstrates how to protect MCP endpoints using OAuth 2.1 authorization. It includes registering the MCP plugin with authorization configuration and accessing authorization context within tool handlers to verify user identity and permissions. Also shows an example of making authorized requests. ```typescript await app.register(mcpPlugin, { serverInfo: { name: 'secure-server', version: '1.0.0' }, capabilities: { tools: {} }, enableSSE: true, authorization: { enabled: true, authorizationServers: ['https://auth.example.com'], resourceUri: 'https://api.example.com', tokenValidation: { jwksUri: 'https://auth.example.com/.well-known/jwks.json', introspectionEndpoint: 'https://auth.example.com/introspect', validateAudience: true } } }) // Access authorization context in handlers app.mcpAddTool({ name: 'get_user_info', description: 'Get current user information', inputSchema: Type.Object({}) // Assuming an empty schema for simplicity }, async (params, context) => { const auth = context.authContext if (!auth?.userId) { return { content: [{ type: 'text', text: 'Unauthorized' }], isError: true } } return { content: [{ type: 'text', text: `User: ${auth.userId}\nScopes: ${auth.scopes?.join(', ')}\nExpires: ${auth.expiresAt}` }] } }) // Making authorized requests (client-side) // curl -X POST http://localhost:3000/mcp \ // -H "Authorization: Bearer " \ // -H "Content-Type: application/json" \ // -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_user_info"},"id":1}' ``` -------------------------------- ### Elicitation Response Examples (JSON) Source: https://github.com/platformatic/mcp/blob/main/spec/elicitation.md Examples of responses to an elicitation request. This includes accepting the request with provided content, declining it, or canceling the process. ```json { "jsonrpc": "2.0", "id": 1, "result": { "action": "accept", "content": { "name": "octocat" } } } ``` ```json { "jsonrpc": "2.0", "id": 2, "result": { "action": "decline" } } ``` ```json { "jsonrpc": "2.0", "id": 2, "result": { "action": "cancel" } } ``` -------------------------------- ### Install Fastify MCP Server Plugin Source: https://github.com/platformatic/mcp/blob/main/README.md Installs the core @platformatic/mcp package using npm. This is the primary dependency for setting up the MCP server. ```bash npm install @platformatic/mcp ``` -------------------------------- ### Run MCP Server over Stdio for CLI Integration (TypeScript) Source: https://context7.com/platformatic/mcp/llms.txt Starts an MCP server that communicates over standard input/output, enabling integration with command-line interfaces and tools like the MCP Inspector. It registers an 'echo' tool for demonstration. Dependencies include 'fastify' and '@platformatic/mcp'. ```typescript import Fastify from 'fastify' import mcpPlugin, { runStdioServer } from '@platformatic/mcp' const app = Fastify() await app.register(mcpPlugin, { serverInfo: { name: 'stdio-server', version: '1.0.0' }, capabilities: { tools: {} } }) app.mcpAddTool({ name: 'echo', description: 'Echo back the input', inputSchema: Type.Object({ message: Type.String() }) }, async (params) => ({ content: [{ type: 'text', text: params.message }] })) // Start stdio transport await runStdioServer(app, { debug: false }) // Use with MCP Inspector or stdio client: // echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}},"id":1}' | node server.js ``` -------------------------------- ### Test Stdio Server with JSON-RPC Source: https://github.com/platformatic/mcp/blob/main/examples/README-stdio.md Sends JSON-RPC messages to the stdio server via stdin to test its functionality. Includes initialization, ping, listing tools, and calling a tool. Outputs are server responses to stdout. ```bash # Initialize the server echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0.0"}}}' | node --experimental-strip-types --no-warnings examples/stdio-server.ts # Ping the server echo '{"jsonrpc":"2.0","id":2,"method":"ping"}' | node --experimental-strip-types --no-warnings examples/stdio-server.ts # List available tools echo '{"jsonrpc":"2.0","id":3,"method":"tools/list"}' | node --experimental-strip-types --no-warnings examples/stdio-server.ts # Call the echo tool echo '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"echo","arguments":{"text":"Hello, stdio!"}}}' | node --experimental-strip-types --no-warnings examples/stdio-server.ts ``` -------------------------------- ### runStdioServer API Source: https://github.com/platformatic/mcp/blob/main/README.md Starts a Fastify MCP server in stdio mode. ```APIDOC ## `runStdioServer(app, options)` ### Description Starts a Fastify MCP server in stdio mode. ### Parameters - `app` - Fastify instance with MCP plugin registered - `options` - Optional stdio transport options ### Options - `debug` - Enable debug logging to stderr (default: false) - `input` - Custom input stream (default: process.stdin) - `output` - Custom output stream (default: process.stdout) - `error` - Custom error stream (default: process.stderr) ``` -------------------------------- ### Run Stdio Transport Tests Source: https://github.com/platformatic/mcp/blob/main/examples/README-stdio.md Executes the comprehensive tests for the Fastify MCP stdio transport. This includes unit tests, integration tests with subprocess servers, and tests for error handling and batch requests. ```bash npm test ``` -------------------------------- ### JSON-RPC Message Processing Source: https://context7.com/platformatic/mcp/llms.txt Provides examples of how to send JSON-RPC requests to MCP endpoints using `curl`. Covers initialization, listing tools, calling tools, and batch requests. ```APIDOC ## JSON-RPC Message Processing ### Description Send JSON-RPC requests to MCP endpoints. ### Method POST ### Endpoint `/mcp` ### Parameters N/A #### Request Body - **jsonrpc** (string) - Required - Specifies the JSON-RPC version (e.g., "2.0"). - **method** (string) - Required - The name of the method to call (e.g., "initialize", "tools/list", "tools/call"). - **params** (object) - Optional - Parameters for the method. - **id** (number | string) - Required - An identifier for the request. ### Request Example #### Initialize Connection ```bash curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "initialize", "params": { "protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": { "name": "curl-client", "version": "1.0.0" } }, "id": 1 }' ``` #### List Available Tools ```bash curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "tools/list", "id": 2 }' ``` #### Call a Tool ```bash curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "calculate", "arguments": { "operation": "add", "a": 5, "b": 3 } }, "id": 3 }' ``` #### Batch Request ```bash curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '[ {"jsonrpc": "2.0", "method": "tools/list", "id": 1}, {"jsonrpc": "2.0", "method": "resources/list", "id": 2}, {"jsonrpc": "2.0", "method": "prompts/list", "id": 3} ]' ``` ### Response #### Success Response (200) - **jsonrpc** (string) - The JSON-RPC version. - **result** (any) - The result of the method call. - **id** (number | string) - The identifier for the request. #### Error Response - **jsonrpc** (string) - The JSON-RPC version. - **error** (object) - An object containing error information. - **code** (number) - The error code. - **message** (string) - A short description of the error. - **data** (any) - Optional, additional error details. - **id** (number | string) - The identifier for the request. ``` -------------------------------- ### Run Stdio Server with Fastify MCP Plugin Source: https://github.com/platformatic/mcp/blob/main/README.md Starts a Fastify MCP server in stdio mode using the `runStdioServer` function. It requires a Fastify instance with the MCP plugin registered and accepts optional configuration for input, output, and error streams. ```javascript import Fastify from 'fastify'; import { runStdioServer } from '@platformatic/mcp'; const app = Fastify({ logger: true }); // Register MCP plugin and then run stdio server await app.register(mcpPlugin, { /* ... options ... */ }); await runStdioServer(app, { /* ... stdio options ... */ }); ``` -------------------------------- ### MCP Client Workflow (POST/GET) Source: https://github.com/platformatic/mcp/blob/main/README.md Demonstrates a complete client-side workflow for interacting with the MCP API. This includes initializing a session via POST, establishing an SSE stream for notifications via GET, and making subsequent MCP requests via POST. ```APIDOC ## MCP Client Workflow ### Description This workflow illustrates how a client can interact with the MCP API. It begins with initializing a session, then sets up a stream for real-time updates, and finally proceeds with making further requests. ### Method POST ### Endpoint /mcp ### Parameters #### Request Body - **jsonrpc** (string) - Required - Specifies the JSON-RPC version. - **method** (string) - Required - The method to be called (e.g., 'initialize', 'tools/call'). - **params** (object) - Optional - Parameters for the method. - **id** (number or string) - Required - The ID of the request. ### Request Example (Initialize) ```json { "jsonrpc": "2.0", "method": "initialize", "params": { "protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": { "name": "my-client", "version": "1.0.0" } }, "id": 1 } ``` ### Response #### Success Response (200) - **mcp-session-id** (string) - Header - The session ID for subsequent requests. --- ### Method GET ### Endpoint /mcp ### Parameters #### Headers - **Accept** (string) - Required - Must be 'text/event-stream'. - **mcp-session-id** (string) - Required - The session ID obtained from the POST request. ### Description Establishes a Server-Sent Events (SSE) stream to receive real-time notifications and updates from the server. --- ### Method POST ### Endpoint /mcp ### Parameters #### Headers - **Content-Type** (string) - Required - Must be 'application/json'. - **Accept** (string) - Required - Must be 'application/json'. - **mcp-session-id** (string) - Required - The session ID. #### Request Body - **jsonrpc** (string) - Required - Specifies the JSON-RPC version. - **method** (string) - Required - The method to be called (e.g., 'tools/call'). - **params** (object) - Optional - Parameters for the method. - **id** (number or string) - Required - The ID of the request. ### Request Example (Tool Call) ```json { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "my-tool", "arguments": {} }, "id": 2 } ``` ### Response #### Success Response (200) - **jsonrpc** (string) - The JSON-RPC version. - **result** (any) - The result of the method call. - **id** (number or string) - The ID of the request. ``` -------------------------------- ### Example Initialization Error in MCP Source: https://github.com/platformatic/mcp/blob/main/spec/lifecycle.md Illustrates a common error response during MCP initialization, specifically a protocol version mismatch. This JSON object details the error code, a descriptive message, and data indicating supported and requested protocol versions. ```json { "jsonrpc": "2.0", "id": 1, "error": { "code": -32602, "message": "Unsupported protocol version", "data": { "supported": ["2024-11-05"], "requested": "1.0.0" } } } ``` -------------------------------- ### Broadcast Notifications to All Sessions (TypeScript) Source: https://context7.com/platformatic/mcp/llms.txt Enables broadcasting notifications to all connected SSE clients, ensuring all active sessions receive updates. It also shows an example of dynamic tool registration followed by a broadcast to inform clients about changes in the tool list. ```typescript // Broadcast a notification to all sessions await app.mcpBroadcastNotification({ jsonrpc: '2.0', method: 'notifications/tools/list_changed', params: {} }) // Example: Dynamic tool registration with broadcast app.post('/admin/tools', async (request, reply) => { const { name, description, schema, handler } = request.body // Register new tool dynamically app.mcpAddTool({ name, description, inputSchema: schema }, handler) // Notify all clients that tool list changed await app.mcpBroadcastNotification({ jsonrpc: '2.0', method: 'notifications/tools/list_changed' }) return { success: true, tool: name } }) ``` -------------------------------- ### Install and Configure Bearer Auth for MCP Source: https://github.com/platformatic/mcp/blob/main/README.md Installs the @fastify/bearer-auth plugin and configures it to secure MCP routes. It specifies how to extract tokens from the Authorization header and provides an example of making an authenticated fetch request. ```bash npm install @fastify/bearer-auth ``` ```typescript import Fastify from 'fastify' import mcpPlugin from '@platformatic/mcp' const app = Fastify({ logger: true }) // Register bearer authentication await app.register(import('@fastify/bearer-auth'), { keys: new Set(['your-secret-bearer-token']), auth: { // Apply to all routes matching this prefix extractToken: (request) => { return request.headers.authorization?.replace('Bearer ', '') } } }) // Register MCP plugin (routes will inherit authentication) await app.register(mcpPlugin, { // ... your configuration }) // Usage with authentication fetch('/mcp', { method: 'POST', headers: { 'Authorization': 'Bearer your-secret-bearer-token', 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', method: 'ping', id: 1 }) }) ``` -------------------------------- ### Register Resource with URI Patterns for File Reading (TypeScript) Source: https://context7.com/platformatic/mcp/llms.txt Shows how to register a resource for MCP clients to read using `app.mcpAddResource`. This example defines a URI schema pattern for reading files and implements a handler that reads file content from the filesystem based on a provided path parameter in the URI. ```typescript import { Type } from '@sinclair/typebox' import { promises as fs } from 'fs' import { join } from 'path' // Define URI schema pattern const FileUriSchema = Type.String({ pattern: '^file://read\?path=.+', description: 'URI pattern for file reading with path parameter' }) // Register resource with handler app.mcpAddResource({ uriPattern: 'file://read', name: 'Read File', description: 'Read the contents of a file from the filesystem', mimeType: 'text/plain', uriSchema: FileUriSchema }, async (uri, context) => { const url = new URL(uri) const filePath = url.searchParams.get('path') if (!filePath) { return { contents: [{ uri, text: 'Error: No file path specified. Use ?path=', mimeType: 'text/plain' }] } } try { const fullPath = join(process.cwd(), filePath) const content = await fs.readFile(fullPath, 'utf-8') const stats = await fs.stat(fullPath) return { contents: [{ uri, text: content, mimeType: 'text/plain' }] } } catch (error) { return { contents: [{ uri, text: `Error reading file: ${error.message}`, mimeType: 'text/plain' }] } } }) ``` -------------------------------- ### Prompt Registration API Source: https://context7.com/platformatic/mcp/llms.txt Register prompt templates with argument schemas for use within the MCP system. ```APIDOC ## POST /platformatic/mcp/prompts ### Description Registers a new prompt template with a specified name, description, and argument schema. This allows for structured input when generating prompts. ### Method POST ### Endpoint /platformatic/mcp/prompts ### Parameters #### Request Body - **name** (string) - Required - The unique name for the prompt template. - **description** (string) - Required - A brief description of the prompt's purpose. - **argumentSchema** (object) - Required - A TypeBox schema defining the expected arguments for the prompt. ### Request Example ```json { "name": "code_review", "description": "Generate a code review prompt for a specific language", "argumentSchema": { "type": "object", "properties": { "language": { "type": "string", "description": "Programming language", "enum": ["javascript", "typescript", "python", "go", "rust"] }, "context": { "type": "string", "description": "Additional context for the review" } }, "required": ["language"] } } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message indicating successful registration. #### Response Example ```json { "message": "Prompt 'code_review' registered successfully." } ``` ``` -------------------------------- ### Install TypeBox for Optional Type Support Source: https://github.com/platformatic/mcp/blob/main/README.md Installs the @sinclair/typebox package, which is optional but recommended for enabling type-safe schema validation and automatic TypeScript inference within the MCP server. ```bash npm install @sinclair/typebox ``` -------------------------------- ### Elicitation Requests API Source: https://context7.com/platformatic/mcp/llms.txt Demonstrates how to request additional information from users via the client using `mcpElicit`. This is useful for interactive confirmation or gathering specific details during a process. ```APIDOC ## Elicitation Requests ### Description Request additional information from users via the client. ### Method N/A (This describes a server-side API for eliciting client input) ### Endpoint N/A (Internal API call within the server) ### Parameters N/A ### Request Example ```typescript // Example of calling mcpElicit within a tool handler const sent = await app.mcpElicit( sessionId, `Confirm deployment to ${params.environment}?`, { type: 'object', properties: { confirmed: { type: 'boolean', title: 'Confirm Deployment', description: 'Check to confirm deployment' }, reason: { type: 'string', title: 'Reason', description: 'Reason for deployment' } }, required: ['confirmed'] } ) ``` ### Response N/A (The result of the elicitation is returned to the tool handler that called `mcpElicit`) ``` -------------------------------- ### Structured Error Handling Example Source: https://github.com/platformatic/mcp/blob/main/README.md Illustrates the structured error messages returned by TypeBox validation when a request fails. The example shows a JSON RPC response with an `isError` flag and detailed content describing the validation failures, including specific paths and expected/received types. ```json { "jsonrpc": "2.0", "id": 1, "result": { "isError": true, "content": [{ "type": "text", "text": "Invalid tool arguments: Validation failed with 2 errors:\n/query: Expected string, received number\n/limit: Expected number <= 100, received 150" }] } } ``` -------------------------------- ### Interact with MCP Endpoints using JSON-RPC (Bash) Source: https://context7.com/platformatic/mcp/llms.txt Demonstrates how to send JSON-RPC requests to MCP endpoints using `curl`. It covers initializing a connection, listing tools, calling a tool ('calculate'), and sending batch requests. This is useful for scripting and testing MCP integrations. ```bash # Initialize connection curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "initialize", "params": { "protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": { "name": "curl-client", "version": "1.0.0" } }, "id": 1 }' # List available tools curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "tools/list", "id": 2 }' # Call a tool curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "calculate", "arguments": { "operation": "add", "a": 5, "b": 3 } }, "id": 3 }' # Batch request curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '[ {"jsonrpc": "2.0", "method": "tools/list", "id": 1}, {"jsonrpc": "2.0", "method": "resources/list", "id": 2}, {"jsonrpc": "2.0", "method": "prompts/list", "id": 3} ]' ``` -------------------------------- ### Deploy Multiple MCP Server Instances Source: https://github.com/platformatic/mcp/blob/main/README.md This example shows how to run multiple instances of the MCP server by setting environment variables for the port and Redis host. This approach leverages Redis for shared state, enabling horizontal scaling. No specific code dependencies are listed, but 'server.js' is assumed to be the entry point for the application. ```bash # Instance 1 PORT=3000 REDIS_HOST=redis.example.com node server.js # Instance 2 PORT=3001 REDIS_HOST=redis.example.com node server.js # Instance 3 PORT=3002 REDIS_HOST=redis.example.com node server.js ``` -------------------------------- ### Create Stdio Transport Instance Source: https://github.com/platformatic/mcp/blob/main/README.md Creates a stdio transport instance for a Fastify MCP server without immediately starting it. This allows for manual control over the transport's lifecycle using `start()` and `stop()` methods. It requires a Fastify instance with the MCP plugin registered. ```javascript import Fastify from 'fastify'; import { createStdioTransport } from '@platformatic/mcp'; const app = Fastify({ logger: true }); await app.register(mcpPlugin, { /* ... options ... */ }); const transport = createStdioTransport(app, { /* ... stdio options ... */ }); // Start and stop the transport manually await transport.start(); // ... await transport.stop(); ``` -------------------------------- ### Testing Authorization Source: https://github.com/platformatic/mcp/blob/main/README.md Examples of how to test the authorization functionality of the MCP plugin. ```APIDOC ## Testing Authorization ### Description Provides examples for testing the authorization mechanisms, including successful requests with valid tokens and handling authorization failures. ### Request Example ```typescript // Test with valid token const response = await app.inject({ method: 'POST', url: '/mcp', headers: { 'Authorization': 'Bearer valid-jwt-token', 'Content-Type': 'application/json' }, payload: { jsonrpc: '2.0', method: 'tools/list', id: 1 } }) // Test authorization failure const unauthorized = await app.inject({ method: 'POST', url: '/mcp', payload: { jsonrpc: '2.0', method: 'tools/list', id: 1 } }) assert.strictEqual(unauthorized.statusCode, 401) ``` ``` -------------------------------- ### createStdioTransport API Source: https://github.com/platformatic/mcp/blob/main/README.md Creates a stdio transport instance without starting it. ```APIDOC ## `createStdioTransport(app, options)` ### Description Creates a stdio transport instance without starting it. ### Parameters - `app` - Fastify instance with MCP plugin registered - `options` - Optional stdio transport options ### Returns `StdioTransport` instance with `start()` and `stop()` methods ``` -------------------------------- ### Boolean Schema Example Source: https://github.com/platformatic/mcp/blob/main/spec/elicitation.md Defines a schema for boolean types, allowing for a default value to be specified. ```json { "type": "boolean", "title": "Display Name", "description": "Description text", "default": false } ``` -------------------------------- ### Elicit User Confirmation for Actions (TypeScript) Source: https://context7.com/platformatic/mcp/llms.txt Adds a tool ('deploy_application') that prompts the user for confirmation before proceeding with an action, using the `mcpElicit` function. It requires a session ID and handles confirmation responses. Dependencies include 'fastify' and '@platformatic/mcp'. ```typescript app.mcpAddTool({ name: 'deploy_application', description: 'Deploy application with user confirmation', inputSchema: Type.Object({ environment: Type.String({ enum: ['staging', 'production'] }) }) }, async (params, context) => { const sessionId = context.sessionId if (!sessionId) { return { content: [{ type: 'text', text: 'Session required' }], isError: true } } // Request user confirmation const sent = await app.mcpElicit( sessionId, `Confirm deployment to ${params.environment}?`, { type: 'object', properties: { confirmed: { type: 'boolean', title: 'Confirm Deployment', description: 'Check to confirm deployment' }, reason: { type: 'string', title: 'Reason', description: 'Reason for deployment' } }, required: ['confirmed'] } ) if (!sent) { return { content: [{ type: 'text', text: 'Failed to request confirmation' }], isError: true } } return { content: [{ type: 'text', text: 'Confirmation request sent. Check client for response.' }] } }) ``` -------------------------------- ### Number Schema Example Source: https://github.com/platformatic/mcp/blob/main/spec/elicitation.md Defines a schema for numeric types (number or integer), with validation for minimum and maximum allowed values. ```json { "type": "number", // or "integer" "title": "Display Name", "description": "Description text", "minimum": 0, "maximum": 100 } ``` -------------------------------- ### Enum Schema Example Source: https://github.com/platformatic/mcp/blob/main/spec/elicitation.md Defines a schema for string types with a restricted set of allowed values (enum) and corresponding display names. ```json { "type": "string", "title": "Display Name", "description": "Description text", "enum": ["option1", "option2", "option3"], "enumNames": ["Option 1", "Option 2", "Option 3"] } ``` -------------------------------- ### Redis-Backed Horizontal Scaling Source: https://context7.com/platformatic/mcp/llms.txt Details how to configure the MCP server for horizontal scaling using Redis for shared state, allowing multiple instances to communicate and maintain session consistency. ```APIDOC ## Redis-Backed Horizontal Scaling ### Description Deploy multiple instances with shared state. ### Method N/A (This describes server configuration, not a specific HTTP request) ### Endpoint N/A (Load balancer distributes requests across instances) ### Parameters #### MCP Plugin Options - **serverInfo** (object) - Required - Information about the server instance. - **name** (string) - Name of the server. - **version** (string) - Version of the server. - **enableSSE** (boolean) - Required - Enable Server-Sent Events. - **redis** (object) - Optional - Redis connection configuration. - **host** (string) - Redis server host. - **port** (number) - Redis server port. - **password** (string) - Redis authentication password. ### Request Example #### Instance 1 Configuration ```typescript const app1 = Fastify() await app1.register(mcpPlugin, { serverInfo: { name: 'server-1', version: '1.0.0' }, enableSSE: true, redis: { host: 'redis.example.com', port: 6379, password: 'secret' } }) await app1.listen({ port: 3001 }) ``` #### Instance 2 Configuration ```typescript const app2 = Fastify() await app2.register(mcpPlugin, { serverInfo: { name: 'server-2', version: '1.0.0' }, enableSSE: true, redis: { host: 'redis.example.com', port: 6379, password: 'secret' } }) await app2.listen({ port: 3002 }) ``` ### Response N/A (This configuration enables distributed communication and state sharing across instances.) ### Notes - Messages sent to one instance are received by sessions on other instances. - Session state is shared across all instances via Redis. - A load balancer can distribute incoming requests across the configured instances. ``` -------------------------------- ### String Schema Example Source: https://github.com/platformatic/mcp/blob/main/spec/elicitation.md Defines a schema for string types, including validation rules like min/max length and specific formats such as email or URI. ```json { "type": "string", "title": "Display Name", "description": "Description text", "minLength": 3, "maxLength": 50, "format": "email" // Supported: "email", "uri", "date", "date-time" } ``` -------------------------------- ### Client Workflow: Initialize, Stream, and Request MCP Data (JavaScript) Source: https://github.com/platformatic/mcp/blob/main/README.md Demonstrates the client-side workflow for interacting with an MCP server. It includes initializing a session via POST, establishing a Server-Sent Events (SSE) stream for notifications via GET, and making subsequent MCP requests using the session ID. ```javascript // 1. Create session and make MCP requests via POST const initResponse = await fetch('/mcp', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', method: 'initialize', params: { protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: 'my-client', version: '1.0.0' } }, id: 1 }) }) const sessionId = initResponse.headers.get('mcp-session-id') // 2. Establish SSE stream for notifications via GET const eventSource = new EventSource('/mcp', { headers: { 'Accept': 'text/event-stream', 'mcp-session-id': sessionId } }) // 3. Continue making MCP requests via POST const toolResponse = await fetch('/mcp', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'mcp-session-id': sessionId }, body: JSON.stringify({ jsonrpc: '2.0', method: 'tools/call', params: { name: 'my-tool', arguments: {} }, id: 2 }) }) // Server can send notifications via the SSE stream // while client makes requests via POST ``` -------------------------------- ### Resource Parameter in Authorization Request Source: https://github.com/platformatic/mcp/blob/main/spec/authorization.md Example of how the 'resource' parameter is included in an authorization request URL for MCP clients. This parameter explicitly identifies the target MCP server, following RFC 8707. ```url &resource=https%3A%2F%2Fmcp.example.com ``` -------------------------------- ### Resuming Broken Connections Source: https://github.com/platformatic/mcp/blob/main/spec/transports.md To handle disconnections, clients can resume SSE streams by including the `Last-Event-ID` header in their HTTP GET request. This allows the server to replay missed messages from the specific stream. ```APIDOC ## GET /platformatic/mcp (Resumption) ### Description When a client's SSE stream disconnects, it can attempt to resume the stream by issuing a new HTTP GET request to the MCP endpoint, including the `Last-Event-ID` header with the ID of the last received event. The server may then replay subsequent messages on that specific stream. ### Method GET ### Endpoint /platformatic/mcp ### Headers - **Accept** (string) - Required - Must include `text/event-stream`. - **Last-Event-ID** (string) - Required - The ID of the last event received by the client before disconnection. ### Response #### Success Response (Content-Type: text/event-stream) - The server may replay messages that were sent after the `Last-Event-ID` on the previously disconnected stream. The stream will resume from that point. #### Error Response (e.g., 404 Not Found) - May be returned if the server cannot fulfill the resumption request. ``` -------------------------------- ### Add Tool with Type-Safe Schemas to MCP Server (TypeScript) Source: https://context7.com/platformatic/mcp/llms.txt Illustrates how to add a tool to an MCP server using `app.mcpAddTool`. It includes defining a TypeBox schema for input validation and a handler function that performs a calculation based on the input parameters, returning structured content and handling potential errors. ```typescript import { Type } from '@sinclair/typebox' // Define a type-safe schema const CalculateSchema = Type.Object({ operation: Type.String({ description: 'Mathematical operation to perform', enum: ['add', 'subtract', 'multiply', 'divide'] }), a: Type.Number({ description: 'First operand' }), b: Type.Number({ description: 'Second operand' }) }) // Register the tool with handler app.mcpAddTool({ name: 'calculate', description: 'Perform basic mathematical operations', inputSchema: CalculateSchema }, async (params, context) => { const { operation, a, b } = params let result: number try { switch (operation) { case 'add': result = a + b; break case 'subtract': result = a - b; break case 'multiply': result = a * b; break case 'divide': if (b === 0) throw new Error('Division by zero') result = a / b break default: throw new Error(`Unknown operation: ${operation}`) } return { content: [{ type: 'text', text: `${a} ${operation} ${b} = ${result}` }], structuredContent: { result, operation, operands: [a, b] } } } catch (error) { return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true } } }) ``` -------------------------------- ### Production Security Configuration for Platformatic MCP Source: https://github.com/platformatic/mcp/blob/main/README.md Example TypeScript configuration for enabling token validation in a production environment. It specifies the JWKS URI for token verification and enables audience validation. ```typescript authorization: { enabled: true, tokenValidation: { jwksUri: 'https://auth.company.com/.well-known/jwks.json', validateAudience: true } } ```