MCP服务器

一个完整的MCP(模型上下文协议)服务器实现,支持OAuth 2.1授权,用于创建Claude AI可安全访问的认证工具。

  • by Dreyyyyy
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 Dreyyyyy/mcp-server

使用说明

带有OAuth 2.1的战斗学校MCP服务器

一个采用TypeScript、Node.js和Express构建的MCP(模型上下文协议)服务器完整实现,支持OAuth 2.1授权。受《终结者游戏》中的战斗学校启发,该服务器展示了如何创建经过认证的MCP工具,以便Claude AI能够安全地访问。所有工作均基于Danila Loginov的文章及其仓库完成,相关资源可在资源部分找到。

🚀 特性

  • 完整的OAuth 2.1实现

    • 服务器元数据发现(/.well-known/oauth-authorization-server)
    • 动态客户端注册
    • 授权码流程
    • 基于JWT的访问令牌
    • HTML授权页面
  • MCP协议支持

    • 可流式传输的HTTP传输
    • 工具列表及执行
    • 协议初始化和通知
    • 针对用户的特定认证工具
  • “Battle School Demo Tools” 翻译成中文是“战斗学校演示工具”

    • get-student-info - 通过ID查询学生详情
    • get-my-info - 获取已认证用户的个人资料
    • get-my-army - 查看你的军队名单和统计数据
    • get-opponent-army - 对敌军的情报了解
  • 已准备好投入生产

    • 使用多阶段构建进行Docker化
    • 具有严格类型的TypeScript
    • 已启用CORS以支持跨域请求
    • 基于环境的配置
    • 内存数据存储(可轻松替换为数据库)

📋 先决条件

  • Node.js 20多个版本(或:Node.js 20+ 版本)
  • Docker & Docker Compose(可选,用于容器化部署)
  • ngrok或类似的隧道服务(用于Claude集成测试)

🛠️ 安装

1. 克隆并安装依赖项

git clone https://github.com/Dreyyyyy/mcp-server.git
cd mcp-server-test
npm install

2. 配置环境

复制 .env.example 到;向;朝 .env:

cp .env.example .env

编辑 .env 并设置您的值:

PORT=3000
NODE_ENV=development
ACCESS_TOKEN_SECRET=your-long-random-secret-key-here
TOKEN_EXPIRATION=1h
SERVER_URL=http://localhost:3000

🏃 在本地运行

开发模式

npm run dev

服务器将在 http://localhost:3000 已启用热重载功能。

生产构建(或生产版本)

npm run build
npm start

🐳 Docker 部署

构建并运行

docker compose up --build

在后台运行

docker compose up -d

停止

docker compose down

🧪 测试服务器

1. 测试基本端点

# Health check
curl http://localhost:3000/

# OAuth metadata
curl http://localhost:3000/.well-known/oauth-authorization-server

# MCP health
curl http://localhost:3000/mcp/health

2. 测试OAuth流程

注册一个客户端:

curl -X POST http://localhost:3000/oauth/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "Test Client",
    "redirect_uris": ["http://localhost:3000/callback"]
  }'

保存 client_id 来自回复。

在浏览器中授权:

http://localhost:3000/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=http://localhost:3000/callback&response_type=code
  • 输入学生ID: BS-2401 (安德·维金)或 BS-2404 (佩特拉·阿尔卡尼安)
  • 点击“授权访问”
  • 复制 code 来自重定向URL

用代码兑换代币:

curl -X POST http://localhost:3000/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "YOUR_CODE",
    "redirect_uri": "http://localhost:3000/callback",
    "client_id": "YOUR_CLIENT_ID"
  }'

拯救 access_token.

3. 测试MCP工具

列出可用工具:

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }'

调用一个工具:

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "get-my-info",
      "arguments": {}
    }
  }'

🔗 与Claude集成

Claude 需要一个可公开访问的 URL。使用 ngrok 进行测试:

1. 安装ngrok

# Linux/WSL
curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null
echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | sudo tee /etc/apt/sources.list.d/ngrok.list
sudo apt update && sudo apt install ngrok

或者从以下链接下载:https://ngrok.com/download

2. 配置ngrok

在 https://dashboard.ngrok.com 上注册并获取您的身份验证令牌:

ngrok config add-authtoken YOUR_AUTH_TOKEN

3. 暴露本地服务器

ngrok http 3000

