Runs the MCP server and tests with Bun runtime, with specific requirements for Bun version 1.0.0 or higher
Provides Git commit message generation with conventional commits support through prompt templates
Built with TypeScript for type safety, requiring TypeScript 5.0.0 or higher
Uses Zod for schema validation in tools, resources, and prompts, enabling type-safe parameter validation
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Elysia MCP Plugincreate a new MCP server project from the starter template"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Elysia MCP Plugin
A comprehensive ElysiaJS plugin for implementing Model Context Protocol (MCP) 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
Related MCP server: MCP Framework
Installation
bun add elysia-mcp
# or
npm install elysia-mcpStarter Template
To quickly get started with a pre-configured Elysia MCP project, you can use our starter template:
# 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 devThe 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
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:
# Run the basic example server (port 3000)
bun run example
# Or with development mode (auto-restart)
bun run devMultiple Servers Example:
# Run the multiple MCP servers example (port 3000)
bun example:multiThis example demonstrates how to create multiple MCP plugins in a single Elysia application:
Math Operations Plugin (
/math) - Basic arithmetic tools:add- Add two numbersmultiply- Multiply two numberspower- Calculate base to the power of exponent
Text Utilities Plugin (
/text) - Text processing tools:uppercase- Convert text to uppercaseword_count- Count words in textreverse- Reverse text charactersreplace- Replace text with global matching
Testing with MCP Inspector
Install MCP Inspector:
npx @modelcontextprotocol/inspectorConnect to your server:
Basic Example:
http://localhost:3000/mcpMultiple Servers Example:
Math Plugin:
http://localhost:3000/mathText Plugin:
http://localhost:3000/text
Configuration Options
serverInfo: Server informationcapabilities: MCP capabilities to advertiselogger: Custom logger instance (pino, winston, etc.) - see Custom Logger sectionsetupServer: Callback to register tools, resources, and promptsbasePath: Base path for MCP endpoints (default: '/mcp')enableJsonResponse: Enable JSON response mode instead of SSE streamingstateless: Enable stateless mode (no session management)authentication: Authentication handler for protected routeseventStore: 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:
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:
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
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
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:
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:
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:
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:
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:
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:
bun testLicense
MIT - see LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Related
Plugin Configuration
Plugin Options
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
flowchart LR
A["HTTP Client"] --> B["Elysia HTTP Handler"]
B --> C["MCP Plugin"]
C --> D["McpServer<br/>(Singleton)"]