Skip to main content
Glama
vmhq

OpenRouter MCP Server

by vmhq

OpenRouter MCP Server

OpenRouter API を介して AI エージェントがより安価なモデルにタスクを委任できるようにするリモート MCP サーバー(ストリーミング可能な HTTP、ステートレス JSON)です。カタログとライブ価格を照会し、.env ファイルでコストポリシーを設定できます。

機能

  • ライブカタログ: OpenRouter の GET /api/v1/models を照会し(5分間のキャッシュ付き)、100万トークンあたりの USD 価格、コンテキストウィンドウ、ツール呼び出しサポートを公開します。

  • 明示的な委任: エージェントは価格を見てモデルを選択し、タスクを委任します。

  • 価格に基づく自動委任: サーバーは設定可能な価格帯を使用して、ティア(economy / balanced / quality)に基づいてモデルを選択します。

  • .env によるポリシー: 最大価格上限、許可/ブロックされたモデルリスト、デフォルトモデル、優先プロバイダー。

  • 実際のコスト: 各委任は、使用されたトークンと推定コスト(USD)を返します。

Related MCP server: frugal

インストール

npm install
cp .env.example .env   # edit and set your OPENROUTER_API_KEY
npm run build
npm start              # listens on http://localhost:3000/mcp

自動リロードでの開発用: npm run dev。

Docker

マルチアーキテクチャイメージ(linux/amd64、linux/arm64)は GitHub Actions によって自動的にビルドされ、GHCR に公開されます:

ghcr.io/vmhq/openrouter-mcp-server

利用可能なタグ: latest(main ブランチ)、vX.Y.Z / X.Y(リリース)、main、sha-<commit>。

Docker Compose

services:
  openrouter-mcp:
    image: ghcr.io/vmhq/openrouter-mcp-server:latest
    container_name: openrouter-mcp
    restart: unless-stopped
    ports:
      - "3000:3000"
    env_file:
      - .env
    volumes:
      # Persists OAuth state (registered clients, token hashes)
      - ./data:/app/data
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
docker compose up -d

注: コンテナは非特権の node ユーザーとして実行されます。マウントされた ./data ディレクトリが UID 1000 で書き込み可能であることを確認してください(chown -R 1000:1000 ./data)。そうしないと、OAuth 状態を永続化できません。

.env の例

# --- Required ---
# Your OpenRouter API key (https://openrouter.ai/keys)
OPENROUTER_API_KEY=sk-or-v1-...

# --- HTTP server ---
# Port where the MCP endpoint is exposed (http://host:PORT/mcp)
PORT=3000
# Optional static bearer token. If set, MCP clients must send
# "Authorization: Bearer <token>". Strongly recommended if the server
# is reachable outside localhost.
MCP_AUTH_TOKEN=

# --- Interactive OAuth with PocketID (for AI agents like Claude) ---
# Public URL of this server (e.g. https://mcp.example.com). Required so the
# OAuth metadata and callback point to the right URL behind a reverse proxy.
MCP_PUBLIC_URL=
# When all three POCKETID_* variables are set, the /oauth/authorize flow
# delegates the human login to your PocketID instance (passkey).
# In PocketID: create an OIDC client and register this callback:
#   <MCP_PUBLIC_URL>/oauth/callback
POCKETID_ISSUER=
POCKETID_CLIENT_ID=
POCKETID_CLIENT_SECRET=
# Optional OIDC scopes (space-separated). Default: "openid profile email".
# POCKETID_SCOPES=openid profile email
# Path of the file where OAuth state is persisted (registered clients,
# one-time codes, and token hashes). Default: ./data/oauth-state.json
# MCP_OAUTH_STATE_PATH=./data/oauth-state.json
# OAuth access token lifetime, in seconds. Default: 2592000 (30 days).
# MCP_OAUTH_TOKEN_TTL_S=2592000

# --- Optional OpenRouter attribution (rankings) ---
APP_URL=
APP_TITLE=OpenRouter MCP Server

