MCP-Framework is a TypeScript framework for building Model Context Protocol (MCP) servers, offering architecture, automatic discovery of tools, resources, and prompts, and multiple transport support. The CLI simplifies project creation and management.
MCP-Framework is a TypeScript framework designed to streamline the creation of Model Context Protocol (MCP) servers. It offers built-in architecture with automatic discovery of tools, resources, and prompts via directory-based conventions. A CLI simplifies project setup and management.
# Install the framework globally
npm install -g mcp-framework
# Create a new MCP server project
mcp create my-mcp-server
# Navigate to your project
cd my-mcp-server
# Your server is ready to use!
The framework provides a CLI for managing your MCP server projects:
# Create a new project
mcp create <your project name here>
# Create a new project with the new EXPERIMENTAL HTTP transport
Heads up: This will set cors allowed origin to "*", modify it in the index if you wish
mcp create <your project name here> --http --port 1337 --cors
# Add a new tool
mcp add tool price-fetcher
# Add a new prompt
mcp add prompt price-analysis
# Add a new prompt
mcp add resource market-data
mcp create my-mcp-server
cd my-mcp-server
mcp add tool data-fetcher
mcp add tool data-processor
mcp add tool report-generator
npm run build
Add this configuration to your Claude Desktop config file:
MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
Windows: `%APPDATA%/Claude/claude_desktop_config.json`
{
"mcpServers": {
"${projectName}": {
"command": "node",
"args":["/absolute/path/to/${projectName}/dist/index.js"]
}
}
}
Add this configuration to your Claude Desktop config file:
MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
Windows: `%APPDATA%/Claude/claude_desktop_config.json`
{
"mcpServers": {
"${projectName}": {
"command": "npx",
"args": ["${projectName}"]
}
}
}
The framework supports the following environment variables for configuration:
Variable | Description | Default |
---|---|---|
MCP_ENABLE_FILE_LOGGING | Enable logging to files (true/false) | false |
MCP_LOG_DIRECTORY | Directory where log files will be stored | logs |
MCP_DEBUG_CONSOLE | Display debug level messages in console (true/false) | false |
Example usage:
# Enable file logging
MCP_ENABLE_FILE_LOGGING=true node dist/index.js
# Specify a custom log directory
MCP_ENABLE_FILE_LOGGING=true MCP_LOG_DIRECTORY=my-logs
# Enable debug messages in console
MCP_DEBUG_CONSOLE=true
import { MCPTool } from "mcp-framework";
import { z } from "zod";
interface ExampleInput {
message: string;
}
class ExampleTool extends MCPTool<ExampleInput> {
name = "example_tool";
description = "An example tool that processes messages";
schema = {
message: {
type: z.string(),
description: "Message to process",
},
};
async execute(input: ExampleInput) {
return `Processed: ${input.message}`;
}
}
export default ExampleTool;
import { MCPServer } from "mcp-framework";
const server = new MCPServer();
// OR (mutually exclusive!) with SSE transport
const server = new MCPServer({
transport: {
type: "sse",
options: {
port: 8080 // Optional (default: 8080)
}
}
});
// Start the server
await server.start();
The stdio transport is used by default if no transport configuration is provided:
const server = new MCPServer();
// or explicitly:
const server = new MCPServer({
transport: { type: "stdio" }
});
To use Server-Sent Events (SSE) transport:
const server = new MCPServer({
transport: {
type: "sse",
options: {
port: 8080, // Optional (default: 8080)
endpoint: "/sse", // Optional (default: "/sse")
messageEndpoint: "/messages", // Optional (default: "/messages")
cors: {
allowOrigin: "*", // Optional (default: "*")
allowMethods: "GET, POST, OPTIONS", // Optional (default: "GET, POST, OPTIONS")
allowHeaders: "Content-Type, Authorization, x-api-key", // Optional (default: "Content-Type, Authorization, x-api-key")
exposeHeaders: "Content-Type, Authorization, x-api-key", // Optional (default: "Content-Type, Authorization, x-api-key")
maxAge: "86400" // Optional (default: "86400")
}
}
}
});
To use HTTP Stream transport:
const server = new MCPServer({
transport: {
type: "http-stream",
options: {
port: 8080, // Optional (default: 8080)
endpoint: "/mcp", // Optional (default: "/mcp")
responseMode: "batch", // Optional (default: "batch"), can be "batch" or "stream"
batchTimeout: 30000, // Optional (default: 30000ms) - timeout for batch responses
maxMessageSize: "4mb", // Optional (default: "4mb") - maximum message size
// Session configuration
session: {
enabled: true, // Optional (default: true)
headerName: "Mcp-Session-Id", // Optional (default: "Mcp-Session-Id")
allowClientTermination: true, // Optional (default: true)
},
// Stream resumability (for missed messages)
resumability: {
enabled: false, // Optional (default: false)
historyDuration: 300000, // Optional (default: 300000ms = 5min) - how long to keep message history
},
// CORS configuration
cors: {
allowOrigin: "*" // Other CORS options use defaults
}
}
}
});
The HTTP Stream transport supports two response modes:
You can configure the response mode based on your specific needs:
// For batch mode (default):
const server = new MCPServer({
transport: {
type: "http-stream",
options: {
responseMode: "batch"
}
}
});
// For stream mode:
const server = new MCPServer({
transport: {
type: "http-stream",
options: {
responseMode: "stream"
}
}
});
MCP Framework provides optional authentication for SSE endpoints. You can choose between JWT and API Key authentication, or implement your own custom authentication provider.
import { MCPServer, JWTAuthProvider } from "mcp-framework";
import { Algorithm } from "jsonwebtoken";
const server = new MCPServer({
transport: {
type: "sse",
options: {
auth: {
provider: new JWTAuthProvider({
secret: process.env.JWT_SECRET,
algorithms: ["HS256" as Algorithm], // Optional (default: ["HS256"])
headerName: "Authorization" // Optional (default: "Authorization")
}),
endpoints: {
sse: true, // Protect SSE endpoint (default: false)
messages: true // Protect message endpoint (default: true)
}
}
}
}
});
Clients must include a valid JWT token in the Authorization header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
import { MCPServer, APIKeyAuthProvider } from "mcp-framework";
const server = new MCPServer({
transport: {
type: "sse",
options: {
auth: {
provider: new APIKeyAuthProvider({
keys: [process.env.API_KEY],
headerName: "X-API-Key" // Optional (default: "X-API-Key")
})
}
}
}
});
Clients must include a valid API key in the X-API-Key header:
X-API-Key: your-api-key
You can implement your own authentication provider by implementing the AuthProvider
interface:
import { AuthProvider, AuthResult } from "mcp-framework";
import { IncomingMessage } from "node:http";
class CustomAuthProvider implements AuthProvider {
async authenticate(req: IncomingMessage): Promise<boolean | AuthResult> {
// Implement your custom authenticatio...
QuantGeekDev/mcp-framework
December 8, 2024
March 28, 2025
TypeScript