模型上下文协议服务器

一个基于TypeScript的MCP服务器实现,展示生产就绪模式,包括计算、API集成和文件系统访问功能,适用于企业级应用开发。

  • by tylerjhayden
  • TypeScript
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 tylerjhayden/mcp-demo

使用说明

MCP演示服务器

模型上下文协议(MCP)服务器实现,演示TypeScript中的生产就绪模式。 四种并行实现 比较裸金属和框架方法。

概述

该项目展示了MCP服务器的实现,包括:

  • 三种核心模式:计算(计算)、API集成(天气)、文件系统访问
  • 四种实施方式:裸金属、FastMCP、EasyMCP*、mcp框架
  • 框架比较:MCP开发方法的现实评估

*注意:由于npm包(v0.0.0-developing)不稳定,EasyMCP实现可能无法运行。

  • 企业模式:所有实现都证明了安全性、可观察性和可靠性
  • 双重运输:Stdio用于桌面应用程序,HTTP/SSE用于远程访问

快速开始

先决条件

  • Node.js 20+
  • pnpm 8+
  • OpenWeatherMap API密钥(免费层:https://openweathermap.org/api)

安装

# Clone and install
git clone <repository-url>
cd mcp-demo
pnpm install

# Configure
cp .env.example .env
# Edit .env and add your WEATHER_API_KEY

与Claude Code一起使用

# Build the server
pnpm build

# Add to Claude Code
claude mcp add demo-server node -- $(pwd)/dist/servers/bare-metal/index.js

# Verify connection
claude mcp list

手动测试(HTTP模式)

# Development
TRANSPORT_MODE=http pnpm dev

# Production
pnpm build
TRANSPORT_MODE=http pnpm start

备注:对于Claude Code(stdio模式),您不需要手动运行服务器,它会自动启动!

建筑

高级设计

┌─────────────┐
│   Client    │
└──────┬──────┘
       │
┌──────▼───────────────────┐
│  Transport Layer         │
│  • Stdio (stdin/stdout)  │
│  • HTTP/SSE (Express)    │
└──────┬───────────────────┘
       │
┌──────▼───────────────┐
│  Middleware Pipeline │
│  • Auth              │
│  • Rate Limiting     │
│  • Logging/Tracing   │
│  • Metrics           │
└──────┬───────────────┘
       │
┌──────▼────────────┐
│  Message Router   │
│  • tools/list     │
│  • tools/call     │
│  • resources/list │
│  • resources/read │
└──────┬────────────┘
       │
┌──────▼──────────────────┐
│  Handler Registries     │
│  • ToolRegistry         │
│  • ResourceRegistry     │
└──────┬──────────────────┘
       │
┌──────▼────────────────────┐
│  Capability Handlers      │
│  • CalculateTool          │
│  • WeatherTool            │
│  • FileResourceHandler    │
└───────────────────────────┘

处理器模式

所有功能都实现了一个通用接口:

interface CapabilityHandler<TParams, TResult> {
  validate(input: unknown): ValidationResult<TParams>;
  execute(params: TParams, context: ExecutionContext): Promise<Result<TResult>>;
  handleError(error: Error): MCPError;
}

这消除了重复,使添加新功能变得简单:

  1. 实现接口
  2. 在适当的注册表中注册
  3. 完成-自动路由和运输工作

框架比较

该项目包括 四种并行实现 相同的MCP服务器功能,允许您比较方法:

实现 代码行 模式 最适合
裸机 (/servers/bare-metal) ~2000 直接MCP SDK 学习MCP内部,完全控制,自定义需求
FastMCP (/servers/fastmcp-impl) ~420 生成器API 生产应用程序,类似于表达式的熟悉程度
EasyMCP (/servers/easymcp-impl) ⚠️ ~400 装饰师 快速原型制作,最小化样板(包装不稳定)
mcp框架 (/servers/mcp-framework-impl) ~455 自动发现 具有多种功能的大型项目

⚠️ EasyMCP实现可能无法运行- easy-mcp npm包在v0.0.0开发中破坏了导出

特征矩阵

功能 裸金属 FastMCP EasyMCP mcp框架
运输:stdio ✓ ✓ ✓ ✓
传输:HTTP/SSE ✓ ✓ ✗ ✓
输入验证 手动Zod Zod模式 类型推理 Zod+助手
自动发现 ✗ ✗ ✗ ✓ (from /tools)
类型安全性 手动 基于模式 装饰推理 MCPInput<this>
设置复杂性 高 中 低 中
样板文件 高 低 最小 低-中
框架依赖性 无 FastMCP EasyMCP mcp框架
学习曲线 陡峭 温和 温和 中等

代码比较:添加工具

裸机 (必须实现完整接口):

class MyTool implements CapabilityHandler {
  validate(input: unknown): ValidationResult { /* ... */ }
  execute(params: MyParams, ctx: ExecutionContext): Promise<Result> { /* ... */ }
  handleError(error: Error): MCPError { /* ... */ }
}
// Register manually
toolRegistry.register('my_tool', new MyTool());

FastMCP (建设者模式):

server.addTool({
  name: 'my_tool',
  parameters: z.object({ input: z.string() }),
  execute: async (args) => processInput(args.input),
});

EasyMCP (装饰师):

class MyMCP extends EasyMCP {
  @Tool({ description: 'Process input' })
  async myTool(input: string) {
    return processInput(input);
  }
}

mcp框架 (自动发现):

// In /tools/my_tool.ts
class MyTool extends MCPTool {
  name = 'my_tool';
  schema = defineSchema({ input: z.string().describe('Input') });
  async execute(input: MCPInput<this>) {
    return processInput(input.input);
  }
}
export default MyTool;
// Automatically discovered - no registration needed

何时选择每种方法

在以下情况下选择裸金属:

  • 学习MCP协议内部
  • 需要最大程度的控制和定制
  • 建造一些不寻常或实验性的东西
  • 想要最小的依赖关系
  • 性能优化至关重要

在以下情况下选择FastMCP:

  • 快速构建生产应用程序
  • 团队熟悉Express.js模式
  • 需要会话管理和身份验证
  • 想要一个经过验证、久经考验的框架

在以下情况下选择EasyMCP:

  • ⚠️ 注: 目前不推荐-软件包存在稳定性问题
  • 快速原型或MVP
  • 构建简单的小型服务器
  • 团队更喜欢TypeScript装饰器
  • 想要绝对最小的样板
  • 开发人员经验是首要任务

在以下情况下选择mcp框架:

  • 构建具有多种功能的大型项目
  • 想要CLI工具(mcp validate, mcp add)
  • 团队更喜欢惯例而不是配置
  • 可扩展性和组织性很重要
  • 需要结构化的文件组织

运行实现

每个实现都在其自己的目录中 /servers:

# Bare-metal
cd servers/bare-metal
pnpm build
node dist/index.js

# FastMCP
cd servers/fastmcp-impl
npm install
npm run dev

# EasyMCP (⚠️ may not work - package unstable)
cd servers/easymcp-impl
npm install
npm run dev

# mcp-framework
cd servers/mcp-framework-impl
npm install
npm run dev

所有实现都支持相同的三种功能(计算、get_weather、文件访问)和相同的API。

能力

1.计算(计算模式)

使用安全控件计算数学表达式。

方法: tools/call

参数:

{
  "name": "calculate",
  "arguments": {
    "expression": "2 + 2 * 10"
  }
}

退货:

{
  "expression": "2 + 2 * 10",
  "result": 22
}

安全:表达式净化可防止代码注入。只允许使用数学运算符。

2.get_weather(API集成模式)

从OpenWeatherMap获取当前天气数据。

方法: tools/call

参数:

{
  "name": "get_weather",
  "arguments": {
    "location": "San Francisco"
  }
}

退货:

{
  "location": "San Francisco, US",
  "temperature": 18.5,
  "conditions": "partly cloudy",
  "timestamp": "2025-10-20T10:37:00Z"
}

特性:10分钟结果缓存,可配置超时,API故障的错误处理。

3.文件://资源(文件系统模式)

提供对允许目录中文件的安全读取访问。

列出资源:

{
  "method": "resources/list"
}

读取资源:

{
  "method": "resources/read",
  "params": {
    "uri": "file:///tmp/example.txt"
  }
}

安全:路径遍历保护,仅限于 ALLOWED_FILE_PATHSMIME类型检测。

配置

所有配置均通过环境变量进行。看 .env.example 了解详情。

关键变量

# Transport
TRANSPORT_MODE=stdio        # or "http"
HTTP_PORT=3000              # HTTP mode only

# Weather API
WEATHER_API_KEY=your_key    # Required for weather tool
WEATHER_CACHE_TTL=600       # Seconds (10 min default)

# Security
ALLOWED_FILE_PATHS=/tmp     # Colon-separated paths
API_KEYS=key1,key2          # HTTP mode only
RATE_LIMIT_REQUESTS=60      # Requests/min per client

# Observability
LOG_LEVEL=info              # debug|info|warn|error
LOG_FORMAT=pretty           # json|pretty

部署

本地开发

# Stdio mode with auto-reload
pnpm dev

# HTTP mode with auto-reload
TRANSPORT_MODE=http pnpm dev

码头工人

# Build image
docker build -t mcp-demo .

# Run container
docker run -p 3000:3000 \
  -e WEATHER_API_KEY=your_key \
  -e API_KEYS=your_api_key \
  mcp-demo

MCP客户端集成

Claude 代码命令行界面 (推荐):

# Build the server first
pnpm build

# Add to Claude Code (stdio mode)
claude mcp add demo-server node -- /path/to/mcp-demo/dist/servers/bare-metal/index.js

# Verify it's connected
claude mcp list

# The server will auto-start when Claude Code needs it
# No need to manually run pnpm start!

克劳德桌面版 (标准版本):

{
  "mcpServers": {
    "demo-server": {
      "command": "node",
      "args": ["/path/to/mcp-demo/dist/servers/bare-metal/index.js"]
    }
  }
}

HTTP客户端:

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_api_key" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "calculate",
      "arguments": {"expression": "2 + 2"}
    }
  }'

