Announcing CIMD support for MCP Client registration
Learn more

OpenRouter MCP vs OpenRouter API for AI Agents

TL;DR

  • OpenRouter ships both an MCP server and an inference API, but they solve different phases of the work. OpenRouter's own docs are explicit: use the MCP server while you build; to actually run models in your app, keep calling the API directly.
  • The OpenRouter MCP server is a build-time and ops assistant. It exposes read-mostly tools for model discovery, pricing, benchmarks, rankings, credit balance, generation cost, and docs search, plus a few billable tools for test messages and media generation.
  • The OpenRouter API is the runtime inference layer: an OpenAI-compatible /api/v1/chat/completions endpoint with streaming, tool calling, structured outputs, provider routing, and fallbacks. This is the surface that carries production traffic.
  • Auth diverges. The MCP path issues a short-lived, spend-capped key over OAuth with PKCE. The API path takes a static key, an OAuth PKCE user-controlled key, or a programmatically provisioned per-customer key. Your credential model changes with the choice.
  • Neither path solves per-user credential isolation for a multi-tenant agent. Scalekit's OpenRouter connector handles the MCP path with per-user connected accounts, scoped tool surfaces, and full auth logs, so the discovery layer is production-safe from the first user.

Your agent needs to talk to OpenRouter. OpenRouter now gives you two distinct surfaces: an official hosted MCP server and the unified inference API your app has probably been calling for a while. They are not two roads to the same place. One is where your agent decides which model to use; the other is where it runs that model in production. Picking the wrong one for a given job is a common and avoidable mistake. Here is the decision framework.

What OpenRouter MCP and OpenRouter API actually are

Most tools in this series ship an MCP server and an API that overlap on the same data. OpenRouter is different: the two surfaces are split by phase, not by capability, and understanding that split is the whole game.

OpenRouter MCP is a build-time assistant

OpenRouter's official Model Context Protocol (MCP) server is a remote server hosted by OpenRouter at https://mcp.openrouter.ai/mcp; nothing is installed locally. Your coding agent connects by adding one URL and approving a browser OAuth login. Once connected, it can pull live OpenRouter data, models, prices, your credit balance, rankings, and docs, and send quick test messages, all without leaving your editor.

The positioning is stated directly in OpenRouter's documentation: use this MCP while you build, and to actually run models in your app, keep calling the API directly. The server proxies the public OpenRouter API with your key; it is a development and operations layer, not a production inference path.

What the MCP surface exposes

The server exposes roughly two dozen tools; Scalekit's connector currently lists 23. Most are read-only lookups against live data: list-models, get-model, list-model-endpoints, list-providers, list-benchmarks, list-daily-model-rankings, list-app-rankings, list-task-classifications, get-credits, get-generation, and search-docs. A handful make billable calls: send-message and generate-image, plus generate-speech and transcribe-audio in the expanded set. It also wraps OpenRouter's Ori eval harness through spawn-ori-eval and install-ori-harness. Full details are in OpenRouter's official MCP server documentation.

OpenRouter API is the runtime inference layer

The OpenRouter API is a single OpenAI-compatible endpoint at /api/v1/chat/completions that routes each request to one of hundreds of models across dozens of providers. You authenticate with Authorization: Bearer <OPENROUTER_API_KEY>, pass a provider/model-slug pair such as openai/gpt-4o-mini, and get streaming, tool calling, structured outputs, provider routing, and automatic fallbacks.

This is the surface that carries real traffic: every user request, at volume, with the wire format your existing OpenAI code already speaks. The setup and quickstart live in OpenRouter's API documentation.

Comparing them where it matters for agents

The comparison is not "which is more capable." It is "which surface belongs at which point in your agent's lifecycle." Four dimensions decide it.

What your agent can actually do

The MCP server owns discovery and account observability. The API owns inference and everything a production request needs.

