Production Server
Prerequisites
Install MCP Fusion before following this recipe: npm install @vinkius-core/mcp-fusion @modelcontextprotocol/sdk zod — or scaffold a project with npx fusion create.
- Introduction
- Stdio Transport
- HTTP/SSE Transport
- Cloudflare Workers
- Vercel Edge Functions
- Graceful Shutdown
Introduction
MCP Fusion tools are transport-agnostic — the same ToolRegistry runs on Stdio (local development), HTTP/SSE (persistent servers), and serverless edge runtimes. For edge deployment, the Vercel Adapter turns your registry into a Next.js App Router route with Edge Runtime support (~0ms cold starts), while the Cloudflare Workers Adapter gives your tool handlers direct access to D1, KV, and R2 from 300+ edge locations. For AWS infrastructure, the @vinkius-core/mcp-fusion-aws connector integrates with Lambda and Step Functions. All adapters cache registry compilation at cold start and handle warm requests as stateless JSON-RPC — no SSE sessions, no streaming state, no infrastructure to manage.
Stdio Transport
The simplest deployment. The MCP client spawns your server as a child process:
import { ToolRegistry } from '@vinkius-core/mcp-fusion';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const registry = new ToolRegistry();
registry.registerAll(...tools);
const server = new McpServer({
name: 'my-mcp-server',
version: '1.0.0',
});
registry.attachToServer(server, {
contextFactory: async (extra) => ({
db: getDatabaseClient(),
tenantId: 'default',
}),
});
const transport = new StdioServerTransport();
await server.connect(transport);Add to claude_desktop_config.json:
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["tsx", "/path/to/src/server.ts"]
}
}
}HTTP/SSE Transport
For remote servers accessible over the network:
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import express from 'express';
const app = express();
const sessions = new Map<string, SSEServerTransport>();
app.get('/sse', async (req, res) => {
const transport = new SSEServerTransport('/messages', res);
sessions.set(transport.sessionId, transport);
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
registry.attachToServer(server, {
contextFactory: async (extra) => ({
db: getDatabaseClient(),
tenantId: req.headers['x-tenant-id'] ?? 'default',
}),
});
await server.connect(transport);
});
app.post('/messages', async (req, res) => {
const sessionId = req.query.sessionId as string;
const transport = sessions.get(sessionId);
if (transport) await transport.handlePostMessage(req, res);
});
app.listen(3000);Cloudflare Workers
See the full Cloudflare Adapter guide. Quick start:
import { ToolRegistry } from '@vinkius-core/mcp-fusion';
import { McpAgent } from 'agents/mcp';
const registry = new ToolRegistry();
registry.registerAll(...tools);
export class MyMcpAgent extends McpAgent {
server = new McpServer({ name: 'cf-server', version: '1.0.0' });
async init() {
registry.attachToServer(this.server, {
contextFactory: async () => ({
db: getDatabaseClient(this.env),
}),
});
}
}Vercel Edge Functions
See the full Vercel Adapter guide. Quick start:
import { createMcpHandler } from '@vercel/mcp-adapter';
import { ToolRegistry } from '@vinkius-core/mcp-fusion';
const registry = new ToolRegistry();
registry.registerAll(...tools);
export const GET = createMcpHandler(
(server) => {
registry.attachToServer(server, {
contextFactory: async () => ({
db: getDatabaseClient(),
}),
});
},
{},
{ basePath: '/api/mcp', maxDuration: 60 },
);Graceful Shutdown
Handle SIGTERM and SIGINT for clean shutdown in containerized environments:
process.on('SIGTERM', async () => {
console.log('Shutting down gracefully...');
await server.close();
await db.$disconnect();
process.exit(0);
});
process.on('SIGINT', async () => {
console.log('Interrupted, shutting down...');
await server.close();
await db.$disconnect();
process.exit(0);
});IMPORTANT
In Docker and Kubernetes, the entrypoint must handle signals. Use exec form in Dockerfile: CMD ["node", "dist/server.js"] (not CMD node dist/server.js).