共享您的服务器

Stdio与HTTP:何时使用

标准模式 (本地,单用户):

  • ✅ 个人使用Claude Code/桌面
  • ✅ 安全(仅限操作系统级权限)
  • ✅ 无网络暴露
  • ✅ 客户端自动启动/停止

HTTP模式 (共享、多用户):

  • ✅ 与其他Claude Code用户共享
  • ✅ 远程访问(部署到云端)
  • ✅ 多个同时运行的客户端
  • ✅ 使用curl/Postman进行测试
  • ✅ 基于浏览器的集成

共享部署

快速测试(ngrok):

# Terminal 1: Start server
TRANSPORT_MODE=http pnpm start

# Terminal 2: Create tunnel
ngrok http 3000

# Share URL: Others add with
# claude mcp add --transport http your-server https://abc123.ngrok.io/mcp

生产(云):

# Deploy to Railway, Render, Fly.io, AWS, etc.
# Set environment:
#   TRANSPORT_MODE=http
#   API_KEYS=key1,key2,key3

# Users connect:
claude mcp add --transport http your-server \
  https://your-domain.com/mcp \
  --header "Authorization: Bearer user_api_key"

自主机(GitHub):

# Share repo - users run their own instance
git clone your-repo
pnpm install && pnpm build
claude mcp add demo-server node -- $(pwd)/dist/servers/bare-metal/index.js

