trackmcp
Back to directory
stabgan

openrouter-mcp-multimodal

View on GitHub

MCP server for OpenRouter providing text chat and image analysis tools

13 stars TypeScriptDeveloper Kits Updated Oct 27, 2025

Documentation

OpenRouter MCP Multimodal

The MCP server for multimodal AI agents.

One install · 19 tools · 300+ OpenRouter models · text, vision, audio & video — analysis and generation.

·

·

·

·

·

·


What is this?

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:

CapabilityToolsHighlights
Chat`chat_completion`, `start_chat_completion`, `get_chat_completion_status`300+ models, `:nitro` / `:floor` / `:free` / `:online` / `:exacto` suffixes, provider routing, web search, response caching, reasoning tokens, async jobs for long-running models
Vision`analyze_image`, `generate_image`, `generate_image_dedicated`OCR, captioning, VQA, image generation with reference inputs, dedicated Image API with resolution/quality/format control
Audio`analyze_audio`, `generate_audio`, `text_to_speech`, `speech_to_text`Transcription, speech/music generation, dedicated TTS (OpenAI/Gemini/Voxtral voices), dedicated STT (Whisper/GPT-4o Transcribe)
Video`analyze_video`, `generate_video`, `generate_video_from_image`, `get_video_status`Clip understanding, Veo 3.1 / Seedance 2.0 / Wan 2.7 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, tool icons (2025-11-25), async video progress notifications, and 770+ automated tests (unit, mock, regression, and live integration).

Quick start

1. Get an API key (free tier works) → openrouter.ai/keys

2. Run the server

bash
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:free` work for chat and vision. Video/audio generation typically needs credits.

Install

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.

MethodRuntimeBest forThis 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**DockerIsolation, no Node on host✅ `stabgan/openrouter-mcp-multimodal`
**GHCR**DockerGitHub-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 OCIOfficial discovery (`io.github.stabgan/openrouter-multimodal`)listing
**One-click deeplinks**Node.jsCursor, VS Code, Kiro
**Claude Code CLI**Node.jsTerminal-first Claude Code users
**MCP Inspector**Node.jsDebug / list tools locally
Windows `cmd /c npx`Node.jsClaude Desktop / Cursor when `npx` not on GUI PATHsee below
pip / uv (direct)Native Python MCP servers only— use uvx row above
DXT desktop extensionsBundled Claude Desktop `.dxt`not yet
Remote HTTP / SSEHosted Smithery / Cloudflare endpointsvia Smithery

> uvx vs npx: In the MCP ecosystem, `npx` runs npm (Node) packages and `uvx` runs PyPI (Python) packages. Because this server is Node-based, `uvx` uses a thin Python launcher that execs `npx -y @stabgan/openrouter-mcp-multimodal` — you still need Node installed.

One-click

Cursor

VS Code

Kiro

Claude Desktop / Windsurf / Cline (pick any method below)

Smithery

MCP Registry — npm + OCI packages

Paste your `OPENROUTER_API_KEY` when prompted — deeplinks use placeholders so secrets never appear in URLs.

Manual config

npx (recommended)

bash
export OPENROUTER_API_KEY=sk-or-v1-...
npx -y @stabgan/openrouter-mcp-multimodal
json
{
  "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.6.2"]`

uvx / pipx (Python launcher)

Install uv (includes `uvx`), ensure Node.js 20+ is also on your `PATH`, then:

