模型上下文协议服务器

一个基于TypeScript实现的模型上下文协议(MCP)服务器,提供工具、动态资源和提示模板,适用于构建更复杂的服务器或与其他MCP服务器组合使用。

  • by sampritidas
  • JavaScript
  • 本地部署
  • 更新于
在 GitHub 查看 sampritidas/MCP_Spike

使用说明

你好,这是README

上下文中心MCP服务器

用TypeScript实现的最小模型上下文协议(MCP)服务器,公开了示例工具、动态资源和提示。旨在作为构建更丰富服务器或与其他MCP服务器组合的起点。

特性

  • 工具:
    • echo -回应提供的消息
    • add_numbers -将两个数字相加
  • 资源:动态问候(greeting://{name})
  • 提示: review_code -代码审查提示模板
  • 运输: stdio 用于本地集成(VS Code、Claude Desktop、MCP Inspector)

聚合器和API扩展

除了这个最小的例子,这个项目现在还包括一个多服务器聚合器(src/multi-server.ts)即:

  • 连接到中定义的多个外部MCP服务器 mcp_servers.json (servers 阵列)
  • 动态列出和委派远程工具/资源(list_remote_tools, call_remote_tool等等)
  • 适配声明性REST API定义( apis 阵列)转换为MCP工具(例如。 google_search)
  • 通过以下方式提供实验性的OAuth支持工具(Google Drive列表) oauthProviders 配置

运行聚合器

npm run build
node build/multi-server.js

然后使用MCP Inspector或客户端调用新工具。

配置文件(mcp_servers.json)

关键部分:

  • servers:外部MCP进程(文件系统、内存等)
  • apis:具有查询参数映射和环境注入的进程中REST适配器
  • oauthProviders:OAuth客户端凭据+用于令牌刷新授权的刷新令牌

OAuth提供者示例(占位符-替换为实际值):

"oauthProviders": [
  {
    "name": "google",
      "clientId": "${GOOGLE_CLIENT_ID}",
      "clientSecret": "${GOOGLE_CLIENT_SECRET}",
      "refreshToken": "${GOOGLE_REFRESH_TOKEN}",
    "tokenEndpoint": "https://oauth2.googleapis.com/token",
    "scopes": ["https://www.googleapis.com/auth/drive.readonly"]
  }
]

价值观包装如下 ${VARNAME} 在启动时从环境变量中替换。在启动之前设置它们:

export GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export GOOGLE_CLIENT_SECRET="your_client_secret"
export GOOGLE_REFRESH_TOKEN="1//04ABCDEF..."

获取Google OAuth凭据和刷新令牌

  1. 在Google Cloud Console中创建/选择项目。
  2. 启用所需的API(例如驱动API,自定义搜索已使用API密钥而不是OAuth)。
  3. 配置OAuth同意屏幕(个人使用时为外部;需要时发布)。
  4. 创建OAuth客户端ID:
  • 应用程序类型:“桌面”(简化安装的应用程序流)或具有环回重定向的“Web” http://127.0.0.1:8085/callback.
  1. 生成授权URL:
AUTH_URL="https://accounts.google.com/o/oauth2/v2/auth?client_id=$GOOGLE_CLIENT_ID&redirect_uri=http://127.0.0.1:8085/callback&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.readonly&access_type=offline&prompt=consent"
echo $AUTH_URL
open "$AUTH_URL"  # macOS opens browser
  1. 捕获授权码:
  • 运行一个小监听器(Python示例):
python - <<'PY'
import http.server, sys
class H(http.server.BaseHTTPRequestHandler):
def do_GET(self):
 from urllib.parse import urlparse, parse_qs
 qs=parse_qs(urlparse(self.path).query)
 code=qs.get('code',[None])[0]
 print('Auth code:', code)
 self.send_response(200); self.end_headers(); self.wfile.write(b'You may close this tab.')
 sys.exit(0)
http.server.HTTPServer(('127.0.0.1',8085), H).serve_forever()
PY
  1. 代币的交换代码(包括首次同意时的refresh_token):
curl -s -X POST https://oauth2.googleapis.com/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d "code=YOUR_CODE" \
-d "client_id=$GOOGLE_CLIENT_ID" \
-d "client_secret=$GOOGLE_CLIENT_SECRET" \
-d "redirect_uri=http://127.0.0.1:8085/callback" \
-d "grant_type=authorization_code" | jq

保存 refresh_token 从JSON导出为 GOOGLE_REFRESH_TOKEN.

设备代码流(备选)

curl -s -X POST https://oauth2.googleapis.com/device/code \
  -d "client_id=$GOOGLE_CLIENT_ID" \
  -d "scope=https://www.googleapis.com/auth/drive.readonly" | jq

响应包括 user_code, verification_url,以及 device_code.访问验证URL,输入代码,然后轮询:

while true; do
  curl -s -X POST https://oauth2.googleapis.com/token \
   -d "client_id=$GOOGLE_CLIENT_ID" \
   -d "client_secret=$GOOGLE_CLIENT_SECRET" \
   -d "device_code=YOUR_DEVICE_CODE" \
   -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" | jq; sleep 5; done

授权后,JSON包含 refresh_token.

安全处理

  • 不要泄露真正的秘密;保持 .env /壳牌出口到当地。
  • 在妥协或开发人员离职时轮换刷新令牌。
  • 将范围限制在所需的最小值。

OAuth(实验)

OAuth脚手架允许对中定义的提供者进行令牌刷新 oauthProviders 并暴露:

  • oauth_refresh_token –强制刷新并返回访问令牌+过期。
  • google_drive_list_files –使用缓存的访问令牌列出前10个驱动器文件。

当前限制

  • 假设您已经拥有有效的 refreshToken (通过标准的Google OAuth同意在带外获得;设备代码流尚未实现)。
  • 令牌仅缓存在内存中(重启后不持久)。
  • 仅支持刷新令牌授予(无授权码PKCE交换;无服务帐户流)。
  • 没有自动范围协商或增量同意——范围是信息性的。
  • 错误处理是基本的;未实现速率限制和重试。

下一步(路线图)

  1. 实现设备代码或本地环回身份验证助手,以交互方式获取刷新令牌。
  2. 安全地持久化令牌缓存(具有受限权限的文件或操作系统密钥链)。
  3. 为瞬态5xx/429响应添加结构化错误类别+指数回退。
  4. 推广到其他谷歌API(Gmail、日历)和非谷歌提供商。
  5. 从OpenAPI规范中引入细粒度的工具模式生成。

安全说明

  • 永远不要承诺真实 clientSecret / refreshToken。使用环境覆盖或本地忽略的机密文件。
  • 定期轮换凭据;授予审计范围。
  • 考虑将不受信任的外部服务器与启用OAuth的进程分开。

如有疑问或需要进一步扩展,请从 src/multi-server.ts 并遵循API+OAuth工具使用的模式。

先决条件

  • Node.js>=18
  • npm或兼容的包管理器

快速开始

1.安装依赖项

重要:如果使用企业npm注册表,请先切换到公共注册表:

npm config set registry https://registry.npmjs.org/

然后安装:

npm install

2.建造

npm run build

这将TypeScript编译为 build/index.js.

3.使用MCP检验员进行测试

npx @modelcontextprotocol/inspector node build/index.js

什么是MCP检查员?

检查员是 调试和测试工具 (想想“MCP服务器的邮递员”)。它提供了一个web UI,用于:

  • 发现服务器公开的内容(工具/资源/提示)
  • 无需编写客户端代码即可测试单个操作
  • 实时查看JSON-RPC消息和响应
  • 在与AI应用程序集成之前调试问题

为什么要使用它?

✅ 快速开发周期:测试立即更改,无需重新启动Claude/VS代码
✅ 隔离:分别调试服务器逻辑和客户端行为
✅ 能见度:查看确切的请求/响应有效载荷以进行故障排除
✅ 文档:了解工具接受哪些参数

检查员展示了什么:

浏览器打开到 http://localhost:6274 有4个主要选项卡:

工具选项卡

列出所有可调用工具及其模式。尝试:

  • 点击 echo → Enter {"message": "hello"} → 点击“呼叫工具”
  • 点击 add_numbers → Enter {"a": 5, "b": 3} → 查看结果 {"result": 8}

资源选项卡

显示可用资源(数据源)。尝试:

  • 点击 greeting://Alice → 查看回复:“你好,爱丽丝!欢迎来到上下文中心。”
  • 更改 greeting://World → 获取自定义问候语

提示选项卡

显示提示模板。尝试:

  • 点击 review_code → Enter {"code": "function add(a,b){return a+b}"}
  • 查看嵌入代码的生成提示消息

通知窗格

显示服务器日志和JSON-RPC流量以进行调试。

快速测试命令:

# If port 6274 is busy, kill existing inspector:
lsof -ti:6274 | xargs kill -9

# Then restart:
npx @modelcontextprotocol/inspector node build/index.js

按 Ctrl+C 在终端中停止检查器和服务器。

4.与VS代码一起使用

添加到 .vscode/mcp.json (已创建):

{
  "servers": {
    "context-hub": {
      "type": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/MCP_Spike/build/index.js"]
    }
  }
}

替换 /absolute/path/to/MCP_Spike 与您的项目路径。

5.与克劳德桌面一起使用

添加到 ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)或 %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "context-hub": {
      "command": "node",
      "args": ["/absolute/path/to/MCP_Spike/build/index.js"]
    }
  }
}

重新启动克劳德桌面。

发展模式

直接使用ts节点运行(无构建步骤):

npm run dev

备注:服务器无限期运行,等待MCP客户端通过stdio连接。这是正常行为——按Ctrl+C停止。

延伸

  • 添加新工具 server.registerTool(name, config, handler).
  • 添加资源 server.registerResource(name, templateOrUri, metadata, handler).
  • 添加提示 server.registerPrompt(name, config, handler).

请参阅TypeScript SDK文档:https://github.com/modelcontextprotocol/typescript-sdk

许可证

麻省理工学院