Capability
OpenRouter MCP
OpenRouter API
Search the live model catalog with pricing, context, modalities
Yes, list-models
Yes, less structured
Compare models by third-party benchmarks
Yes, list-benchmarks
No native tool
See providers serving a model, price, latency, uptime
Yes, endpoint and uptime tools
Partial, endpoints only
Check account credit balance
Yes, get-credits
Yes, credits endpoint
Inspect a generation's cost, tokens, provider
Yes, get-generation
Yes, generation endpoint
Run production inference at volume with streaming
No, test messages only
Yes, /api/v1/chat/completions
Tool and function calling inside your model calls
No
Yes
Structured outputs via JSON Schema
No
Yes, response_format
Provider routing, model routing, fallbacks
Test messages only
Yes
Generate images, speech, transcribe audio
Yes, billable single-shot
Yes, dedicated endpoints
Search OpenRouter docs from the editor
Yes, search-docs
No
Run model evals on your own data
Yes, Ori tools
No, separate tooling

Where the line actually falls

Read the table top to bottom and the split is clean. Everything above the inference rows is the MCP server earning its keep as a decision aid; everything from inference down is the API doing production work. The send-message tool blurs this only in appearance. It exists to test a prompt or compare models in your editor, not to serve users. Building a production feature on MCP send-message means running your traffic through a development tool with a weekly-expiring key.

The auth path each one puts you on

Auth is where the two surfaces diverge hardest, and it is the part that decides whether your choice survives a second user.

MCP: OAuth with PKCE, short-lived and capped

The MCP server authenticates over OAuth. An unauthenticated request returns a 401 that points the client to OpenRouter's authorization server; the client registers via Dynamic Client Registration, the user approves a consent page, and a token is issued via PKCE. That token is a standard OpenRouter API key labeled OpenRouter MCP: <app name>, minted with a 7-day expiry and a $10 default spend limit. It is built for a developer at an editor, not an unattended fleet.

API: three credential models

The API supports three patterns, and they carry different risk. A static API key is the simplest: one credential, all usage billed to you, no per-user attribution; the service-account model of LLM gateways. An OAuth PKCE user-controlled key lets each user connect their own OpenRouter account: send them to /auth with a code_challenge, exchange the returned code at /api/v1/auth/keys for their own sk-or-... key, with the PKCE challenge as the only proof of identity. A provisioning key mints per-customer keys programmatically under /api/v1/keys, each with its own spend limit; provisioning keys cannot call completion endpoints, only manage keys.

The isolation problem that follows you either way

This is the architectural point. In a multi-tenant B2B agent, every user needs their own OpenRouter identity: their own credits, their own spend ceiling, their own attribution. The MCP path gives you one short-lived key per user. The API path gives you a per-user PKCE key, a shared static key with no isolation, or a provisioned sub-key per customer. In none of these cases does the path itself store, rotate, or revoke anything. That is infrastructure, and it is the same problem on both sides. The tradeoffs are laid out in single-tenant versus multi-tenant tool calling.

What you own in production

Both surfaces hand you real operational work; the shape of that work differs.

On the MCP path

OpenRouter hosts the server, maintains the tool schemas, and proxies the public API with your key. You still own per-user token storage, refresh, revocation, and tenant isolation. The 7-day key expiry is not a footnote: a key that dies weekly is fine for a developer who re-approves in a browser, and a recurring failure for an unattended multi-user agent that has no browser in the loop. Token lifecycle for long-running agents is covered in handling token refresh for AI agents.

On the API path

You own the full stack: request construction, streaming, retries, provider routing configuration, error handling, rate limits, and the token lifecycle for whichever auth model you chose. The maintenance surface is larger, and the operational model is more stable; the wire format is OpenAI-compatible and versioned, so a nightly pipeline calling the same endpoint is not disturbed by an MCP server update that restructures a tool schema.

When to use MCP, when to use the API

The split maps directly onto agent use cases.

Use OpenRouter MCP when:

  • Your agent is an interactive coding assistant (Claude Code, Cursor, Codex) and a developer is present to pick or compare models while building
  • You are building a model-selection or ops assistant that answers "which model is best, cheapest, or fastest for this task right now" from live catalog, benchmark, and ranking data
  • You want to check credits, inspect a generation's cost and routing, or search OpenRouter docs without leaving the editor
  • You are running Ori evals to compare models on your own prompts and catch regressions

