Supports distribution through npm, allowing developers to publish their MCP servers and have users install them with a simple npx command.
Built specifically for TypeScript with full type safety, enabling developers to create MCP tools, prompts, and resources with proper typing and validation.
Uses Zod for schema validation in tools, allowing developers to define input validation schemas for tool parameters with proper typing and runtime 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., "@MCP Frameworkcreate a new MCP server project called 'stock-analyzer'"
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.
MCP Framework
A TypeScript framework for building Model Context Protocol (MCP) servers.
Changes from Original
This fork (@ronangrant/mcp-framework) includes the following improvements:
Replaced file-based logging with console-only logging for better compatibility and reliability
Removed dependency on filesystem for logs, eliminating ENOENT errors
Simplified logging implementation while maintaining the same interface
All logs now output to stderr via console.error()
Related MCP server: MCP Server Starter
Installation
npm install @ronangrant/mcp-frameworkUsage
Create a new MCP server:
import { MCPServer } from '@ronangrant/mcp-framework';
const server = new MCPServer({
name: "my-server",
version: "1.0.0"
});
await server.start();Features
Easy-to-use API for creating MCP servers
Built-in support for tools, prompts, and resources
Simplified logging system with console output
Full TypeScript support
Flexible transport options
License
MIT
MCP-Framework is a framework for building Model Context Protocol (MCP) servers elegantly in TypeScript.
MCP-Framework gives you architecture out of the box, with automatic directory-based discovery for tools, resources, and prompts. Use our powerful MCP abstractions to define tools, resources, or prompts in an elegant way. Our cli makes getting started with your own MCP server a breeze
Features
🛠️ Automatic discovery and loading of tools, resources, and prompts
Multiple transport support (stdio, SSE)
TypeScript-first development with full type safety
Built on the official MCP SDK
Easy-to-use base classes for tools, prompts, and resources
Out of the box authentication for SSE endpoints
Read the full docs here
Creating a repository with mcp-framework
Using the CLI (Recommended)
# 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!CLI Usage
The framework provides a powerful CLI for managing your MCP server projects:
Project Creation
# Create a new project
mcp create <your project name here>Adding a Tool
# Add a new tool
mcp add tool price-fetcherAdding a Prompt
# Add a new prompt
mcp add prompt price-analysisAdding a Resource
# Add a new prompt
mcp add resource market-dataDevelopment Workflow
Create your project:
mcp create my-mcp-server
cd my-mcp-serverAdd tools as needed:
mcp add tool data-fetcher mcp add tool data-processor mcp add tool report-generatorBuild:
npm run buildAdd to MCP Client (Read below for Claude Desktop example)
Using with Claude Desktop
Local Development
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"]
}
}
}After Publishing
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}"]
}
}
}Building and Testing
Make changes to your tools
Run `npm run build` to compile
The server will automatically load your tools on startup
Quick Start
Creating a Tool
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;Setting up the Server
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();Transport Configuration
stdio Transport (Default)
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" }
});SSE Transport
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")
}
}
}
});CORS Configuration
The SSE transport supports flexible CORS configuration. By default, it uses permissive settings suitable for development. For production, you should configure CORS according to your security requirements:
const server = new MCPServer({
transport: {
type: "sse",
options: {
// Restrict to specific origin
cors: {
allowOrigin: "https://myapp.com",
allowMethods: "GET, POST",
allowHeaders: "Content-Type, Authorization",
exposeHeaders: "Content-Type, Authorization",
maxAge: "3600"
}
}
}
});
// Or with multiple allowed origins
const server = new MCPServer({
transport: {
type: "sse",
options: {
cors: {
allowOrigin: "https://app1.com, https://app2.com",
allowMethods: "GET, POST, OPTIONS",
allowHeaders: "Content-Type, Authorization, Custom-Header",
exposeHeaders: "Content-Type, Authorization",
maxAge: "86400"
}
}
}
});Authentication
MCP Framework provides optional authentication for SSE endpoints. You can choose between JWT and API Key authentication, or implement your own custom authentication provider.
JWT Authentication
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...API Key Authentication
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-keyCustom Authentication
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 authentication logic
return true;
}
getAuthError() {
return {
status: 401,
message: "Authentication failed"
};
}
}License
MIT