# --- Delegation policy ---
# Default model when the agent doesn't specify one in openrouter_delegate_task
DEFAULT_MODEL=

# Price caps (USD per million tokens). Models above them are rejected
# with an explanatory error. Empty = no limit.
MAX_PROMPT_PRICE_PER_M=
MAX_COMPLETION_PRICE_PER_M=

# Comma-separated control lists. Accept exact ids ("openai/gpt-4.1-mini")
# or provider prefixes ("openai/"). Empty ALLOWED_MODELS = all allowed
# (except blocked ones).
ALLOWED_MODELS=
BLOCKED_MODELS=

# Allow free models (price 0)? They usually have strict rate limits.
ALLOW_FREE_MODELS=true

# Preferred providers for automatic selection (openrouter_auto_delegate)
PREFERRED_PROVIDERS=openai,anthropic,google,meta-llama,mistralai,deepseek,qwen,x-ai,amazon

# "Combined" price caps (70% prompt + 30% completion, USD/M tokens)
# for each tier of the automatic selection.
TIER_ECONOMY_MAX_PRICE=0.5
TIER_BALANCED_MAX_PRICE=3
TIER_QUALITY_MAX_PRICE=15

# Model catalog cache, in seconds
MODELS_CACHE_TTL_SECONDS=300

環境変数

.env.example を参照してください。主なものは次のとおりです:

変数

説明

OPENROUTER_API_KEY

必須。 https://openrouter.ai/keys から取得したキー

PORT

HTTP ポート(デフォルト 3000)

MCP_AUTH_TOKEN

設定すると、クライアントは Authorization: Bearer <token> を送信する必要があります。サーバーを localhost の外部に公開する場合は事実上必須です。

MCP_PUBLIC_URL