Use the OpenRouter API when:

  • Your agent serves production inference: every user request, at volume, with streaming
  • You need deterministic behavior, structured outputs via JSON Schema, tool calling, or fixed provider and model routing
  • Your agent runs headless, on a schedule or in the background, with no editor or browser in the loop
  • You are multi-tenant and each user's usage must be billed, capped, and isolated through their own key or a provisioned sub-key

The credential problem that exists on both paths

Both surfaces give you a token or key per user. Neither gives you a vault, rotation logic, or a revocation flow. That has to be built separately, whichever surface you chose.

The shared static key failure mode

A single static API key looks correct in a demo. In production it means every user's inference is billed to one pooled account, any single run can exhaust the shared budget, and there is no attribution tying a call back to the person who triggered it. For the MCP path the equivalent trap is a shared connection: one developer's OpenRouter key answering for everyone, spending everyone's credits, and expiring for everyone at once.

The N-credential problem

In a multi-tenant agent, which is the norm rather than the exception, every user has their own OpenRouter credential. That is N keys to store, refresh, cap, and revoke at scale. Offboarding makes the gap concrete: the identity provider account is disabled, but a user-controlled OpenRouter key minted months ago and stored locally is still valid and still spending until something explicitly kills it. This is the core of credential ownership across agent tool-calling patterns.

Where Scalekit fits

Scalekit's OpenRouter connector wraps OpenRouter's official MCP server as a per-user connected account. It runs the OAuth flow with PKCE, vaults the token in an AES-256 encrypted store the model never sees, and resolves the right user's credential on every call. The connector covers the MCP surface, the discovery and ops layer; the runtime API path is yours to call directly, and the per-user OpenRouter keys it needs are the same vaulting problem, not a different one.

Building an OpenRouter agent with Scalekit

Scalekit ships OpenRouter as a Vendor MCP connector: the official OpenRouter MCP server, wrapped with OAuth 2.1 and Dynamic Client Registration, exposed as 23 scoped tools your agent can call as a specific user. The steps below use the Python SDK and the Anthropic Claude SDK; the connector reference is in the Scalekit OpenRouter connector docs.

Install and configure

Create the OpenRouter MCP connection once in the Scalekit dashboard under AgentKit, then note its connection name; the string you pass in code must match it exactly, which is the single most common integration error. Install the SDKs and set your credentials.

pip install anthropic scalekit-sdk-python protobuf python-dotenv # .env SCALEKIT_ENVIRONMENT_URL=https://<your-env>.scalekit.cloud SCALEKIT_CLIENT_ID=skc_... SCALEKIT_CLIENT_SECRET=sks_... ANTHROPIC_API_KEY=sk-ant-... USER_IDENTIFIER=user_123

Connect a user's OpenRouter account

Each user authorizes once. Scalekit runs the OAuth flow, stores the token per identifier, and creates a connected account. The connection_name here must match the dashboard connection exactly.

import os from scalekit.client import ScalekitClient from dotenv import load_dotenv load_dotenv() scalekit = ScalekitClient( env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], ) actions = scalekit.actions CONNECTION = "openrouter-mcp" # must match the connection name in your Scalekit dashboard identifier = os.getenv("USER_IDENTIFIER", "user_123") account = actions.get_or_create_connected_account( connection_name=CONNECTION, identifier=identifier, ) if account.connected_account.status != "ACTIVE": link = actions.get_authorization_link(connection_name=CONNECTION, identifier=identifier) print("Authorize OpenRouter:", link.link) print("Re-run after completing the OAuth flow.") exit(0)

Scope the tools to the user

Before the agent reasons, retrieve the tools this user's connected account is authorized to call. This is not a flat catalog of everything OpenRouter exposes; it is the scoped surface for this identity, returned in Anthropic's native tool format, so there is no schema to hand-write.

from google.protobuf.json_format import MessageToDict scoped_response, _ = actions.tools.list_scoped_tools( identifier=identifier, filter={"connection_names": [CONNECTION]}, ) llm_tools = [ { "name": MessageToDict(t.tool).get("definition", {}).get("name"), "description": MessageToDict(t.tool).get("definition", {}).get("description", ""), "input_schema": MessageToDict(t.tool).get("definition", {}).get("input_schema", {}), } for t in scoped_response.tools ]

