loading…
Search for a command to run...
loading…
All-in-one multimodal MCP for 300+ OpenRouter models: text chat, image / audio / video analysis, and image / audio / video generation (Veo 3.1, Sora 2 Pro, Seed
All-in-one multimodal MCP for 300+ OpenRouter models: text chat, image / audio / video analysis, and image / audio / video generation (Veo 3.1, Sora 2 Pro, Seedance, Wan). Structured meta.code error taxonomy, IPv4+IPv6 SSRF guards, path-sandbox for disk writes, retry-after-aware backoff, multi-arch Docker.
The only MCP server that does text + image + audio + video analysis AND generation in one package.
Connect Claude Desktop, Cursor, Kiro, VS Code, Windsurf, or Cline to 300+ LLMs via OpenRouter.
Install · Tools · Examples · Config · Changelog
npx -y @stabgan/openrouter-mcp-multimodal # that's it — needs OPENROUTER_API_KEY env var
Get a free API key → openrouter.ai/keys
| Kiro | |
| Cursor | |
| VS Code | |
| VS Code Insiders | |
| Claude Desktop | Manual config — Add to claude_desktop_config.json |
| Windsurf | Manual config — Add to ~/.codeium/windsurf/mcp_config.json |
| Cline | Manual config — Add via Cline MCP settings |
| Smithery | npx -y @smithery/cli install @stabgan/openrouter-mcp-multimodal --client claude |
After clicking, the target client opens a confirmation prompt. Paste your
OPENROUTER_API_KEY— the deeplink ships a placeholder so no secrets end up in shared links.
{
"mcpServers": {
"openrouter": {
"command": "npx",
"args": ["-y", "@stabgan/openrouter-mcp-multimodal"],
"env": {
"OPENROUTER_API_KEY": "sk-or-v1-..."
}
}
}
}
{
"mcpServers": {
"openrouter": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "OPENROUTER_API_KEY=sk-or-v1-...",
"stabgan/openrouter-mcp-multimodal:latest"
]
}
}
}
npm install -g @stabgan/openrouter-mcp-multimodal
{
"mcpServers": {
"openrouter": {
"command": "openrouter-multimodal",
"env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
}
}
}
| Capability | This server | Others |
|---|---|---|
| Text chat with 300+ models | ✅ | ✅ |
| Image analysis (vision) | ✅ sharp-optimized | some |
| Audio analysis + generation | ✅ | ❌ |
| Video understanding (mp4/mov/webm) | ✅ | ❌ |
| Video generation (Veo 3.1, Sora 2 Pro) | ✅ | ❌ |
| Response caching (zero tokens on hit) | ✅ | ❌ |
| Web search, rerank, health check | ✅ | ❌ |
| MCP 2025-06-18 spec (structured outputs, progress) | ✅ | ❌ |
| Tool | What it does |
|---|---|
chat_completion |
Send messages to any model. Supports provider routing, model suffixes (:nitro, :floor, :exacto), response caching, reasoning passthrough, and web search. |
analyze_image |
Analyze images from local files, URLs, or data URIs. Auto-optimized with sharp. |
analyze_audio |
Transcribe/analyze audio (WAV, MP3, FLAC, OGG) from files, URLs, or data URIs. |
analyze_video |
Analyze video (mp4, mpeg, mov, webm) from files, URLs, or data URIs. |
generate_image |
Generate images with aspect ratio control and optional path-sandboxed disk save. |
generate_audio |
Generate speech or music. Auto-detects format, wraps raw PCM in WAV. |
generate_video |
Generate video via async API (Veo 3.1 / Sora 2 Pro / Seedance / Wan) with MCP progress notifications. |
generate_video_from_image |
Image-to-video. Narrower schema than generate_video for higher tool-call accuracy. |
get_video_status |
Resume polling a video generation job by ID. |
rerank_documents |
Rerank documents against a query (Cohere, Fireworks). |
search_models |
Search/filter models by name, provider, or modality. Paginated. |
get_model_info |
Get pricing, context length, and capabilities for any model. |
validate_model |
Check if a model ID exists on OpenRouter. |
health_check |
Verify API key, OpenRouter reachability, server + protocol versions. |
All errors carry
_meta.codefrom a closed taxonomy:INVALID_INPUT·UNSAFE_PATH·UPSTREAM_HTTP·UPSTREAM_TIMEOUT·UPSTREAM_REFUSED·UNSUPPORTED_FORMAT·RESOURCE_TOO_LARGE·ZDR_INCOMPATIBLE·MODEL_NOT_FOUND·JOB_FAILED·JOB_STILL_RUNNING·INTERNAL
Chat with provider routing:
{
"tool": "chat_completion",
"arguments": {
"model": "anthropic/claude-sonnet-4",
"messages": [{ "role": "user", "content": "Summarize this document" }],
"provider": { "sort": "price", "ignore": ["openai"], "data_collection": "deny" }
}
}
Generate video from Claude Desktop:
{
"tool": "generate_video",
"arguments": {
"model": "google/veo-3.1",
"prompt": "a calm river at sunrise, cinematic drone shot",
"duration": 4,
"save_path": "./river.mp4"
}
}
Analyze an image:
{
"tool": "analyze_image",
"arguments": {
"image": "/path/to/photo.jpg",
"prompt": "Describe what you see in detail"
}
}
Chat with caching + reasoning (v4.5):
{
"tool": "chat_completion",
"arguments": {
"model": "deepseek/deepseek-r1",
"messages": [{ "role": "user", "content": "Prove sqrt(2) is irrational" }],
"cache": true,
"include_reasoning": true
}
}
Web search:
{
"tool": "chat_completion",
"arguments": {
"model": "openai/gpt-4o",
"messages": [{ "role": "user", "content": "What shipped in OpenRouter last week?" }],
"online": true
}
}
Rerank documents:
{
"tool": "rerank_documents",
"arguments": {
"query": "best practices for MCP server auth",
"documents": ["doc A text...", "doc B text...", "doc C text..."],
"top_n": 3
}
}
| Variable | Required | Default | Description |
|---|---|---|---|
OPENROUTER_API_KEY |
Yes | — | Your OpenRouter API key |
OPENROUTER_DEFAULT_MODEL |
No | nvidia/nemotron-nano-12b-v2-vl:free |
Default model for chat + analyze tools |
DEFAULT_MODEL |
No | — | Alias for above |
OPENROUTER_MAX_TOKENS |
No | — | Default max_tokens when not set per-request |
OPENROUTER_PROVIDER_QUANTIZATIONS |
No | — | CSV. Filter by quantization (e.g. fp16,int8) |
OPENROUTER_PROVIDER_IGNORE |
No | — | CSV. Exclude provider slugs |
OPENROUTER_PROVIDER_SORT |
No | — | price / throughput / latency |
OPENROUTER_PROVIDER_ORDER |
No | — | JSON array or CSV of provider IDs |
OPENROUTER_PROVIDER_REQUIRE_PARAMETERS |
No | — | true / false |
OPENROUTER_PROVIDER_DATA_COLLECTION |
No | — | allow / deny |
OPENROUTER_PROVIDER_ALLOW_FALLBACKS |
No | — | true / false |
OPENROUTER_CACHE_RESPONSES |
No | — | 1 / true. Enable response caching server-wide |
OPENROUTER_INCLUDE_REASONING |
No | — | 1 / true. Enable reasoning passthrough server-wide |
OPENROUTER_MODEL_CACHE_TTL_MS |
No | 3600000 |
Model cache TTL (ms) |
OPENROUTER_IMAGE_MAX_DIMENSION |
No | 800 |
Longest edge for resize (px) |
OPENROUTER_IMAGE_JPEG_QUALITY |
No | 80 |
JPEG quality (1–100) |
OPENROUTER_IMAGE_FETCH_TIMEOUT_MS |
No | 30000 |
Image URL timeout |
OPENROUTER_IMAGE_MAX_DOWNLOAD_BYTES |
No | 26214400 |
Image URL size cap (~25 MB) |
OPENROUTER_IMAGE_MAX_REDIRECTS |
No | 8 |
Image URL redirect cap |
OPENROUTER_IMAGE_MAX_DATA_URL_BYTES |
No | 20971520 |
Image data URL size cap (~20 MB) |
OPENROUTER_AUDIO_FETCH_TIMEOUT_MS |
No | 30000 |
Audio URL timeout |
OPENROUTER_AUDIO_MAX_DOWNLOAD_BYTES |
No | 26214400 |
Audio URL size cap (~25 MB) |
OPENROUTER_AUDIO_MAX_REDIRECTS |
No | 8 |
Audio URL redirect cap |
OPENROUTER_AUDIO_MAX_DATA_URL_BYTES |
No | 20971520 |
Audio data URL size cap |
OPENROUTER_DEFAULT_VIDEO_MODEL |
No | google/gemini-2.5-flash |
Default for analyze_video |
OPENROUTER_DEFAULT_VIDEO_GEN_MODEL |
No | google/veo-3.1 |
Default for generate_video |
OPENROUTER_VIDEO_FETCH_TIMEOUT_MS |
No | 60000 |
Video URL timeout |
OPENROUTER_VIDEO_MAX_DOWNLOAD_BYTES |
No | 104857600 |
Video URL size cap (~100 MB) |
OPENROUTER_VIDEO_MAX_REDIRECTS |
No | 8 |
Video URL redirect cap |
OPENROUTER_VIDEO_MAX_DATA_URL_BYTES |
No | 104857600 |
Video data URL size cap |
OPENROUTER_VIDEO_POLL_INTERVAL_MS |
No | 15000 |
Async video poll cadence |
OPENROUTER_VIDEO_MAX_WAIT_MS |
No | 600000 |
Max wait before returning a resumable handle |
OPENROUTER_VIDEO_GEN_MAX_BYTES |
No | 268435456 |
Generated video download cap (~256 MB) |
OPENROUTER_VIDEO_INLINE_MAX_BYTES |
No | 10485760 |
Inline video ceiling (~10 MB) |
OPENROUTER_OUTPUT_DIR |
No | process.cwd() |
Sandbox root for save_path |
OPENROUTER_ALLOW_UNSAFE_PATHS |
No | — | 1 disables the sandbox |
OPENROUTER_LOG_LEVEL |
No | info |
error / warn / info / debug |
save_path is resolved against OPENROUTER_OUTPUT_DIR; traversal attempts are rejected. Override: OPENROUTER_ALLOW_UNSAFE_PATHS=1.src/
├── index.ts # Entry, env validation, graceful shutdown
├── tool-handlers.ts # 14 tools (annotated) + dispatch
├── model-cache.ts # TTL + in-flight coalescing
├── openrouter-api.ts # REST client (chat + /videos)
├── errors.ts # Closed ErrorCode enum
├── logger.ts # JSON-line structured logger
└── tool-handlers/
├── fetch-utils.ts # SSRF, bounded fetch, data-URL parser
├── openrouter-errors.ts # SDK/HTTP → ErrorCode classifier
├── completion-utils.ts # Reasoning-model cutoff detection
├── path-safety.ts # save_path sandbox
├── chat-completion.ts # Text + multimodal chat
├── analyze-image.ts # Vision analysis
├── analyze-audio.ts # Audio transcription
├── analyze-video.ts # Video understanding
├── generate-image.ts # Image generation
├── generate-audio.ts # Audio generation + streaming
├── generate-video.ts # Video generation (async)
├── image-utils.ts # Sharp optimization, MIME sniffing
├── audio-utils.ts # Audio format detection
├── video-utils.ts # Video format detection
├── search-models.ts # Model search
├── get-model-info.ts # Model detail lookup
└── validate-model.ts # Model existence check
v4.5's design draws from MCP best practices and academic research:
_meta.content_is_untrusted: true to mitigate indirect prompt injection (Zhao et al., ClawGuard)._meta.code taxonomy + retry_after_seconds beats raw error strings. Per Apigene's 12 Rules.outputSchema), progress notifications, tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint).OpenRouter platform features surfaced: Response caching · Web search · Reasoning tokens · Auto Exacto · Rerank · Prompt caching
v3+ is additive — no tool schemas or env vars were removed.
analyze_video, generate_video, generate_video_from_image, get_video_status, rerank_documents, health_check_meta.code on every error responsesave_path sandboxed by default — set OPENROUTER_OUTPUT_DIR or OPENROUTER_ALLOW_UNSAFE_PATHS=1git clone https://github.com/stabgan/openrouter-mcp-multimodal.git
cd openrouter-mcp-multimodal
npm install && cp .env.example .env # Add your API key
npm run build && npm start
npm test # 288 unit tests, <1s
npm run test:integration # Live API tests (16 scenarios)
npm run lint
node scripts/live-e2e.mjs # 16 live E2E scenarios
Works with any MCP client: Kiro · Claude Desktop · Cursor · Windsurf · Cline · any MCP-compatible client.
Apache 2.0 — see LICENSE.
Issues and PRs welcome. Please open an issue first for major changes.
Выполни в терминале:
claude mcp add stabgan-openrouter-mcp-multimodal -- npx Read, send and search emails from Claude
автор: GoogleSend, search and summarize Slack messages
автор: SlackNo-code MCP client for team chat platforms, such as Slack, Microsoft Teams, and Discord.
A community discord server dedicated to MCP by [Frank Fiegel](https://github.com/punkpeye)
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории communication