MCP server by jfdjaf
mcp-model-proxy
一个最小的本地 MCP Server,把任意兼容 Claude Messages API 的上游包装成统一的 MCP 工具 ask_model。
注意:本项目转发的是 Claude Messages API 格式的请求。其他服务(如 OpenAI、Gemini 原生 API)与此格式不兼容,直接填入不会生效。部分中转服务或网关会把 Claude Messages API 格式转发给 GPT/Gemini,这类服务可以用,但兼容性由中转服务保证,与本项目无关。
不负责账号管理、provider 切换或流式输出。就一件事:把上游接口变成 MCP 工具,让 MCP Inspector、编辑器插件或其他支持 MCP 的客户端能直接调用。
运行模式:本项目使用 stdio 传输,必须由宿主客户端以子进程方式启动(即在 MCP 配置里指定
command和args)。直接运行node server.mjs不会监听任何端口,进程会挂起等待 stdin 输入,这是正常行为。
目录
系统要求
- Node.js 18+
- npm 7+
- 可访问兼容 Claude Messages API 的上游服务的网络环境(Node.js 默认不走系统代理,如需代理请设置
HTTPS_PROXY环境变量)
依赖包:
@modelcontextprotocol/sdkzod
快速开始
1. 安装依赖
npm install
2. 设置环境变量
Windows PowerShell:
$env:CLAUDE_MCP_BASE_URL = "https://your-base-url"
$env:CLAUDE_MCP_API_KEY = "your-token"
$env:CLAUDE_MCP_MODEL = "claude-sonnet-4-5"
$env:CLAUDE_MCP_ANTHROPIC_VERSION = "2023-06-01"
$env:CLAUDE_MCP_TIMEOUT_MS = "60000"
其中 CLAUDE_MCP_ANTHROPIC_VERSION 和 CLAUDE_MCP_TIMEOUT_MS 是可选项。参考 .env.example 维护自己的本地模板,不要把真实 token 提交到仓库。
3. 用 Inspector 测试
以下命令为 PowerShell 格式(Windows),macOS/Linux 请将行末的 ` 换成 \:
npx @modelcontextprotocol/inspector --cli `
node /path/to/mcp-model-proxy/server.mjs `
--method tools/call `
--tool-name ask_model `
--tool-arg "prompt=介绍一下你自己"
4. 预期结果
// 示意,非真实数据,实际 token 数取决于模型和 prompt
{
"model": "claude-sonnet-4-5",
"stop_reason": "end_turn",
"usage": {
"input_tokens": 100,
"output_tokens": 76
},
"text": "..."
}
项目结构
mcp-model-proxy/
├─ examples/
│ ├─ assets/
│ │ ├─ core-call-flow.drawio
│ │ └─ core-call-flow.svg
│ ├─ mcp-client-config.windows.json
│ ├─ mcp-client-config.macos.json
│ └─ inspector-powershell.md
├─ .env.example
├─ .gitignore
├─ CHANGELOG.md
├─ LICENSE
├─ package.json
├─ package-lock.json
├─ server.mjs
└─ README.md
其中:
server.mjs是 MCP Server 主入口examples/mcp-client-config.*.json是不同平台的宿主客户端配置示例examples/assets/放 README 用到的流程图源文件和导出图
核心调用流程
可编辑源文件见 ./examples/assets/core-call-flow.drawio,后续如果要改节点文案、配色或布局,可以直接用 draw.io 或 next-ai-draw-io 打开继续调整。
工作原理
环境变量
| 变量 | 必填 | 说明 |
|------|------|------|
| CLAUDE_MCP_BASE_URL | 是 | Claude 兼容上游地址 |
| CLAUDE_MCP_API_KEY | 是 | 上游 API Key |
| CLAUDE_MCP_MODEL | 否 | 默认模型,默认 claude-sonnet-4-5 |
| CLAUDE_MCP_ANTHROPIC_VERSION | 否 | 默认 2023-06-01 |
| CLAUDE_MCP_TIMEOUT_MS | 否 | 上游请求超时,默认 60000,最小 1000 |
URL 自动补全
以下三种写法均可:
https://example.com
https://example.com/v1
https://example.com/v1/messages
请求头
x-api-key: <your-key>
anthropic-version: 2023-06-01
content-type: application/json
返回结构
{
"model": "claude-sonnet-4-5-20250929",
"stop_reason": "end_turn",
"usage": { "input_tokens": 100, "output_tokens": 76 },
"text": "模型返回的正文"
}
MCP 工具说明
当前只暴露一个工具:ask_model
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| prompt | string | 是 | 用户输入 |
| system | string | 否 | 系统提示词 |
| model | string | 否 | 覆盖默认模型 |
| maxTokens | number | 否 | 最大输出 token,默认 1024,上限 65536 |
补充说明:
- 传入超过
65536的maxTokens不会发到上游,而会在本地参数校验阶段直接报错 - 真实可用的输出上限仍然取决于你的上游服务和模型本身
调用示例(maxTokens 不传时默认 1024,此处显式设为 512 以演示用法):
{
"prompt": "介绍一下你自己",
"model": "claude-sonnet-4-5",
"maxTokens": 512
}
使用 system 限定模型行为:
{
"prompt": "What is MCP?",
"system": "You are a concise technical assistant. Reply in English only.",
"maxTokens": 256
}
接入常见 MCP 客户端
这类客户端的接入思路都差不多:
- 指定启动命令为
node /path/to/mcp-model-proxy/server.mjs - 通过环境变量传入上游地址、API Key 和默认模型
- 在客户端工具列表里调用
ask_model
下面以 Claude Code 这类支持 JSON MCP 配置的客户端为例(Windows,使用 cmd /c 启动;macOS/Linux 见 examples/mcp-client-config.macos.json):
Windows 上部分 MCP 宿主(如 Claude Code)需要通过
cmd /c间接调用node,否则会出现路径解析失败。macOS/Linux 直接用"command": "node"即可。
{
"mcpServers": {
"mcp-model-proxy": {
"command": "cmd",
"args": [
"/c",
"node",
"/path/to/mcp-model-proxy/server.mjs"
],
"env": {
"CLAUDE_MCP_BASE_URL": "https://your-base-url",
"CLAUDE_MCP_API_KEY": "your-token",
"CLAUDE_MCP_MODEL": "claude-sonnet-4-5",
"CLAUDE_MCP_ANTHROPIC_VERSION": "2023-06-01",
"CLAUDE_MCP_TIMEOUT_MS": "60000"
}
}
}
}
完整示例见 examples/mcp-client-config.windows.json。
如果你使用的是其他支持 MCP 的宿主,按同样思路把命令、参数和环境变量填进去即可。
验证方式
建议按顺序分层验证,不要直接看界面。
验证 1:直接打上游
以下为 Windows PowerShell 写法(curl.exe 避免 PowerShell 别名问题);macOS/Linux 将 curl.exe 改为 curl,行末反引号 ` 改为 \:
curl.exe -sS -D - -X POST "https://your-base-url/v1/messages" `
-H "x-api-key: your-token" `
-H "anthropic-version: 2023-06-01" `
-H "content-type: application/json" `
--data-raw "{\"model\":\"claude-sonnet-4-5\",\"max_tokens\":64,\"messages\":[{\"role\":\"user\",\"content\":\"请只回复OK\"}]}"
### 验证 2:用 Inspector 调 MCP
```powershell
npx @modelcontextprotocol/inspector --cli `
node /path/to/mcp-model-proxy/server.mjs `
--method tools/call `
--tool-name ask_model `
--tool-arg "prompt=介绍一下你自己"
故障排查
401 无效的令牌
先分清楚是哪里报的:
- 上游直连就
401:token 或 provider 本身有问题 - 直连上游
200,但经过本地代理401:代理层 token 配置不同步 - MCP 成功,但宿主客户端失败:宿主客户端走的不是同一条链路,或它自身的 MCP 配置没有生效
MCP 成功,但宿主客户端不出结果
检查:
- 宿主客户端的 MCP 配置文件里命令、参数和环境变量是否正确
- MCP 工具列表里能否看到
ask_model - 宿主客户端日志里最后一次请求是
200还是401
Request timed out after 60000ms
说明本地 MCP 已经发出请求,但你的上游在设定时间内没有返回。
检查:
- 上游地址是否可达,网络或代理是否正常
- 模型本身是否响应过慢
CLAUDE_MCP_TIMEOUT_MS是否设置得过小
PowerShell 里输入中文报错
终端会把自然语言当命令执行。要把问题作为 prompt 参数传给 ask_model,不能直接在终端敲自然语言。
已知限制
- 单工具、非流式:每次调用发一条新请求,不维护会话状态,不支持流式输出
- 单 provider:只认一套环境变量,不做自动切换或 fallback
- 上游行为不保证:不同上游的响应行为可能存在差异,建议以实际响应为准
- maxTokens 上限 65536:默认给出更宽松的上限,具体可用值仍然取决于你的上游和模型
- 默认 60 秒超时:超时会直接返回错误,需要按上游速度调大
CLAUDE_MCP_TIMEOUT_MS
适用场景
- 手里有兼容 Claude Messages API 的上游,但宿主工具只支持 MCP
- 想把上游能力统一包装成一个 MCP 工具供多个客户端复用
- 想先验证「模型和 token 能不能用」,再去排查 UI 和代理问题
不适合:
- 完整聊天应用、多 provider 管理、流式输出、生产级网关
FAQ
这是官方 Claude MCP 吗? 不是,这是本地自建的轻量适配层。
和直接调 API 相比,这个项目的优势是什么? 直接调 API 最简单,但每个宿主都要自己实现一遍接入逻辑。这个项目的价值是把上游接口统一包装成 MCP 工具,让多个支持 MCP 的客户端复用同一层适配。
为什么 Inspector 能用,宿主客户端里不能用? 两者链路不同。Inspector 通常是最短路径;宿主客户端往往还叠加了自己的配置、权限、日志和工具管理逻辑。排障时必须分层验证。
模型名写的是 Claude,返回内容像别的产品?
通常是上游做了包装或角色改写,不是 server.mjs 的问题。可以用验证方式章节的方法直接打上游确认原始响应。
安全建议
公开发布这个仓库时,建议保持下面这些边界:
README.md、examples/、.env.example里只放占位符,不放真实 token- 本机配置文件、数据库、用户目录下的私有文件不要进入仓库
.env这类本地变量文件继续保持在.gitignore中- 如果后面增加更多示例,优先使用
/path/to/...这类通用占位符路径
免责声明
本项目仅为技术适配工具,不提供任何 AI 模型服务,不存储任何用户数据。
使用本项目时,你需要自行:
- 确保你使用的上游 API 服务符合其服务条款
- 承担因使用上游服务产生的一切费用、法律责任和风险
- 遵守所在地区关于 AI 服务使用的相关法律法规
本项目作者不对以下情况承担任何责任:
- 上游服务的可用性、准确性或合法性
- 因使用本项目导致的任何直接或间接损失
- 任何第三方服务的条款变更或访问限制
本软件按"原样"提供,不附带任何明示或暗示的保证。使用风险由用户自行承担。