OpenRouter MCP Server
This server connects agents to OpenRouter through a stateless MCP server and CLI, exposing model discovery, rankings, account/analytics tools, and chat/comparison operations.
list_models – search, filter, sort, and page the live model catalog
get_model – fetch one exact model, variant, or alias (replaces
get_model_info)list_model_endpoints – compare providers serving a model by price, context, uptime, latency, throughput, and supported parameters
list_providers – filter providers by name, headquarters, or datacenter
list_model_rankings / list_app_rankings – read bounded rankings data
get_credits – read purchased, used, and remaining credits
list_activity – read endpoint-level daily account activity
get_analytics_schema / query_analytics – discover and query bounded analytics aggregates
chat_with_model – generate a response and return a generation ID
compare_models – generate with 2–8 models, three calls at a time
get_generation – fetch provider, token, latency, and cost metadata for a generation
Also serves the
openrouter://usageresource for API-key usage and limits
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@OpenRouter MCP Servercompare responses from GPT-4 and Claude-3 about the future of AI"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
OpenRouter MCP server
This project connects agents to OpenRouter through two front doors: an agent-first command-line interface and a strict stateless MCP server. Both use the same operation layer and stable response shapes. The MCP server exposes thirteen focused tools and one API-key usage resource.
Version 3.0 targets MCP 2026-07-28 only. Each HTTP POST is independent. The server does not accept initialize, create Mcp-Session-Id sessions, expose a GET event stream, or run a legacy fallback.
Design notes and the reasoning behind the stateless 2026-07-28 surface are in the engineering note Building a strict stateless MCP 2026-07-28 server for OpenRouter. More notes and case studies: th3nolo.com. Author: Manuel Parra.
What changed in 3.0
list_modelssends pagination, filters, and sorting to OpenRouter instead of downloading the full catalog.get_modelcalls OpenRouter's direct model endpoint. It replacesget_model_info; there is no alias.list_model_endpointsreturns provider price, context, uptime, latency, throughput, and supported parameters.list_providersexposes provider geography, policy links, and service-status metadata without a browser.list_model_rankingsandlist_app_rankingsexpose bounded versions of OpenRouter's public rankings pages.get_creditsandlist_activityexpose account data with a separate management-key boundary.get_analytics_schemaandquery_analyticsexpose the current Activity Explore analytics contract with explicit time ranges and bounded results.chat_with_modelandcompare_modelsreturn ageneration_idand the resolved model.get_generationuses that ID to fetch exact provider, token, latency, and cost metadata.The
openrouter-mcpCLI exposes the same operations directly, emits JSON automatically when piped, and never prompts.Browser inspection informed the surface contract, but no browser, cookie, HAR file, or browser session is required at runtime.
openrouter://modelsandopenrouter://pricingwere removed. Their unbounded catalog payloads are not retained as fallbacks.Unknown fields added by OpenRouter are stripped at the API boundary. The MCP output schemas remain stable.
Static discovery responses declare a one-hour public cache hint. API-key usage remains private with a five-second hint.
Model comparisons run at most three OpenRouter calls at once. Paid calls are never retried automatically.
Custom OpenRouter base URLs must use HTTPS. Plain HTTP is accepted only for loopback development.
See docs/API.md for the complete tool contract, docs/CLI.md for direct CLI use, and docs/MCP-2026-07-28.md for wire-level behavior.
Related MCP server: OpenRouter MCP Multimodal Server
Requirements
Node.js 24 LTS
pnpm 12.0.0, exactly as pinned in
package.jsonAn OpenRouter API key for rankings, inference, generation metadata, and key-usage data
An OpenRouter management key for credit totals, account activity, and analytics
OpenRouter currently serves public model and provider discovery without a key. That anonymous behavior may be rate-limited or changed upstream.
Install
git clone https://github.com/th3nolo/openrouter-mcp.git
cd openrouter-mcp
pnpm install
pnpm run checkpnpm-workspace.yaml waits 72 hours before resolving a release. It also blocks exotic transitive sources and trust downgrades. Only esbuild@0.28.2 may run a dependency lifecycle script.
On Windows, pnpm@12.0.0 does not carry an Authenticode signature. Windows may label it "Unknown publisher." Install it with a method from pnpm's installation guide, and do not weaken Defender or PowerShell execution policy to suppress the warning.
Copy .env.example to .env, then set:
OPENROUTER_API_KEY=your_openrouter_api_key_here
# Optional; required only for get_credits and list_activity
OPENROUTER_MANAGEMENT_KEY=your_openrouter_management_key_hereKeep .env out of Git.
Use the CLI
Build once, then call the same operations without starting an MCP client:
pnpm run build
node dist/cli.js schema
node dist/cli.js models list --q claude --limit 5
node dist/cli.js providers list --datacenter DE
node dist/cli.js rankings models --limit 10
node dist/cli.js account credits
node dist/cli.js analytics schemaInteractive terminals receive compact text or tables. Redirected output is JSON automatically; --json makes that behavior explicit. Diagnostics use stderr, usage failures exit with status 2, operation failures exit with status 1, and commands never prompt. Run the strict stateless server through the same binary with node dist/cli.js serve --transport stdio.
Use with Claude over stdio
stdio is the default transport for local Claude integrations.
pnpm run build
claude mcp add --transport stdio --scope user \
--env OPENROUTER_API_KEY=your_openrouter_api_key_here \
openrouter -- node /absolute/path/to/openrouter-mcp/dist/server.jsThe equivalent Claude Desktop configuration is in examples/claude-config.json.
Use with Claude over local HTTP
Start the loopback-only server:
pnpm run build
OPENROUTER_API_KEY=your_openrouter_api_key_here pnpm run start:httpOn PowerShell:
$env:OPENROUTER_API_KEY = "your_openrouter_api_key_here"
pnpm run start:httpThen register its URL:
claude mcp add --transport http --scope user openrouter http://127.0.0.1:3000/mcpHTTP mode listens only on 127.0.0.1 and validates the Host and Origin headers. It does not implement a bearer-token shortcut.
Do not expose this listener directly to the internet. Put an HTTPS gateway that implements the MCP OAuth 2.1 resource-server flow in front of it.
Tools
Tool | Purpose | External effect |
| Search, filter, sort, and page the live model catalog | Read-only OpenRouter request |
| Read one exact model, variant, or alias | Read-only OpenRouter request |
| Compare the providers serving one model | Read-only OpenRouter request |
| Filter providers by name, headquarters, or datacenter | Read-only public request |
| Read one completed UTC day of model rankings | Read-only API-key request |
| Read popular or trending public apps | Read-only API-key request |
| Read purchased, used, and remaining credits | Read-only management request |
| Read endpoint-level daily account activity | Read-only management request |
| Discover current analytics metrics, dimensions, operators, and granularities | Read-only management request |
| Query bounded Activity Explore aggregates over an explicit time range | Read-only management request |
| Generate one response and return its generation ID | Can consume API credits |
| Generate with two to eight models, three calls at a time | Can consume API credits per model |
| Read provider, tokens, latency, and cost for one generation ID | Read-only authenticated request |
Each tool returns a text block and structuredContent. Zod rejects invalid input before the handler runs. The SDK converts upstream failures into MCP tool errors.
Resource
URI | Data | Cache hint |
| Usage and limits for the configured API key | Private, five seconds |
Model and pricing catalogs are tools rather than resources so every response can be filtered and bounded.
Verify the live API
pnpm run test:liveThe command always checks live model pagination, direct model lookup, model endpoints, and provider discovery. If OPENROUTER_API_KEY is configured, it also checks both ranking datasets, sends one short request through openrouter/free, and resolves the returned generation metadata. If OPENROUTER_MANAGEMENT_KEY is configured, it checks credits, bounded activity, analytics schema discovery, and a small seven-day analytics query. The report never prints a credential or generation ID.
Environment
Variable | Default | Meaning |
| none | OpenRouter key for rankings, inference, generation metadata, and |
|
| OpenRouter management key for credits, account activity, and analytics |
|
| HTTPS OpenRouter API base URL; HTTP is loopback-only |
| none | Optional |
|
|
|
|
| Per-request timeout |
|
|
|
|
| Local HTTP port |
Command-line --transport and --port values override their environment variables.
Development
pnpm run typecheck
pnpm run lint
pnpm run test
pnpm run build
# Complete release gate
pnpm run checkThe deterministic tests cover modern HTTP without initialize, strict legacy rejection, real stdio negotiation, CLI schema output, cache hints, credential separation, upstream and local pagination, direct API routes, generation handles, comparison concurrency, cancellation, schema drift, bounded errors, and HTTPS enforcement. The live contract test is separate because it depends on current network and OpenRouter availability.
Sources
License
MIT
Available Tools
4 toolschat_with_modelB
Send a message to a specific OpenRouter model
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | OpenRouter model ID (e.g., 'openai/gpt-4') | |
| message | Yes | Message to send to the model | |
| max_tokens | No | Maximum tokens in response | |
| temperature | No | Temperature for response randomness | |
| system_prompt | No | System prompt for the conversation |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility for disclosing behavior. It only states that the tool sends a message, without explaining whether the operation is idempotent, what side effects exist, rate limits, or the nature of the response. For a tool with no annotations, this is insufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no wasted words. However, it is overly brief and could benefit from a brief note on usage or behavior. Still, it achieves clarity without verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema, the description should explain what the tool returns (e.g., the model's response). It also fails to address the complexity of 5 parameters, such as how system_prompt interacts with message. The description is incomplete for a tool of this nature.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, meaning each parameter is already described in the schema. The description does not add extra meaning beyond the schema. Baseline score of 3 is appropriate because the schema handles documentation, but the description contributes no additional parameter context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Send a message to a specific OpenRouter model' uses a specific verb (send) and identifies the resource (message to model). It clearly distinguishes from sibling tools like analyze_document, compare_models, get_model_info, and list_models.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. The description lacks context about prerequisites, when to choose chat_with_model over other tools, or any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_modelsC
Compare responses from multiple models
| Name | Required | Description | Default |
|---|---|---|---|
| models | Yes | Array of model IDs to compare | |
| message | Yes | Message to send to all models | |
| max_tokens | No | Maximum tokens per response |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description only says 'compare responses' without disclosing behavioral traits such as whether it is read-only, how errors are handled, or the format of the output (e.g., does it return all responses or a summary?). This is a critical gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single short sentence, which is concise but lacks necessary detail. It is not verbose, but the under-specification reduces informativeness, balancing to a mediocre score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool that compares models, agents need return format, ordering, and error handling information. The description provides none of this, and with no output schema or annotations, the completeness is poor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema coverage is 100% with descriptions for all three parameters (models, message, max_tokens). The tool description adds no additional meaning beyond what the schema already provides, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it compares responses from multiple models, distinguishing it from sibling tools like chat_with_model (single model) and list_models (model listing). However, it lacks specificity about the comparison mechanism (e.g., side-by-side display).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like chat_with_model. Does not mention scenarios where comparing responses is beneficial or when a different tool would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_model_infoC
Get detailed information about a specific model
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Model ID to get information about |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided. Description does not disclose any behavioral traits, side effects, or what 'detailed information' entails.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded, but lacks detail. Could be more informative without being verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 1 parameter, no output schema, and no annotations, description is too sparse. Does not specify what information is returned.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% of parameters with descriptions. Description adds no extra meaning beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it gets info about a specific model. Sibling tools like list_models or compare_models have different purposes, so purpose is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. No context about prerequisites or use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_modelsB
Get list of available OpenRouter models
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It fails to disclose essential behaviors like whether authentication is required, if the list is paginated, what fields are returned, or any rate limits. The minimal description leaves agents with unclear expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words, but it sacrifices important information. Conciseness is acceptable, but the lack of structure (e.g., no separation of core behavior from usage notes) reduces usefulness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters, no annotations, and no output schema, the description should provide context about the returned data (e.g., model IDs, names) and prerequisites. It fails to do so, resulting in an incomplete tool definition for effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the baseline is 4. The description adds minimal meaning ('Get list of available OpenRouter models') beyond the empty schema, confirming the purpose of the tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get list') and the resource ('available OpenRouter models'), which distinguishes it from siblings like 'get_model_info' (detailed info on a specific model) and 'compare_models' (comparison).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for retrieving the model list but offers no guidance on when to use it versus alternatives (e.g., 'get_model_info' for details, 'compare_models' for comparison). No explicit context provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v1.0.0- First observed
chat_with_model - First observed
compare_models - First observed
get_model_info - First observed
list_models
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose: chat_with_model is for sending messages, compare_models is for comparing multiple models, get_model_info is for retrieving details about a specific model, and list_models is for listing available models. There is no overlap or ambiguity between these functions.
All tool names follow a consistent verb_noun pattern (e.g., chat_with_model, compare_models, get_model_info, list_models). The naming is uniform and predictable throughout the set.
With 4 tools, the server is well-scoped for interacting with OpenRouter models. Each tool serves a distinct and necessary function, and the count is appropriate for the domain without being too sparse or bloated.
The tool set covers core operations for model interaction: listing, getting info, chatting, and comparing. A minor gap is the lack of tools for managing API keys or handling billing, but these are not essential for the primary use case.
Maintenance
Related MCP Connectors
AI model routing on your own vendor keys: pick the best model per prompt, or route and run it.
OpenRouter for tools and data. Compare catalog providers and call them from one hosted MCP endpoint.
Sourced AI-model pricing and capability data — compare and route to the cheapest capable model.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides integration with OpenRouter.ai, allowing access to various AI models through a unified interface.4211 npm63Apache 2.0
- AlicenseBqualityAmaintenanceProvides chat and image analysis capabilities through OpenRouter.ai's diverse model ecosystem, enabling both text conversations and powerful multimodal image processing with various AI models.11787 npm88Apache 2.0
- FlicenseBqualityDmaintenanceProvides access to OpenRouter.ai's diverse model ecosystem for text chat and image analysis capabilities, with support for multimodal conversations and automatic image optimization.712 npm-
- AlicenseNot gradedqualityDmaintenanceProvides seamless access to 200+ AI models through OpenRouter's unified API, featuring multi-model collaboration, vision support, intelligent benchmarking, and collective intelligence capabilities for enhanced decision-making.133 npm9MIT