实现细节

裸金属方法

此实现最低限度地使用官方MCP SDK,手动实现核心模式:

优势:

  • 完全控制和透明
  • 对MCP机制有清晰的理解
  • 易于根据特定需求进行定制
  • 最小依赖性

组件:

  • 手动请求路由和处理程序注册
  • 自定义中间件管道
  • 直接传输设置(stdio读线、Express HTTP)
  • 显式错误处理模式

代码行:~2500(不包括测试)

安全注意事项

生产清单:

  • [x] 使用Zod模式进行输入验证
  • [x] 文件访问的路径遍历保护
  • [x] 表达式净化以防止代码注入
  • [x] API密钥认证(HTTP模式)
  • [x] 速率限制(令牌桶算法)
  • [x] 请求跟踪审计日志
  • [x] 安全的环境变量处理
  • []用于HTTP传输的HTTPS/TLS(配置反向代理)
  • []API键旋转机制(添加到配置中)

扩展指南

添加新工具很简单:

1.创建处理程序 (服务器/裸机/处理器/MyTool.ts):

export class MyTool implements CapabilityHandler<MyParams, MyResult> {
  validate(input: unknown): ValidationResult<MyParams> {
    return validateWithSchema(MyParamsSchema, input);
  }

  async execute(params: MyParams, context: ExecutionContext): Promise<Result<MyResult>> {
    // Your logic here
    return { success: true, data: result };
  }

  handleError(error: Error): MCPError {
    return { code: MCPErrorCode.InternalError, message: error.message };
  }
}

2.在index.ts中注册:

toolRegistry.register('my_tool', new MyTool(), {
  name: 'my_tool',
  description: 'Does something useful',
  inputSchema: { /* JSON schema */ }
});

完成! 传输、路由、日志记录和度量自动工作。

测试

# Run all tests
pnpm test

# Watch mode
pnpm test:watch

# Coverage report
pnpm test:coverage

测试包括:

  • 所有处理程序的单元测试
  • 安全验证(路径遍历、注入尝试)
  • 中间件功能(身份验证、速率限制)
  • 两种运输工具的集成测试

项目结构

/mcp-demo
  /shared                    # Common utilities
    /types                   # TypeScript interfaces
    /security                # Validation, sanitization
    /observability           # Logging, metrics, tracing
    /config                  # Configuration management
    /utils                   # HTTP client, helpers
  /servers/bare-metal        # Bare-metal implementation
    /handlers                # Tool and resource handlers
    /transport               # Stdio and HTTP transports
    /middleware              # Auth, rate limiting
    /registry                # Capability registration
    /core                    # Message routing
    index.ts                 # Main entry point
  /tests                     # Test suites
  /docs                      # Specifications

许可证

麻省理工学院

贡献

欢迎投稿!该项目旨在为生产MCP服务器提供学习资源和模板。

重点领域:

  • 其他功能示例(数据库、缓存等)
  • 增强的安全模式
  • 性能优化
  • 框架比较实现