サーバーの公開 URL(例: https://mcp.example.com)。リバースプロキシの背後での OAuth フローに必要です。

POCKETID_ISSUER / POCKETID_CLIENT_ID / POCKETID_CLIENT_SECRET

認証を PocketID インスタンスに委任して、対話型 OAuth ログインを有効にします(下記参照)

DEFAULT_MODEL

エージェントが指定しない場合に openrouter_delegate_task が使用するモデル

MAX_PROMPT_PRICE_PER_M / MAX_COMPLETION_PRICE_PER_M

価格上限(USD/100万トークン)。これより高価なモデルは拒否されます。

ALLOWED_MODELS / BLOCKED_MODELS

カンマ区切りのリスト: 正確な ID またはプレフィックス(openai/)

ALLOW_FREE_MODELS

無料モデルを許可(デフォルト true)

TIER_*_MAX_PRICE

自動選択の各ティアの複合価格上限(0.7·入力 + 0.3·出力)

公開ツール

ツール

説明

openrouter_list_models

ライブ価格でモデルを一覧表示。テキスト、価格、コンテキスト、ツール呼び出しでフィルタリング。価格/コンテキスト/新しさで並べ替え。ページネーション対応。

openrouter_get_model

モデルの完全な詳細と、.env ポリシーがそれを許可するかどうか

openrouter_delegate_task

タスクを特定のモデルに委任。応答、トークン、推定コストを返します。

openrouter_auto_delegate

サーバーが価格ティア(economy/balanced/quality)でモデルを選択し、委任します。

openrouter_check_credits

設定された API キーの使用量と制限

典型的なエージェントのフロー: openrouter_list_models(または economy ティアで直接 openrouter_auto_delegate)→ タスクを委任 → コストを把握して応答を使用。

重要: 委任されたモデルはエージェントの会話を見ることはできません。タスク(task)は、必要なコンテキストをすべて含む自己完結型である必要があります。

エージェントの接続

Claude Code:

claude mcp add --transport http openrouter http://localhost:3000/mcp

認証トークンを使用する場合:

claude mcp add --transport http openrouter http://YOUR_HOST:3000/mcp --header "Authorization: Bearer YOUR_TOKEN"

任意の MCP クライアント: "streamable HTTP" トランスポートで POST /mcp エンドポイントを指定します。監視用の GET /health エンドポイントもあります。

claude.ai(リモートコネクタ): 公開 HTTPS URL が必要です。リバースプロキシ(Caddy/nginx)の背後にある VPS にサーバーをデプロイするか、トンネル(例: cloudflared tunnel)を使用します。OAuth を有効にすると(下記参照)、https://YOUR_HOST/mcp を指すコネクタを追加し、詳細な OAuth クライアント ID/シークレットフィールドは空のままにします。サーバーは OAuth メタデータを公開し、動的クライアント登録をサポートするため、Authorize をクリックすると Claude が自動的に登録してトークンを取得します。

PocketID を使用した OAuth

サーバーは AI エージェント(Claude、Cursor など)向けの完全な OAuth 2.1 を実装しています。MCP クライアントに対して認可サーバーとして機能し(RFC 7591 動的クライアント登録 + PKCE S256 + 独自トークンの発行、RFC 8414/9728 メタデータ)、人間のログインを PocketID インスタンスに OIDC(パスキー)経由で委任します。

フロー: MCP クライアントは 401 と WWW-Authenticate を受け取ります → /.well-known/oauth-protected-resource でメタデータを発見します → /oauth/register で登録します → ブラウザで /oauth/authorize を開きます → ユーザーはパスキーで PocketID にサインインします → PocketID は /oauth/callback に戻ります → サーバーは独自のコードを発行し、クライアントは /oauth/token でアクセストークン(デフォルト 30 日)と交換します。

セットアップ:

  1. PocketID で新しい OIDC クライアントを作成します。

  2. コールバックを登録します: <MCP_PUBLIC_URL>/oauth/callback。

  3. PocketID の OIDC クライアントの許可グループを使用して、サインインできるユーザーを制限します。

  4. クライアント ID とクライアントシークレットを POCKETID_CLIENT_ID / POCKETID_CLIENT_SECRET にコピーし、PocketID のベース URL を POCKETID_ISSUER に設定します。

  5. MCP_PUBLIC_URL をサーバーの公開 HTTPS URL に設定します。

POCKETID_* 変数が設定されていない場合、対話型の /oauth/authorize フローはエラーを表示します。静的 MCP_AUTH_TOKEN ベアラーは、マシン間アクセス(curl、Codex など)のために並行して機能し続けます。

OAuth 状態(登録済みクライアント、ワンタイムコード、トークンの SHA-256 ハッシュ — 平文トークンは決して保存されません)は ./data/oauth-state.json に永続化されます(MCP_OAUTH_STATE_PATH で設定可能)。再起動後に状態が消去されてコネクタが失敗した場合は、Claude で削除して再度追加し、再登録させてください。

openrouter_auto_delegate がモデルを選択する方法

  1. .env ポリシーと呼び出しの要件(require_tools、min_context、テキスト出力)でカタログをフィルタリングします。

  2. モデルごとの複合価格を計算します: 0.7·input_price + 0.3·output_price(USD/100万トークン)。

  3. ティアに応じて、その価格帯内で検索します(空の場合は隣接する帯にフォールバック):

    • economy(デフォルトで ≤ $0.5/M): 最も安い。

    • balanced($0.5–$3/M): 中間帯で最も安い。

    • quality($3–$15/M): 上限内で最も高価(能力のプロキシとしての価格。フラッグシップモデルには到達しない)。

  4. PREFERRED_PROVIDERS のプロバイダーを優先し、応答で選択したモデル、理由、破棄された代替案を報告します。

セキュリティ

  • OpenRouter API キーはサーバーの .env にのみ存在し、エージェントに公開されることはありません。

  • .env ファイルは .gitignore に含まれています。

  • ポートが外部から到達可能な場合は、MCP_AUTH_TOKEN を設定し、HTTPS の背後で提供してください。

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers