Skip to main content
Glama
OpenRouter MCP Multimodal Server

OpenRouter MCP Multimodal Server


Access 300+ LLMs — Claude, Gemini, GPT, Llama, Qwen, Grok, and more — through OpenRouter via the Model Context Protocol. Analyze images, audio, and video. Generate images, speech, music, and video (Veo 3.1, Sora 2 Pro, Seedance, Wan). Chat with any model. Works with Claude Desktop, Cursor, Kiro, VS Code, Windsurf, Cline, and any MCP-compatible client. Every tool returns structured _meta.code errors so MCP clients can switch on failure modes without parsing strings.

One-Click Install

After clicking, the target client opens a confirmation prompt. You'll need to paste your OPENROUTER_API_KEY — the deeplink ships a placeholder so no secrets end up in shared links.

Related MCP server: OpenRouter MCP Multimodal Server

Why This One?

Feature

Status

Text chat with 300+ models

✅

Image analysis (vision)

✅ Native with sharp optimization

Audio analysis

✅ Transcription + analysis, base64 auto-encoded

Audio generation

✅ Conversational, speech, and music with format auto-detection

Image generation

✅ Path-sandboxed disk output

Video understanding

✅ v3 — mp4, mpeg, mov, webm from files, URLs, or data URLs

Video generation

✅ v3 — Veo 3.1 / Sora 2 Pro / Seedance / Wan via async API with progress notifications

Auto image resize + compress

✅ Configurable (defaults 800px max, JPEG 80%)

Model search + validation

✅ Filter by vision / audio / video modality

Free model support

✅ Default: free Nemotron VL

Docker support

✅ Multi-arch (amd64 + arm64), ~345 MB Alpine

Retry-After + jitter

✅ Honors Retry-After header, avoids thundering herd

IPv4 + IPv6 SSRF blocklist

✅ Covers mapped, compat, multicast, 6to4, Teredo, ORCHID

Structured error taxonomy

✅ Closed _meta.code so clients can switch on failure modes

Reasoning-model awareness

✅ Detects max_tokens cutoff during CoT, guides the caller

MCP 2025 tool annotations

✅ readOnlyHint / destructiveHint / idempotentHint on every tool

Tools

Tool

Description

chat_completion

Send messages to any OpenRouter model. Detects reasoning-model cutoffs.

analyze_image

Analyze images from local files, URLs, or data URIs. Auto-optimized with sharp.

analyze_audio

Analyze/transcribe audio (WAV, MP3, FLAC, OGG, etc.) from files, URLs, or data URIs.

analyze_video

Analyze/transcribe video (mp4, mpeg, mov, webm) from files, URLs, or data URIs.

generate_image

Generate images from text prompts. Supports aspect_ratio (14 values), image_size (0.5K–4K), and max_tokens. Optional path-sandboxed disk save.

generate_audio

Generate audio from text. Auto-detects format, wraps raw PCM in WAV.

generate_video

Generate video via OpenRouter's async API (Veo 3.1 / Sora 2 Pro / Seedance / Wan). Submits, polls, downloads, saves.

get_video_status

Resume polling a generate_video job by id. Download + save when complete.

search_models

Search/filter models by name, provider, or capabilities (vision / audio / video).

get_model_info

Get pricing, context length, and capabilities for any model.

validate_model

Check if a model ID exists on OpenRouter.

All error responses carry _meta.code from 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

Quick Start

Prerequisites

Get a free API key from openrouter.ai/keys.

Option 1: npx (no install)

{
  "mcpServers": {
    "openrouter": {
      "command": "npx",
      "args": ["-y", "@stabgan/openrouter-mcp-multimodal"],
      "env": {
        "OPENROUTER_API_KEY": "sk-or-v1-..."
      }
    }
  }
}

Option 2: Docker

{
  "mcpServers": {
    "openrouter": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-e", "OPENROUTER_API_KEY=sk-or-v1-...",
        "stabgan/openrouter-mcp-multimodal:latest"
      ]
    }
  }
}

Option 3: Global install

npm install -g @stabgan/openrouter-mcp-multimodal
{
  "mcpServers": {
    "openrouter": {
      "command": "openrouter-multimodal",
      "env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
    }
  }
}

Option 4: Smithery

npx -y @smithery/cli install @stabgan/openrouter-mcp-multimodal --client claude

Configuration

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_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

Security notes

  • Analyze tools can read local files and fetch HTTP(S) URLs. URL fetches block private/link-local/reserved IPv4 and IPv6 targets (SSRF mitigation) and cap response size.

  • Generate tools write to disk through a path sandbox: save_path is resolved against OPENROUTER_OUTPUT_DIR and any traversal attempt is rejected. Override with OPENROUTER_ALLOW_UNSAFE_PATHS=1.

  • IPv6 SSRF blocklist covers loopback, unspecified, IPv4-mapped, IPv4-compatible, link-local, site-local, ULA, multicast, documentation, Teredo, ORCHID, and 6to4 of private IPv4.

Usage Examples

# Chat
Use chat_completion to explain quantum computing in simple terms.

# Vision
Use analyze_image on /path/to/photo.jpg and tell me what you see.

# Audio transcription
Use analyze_audio on /path/to/recording.mp3 to transcribe it.

# Video understanding
Use analyze_video on /path/to/clip.mp4 — what happens at 00:15?

# Generate audio
Use generate_audio with prompt "Explain neural networks" and voice "alloy", save to ./response.wav

# Generate music
Use generate_audio with model "google/lyria-3-clip-preview" and prompt "upbeat jazz piano trio"

# Generate image
Use generate_image with prompt "a cat astronaut on mars", aspect_ratio "16:9", image_size "1K", save to ./cat.png

# Generate video
Use generate_video with model "google/veo-3.1", prompt "a calm river at sunrise",
resolution 720p, duration 4, save to ./river.mp4

# Resume a video job
Use get_video_status with video_id "vid_abc123" and save_path "./river.mp4"

Architecture

src/
├── index.ts                    # Entry, env validation, graceful shutdown
├── tool-handlers.ts            # 11 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

Development

git 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                    # 163 unit tests, <1s
npm run test:integration    # Live API tests
npm run lint
node scripts/live-e2e.mjs  # 16 live E2E scenarios

Upgrading from v2

v3 is additive — no tool schemas or env vars were removed.

  • Three new tools: analyze_video, generate_video, get_video_status

  • Structured _meta.code on every error response (text messages preserved)

  • save_path sandboxed by default — set OPENROUTER_OUTPUT_DIR or OPENROUTER_ALLOW_UNSAFE_PATHS=1

  • Reasoning-model awareness: content: null + finish_reason: length now returns INVALID_INPUT with a preview instead of empty string

  • IPv6 SSRF coverage extended to mapped, compat, multicast, 6to4, Teredo, ORCHID

Compatibility

Works with any MCP client: Kiro · Claude Desktop · Cursor · Windsurf · Cline · any MCP-compatible client.

License

MIT

Contributing

Issues and PRs welcome. Please open an issue first for major changes.

Available Tools

11 tools
analyze_audioB
Read-only

Analyze or transcribe an audio file using a multimodal model

Inputs: audio_path (required), model, question.

analyze_imageB
Read-only

Analyze an image using a vision model

Inputs: image_path (required), model, question.

analyze_videoA
Read-only

Analyze or transcribe a video file using a multimodal model. Accepts mp4, mpeg, mov, or webm from a local file path, HTTP(S) URL, or base64 data URL. Default model: google/gemini-2.5-flash.

Inputs: video_path (required), model, question.

chat_completionB

Send messages to an OpenRouter model and get a response

Inputs: messages (required), model, max_tokens, temperature.

generate_audioA

Generate audio from a text prompt. Conversational models (e.g. openai/gpt-audio) respond in spoken audio. Music models (e.g. google/lyria-3-clip-preview) need a structured prompt. Output format is auto-detected and file extension is corrected automatically.

Inputs: prompt (required), model, voice, format, +1 more.

generate_imageA

Generate an image from a text prompt. Optionally conditioned on one or more reference images (file paths, http(s) URLs, or data URLs) for character / style consistency. Sends modalities: ["image","text"] by default; override via the modalities field if needed.

Inputs: prompt (required), model, save_path, image_size, +4 more.

generate_videoA

Generate a video from a text prompt using an OpenRouter video-generation model (default: google/veo-3.1). Submits an async job, polls until completion or max_wait_ms, then downloads the result. Optionally conditioned on first/last-frame images or reference images. Large outputs are auto-saved when save_path is provided and path-sandboxed.

Inputs: prompt (required), seed, model, duration, +9 more.

get_model_infoC
Read-onlyIdempotent

Get details about a specific model

Inputs: model (required).

get_video_statusA
Read-onlyIdempotent

Resume a previously submitted video generation job by id. Returns the latest status; if completed, downloads the video (and saves it when save_path is provided).

Inputs: video_id (required), save_path.

search_modelsC
Read-onlyIdempotent

Search available OpenRouter models

Inputs: limit, query, provider, capabilities.

validate_modelA
Read-onlyIdempotent

Check if a model ID exists

Inputs: model (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 11 tools

    Disambiguation5/5

    Each tool targets a distinct function: analyzing audio/image/video, generating content, chat completions, and model queries. No two tools have overlapping purposes, and even the video generation status tool is clearly a helper for async workflows.

    Naming Consistency4/5

    Most tools follow a verb_noun pattern (analyze_, generate_, get_, search_, validate_). The exception is 'chat_completion', which combines two nouns rather than a verb_noun, causing a minor inconsistency in the naming style.

    Tool Count5/5

    With 11 tools, the set covers all major modalities (audio, image, video, text) and supporting functions (model info, search, validation). The count is well-balanced—not excessive or too sparse for the server's multimodal purpose.

    Completeness4/5

    Core analysis, generation, and query tools are present. Some minor gaps exist (e.g., no explicit tool for listing all models, though search_models and get_model_info cover it). Overall, the surface is comprehensive for typical multimodal workflows.

    Maintenance

    ActivityMaintained
    ResponsivenessMixed handling

    Related MCP Connectors

    Related MCP Servers