A unified multimodal bridge to OpenRouter's 300+ model catalog. Exposes six tools: chat_completion for text generation with provider routing and response caching, analyze_image/audio/video for understanding media files or URLs, and generate_image/audio for creation workflows. The video analysis tool handles mp4, mov, and webm formats, while video generation taps models like Veo 3.1 and Sora 2 Pro. Image inputs get sharp optimization automatically. Audio generation wraps raw PCM in WAV containers. Works with Claude Desktop, Cursor, VS Code, Windsurf, Cline, and Kiro. You'd reach for this when you need vision, speech, or video capabilities without juggling multiple API clients or when OpenRouter's per-request model switching matters more than provider lock-in.
The MCP server for multimodal AI agents.
One install · 14 tools · 300+ OpenRouter models · text, vision, audio & video — analysis and generation.
Quick start · Tools · Examples · Security · Development · FAQ
OpenRouter MCP Multimodal is a production-grade Model Context Protocol (MCP) server — listed on the official MCP Registry as io.github.stabgan/openrouter-multimodal. It connects AI coding agents (Cursor, Claude Desktop, VS Code, Windsurf, Cline, and others) to OpenRouter's unified LLM API over stdio.
Unlike text-only MCP servers, one install covers the full multimodal surface:
| Capability | Tools | Highlights |
|---|---|---|
| Chat | chat_completion | 300+ models, :nitro / :exacto suffixes, provider routing, web search, response caching, reasoning tokens |
| Vision | analyze_image, generate_image | OCR, captioning, VQA, image generation with reference inputs |
| Audio | analyze_audio, generate_audio | Transcription, speech/music generation |
| Video | analyze_video, generate_video, generate_video_from_image, get_video_status | Clip understanding, Veo / Sora / Seedance / Wan generation with progress notifications |
| Catalog | search_models, get_model_info, validate_model, rerank_documents, health_check | Model discovery, validation, reranking, ops health |
Production hardening: input/output path sandboxes (including analyze_* local files as of v4.5.2), SSRF guards, structured errors with _meta.code, MCP 2025-06-18 structured outputs, async video progress notifications, and 650+ automated tests (unit, mock, regression, and live integration).
1. Get an API key (free tier works) → openrouter.ai/keys
2. Run the server
export OPENROUTER_API_KEY=sk-or-v1-...
npx -y @stabgan/openrouter-mcp-multimodal
3. Add to your MCP client (Cursor, Claude Desktop, VS Code, etc.) — see Install below.
No credits required to start. Free models such as
google/gemma-4-26b-a4b-it:freework for chat and vision. Video/audio generation typically needs credits.
MCP servers are distributed through several packaging models. This server is implemented in Node.js/TypeScript; the table below maps each ecosystem method to how you run it here.
| Method | Runtime | Best for | This server |
|---|---|---|---|
| npx | Node.js 20+ | Most MCP clients (default) | ✅ @stabgan/openrouter-mcp-multimodal |
| uvx / pipx | Python 3.10+ and Node.js 20+ | Python-first workflows, same pattern as PyPI MCP servers | ✅ mcp-server-openrouter-multimodal |
| npm global | Node.js 20+ | Pin a version without re-downloading | ✅ |
| node (local) | Node.js 20+ | Contributors / air-gapped builds | ✅ |
| Docker Hub | Docker | Isolation, no Node on host | ✅ stabgan/openrouter-mcp-multimodal |
| GHCR | Docker | GitHub-native OCI pulls | ✅ ghcr.io/stabgan/openrouter-mcp-multimodal |
| Smithery CLI | Node.js (via installer) | Interactive install into Claude/Cursor/etc. | ✅ |
| MCP Registry | npm or OCI | Official discovery (io.github.stabgan/openrouter-multimodal) | ✅ listing |
| One-click deeplinks | Node.js | Cursor, VS Code, Kiro | ✅ |
| Claude Code CLI | Node.js | Terminal-first Claude Code users | ✅ |
| MCP Inspector | Node.js | Debug / list tools locally | ✅ |
Windows cmd /c npx | Node.js | Claude Desktop / Cursor when npx not on GUI PATH | ✅ see below |
| pip / uv (direct) | — | Native Python MCP servers only | — use uvx row above |
| DXT desktop extensions | — | Bundled Claude Desktop .dxt | not yet |
| Remote HTTP / SSE | — | Hosted Smithery / Cloudflare endpoints | via Smithery |
uvx vs npx: In the MCP ecosystem,
npxruns npm (Node) packages anduvxruns PyPI (Python) packages. Because this server is Node-based,uvxuses a thin Python launcher that execsnpx -y @stabgan/openrouter-mcp-multimodal— you still need Node installed.
| Cursor | |
| VS Code | |
| Kiro | |
| Claude Desktop / Windsurf / Cline | Manual JSON config (pick any method below) |
| Smithery | npx -y @smithery/cli install @stabgan/openrouter-mcp-multimodal --client claude |
| MCP Registry | Official registry page — npm + OCI packages |
Paste your OPENROUTER_API_KEY when prompted — deeplinks use placeholders so secrets never appear in URLs.
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-..."
}
}
}
}
Pin a release: "args": ["-y", "@stabgan/openrouter-mcp-multimodal@4.5.3"]
Install uv (includes uvx), ensure Node.js 20+ is also on your PATH, then:
export OPENROUTER_API_KEY=sk-or-v1-...
uvx mcp-server-openrouter-multimodal
# pin npm version: OPENROUTER_MCP_NPM_VERSION=4.5.3 uvx mcp-server-openrouter-multimodal
{
"mcpServers": {
"openrouter": {
"command": "uvx",
"args": ["mcp-server-openrouter-multimodal"],
"env": {
"OPENROUTER_API_KEY": "sk-or-v1-..."
}
}
}
}
pipx equivalent: pipx run mcp-server-openrouter-multimodal
Optional: OPENROUTER_MCP_NPM_VERSION=4.5.3 pins the underlying npm package.
npm install -g @stabgan/openrouter-mcp-multimodal
{
"mcpServers": {
"openrouter": {
"command": "openrouter-multimodal",
"env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
}
}
}
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 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"
]
}
}
}
Use -i (interactive stdio). Avoid -t (TTY corrupts MCP framing on some hosts).
docker run --rm -i -e OPENROUTER_API_KEY=sk-or-v1-... \
ghcr.io/stabgan/openrouter-mcp-multimodal:4.5.3
{
"mcpServers": {
"openrouter": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "OPENROUTER_API_KEY=sk-or-v1-...",
"ghcr.io/stabgan/openrouter-mcp-multimodal:latest"
]
}
}
}
Interactive install (writes config for your client):
npx -y @smithery/cli install @stabgan/openrouter-mcp-multimodal --client claude
# or: --client cursor | vscode | windsurf | ...
Listing: smithery.ai/server/@stabgan/openrouter-mcp-multimodal
Official name: io.github.stabgan/openrouter-multimodal
@stabgan/openrouter-mcp-multimodaldocker.io/stabgan/openrouter-mcp-multimodalClients that support registry-driven install will offer npm or Docker; otherwise use the JSON blocks above.
claude mcp add openrouter -- npx -y @stabgan/openrouter-mcp-multimodal
# project scope:
claude mcp add --scope project openrouter -- npx -y @stabgan/openrouter-mcp-multimodal
Set OPENROUTER_API_KEY in your shell or client env before starting Claude Code.
Debug tools/list and tool calls against a live OpenRouter key:
export OPENROUTER_API_KEY=sk-or-v1-...
npx -y @modelcontextprotocol/inspector npx -y @stabgan/openrouter-mcp-multimodal
When Claude Desktop or Cursor cannot find npx (GUI apps often miss shell PATH), wrap with cmd:
{
"mcpServers": {
"openrouter": {
"command": "cmd",
"args": ["/c", "npx", "-y", "@stabgan/openrouter-mcp-multimodal"],
"env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
}
}
}
If still failing, use the full path from where npx as the command.
| Capability | This server | Typical MCP LLM servers |
|---|---|---|
| Text chat (300+ models) | ✅ | ✅ |
| Image analysis + generation | ✅ | partial |
| Audio analysis + TTS | ✅ | ❌ |
| Video analysis + generation | ✅ | ❌ |
| Model search / validate / rerank | ✅ | ❌ |
| Path sandbox + SSRF protection | ✅ | rare |
| MCP 2025 structured outputs | ✅ | rare |
| Async video + progress notifications | ✅ | ❌ |
14 MCP tools. Each description includes Use when, Good/Bad examples, Fails when, and Works with so agents pick the right tool and recover from errors.
| Tool | Purpose |
|---|---|
chat_completion | Text chat, web search, provider routing, caching, reasoning |
analyze_image | Vision — local path, URL, or data URL + question |
analyze_audio | Transcribe / analyze audio files |
analyze_video | Describe / Q&A over video files |
generate_image | Text-to-image with optional reference images |
generate_audio | Text-to-speech / music |
generate_video | Text-to-video (async, resumable) |
generate_video_from_image | Image-to-video (narrower schema) |
get_video_status | Poll / resume video jobs |
search_models | Paginated model catalog search |
get_model_info | Pricing, context, modalities |
validate_model | Cheap model ID existence check |
rerank_documents | Relevance ranking for RAG |
health_check | API key + reachability probe |
Errors use a closed _meta.code taxonomy: INVALID_INPUT · UNSAFE_PATH · UPSTREAM_* · MODEL_NOT_FOUND · JOB_STILL_RUNNING · and more.
{
"tool": "chat_completion",
"arguments": {
"model": "google/gemma-4-26b-a4b-it:free",
"messages": [{ "role": "user", "content": "Summarize MCP in one sentence." }]
}
}
{
"tool": "analyze_image",
"arguments": {
"image_path": "diagram.png",
"question": "List every label in this diagram."
}
}
Use
image_pathandquestion— notimage/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"
}
}
If the job is still running when max_wait_ms elapses, the response succeeds with _meta.code: JOB_STILL_RUNNING and a video_id — call get_video_status to resume. This is not an error.
More examples: docs/plans/tool-description-improvement.md
analyze_* and reference images must stay inside OPENROUTER_INPUT_DIRsave_path must stay inside OPENROUTER_OUTPUT_DIR_meta.content_is_untrusted: trueOverride sandboxes only with OPENROUTER_ALLOW_UNSAFE_PATHS=1 (discouraged).
| Variable | Required | Default | Description |
|---|---|---|---|
OPENROUTER_API_KEY | Yes | — | OpenRouter API key |
OPENROUTER_DEFAULT_MODEL | No | nvidia/nemotron-nano-12b-v2-vl:free | Default when tools omit model |
OPENROUTER_INTEGRATION_MODEL | No | google/gemma-4-26b-a4b-it:free | Model used by live integration tests |
OPENROUTER_OUTPUT_DIR | No | cwd | Sandbox root for save_path |
OPENROUTER_INPUT_DIR | No | — | Sandbox root for local input files |
OPENROUTER_LOG_LEVEL | No | info | error / warn / info / debug |
See .env.example for the full list (provider routing, image/audio/video limits, caching, video polling).
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
| Command | What it runs |
|---|---|
npm test | 652 unit + mock tests (no API key, <2s) |
npm run test:regression | Security + schema regression guards |
npm run test:integration | 16 live OpenRouter scenarios (requires .env key) |
npm run test:e2e | Full MCP stdio smoke (scripts/live-e2e.mjs) |
npm run ci | lint + format + build + all of the above except e2e |
Free models for CI / zero-credit accounts: integration tests default to google/gemma-4-26b-a4b-it:free (override with OPENROUTER_INTEGRATION_MODEL). GitHub Actions requires the OPENROUTER_API_KEY repository secret.
Mock tests live under src/__tests__/mock/ and cover handlers, path sandboxes, SSRF blocks, model-cache pagination, tool descriptions, and structured outputs — 330+ additional cases beyond the core suite.
npm run lint
npm run format:check
No, to get started. Free models work for chat and vision. Audio/video generation usually requires credits; analysis may return 402 on some models — the server surfaces that as a structured error.
Any MCP-compatible client over stdio: Cursor, Claude Desktop, VS Code Copilot, Windsurf, Cline, Kiro, and custom agents.
This server adds MCP tool schemas, security sandboxes, error taxonomy, model caching, async video polling with progress notifications, and agent-oriented tool descriptions — so LLMs invoke the right capability without custom HTTP glue.
Fixed in 4.5.2+ — see GHSA-3q7p-736f-x44v and docs/solutions/security-issues/.
Works with any MCP client. Protocol: MCP 2025-06-18. Node ≥ 20 (Docker image uses Node 22).
Apache 2.0 — see LICENSE.
Issues and PRs welcome. For large changes, open an issue first. Run npm run ci before submitting.
OPENROUTER_API_KEY*secretOpenRouter API key. Get one free at https://openrouter.ai/keys
OPENROUTER_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_TOKENSDefault max_tokens for chat_completion when unset in the request.
OPENROUTER_PROVIDER_SORTprice / throughput / latency
OPENROUTER_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/deny
OPENROUTER_PROVIDER_ALLOW_FALLBACKStrue/false
OPENROUTER_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.
io.github.mindstone/mcp-server-microsoft-teams
com.mintmcp/outlook-email
helbertparanhos/resend-email-mcp
marlinjai/email-mcp
io.github.mindstone/mcp-server-email-imap
io.github.osamahassouna/email-playbook-mcp