bash
export OPENROUTER_API_KEY=sk-or-v1-...
uvx mcp-server-openrouter-multimodal
# pin npm version: OPENROUTER_MCP_NPM_VERSION=4.6.2 uvx mcp-server-openrouter-multimodal
json
{
  "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.6.2` pins the underlying npm package.

npm global

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

node (local clone)

bash
git clone https://github.com/stabgan/openrouter-mcp-multimodal.git
cd openrouter-mcp-multimodal
npm ci && npm run build
json
{
  "mcpServers": {
    "openrouter": {
      "command": "node",
      "args": ["/absolute/path/to/openrouter-mcp-multimodal/dist/index.js"],
      "env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
    }
  }
}

Docker

bash
docker run --rm -i -e OPENROUTER_API_KEY=sk-or-v1-... stabgan/openrouter-mcp-multimodal:latest
json
{
  "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).

GHCR (GitHub Container Registry)

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

Smithery

Interactive install (writes config for your client):

bash
npx -y @smithery/cli install @stabgan/openrouter-mcp-multimodal --client claude
# or: --client cursor | vscode | windsurf | ...

Listing: smithery.ai/server/@stabgan/openrouter-mcp-multimodal

MCP Registry

Official name: `io.github.stabgan/openrouter-multimodal`

Clients that support registry-driven install will offer npm or Docker; otherwise use the JSON blocks above.

Claude Code CLI

bash
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.

MCP Inspector

Debug tools/list and tool calls against a live OpenRouter key:

bash
export OPENROUTER_API_KEY=sk-or-v1-...
npx -y @modelcontextprotocol/inspector npx -y @stabgan/openrouter-mcp-multimodal

Windows npx

When Claude Desktop or Cursor cannot find `npx` (GUI apps often miss shell `PATH`), wrap with `cmd`:

json
{
  "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.

Why this server?

CapabilityThis serverTypical MCP LLM servers
Text chat (300+ models)
Image analysis + generationpartial
Audio analysis + TTS
Video analysis + generation
Model search / validate / rerank
Path sandbox + SSRF protectionrare
MCP 2025 structured outputsrare
Async video + progress notifications

Tools

19 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.

ToolPurpose
`chat_completion`Text chat, web search, provider routing, caching, reasoning
`start_chat_completion`Async background job for long-running reasoning models
`get_chat_completion_status`Poll / retrieve async completion results
`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 via chat completions with reference images
`generate_image_dedicated`Text-to-image via dedicated `/api/v1/images` (resolution, quality, format)
`generate_audio`Text-to-speech / music via chat completions
`text_to_speech`Dedicated TTS (`/api/v1/audio/speech`) — voices, speed, format
`speech_to_text`Dedicated STT (`/api/v1/audio/transcriptions`) — Whisper, GPT-4o
`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.

Examples

Chat (free model)

json
{
  "tool": "chat_completion",
  "arguments": {
    "model": "google/gemma-4-26b-a4b-it:free",
    "messages": [{ "role": "user", "content": "Summarize MCP in one sentence." }]
  }
}

Analyze an image

json
{
  "tool": "analyze_image",
  "arguments": {
    "image_path": "diagram.png",
    "question": "List every label in this diagram."
  }
}

> Use `image_path` and `question` — not `image` / `prompt`.

Search models (vision + free)

json
{
  "tool": "search_models",
  "arguments": {
    "query": "gemma",
    "capabilities": { "vision": true },
    "limit": 10,
    "offset": 0
  }
}

Generate video (async)

json
{
  "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

Security

  • Input path sandbox — `analyze_*` and reference images must stay inside `OPENROUTER_INPUT_DIR`
  • Output path sandbox — `save_path` must stay inside `OPENROUTER_OUTPUT_DIR`
  • SSRF protection — private/reserved IPs blocked on URL fetches
  • Untrusted content — analyze outputs tagged `_meta.content_is_untrusted: true`

Override sandboxes only with `OPENROUTER_ALLOW_UNSAFE_PATHS=1` (discouraged).

Configuration

Environment variables

VariableRequiredDefaultDescription
`OPENROUTER_API_KEY`YesOpenRouter 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`NoSandbox 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).

Development

bash
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

Testing

CommandWhat it runs
`npm test`773 unit + mock tests (no API key, <20s)
`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.

bash
npm run lint
npm run format:check
npm run version:check   # package.json vs src/version.ts, server.json, pyproject.toml

Releasing

Published artifacts (npm, PyPI/uvx, Docker, GHCR) all ship from the same semver on a git tag (`vX.Y.Z`). Pushing to `main` runs tests but does not publish to npm or PyPI.

Normal flow: merge conventional commits to `main` → Release Please opens a Release PR → merge it → tag is created → CI publishes everywhere.

Manual flow: bump all version files → `npm run version:check` → `npm run ci` + smoke tests → commit → `git tag vX.Y.Z` → `git push origin vX.Y.Z`.

Full checklist, file list, CI secrets, and agent instructions:

FAQ

Do I need paid OpenRouter credits?

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.

Which MCP clients are supported?

Any MCP-compatible client over stdio: Cursor, Claude Desktop, VS Code Copilot, Windsurf, Cline, Kiro, and custom agents.

How is this different from calling OpenRouter directly?

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.

Where is the security advisory for path traversal?

Fixed in 4.5.2+ — see GHSA-3q7p-736f-x44v and `docs/solutions/security-issues/`.

Compatibility

Works with any MCP client. Protocol: MCP 2025-06-18. Node ≥ 20 (Docker image uses Node 22).

License

Apache 2.0 — see LICENSE.

Contributing

Issues and PRs welcome. For large changes, open an issue first.

Before submitting: run `npm run ci`. Use Conventional Commits (`fix:`, `feat:`, etc.) so Release Please can cut the next release. See **`docs/RELEASING.md`** if you need to ship a version.

Frequently asked questions

What is openrouter-mcp-multimodal?

openrouter-mcp-multimodal is MCP server for OpenRouter providing text chat and image analysis tools

How do I install openrouter-mcp-multimodal?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is openrouter-mcp-multimodal open source?

Yes — it is hosted on GitHub at https://github.com/stabgan/openrouter-mcp-multimodal and has 13 stars.

Related MCP tools

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP