关于 OpenRouter MCP Multimodal Server
OpenRouter MCP Multimodal Server 将 MCP 客户端和编码 Agent 接入 OpenRouter,支持聊天以及多模态分析与生成。它还整合了模型发现、嵌入、决策和媒体工具。
主要功能
- 01调用 300 多个 OpenRouter 模型聊天
- 02分析和生成图像、音频与视频
- 03生成文本和语音转录
- 04生成文本嵌入并作结构化决策
- 05搜索、验证和重排模型
适用场景
- 01让 MCP 客户端比较不同模型的回答
- 02从图像、音频或视频中提取信息
- 03生成语音、音乐、图像或视频
- 04生成嵌入或重排文档
MCP 相关
它通过 stdio 向 MCP 客户端提供 21 个工具,涵盖聊天、多模态分析与生成、模型目录和嵌入。它支持 MCP 结构化输出及异步视频进度通知。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @stabgan/openrouter-mcp-multimodalOPENROUTER_API_KEY密钥OpenRouter API key. Get one free at https://openrouter.ai/keysOPENROUTER_DEFAULT_MODELDefault model for chat + analyze tools. Defaults to nvidia/nemotron-nano-12b-v2-vl:free.OPENROUTER_OUTPUT_DIRSandbox root for save_path on generate_* tools. Defaults to the current working directory.OPENROUTER_MAX_TOKENS密钥Default max_tokens for chat_completion when unset in the request.OPENROUTER_PROVIDER_SORTprice / throughput / latencyOPENROUTER_PROVIDER_IGNORECSV of provider slugs to exclude.OPENROUTER_PROVIDER_ORDERJSON array or CSV of preferred provider IDs.OPENROUTER_PROVIDER_QUANTIZATIONSCSV of quantization levels (fp16,int8).OPENROUTER_PROVIDER_REQUIRE_PARAMETERStrue/false. Require providers to support all request params.OPENROUTER_PROVIDER_DATA_COLLECTIONallow/denyOPENROUTER_PROVIDER_ALLOW_FALLBACKStrue/falseOPENROUTER_CACHE_RESPONSESEnable response caching server-wide. Sends X-OpenRouter-Cache: true on every chat/analyze call unless overridden per-request. Zero tokens billed on cache hits.OPENROUTER_INCLUDE_REASONINGEnable reasoning tokens passthrough server-wide. Adds _meta.reasoning to chat_completion responses for DeepSeek R1 / Gemini Thinking / Opus 4.7.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
14收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cache | boolean | 否 | 通过 `X-OpenRouter-Cache: true` 启用 OpenRouter 响应缓存。可通过 `OPENROUTER_CACHE_RESPONSES=1` 设置服务器级默认值。 |
| model | string | 否 | 模型 ID(可选,使用默认值)。追加 `:nitro` 使用最快变体,`:floor` 使用最便宜变体,或 `:exacto` 使用工具调用准确度最高的变体。例如:`openai/gpt-4o:nitro`。 |
| online | boolean | 否 | 启用 OpenRouter 的网页搜索插件(基于 Exa,每 1000 条结果 $4)。 |
| messages | array | 是 | |
| provider | object | 否 | OpenRouter 提供商路由覆盖项。与 `OPENROUTER_PROVIDER_*` 环境变量默认值合并。参见 https://openrouter.ai/docs/features/provider-routing |
| provider.sort | enum | 否 | price | throughput | latency |
| provider.order | array | 否 | |
| provider.ignore | array | 否 | 排除这些提供商 slug。 |
| provider.quantizations | array | 否 | 按量化方式筛选提供商(例如 `["fp16","int8"]`)。 |
| provider.allow_fallbacks | boolean | 否 | |
| provider.data_collection | enum | 否 | allow | deny |
| provider.require_parameters | boolean | 否 | |
| cache_ttl | string | 否 | 缓存 TTL(例如 `"5m"`、`"1h"`、`"24h"`;范围为 1s–24h)。 |
| max_tokens | number | 否 | 最大 completion token 数。未设置时回退到 `OPENROUTER_MAX_TOKENS` 环境变量。 |
| cache_clear | boolean | 否 | 清除与此精确请求对应的缓存条目。 |
| temperature | number | 否 | |
| web_max_results | number | 否 | `online: true` 时的网页搜索结果上限(默认 5)。 |
| include_reasoning | boolean | 否 | 将模型的思维链显示在 `_meta.reasoning` 中,适用于 R1 / Opus 4.7 / Gemini Thinking。 |
详细介绍
OpenRouter MCP 多模态
面向多模态 AI Agent 的 MCP 服务。
一次安装 · 21 个工具 · 300 多个 OpenRouter 模型 · 文本、视觉、音频和视频的分析与生成。
快速开始 · 工具 · 示例 · 安全 · 故障排除 · 开发 · 发布 · 常见问题
这是什么?
OpenRouter MCP Multimodal 是一款生产级的 Model Context Protocol(MCP) 服务,已列入官方 MCP 注册表,标识为 io.github.stabgan/openrouter-multimodal。它通过 stdio 将 AI 编码 Agent(Cursor、Claude Desktop、VS Code、Windsurf、Cline 等)连接到 OpenRouter 统一的大模型 API。
与仅支持文本的 MCP 服务不同,只需安装一次,即可覆盖完整的多模态功能:
| 能力 | 工具 | 亮点 |
|---|---|---|
| 聊天 | chat_completion、start_chat_completion、get_chat_completion_status | 300+ 个模型、:nitro / :floor / :free / :online / :exacto 后缀、提供商路由、网页搜索、响应缓存、推理 Token、推理力度控制、结构化输出(JSON Schema)、异步任务、多模型融合、子 Agent 委派、响应修复 |
| 视觉 | analyze_image、generate_image、generate_image_dedicated | OCR、图像描述、视觉问答(VQA)、支持参考输入的图像生成、可控制分辨率/质量/格式的专用图像 API |
| 音频 | analyze_audio、generate_audio、text_to_speech、speech_to_text | 转录、语音/音乐生成、专用 TTS(Deepgram、ElevenLabs、OpenAI;默认免费使用 Deepgram,支持音色、mp3/pcm)、专用 STT(Whisper、GPT-4o Transcribe、Voxtral、ElevenLabs Scribe) |
| 视频 | analyze_video、generate_video、generate_video_from_image、get_video_status | 视频片段理解、Veo 3.1 / Seedance 2.5 / Kling v3.0 / Wan 2.7 / Grok Imagine Video 生成,支持进度通知 |
| 嵌入 | embed_text | 37+ 个嵌入模型(text-embedding-3-small/large、Nomic、Jina、Voyage 等) |
| 决策 | decide | 结构化的是/否、选项或评分决策,并提供经过校准的概率(System One 模型) |
| 目录 | search_models、get_model_info、validate_model、rerank_documents、health_check | 模型发现、验证、重排序、运维健康检查 |
生产环境加固: 输入/输出路径沙箱(从 v4.5.2 开始也涵盖 analyze_* 本地文件)、SSRF 防护、包含 _meta.code 的结构化错误、MCP 2025-11-25 结构化输出 + 工具图标、异步视频进度通知,以及 3929 项自动化测试(3905 项单元/模拟测试 + 7 项回归测试 + 17 项实时集成测试)。
快速开始
1. 获取 API 密钥(免费套餐即可)→ openrouter.ai/keys
2. 运行服务
export OPENROUTER_API_KEY=sk-or-v1-...
npx -y @stabgan/openrouter-mcp-multimodal
3. 添加到 MCP 客户端 — 从 安装 复制一个 JSON 配置块到客户端配置中:
| 客户端 | 配置位置 |
|---|---|
| Cursor | 项目:.cursor/mcp.json · 用户:Cursor 设置 → MCP |
| Claude Desktop | macOS:~/Library/Application Support/Claude/claude_desktop_config.json · Windows:%APPDATA%\Claude\claude_desktop_config.json |
| VS Code | .vscode/mcp.json(工作区)或用户设置 → MCP |
| Windsurf | Windsurf 设置 → MCP(与 Cursor 使用相同的 mcpServers JSON 结构) |
使用下方手动配置中的 mcpServers 对象。
开始使用无需积分。
google/gemma-4-26b-a4b-it:free等免费模型可用于聊天和视觉任务。视频/音频生成通常需要积分。
安装
MCP 服务通过多种打包方式分发。此服务使用 Node.js/TypeScript 实现;下表列出了各生态系统的安装方式,以及在此处的运行方式。
| 方法 | 运行时 | 适用场景 | 本服务 |
|---|---|---|---|
| npx | Node.js 22+ | 大多数 MCP 客户端(默认) | ✅ @stabgan/openrouter-mcp-multimodal |
| uvx / pipx | Python 3.10+ and Node.js 22+ | 以 Python 为先的工作流,模式与 PyPI MCP 服务相同 | ✅ mcp-server-openrouter-multimodal |
| npm global | Node.js 22+ | 固定版本,无需重新下载 | ✅ |
| node (local) | Node.js 22+ | 贡献者/隔离网络构建 | ✅ |
| Docker Hub | Docker | 隔离运行,主机上无需安装 Node | ✅ stabgan/openrouter-mcp-multimodal |
| GHCR | Docker | 原生使用 GitHub 拉取 OCI 镜像 | ✅ ghcr.io/stabgan/openrouter-mcp-multimodal |
| Smithery CLI | Node.js(通过安装程序) | 交互式安装到 Claude/Cursor 等 | ✅ |
| MCP Registry | npm 或 OCI | 官方发现(io.github.stabgan/openrouter-multimodal) | ✅ 列表 |
| One-click deeplinks | Node.js | Cursor、VS Code、Kiro | ✅ |
| Claude Code CLI | Node.js | 以终端为主的 Claude Code 用户 | ✅ |
| MCP Inspector | Node.js | 在本地调试/列出工具 | ✅ |
Windows cmd /c npx | Node.js | 当 GUI PATH 中没有 npx 时,用于 Claude Desktop / Cursor | ✅ 见下文 |
| pip / uv (direct) | — | 仅原生 Python MCP 服务 | — 请使用上方的 uvx 行 |
| DXT desktop extensions | — | 打包的 Claude Desktop .dxt | 尚未提供 |
| Remote HTTP / SSE | — | 托管的 Smithery / Cloudflare 端点 | 通过 Smithery |
uvx 与 npx: 在 MCP 生态中,
npx运行 npm(Node)包,而uvx运行 PyPI(Python)包。由于此服务基于 Node,uvx会使用一个精简的 Python 启动器,该启动器会执行npx -y @stabgan/openrouter-mcp-multimodal——你仍然需要安装 Node。
一键安装
| Cursor | |
| VS Code | |
| Kiro | |
| Claude Desktop / Windsurf / Cline | 手动配置 JSON(从下方选择任意一种方法) |
| Smithery | npx -y @smithery/cli install @stabgan/openrouter-mcp-multimodal --client claude |
| MCP Registry | 官方注册表页面 — npm 和 OCI 包 |
出现提示时,请粘贴你的 OPENROUTER_API_KEY——深层链接使用占位符,因此密钥不会出现在 URL 中。
手动配置
npx(推荐)
export OPENROUTER_API_KEY=sk-or-v1-...
npx -y @stabgan/openrouter-mcp-multimodal
{
"mcpServers": {
"openrouter": {
"command": "npx",
"args": ["-y", "@stabgan/openrouter-mcp-multimodal"],
"env": {
"OPENROUTER_API_KEY": "sk-or-v1-..."
}
}
}
}
固定版本:"args": ["-y", "@stabgan/[email protected]"]
uvx / pipx(Python 启动器)
安装 uv(包含 uvx),并确保 Node.js 22+ 也在你的 PATH 中,然后:
export OPENROUTER_API_KEY=sk-or-v1-...
uvx mcp-server-openrouter-multimodal
# pin npm version: OPENROUTER_MCP_NPM_VERSION=5.1.3 uvx mcp-server-openrouter-multimodal
{
"mcpServers": {
"openrouter": {
"command": "uvx",
"args": ["mcp-server-openrouter-multimodal"],
"env": {
"OPENROUTER_API_KEY": "sk-or-v1-..."
}
}
}
}
pipx 等效命令: pipx run mcp-server-openrouter-multimodal
可选:OPENROUTER_MCP_NPM_VERSION=5.1.3 可固定底层 npm 包的版本。
npm 全局安装
npm install -g @stabgan/openrouter-mcp-multimodal
{
"mcpServers": {
"openrouter": {
"command": "openrouter-multimodal",
"env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
}
}
}
node(本地克隆)
git clone https://github.com/stabgan/openrouter-mcp-multimodal.git
cd openrouter-mcp-multimodal
npm ci && npm run build
{
"mcpServers": {
"openrouter": {
"command": "node",
"args": ["/absolute/path/to/openrouter-mcp-multimodal/dist/index.js"],
"env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
}
}
}
Docker
docker run --rm -i -e OPENROUTER_API_KEY=sk-or-v1-... stabgan/openrouter-mcp-multimodal:latest
{
"mcpServers": {
"openrouter": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"OPENROUTER_API_KEY=sk-or-v1-...",
"stabgan/openrouter-mcp-multimodal:latest"
]
}
}
}
使用 -i(交互式 stdio)。避免使用 -t(TTY 会导致某些主机上的 MCP 帧格式损坏)。
GHCR(GitHub Container Registry)
docker run --rm -i -e OPENROUTER_API_KEY=sk-or-v1-... \
ghcr.io/stabgan/openrouter-mcp-multimodal:5.1.3
{
"mcpServers": {
"openrouter": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"OPENROUTER_API_KEY=sk-or-v1-...",
"ghcr.io/stabgan/openrouter-mcp-multimodal:5.1.3"
]
}
}
}
Smithery
交互式安装(为你的客户端写入配置):
npx -y @smithery/cli install @stabgan/openrouter-mcp-multimodal --client claude
# or: --client cursor | vscode | windsurf | ...
MCP Registry
官方名称:io.github.stabgan/openrouter-multimodal
- 注册表:registry.modelcontextprotocol.io
- npm 包:
@stabgan/openrouter-mcp-multimodal - OCI 镜像:
docker.io/stabgan/openrouter-mcp-multimodal
支持注册表驱动安装的客户端会提供 npm 或 Docker 选项;否则请使用上面的 JSON 配置块。
Claude Code CLI
claude mcp add openrouter -- npx -y @stabgan/openrouter-mcp-multimodal
# project scope:
claude mcp add --scope project openrouter -- npx -y @stabgan/openrouter-mcp-multimodal
启动 Claude Code 前,请在 shell 或客户端环境中设置 OPENROUTER_API_KEY。
MCP Inspector
使用有效的 OpenRouter 密钥调试 tools/list 和工具调用:
export OPENROUTER_API_KEY=sk-or-v1-...
npx -y @modelcontextprotocol/inspector npx -y @stabgan/openrouter-mcp-multimodal
Windows npx
当 Claude Desktop 或 Cursor 找不到 npx 时(GUI 应用通常无法获取 shell 的 PATH),请使用 cmd 包装:
{
"mcpServers": {
"openrouter": {
"command": "cmd",
"args": ["/c", "npx", "-y", "@stabgan/openrouter-mcp-multimodal"],
"env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
}
}
}
如果仍然失败,请使用 where npx 输出的完整路径作为命令。
为什么选择此服务?
| 功能 | 此服务 | 典型 MCP 大模型服务 |
|---|---|---|
| 文本聊天(300+ 个模型) | ✅ | ✅ |
| 图像分析与生成 | ✅ | 部分支持 |
| 音频分析 + TTS + STT | ✅ | ❌ |
| 视频分析与生成 | ✅ | ❌ |
| 向量嵌入(37+ 个模型) | ✅ | ❌ |
| 结构化决策(System One) | ✅ | ❌ |
| 模型搜索 / 验证 / 重排 | ✅ | ❌ |
| 路径沙箱 + SSRF 防护 | ✅ | 少见 |
| MCP 2025 结构化输出 | ✅ | 少见 |
| 异步视频 + 进度通知 | ✅ | ❌ |
工具
共 21 个 MCP 工具。每个工具的描述都包含适用场景、良好 / 不良示例、失败条件和适用范围,帮助 Agent 选对工具并从错误中恢复。
| 工具 | 用途 |
|---|---|
chat_completion | 文本聊天、网络搜索、提供商路由、缓存、推理、结构化输出 |
start_chat_completion | 为长时间运行的推理模型启动异步后台任务 |
get_chat_completion_status | 轮询 / 获取异步完成结果 |
analyze_image | 视觉分析——本地路径、URL 或数据 URL + question |
analyze_audio | 转录 / 分析音频文件 |
analyze_video | 描述视频文件 / 基于视频文件进行问答 |
generate_image | 通过聊天补全和参考图像进行文生图 |
generate_image_dedicated | 通过专用 /api/v1/images 进行文生图(分辨率、质量、格式) |
generate_audio | 通过聊天补全进行文本转语音 / 音乐生成 |
text_to_speech | 专用 TTS(/api/v1/audio/speech)——Deepgram、ElevenLabs、OpenAI;音色、语速、mp3/pcm |
speech_to_text | 专用 STT(/api/v1/audio/transcriptions)——Whisper、GPT-4o Transcribe、Voxtral、ElevenLabs Scribe |
generate_video | 文本生成视频(异步、可恢复) |
generate_video_from_image | 图像生成视频(更精简的架构) |
get_video_status | 轮询 / 恢复视频任务 |
search_models | 分页搜索模型目录 |
get_model_info | 定价、上下文、模态 |
validate_model | 低成本检查模型 ID 是否存在 |
rerank_documents | RAG 相关性排序 |
embed_text | 向量嵌入(37+ 个模型:text-embedding-3-small/large、Nomic 等) |
decide | 使用经过校准的概率进行结构化决策(System One 模型) |
health_check | API 密钥 + 可访问性探测 |
每个错误都包含来自封闭分类体系(13 个代码)的 _meta.code。可根据这些代码进行分支处理,实现程序化处理:
_meta.code | 含义 | 解决方法 |
|---|---|---|
INVALID_INPUT | 参数错误或缺失 | 查看工具说明,确认正确的参数架构 |
INVALID_CREDENTIALS | API 密钥缺失、无效或已撤销 | 在 openrouter.ai/keys 重新生成 |
UNSAFE_PATH | 本地路径超出输入/输出沙箱 | 将文件移至 OPENROUTER_INPUT_DIR / OPENROUTER_OUTPUT_DIR 下 |
UPSTREAM_HTTP | OpenRouter 返回的非身份验证类 HTTP 错误(4xx/5xx) | 查看 _meta.details.status;若为暂时性错误,请重试 |
UPSTREAM_TIMEOUT | 上游未能及时响应 | 请重试,或对响应较慢的模型使用 start_chat_completion |
UPSTREAM_REFUSED | 内容政策、速率限制或额度不足 | 查看 _meta.retry_after_seconds;检查提示词或充值 |
UNSUPPORTED_FORMAT | 文件不是可识别的媒体格式 | 确认文件类型符合工具要求 |
RESOURCE_TOO_LARGE | 文件超出获取/内联大小限制 | 缩减文件,或使用 save_path 跳过内联 |
ZDR_INCOMPATIBLE | 模型/提供商要求零数据留存 | 使用兼容 ZDR 的提供商或其他模型 |
MODEL_NOT_FOUND | OpenRouter 目录中不存在该模型标识符 | 先运行 validate_model 或 search_models |
JOB_FAILED | 异步任务(视频/聊天)在提供商端失败 | 查看 _meta.details;重试或更换模型 |
JOB_STILL_RUNNING | 异步任务尚未完成(并非错误) | 调用 get_video_status / get_chat_completion_status 轮询 |
INTERNAL | 意外的服务端错误 | 如果可以复现,请报告 |
错误信息中会包含 _meta.suggestions,在可用时提供面向 Agent 的后续操作建议。
二进制工具结果(v4.7.0+)
生成工具(generate_image、generate_image_dedicated、generate_audio、text_to_speech、generate_video、generate_video_from_image、get_video_status)会返回图像、音频或视频字节。从 4.7.0 起,行为明确如下:
save_path | 工具结果 |
|---|---|
| 已设置 | 仅文本指针 — 例如 Image saved to: out.png (… bytes, image/png) 加上 _meta.save_path。不含内联 base64(避免在 MCP 通道中重复大型负载)。 |
| 未设置,低于字节上限 | 内联媒体块和摘要文本(图像/音频使用 MCP image / audio 类型;视频使用 MCP resource 块)。 |
| 未设置,超过上限 | 仅文本,并提示传入 save_path。 |
默认内联上限(可按类型或全局覆盖):
| 类型 | 默认值 | 环境变量(优先级:按类型 → 全局) |
|---|---|---|
| 图像 | 1 MiB | OPENROUTER_IMAGE_INLINE_MAX_BYTES → OPENROUTER_INLINE_MAX_BYTES |
| 音频 | 1 MiB | OPENROUTER_AUDIO_INLINE_MAX_BYTES → OPENROUTER_INLINE_MAX_BYTES |
| 视频 | 10 MiB | OPENROUTER_VIDEO_INLINE_MAX_BYTES → OPENROUTER_INLINE_MAX_BYTES |
如果你之前依赖同一工具结果中同时包含已保存文件和内联媒体,请从 _meta.save_path 读取文件(或省略 save_path,以便在低于上限时获取内联媒体)。
示例
聊天(免费模型)
{
"tool": "chat_completion",
"arguments": {
"model": "google/gemma-4-26b-a4b-it:free",
"messages": [{ "role": "user", "content": "Summarize MCP in one sentence." }]
}
}
带结构化输出的聊天(JSON Schema)
{
"tool": "chat_completion",
"arguments": {
"model": "openai/gpt-4o",
"messages": [{ "role": "user", "content": "Extract the name and age from: 'Alice is 30 years old.'" }],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "person",
"schema": {
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" }
},
"required": ["name", "age"]
}
}
}
}
}
如需不使用架构的简单 JSON,请使用
"response_format": { "type": "json_object" }。添加"response_healing": true可自动修复格式错误的 JSON。
分析图像
{
"tool": "analyze_image",
"arguments": {
"image_path": "diagram.png",
"question": "List every label in this diagram."
}
}
使用
image_path和question,而不是image/prompt。
搜索模型(视觉 + 免费)
{
"tool": "search_models",
"arguments": {
"query": "gemma",
"capabilities": { "vision": true },
"limit": 10,
"offset": 0
}
}
生成视频(异步)
{
"tool": "generate_video",
"arguments": {
"model": "google/veo-3.1",
"prompt": "Ocean waves at sunrise, cinematic drone shot",
"duration": 4,
"save_path": "river.mp4"
}
}
如果 max_wait_ms 到期时任务仍在运行,响应会成功返回 _meta.code: JOB_STILL_RUNNING 和一个 video_id — 调用 get_video_status 即可继续。这不是错误。
设置了 save_path 时(如上所示),任务完成后结果会是指向已保存文件的文本指针,而不是内联视频。请参阅二进制工具结果。
嵌入文本(向量嵌入)
{
"tool": "embed_text",
"arguments": {
"texts": ["What is MCP?", "Model Context Protocol enables tool use for LLMs."],
"model": "openai/text-embedding-3-small",
"dimensions": 1024
}
}
返回用于 RAG、语义搜索或聚类的嵌入数组。支持 37+ 个模型 — 传入单个字符串或最多包含 2048 条文本的数组。
结构化决策(System One)
{
"tool": "decide",
"arguments": {
"questions": {
"is_bug": {
"type": "noul",
"instructions": "Is this a bug report or a feature request?",
"criteria": {
"true": "Describes broken or incorrect behavior",
"false": "Requests new functionality"
}
}
},
"state": {
"ticket": "The login button does not respond when clicked on Safari."
}
}
}
返回校准后的概率,而不是生成的文本。包含三种问题类型:noul(是/否)、choice(选择一个类别)、score(序数评分标准)。模型:typesafe/jev-1.13(默认)、upstage/solar-decide、microsoft/decision-1。
更多示例:docs/plans/tool-description-improvement.md
安全
- 输入路径沙箱 —
analyze_*中的本地路径和参考图像必须位于OPENROUTER_INPUT_DIR内(未设置时回退到OPENROUTER_OUTPUT_DIR,再回退到cwd) - 输出路径沙箱 —
save_path必须位于OPENROUTER_OUTPUT_DIR内 - 异步任务读取 —
get_chat_completion_status仅解析OPENROUTER_OUTPUT_DIR/openrouter-jobs/下的磁盘路径(4.7.0+) - SSRF 防护 — 获取 URL 时会阻止私有 IP 和保留 IP
- 不可信内容 — 分析输出会标记
_meta.content_is_untrusted: true - 原型污染防御 — 所有 API 输出边界(模型记录、嵌入、决策、重排结果、日志上下文)都会递归移除
__proto__、constructor和prototype键,然后再转发给 MCP 客户端 - 密钥脱敏 — stderr JSON 日志记录器会对 API 密钥和敏感值进行脱敏;stdout 专用于 MCP 协议流量
仅在 OPENROUTER_ALLOW_UNSAFE_PATHS=1 时覆盖沙箱(不建议)。
报告漏洞:SECURITY.md(私下披露 — 请勿公开提交漏洞利用相关的问题)。
配置
环境变量
| 变量 | 必需 | 默认值 | 描述 |
|---|---|---|---|
OPENROUTER_API_KEY | 是 | — | OpenRouter API 密钥 |
OPENROUTER_DEFAULT_MODEL | 否 | google/gemma-4-26b-a4b-it:free | 工具未指定 model 时使用的默认值 |
OPENROUTER_OUTPUT_DIR | 否 | cwd | save_path 的沙箱根目录 |
OPENROUTER_INPUT_DIR | 否 | OUTPUT_DIR 或 cwd | 本地输入文件的沙箱根目录 |
OPENROUTER_INLINE_MAX_BYTES | 否 | 1048576(图像/音频) | 全局内联媒体上限 |
OPENROUTER_IMAGE_INLINE_MAX_BYTES | 否 | 回退到全局值 | 各类型内联上限 |
OPENROUTER_AUDIO_INLINE_MAX_BYTES | 否 | 回退到全局值 | 各类型内联上限 |
OPENROUTER_VIDEO_INLINE_MAX_BYTES | 否 | 10485760 | 视频内联上限 |
OPENROUTER_LOG_LEVEL | 否 | info | error / warn / info / debug |
完整列表(提供商路由、获取限制、缓存、视频轮询、异步任务、集成测试覆盖项)请参阅 .env.example。
开发
git clone https://github.com/stabgan/openrouter-mcp-multimodal.git
cd openrouter-mcp-multimodal
npm install
cp .env.example .env # add OPENROUTER_API_KEY
npm run build
测试
| 命令 | 运行内容 |
|---|---|
npm test | 3905 个单元测试和模拟测试(无需 API 密钥,<20s) |
npm run test:regression | 7 个安全性和架构回归防护测试 |
npm run test:integration | 17 个 OpenRouter 在线场景(需要 .env 密钥) |
npm run test:e2e | 完整 MCP stdio 冒烟测试(scripts/live-e2e.mjs) |
npm run ci | lint + 格式检查 + 版本同步 + 构建 + 所有测试 |
**适用于 CI / 零额度账户的免费模型:**集成测试默认使用 google/gemma-4-26b-a4b-it:free(可通过 OPENROUTER_INTEGRATION_MODEL 覆盖)。GitHub Actions 需要 OPENROUTER_API_KEY 仓库密钥。
模拟测试位于 src/__tests__/mock/ 下,涵盖处理程序、路径沙箱、SSRF 阻止、模型缓存分页、工具描述和结构化输出 — 在核心测试套件之外还增加了 396 个用例。
npm run lint
npm run format:check
npm run version:check # package.json vs src/version.ts, server.json, pyproject.toml
发布
已发布的制品(npm、PyPI/uvx、Docker、GHCR)均使用 git 标签(vX.Y.Z)中的同一 semver 版本。向 main 推送会运行测试,但不会发布到 npm 或 PyPI。
**常规流程:**将符合 Conventional Commits 规范的提交合并到 main → Release Please 创建 Release PR → 合并该 PR → 创建标签 → CI 发布到所有平台。
**手动流程:**更新所有版本文件 → npm run version:check → npm run ci + 冒烟测试 → 提交 → git tag vX.Y.Z → git push origin vX.Y.Z。
完整清单、文件列表、CI 密钥和 Agent 说明:
docs/RELEASING.md— 维护者发布指南AGENTS.md— AI Agent 快速参考
故障排除
| 症状 | 可能原因 | 修复 |
|---|---|---|
服务立即退出 / OPENROUTER_API_KEY is required | API 密钥缺失或为空 | 在客户端的 env 或 shell 中设置 OPENROUTER_API_KEY — 在 openrouter.ai/keys 获取密钥 |
_meta.code: INVALID_CREDENTIALS 或 HTTP 401 | 密钥无效或已撤销 | 在 openrouter.ai/keys 重新生成;重启 MCP 客户端 |
_meta.code: MODEL_NOT_FOUND | 模型 ID 拼写错误或已停用 | 运行 search_models 或 validate_model;查看 openrouter.ai/models |
| HTTP 402 / 额度不足 | 使用付费模型或余额为零时进行生成 | 在 openrouter.ai/credits 充值,或使用 :free 模型 |
_meta.code: UPSTREAM_HTTP with 429 | 速率限制 | 如果存在 _meta.retry_after_seconds,请等待指定时间;降低并发数 |
_meta.code: UNSAFE_PATH | 本地路径位于沙箱之外 | 将文件放在 OPENROUTER_INPUT_DIR 下,或扩大 OPENROUTER_OUTPUT_DIR 范围;参见安全 |
找不到 npx(Windows GUI 应用) | GUI 的 PATH 与终端不同 | 使用 Windows npx 的 cmd /c 包装命令 |
| 升级后没有内嵌图像/音频 | 设置了 save_path 的 v4.7.0 | 这是预期行为 — 结果仅包含文本和 _meta.save_path;省略 save_path 或读取已保存的文件 |
| MCP 客户端显示过时的工具列表 | 客户端缓存 | 升级软件包版本后重启 MCP 客户端 / 重新加载窗口 |
结构化错误在适用时会包含 _meta.suggestions,提供面向 Agent 的后续操作建议。
常见问题
我需要购买 OpenRouter 额度吗?
开始使用不需要。免费模型可用于聊天和视觉任务。音频/视频生成通常需要额度;部分模型的分析可能返回 402 — 服务会将其作为结构化错误呈现。
支持哪些 MCP 客户端?
任何通过 stdio 连接的兼容 MCP 客户端:Cursor、Claude Desktop、VS Code Copilot、Windsurf、Cline、Kiro 和自定义 Agent。
这与直接调用 OpenRouter 有何不同?
此服务添加了 MCP 工具架构、安全沙箱、错误分类、模型缓存、带进度通知的异步视频轮询,以及面向 Agent 的工具描述,因此大模型无需编写自定义 HTTP 代码,就能调用正确的功能。
路径遍历的安全公告在哪里?
已在 4.5.2+ 中修复——请参阅 GHSA-3q7p-736f-x44v、SECURITY.md 和 docs/solutions/security-issues/。
兼容性
适用于任何 MCP 客户端。协议:MCP 2025-11-25(向后兼容 2025-06-18 及更早版本)。Node ≥ 22(Docker 镜像使用 Node 24)。
许可证
Apache 2.0——请参阅 LICENSE。
贡献
欢迎提交 Issue 和 PR。对于较大的更改,请先创建 Issue。
提交前:运行 npm run ci。请使用 Conventional Commits(fix:、feat: 等),以便 Release Please 创建下一个版本。如果需要发布版本,请参阅 docs/RELEASING.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。