Skip to main content
Glama
README.md10.1 kB
# Elysia MCP Plugin > ⚠️ Under Development A comprehensive ElysiaJS plugin for implementing [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers with HTTP transport support. ## Features - **HTTP Transport**: Full HTTP-based MCP transport with Streamable HTTP - **Session Management**: Stateful session handling via headers - **Type-Safe**: Built with TypeScript and Zod validation - **Easy Integration**: Simple plugin architecture for Elysia apps - **Comprehensive Support**: Tools, Resources, Prompts, and Logging - **Custom Logger Support**: Use any logger (pino, winston, bunyan, etc.) - **Error Handling**: Proper JSON-RPC 2.0 error responses - **Testing**: Full unit test coverage with Bun test runner ## Installation ```bash bun add elysia-mcp # or npm install elysia-mcp ``` ## Starter Template To quickly get started with a pre-configured Elysia MCP project, you can use our starter template: ```bash # Create a new project from the starter template bun create https://github.com/kerlos/elysia-mcp-starter my-mcp-project # Navigate to the project cd my-mcp-project # Install dependencies bun install # Start development server bun run dev ``` The [elysia-mcp-starter](https://github.com/kerlos/elysia-mcp-starter) template includes: - Pre-configured Elysia setup with MCP plugin - TypeScript configuration - Development scripts - Basic project structure - Example MCP server implementation ## Quick Start ```typescript import { Elysia } from 'elysia'; import { mcp } from 'elysia-mcp'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; const app = new Elysia() .use( mcp({ serverInfo: { name: 'my-mcp-server', version: '1.0.0', }, capabilities: { tools: {}, resources: {}, prompts: {}, logging: {}, }, setupServer: async (server: McpServer) => { // Register your MCP tools, resources, and prompts here server.registerTool( 'echo', { description: 'Echoes back the provided text', inputSchema: { text: z.string().describe('Text to echo back'), }, }, async (args) => { return { content: [{ type: 'text', text: `Echo: ${args.text}` }], }; } ); }, }) ) .listen(3000); ``` ## Usage ### Running the Examples **Basic Example:** ```bash # Run the basic example server (port 3000) bun run example # Or with development mode (auto-restart) bun run dev ``` **Multiple Servers Example:** ```bash # Run the multiple MCP servers example (port 3000) bun example:multi ``` This example demonstrates how to create multiple MCP plugins in a single Elysia application: - **Math Operations Plugin** (`/math`) - Basic arithmetic tools: - `add` - Add two numbers - `multiply` - Multiply two numbers - `power` - Calculate base to the power of exponent - **Text Utilities Plugin** (`/text`) - Text processing tools: - `uppercase` - Convert text to uppercase - `word_count` - Count words in text - `reverse` - Reverse text characters - `replace` - Replace text with global matching ### Testing with MCP Inspector 1. Install MCP Inspector: ```bash npx @modelcontextprotocol/inspector ``` 2. Connect to your server: - **Basic Example**: `http://localhost:3000/mcp` - **Multiple Servers Example**: - Math Plugin: `http://localhost:3000/math` - Text Plugin: `http://localhost:3000/text` ### Configuration Options - `serverInfo`: Server information - `capabilities`: MCP capabilities to advertise - `logger`: Custom logger instance (pino, winston, etc.) - see [Custom Logger](#custom-logger) section - `setupServer`: Callback to register tools, resources, and prompts - `basePath`: Base path for MCP endpoints (default: '/mcp') - `enableJsonResponse`: Enable JSON response mode instead of SSE streaming - `stateless`: Enable stateless mode (no session management) - `authentication`: Authentication handler for protected routes - `eventStore`: Event store for resumability support ### Session Management The plugin automatically handles session management via the `Mcp-Session-Id` header. Each session maintains its own state and can be terminated cleanly. ### Modular Handler Architecture The plugin supports a modular handler architecture that allows you to create specialized endpoints for different MCP capabilities: ```typescript import { mcp, ToolsHandler, ResourcesHandler, PromptsHandler, } from 'elysia-mcp'; const app = new Elysia().use( mcp({ /* config */ }) ); ``` ## Custom Logger The plugin supports custom logger instances, allowing you to use any logging library that conforms to the `ILogger` interface: ```typescript interface ILogger { info(message: string, ...args: unknown[]): void; error(message: string, ...args: unknown[]): void; warn(message: string, ...args: unknown[]): void; debug(message: string, ...args: unknown[]): void; } ``` ### Using Pino Logger ```typescript import { Elysia } from 'elysia'; import { mcp } from 'elysia-mcp'; import pino from 'pino'; const logger = pino({ level: 'debug' }); const app = new Elysia() .use( mcp({ logger, // Pass your custom logger serverInfo: { name: 'my-mcp-server', version: '1.0.0', }, // ... other options }) ) .listen(3000); ``` ### Using Winston Logger ```typescript import winston from 'winston'; const logger = winston.createLogger({ level: 'debug', format: winston.format.json(), transports: [new winston.transports.Console()], }); const app = new Elysia() .use( mcp({ logger, // Pass your winston logger // ... other options }) ) .listen(3000); ``` ### Default Console Logger If you don't provide a custom logger, the plugin will use a default console logger when `enableLogging` is set to `true`: ```typescript const app = new Elysia() .use( mcp({ enableLogging: true, // Uses default console logger with colors // ... other options }) ) .listen(3000); ``` ### Custom Logger Implementation You can also implement your own logger: ```typescript import type { ILogger } from 'elysia-mcp'; class MyCustomLogger implements ILogger { info(message: string, ...args: unknown[]): void { // Your custom implementation } error(message: string, ...args: unknown[]): void { // Your custom implementation } warn(message: string, ...args: unknown[]): void { // Your custom implementation } debug(message: string, ...args: unknown[]): void { // Your custom implementation } } const logger = new MyCustomLogger(); const app = new Elysia() .use( mcp({ logger, // ... other options }) ) .listen(3000); ``` ## API Reference ### Tools Register tools using the MCP Server instance: ```typescript server.registerTool( 'tool-name', { description: 'Tool description', inputSchema: { param: z.string().describe('Parameter description'), }, }, async (args) => { // Tool implementation return { content: [{ type: 'text', text: 'Tool result' }], }; } ); ``` ### Resources Register resources for file or data access: ```typescript server.registerResource( 'resource-name', 'resource://uri', { title: 'Resource Name', description: 'Resource description', }, async () => { return { contents: [ { uri: 'resource://uri', mimeType: 'text/plain', text: 'Resource content', }, ], }; } ); ``` ### Prompts Register reusable prompt templates following MCP best practices: ```typescript server.registerPrompt( 'prompt-name', { title: 'Prompt Title', description: 'Prompt description', argsSchema: { param: z.string().describe('Parameter description'), }, }, async (args) => { return { description: 'Generated prompt', messages: [ { role: 'user', content: { type: 'text', text: `Generated prompt with ${args.param}`, }, }, ], }; } ); ``` ## Testing Run the comprehensive test suite: ```bash bun test ``` ## License MIT - see [LICENSE](./LICENSE) file for details. ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## Related - [Model Context Protocol](https://modelcontextprotocol.io/) - [ElysiaJS](https://elysiajs.com/) - [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) ## Plugin Configuration ### Plugin Options ```typescript interface MCPPluginOptions { /** * Base path for MCP endpoints (default: '/mcp') */ basePath?: string; /** * Server information */ serverInfo?: { name: string; version: string; }; /** * MCP server capabilities */ capabilities?: ServerCapabilities; /** * @deprecated Use logger option instead * Enable or disable logging */ enableLogging?: boolean; /** * Custom logger instance (pino, winston, etc.) * If not provided and enableLogging is true, will use default console logger */ logger?: ILogger; /** * Enable JSON response mode instead of SSE streaming */ enableJsonResponse?: boolean; /** * Authentication handler */ authentication?: ( context: McpContext ) => Promise<{ authInfo?: AuthInfo; response?: unknown }>; /** * Setup function to configure the MCP server with tools, resources, and prompts */ setupServer?: (server: McpServer) => void | Promise<void>; /** * Enable stateless mode (no session management) */ stateless?: boolean; /** * Provide a custom MCP server instance */ mcpServer?: McpServer; /** * Event store for resumability support */ eventStore?: EventStore; } ``` ## Architecture ```mermaid flowchart LR A["HTTP Client"] --> B["Elysia HTTP Handler"] B --> C["MCP Plugin"] C --> D["McpServer<br/>(Singleton)"] ```

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kerlos/elysia-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server