Scoping is the accuracy and cost lever, not a convenience. Handing a model all 23 tools, four of which spend real money, produces worse tool selection and burns tokens before the agent does any work. Scope is a function of identity, not connector configuration: what the user cannot do on OpenRouter, the agent cannot do either.

Run the agent loop

This is the standard Anthropic tool-use loop. Claude decides what to call; your code executes each call through execute_tool with the user's identifier attached, so every OpenRouter request runs under that user's own account. The loop runs to a final text response.

import anthropic claude = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"]) messages = [{ "role": "user", "content": ( "Pick the cheapest model that scores well for coding, confirm I have " "credits, then send it a one-line test prompt and report the cost." ), }] while True: response = claude.messages.create( model=os.getenv("ANTHROPIC_MODEL", "claude-sonnet-4-6"), max_tokens=1024, tools=llm_tools, messages=messages, ) if response.stop_reason == "end_turn": print(response.content[0].text) break tool_results = [] for block in response.content: if block.type == "tool_use": result = actions.execute_tool( tool_name=block.name, identifier=identifier, tool_input=block.input, connection_name=CONNECTION, ) tool_results.append({ "type": "tool_result", "tool_use_id": block.id, "content": str(result.data), }) messages.append({"role": "assistant", "content": response.content}) messages.append({"role": "user", "content": tool_results})

The same pattern backs agents on other frameworks; Scalekit ships a LangChain adapter through actions.langchain.get_tools(identifier=...) that returns the scoped surface as StructuredTool objects, and the full catalog is in the AgentKit connectors reference.

Scope spend and tools with a Virtual MCP server

The OpenRouter MCP server exposes every tool it has, including the four that spend a user's credits. A model-selection agent needs list-models, list-benchmarks, get-credits, and get-generation; it does not need generate-image or generate-speech. Handing it the full server widens the blast radius for no benefit, and for billable tools the blast radius is measured in dollars.

Virtual MCP servers enforce least privilege at the tool level: one server definition per agent role declares exactly which tools the agent can see and whose credentials it acts with, and there is no MCP server to deploy, host, or maintain. Per-user isolation is handled by session tokens; one definition serves all users, and a short-lived token scoped to that user's connected account is minted before each run. The endpoint is static; the identity is per-user. When each surface is worth using is covered in MCP vs CLI use cases.

See every call with agent auth logs

OpenRouter's get-generation tells you what one call cost and which provider served it. It does not tell you which user authorized it or which agent ran it. Scalekit's agent tool observability adds that attribution: every tool call is logged with who authorized it, which agent made it, and the response, with failures separated by source and the chain exportable to your SIEM.

For a spend-bearing surface, this is the difference between a credit-usage anomaly you can trace to a user and agent in one query, and a three-week investigation. Paired with per-user connected accounts, "what did the agent run on behalf of user X, and what did it cost" becomes one filtered lookup.

Which one to build against

If your agent is a coding assistant or a model-ops helper, and a developer or an interactive session is driving it, the MCP server is the right surface. It exists to make informed model decisions from live data while you build, and OpenRouter maintains it for you. Plan around the 7-day key expiry and the browser consent step.

If your agent serves production inference, runs headless, needs structured outputs or provider routing, or must isolate spend per tenant, call the API directly. It is the only surface built to carry traffic, and its OpenAI-compatible contract is the stable one.

Most real systems use both: the API in the hot path, the MCP server in the build and ops loop around it. Whichever you reach for, per-user credential isolation is the same problem, and it is the part that needs production-grade infrastructure. The cost implications of building OAuth internally for AI agents are worth understanding before you decide what to own. See AgentKit pricing and the OpenRouter connector page to start, or spin up a DevOps assistant or release-notes agent from a template.

Building OpenRouter agents and want a second pair of eyes on the auth model? Join the Scalekit Slack community, or use the talk to us page for immediate help.

No items found.
Agent
Auth Quickstart
On this page
Share this article
Agent
Auth Quickstart

Acquire enterprise customers with
zero upfront cost.

Every feature unlocked. No hidden fees.