复制HTTPS网址(例如。, https://abc123.ngrok-free.app)

4. 更新配置

更新您的 .env 或者 docker-compose.yaml:

SERVER_URL=https://abc123.ngrok-free.app

重启您的服务器:

docker compose down
docker compose up

5. 添加到Claude

  1. 打开Claude 设置 → 集成
  2. 点击 “添加集成”
  3. 姓名: Battle School MCP
  4. 网址: https://abc123.ngrok-free.app/mcp
  5. 点击 “Connect”翻译成中文是“连接”
  6. 您将被重定向以进行授权
  7. 输入学生ID(例如。, BS-2401)
  8. 点击 “授权访问”
  9. 完成了! ✅

6. 使用Claude进行测试

开始一场新的对话并尝试:

  • “给我看看我的学生档案”
  • “我的军队名册是什么?”
  • “获取有关凤凰军的情报”
  • “查询学生BS-2402”

克劳德将使用您的MCP工具来提供个性化数据的回复!

📁 项目结构

mcp-server-test/
├── src/
│   ├── index.ts              # Main Express server
│   ├── config.ts             # Environment configuration
│   ├── interfaces/
│   │   └── index.ts          # TypeScript interfaces
│   ├── data/
│   │   └── mock-data.ts      # Mock Battle School data
│   ├── utils/
│   │   ├── oauth-storage.ts  # In-memory OAuth state
│   │   └── token.ts          # JWT utilities
│   ├── middleware/
│   │   └── auth.ts           # Bearer token authentication
│   ├── routes/
│   │   ├── oauth.ts          # OAuth 2.1 endpoints
│   │   └── mcp.ts            # MCP protocol endpoints
│   └── mcp/
│       ├── server.ts         # MCP tool definitions
│       └── tools.ts          # Tool implementations
├── views/
│   └── authorize.html        # OAuth authorization page
├── Dockerfile                # Multi-stage Docker build
├── docker-compose.yaml       # Docker Compose config
├── package.json              # Dependencies and scripts
├── tsconfig.json             # TypeScript configuration
├── .env.example              # Environment template
└── README.md                 # This file

🔐 OAuth 2.1 流程

┌─────────┐                                ┌──────────────┐
│ Claude  │                                │  MCP Server  │
└────┬────┘                                └──────┬───────┘
     │                                            │
     │  1. Discover OAuth metadata                │
     ├───────────────────────────────────────────>│
     │    GET /.well-known/oauth-authorization... │
     │                                            │
     │  2. Register as client                     │
     ├───────────────────────────────────────────>│
     │    POST /oauth/register                    │
     │                                            │
     │  3. Redirect user to authorize             │
     ├───────────────────────────────────────────>│
     │    GET /oauth/authorize?client_id=...      │
     │                                            │
     │    4. User sees authorization page         │
     │       and enters credentials (BS-2401)     │
     │                                            │
     │  5. Authorization code issued              │
     │<───────────────────────────────────────────┤
     │    Redirect with code parameter            │
     │                                            │
     │  6. Exchange code for access token         │
     ├───────────────────────────────────────────>│
     │    POST /oauth/token                       │
     │                                            │
     │  7. Access token (JWT) returned            │
     │<───────────────────────────────────────────┤
     │                                            │
     │  8. Use MCP tools with Bearer token        │
     ├───────────────────────────────────────────>│
     │    POST /mcp                               │
     │    Authorization: Bearer <token>           │
     │                                            │

🛠️ 可用的MCP工具

get-student-info

通过学生ID获取该学生的详细信息。

参数:

  • studentId (字符串,必填):学生ID(例如,“BS-2401”)

示例:

{
  "name": "get-student-info",
  "arguments": {
    "studentId": "BS-2401"
  }
}

get-my-info

获取已认证用户自己的个人资料和统计数据。

参数: 无

get-my-army

获取由已认证用户指挥的军队的相关信息。

参数: 无

get-opponent-army

通过ID获取对手军队的情报。

参数:

  • armyId (字符串,必填):军队标识(例如,“龙”,“凤凰”)

示例:

{
  "name": "get-opponent-army",
  "arguments": {
    "armyId": "phoenix"
  }
}

📝 环境变量

变量 描述 默认值 是否必需
(无对应中文) (无对应中文) (无对应中文) (无对应中文)
不 NODE_ENV development 环境
编号 ACCESS_TOKEN_SECRET dev-secret-key JWT 签名密钥
是(制作中) TOKEN_EXPIRATION 1h 令牌有效性
不(编号) SERVER_URL http://localhost:3000 公共服务器URL

| 是 |

🚀 部署

Docker 见 Docker 部署

上面的部分。

🤝 贡献

  • 这是一个演示如何使用OAuth实现MCP(可能是指某种认证或授权机制)的学习项目。

将其作为您自己的MCP服务器的模板使用

原文文章

📄 许可证

MIT 许可证 - 欢迎随意使用此项目!

  • 🙏 致谢
  • 受丹尼拉·洛吉诺夫(Danila Loginov)所著文章《构建带授权的远程MCP》的启发

奥森·斯科特·卡德(Orson Scott Card)《安德的游戏》(Ender's Game)中的“战斗学校”概念