Cursor × OpenRouter × LiteLLM:任意のモデルを利用する方法

#AI

Cursor から OpenRouter 経由で複数 LLM ベンダーのモデルを利用したかったのですが、Cursor 側の制約により直接接続が困難でした。LiteLLM を OpenAI 互換プロキシとして挟み、ngrok を使ってローカル環境から接続する構成とハマりどころをまとめます。


1. 背景:Cursor の OpenRouter 対応の制約

1.1. 何が問題だったか

Cursor は OpenAI / Anthropic / Azure OpenAI など主要プロバイダへの直接接続は UI で用意されていますが、OpenRouter のような LLM アグリゲーターへの対応は標準では提供されていません。

OpenRouter は OpenAI 互換 API を提供しているため、理論上は「OpenAI 設定に OpenRouter の Endpoint と API Key を入れれば動く」はずです。しかし実際には以下の問題が発生します:

1.2. 解決のアプローチ

LiteLLM を中間プロキシとして配置し、Cursor → LiteLLM → OpenRouter という経路にすることで、以下を実現します:


2. アーキテクチャ

graph TD
    A["Cursor<br/>(AI Code Editor)"]
    B["ngrok<br/>(トンネル)"]
    C["LiteLLM<br/>(Proxy Server)<br/>127.0.0.1:4000"]
    D["OpenRouter<br/>(LLM Hub)"]

    A -->|HTTPS| B
    B -->|ローカルネットワーク| C
    C -->|OpenRouter API| D

    style A fill:#e1f5ff
    style B fill:#fff3e0
    style C fill:#f3e5f5
    style D fill:#e8f5e9

3. 実装:ローカル環境での検証

3.1. 1. LiteLLM のインストール

python3 -m venv .venv
source .venv/bin/activate
pip install "litellm[proxy]"

3.2. 2. 設定ファイル(litellm_config.yaml)

model_list:
  - model_name: or-claude-sonnet
    litellm_params:
      model: openrouter/anthropic/claude-sonnet-4.5
      api_base: os.environ/OPENROUTER_API_BASE
      api_key: os.environ/OPENROUTER_API_KEY
  - model_name: or-gpt-codex
    litellm_params:
      model: openrouter/openai/gpt-5.2-codex
      api_base: os.environ/OPENROUTER_API_BASE
      api_key: os.environ/OPENROUTER_API_KEY
  - model_name: or-gemini-pro
    litellm_params:
      model: openrouter/google/gemini-3-pro-preview
      api_base: os.environ/OPENROUTER_API_BASE
      api_key: os.environ/OPENROUTER_API_KEY

litellm_settings:
  master_key: sk-litellm-master-key-1234 # 任意のKeyに変更してださい。ただし「sk-」ではじまる必要があります。
  drop_params: true  # OpenRouter が認識しないパラメータを自動で削除

ポイント:

3.3. 3. 環境変数の設定

export OPENROUTER_API_KEY="sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export OPENROUTER_API_BASE="https://openrouter.ai/api/v1"

OpenRouter のダッシュボードから API Key を取得し、シェル環境に設定します。

3.4. 4. LiteLLM Proxy の起動

ターミナル 1:

cd /path/to/litellm
source .venv/bin/activate
litellm --config litellm_config.yaml --port 4000 --host 127.0.0.1

起動ログ例:

INFO:     Uvicorn running on http://127.0.0.1:4000 (Press CTRL+C to quit)

3.5. 5. 動作確認(curl テスト)

別のターミナルで:

# モデル一覧の取得
curl http://127.0.0.1:4000/v1/models \
  -H "Authorization: Bearer sk-litellm-master-key-1234"

# Chat Completion テスト
curl http://127.0.0.1:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-litellm-master-key-1234" \
  -d '{
    "model": "or-gemini-pro",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": false
  }'

4. ハマりポイント:Cursor の SSRF 制約

4.1. 問題

ローカルで LiteLLM を起動後、Cursor の設定に以下を入力します:

Base URL: http://127.0.0.1:4000/v1
API Key: sk-litellm-master-key-1234
Model: or-gemini-pro

しかし接続時に以下のエラーが発生します:

{
  "error": {
    "type": "client",
    "reason": "ssrf_blocked",
    "message": "connection to private IP is blocked",
    "retryable": false
  }
}

4.2. 原因

Cursor のリクエストは Cursor 社のバックエンド経由で処理される設計になっており、SSRF(Server-Side Request Forgery)対策として、プライベート IP アドレス(127.0.0.1、10.x.x.x、192.168.x.x など)への接続がブロックされています

これはセキュリティ上の理由から正しい実装ですが、ローカル開発時の接続を妨げます。


5. 解決策:ngrok による外部公開

5.1. ngrok とは

ngrok はローカルマシン上のサービス(HTTP)に対して、一時的な HTTPS の公開 URL を割り当てるトンネリングツールです。

ローカルの http://127.0.0.1:4000 に対して、https://xxx-yyy-zzz.ngrok-free.app のような外部 URL を提供します。その URL 経由で通信を行うと、自動的にローカルにフォワードされます。

5.2. インストールと初期設定

# macOS の場合(Homebrew)
brew install ngrok

# 認証トークンの設定(初回のみ)
ngrok config add-authtoken <YOUR_AUTHTOKEN>

5.3. ngrok の起動

ターミナル 2(LiteLLM を起動したターミナル 1 とは別):

ngrok http 4000

出力例:

Session Status       online
Session Expires      4 hours, 59 minutes

Version              3.19.0
Region               us (United States)
Forwarding           https://abc123def456.ngrok-free.app -> http://127.0.0.1:4000

5.4. Cursor の設定

Cursor の設定画面で以下を入力します:

Add Custom Model: or-gemini-pro
OpenAI API Key: sk-litellm-master-key-1234
Override OpenAI Base URL: https://abc123def456.ngrok-free.app/v1

以上です。Cursor が LiteLLM 経由で OpenRouter のモデルを呼び出せるようになります。

5.5. ngrok のトレードオフ

メリット:

デメリット:


6. OpenRouter の課金設計とコスト管理

6.1. OpenRouter の特徴

6.2. LiteLLM との組み合わせによるコスト管理

model_list:
  # 開発環境用(低コストモデル)
  - model_name: dev-fast
    litellm_params:
      model: openrouter/google/gemini-flash-1.5
      api_key: os.environ/OPENROUTER_API_KEY

  # 実験用(高品質モデル)
  - model_name: experiment-quality
    litellm_params:
      model: openrouter/anthropic/claude-3.5-sonnet
      api_key: os.environ/OPENROUTER_API_KEY

OpenRouter のダッシュボードで各 API Key に上限を設定することで、用途別にコストを管理できます。例えば:

この設定により、API Key の上限に達すると自動的にリクエストがブロックされるため、予期しない高額請求を防げます。


7. ローカル環境での運用上の注意

7.1. LiteLLM と ngrok の両方を起動し続ける

Cursor を使用している間は、以下の 2 つのプロセスをバックグラウンドで実行し続ける必要があります:

どちらかが落ちると Cursor から接続できなくなります。

7.2. ngrok セッションの時間制限

無料プランでは、ngrok セッションが一定時間(通常数時間)で自動的にリセットされます。リセットされると URL が変わるため、Cursor の設定を更新する必要があります。

7.3. ローカルネットワークからのアクセス

ngrok のトンネルを経由しているため、同じ WiFi 上の別マシン(例:iPhone)からも Cursor の同じエンドポイントを使用できます。これは複数端末での開発に便利ですが、セキュリティリスク(ローカルネットが外部公開される)があります。


8. まとめ

8.1. 技術的な成果

8.2. 技術的な制約

8.3. 推奨される使用シーン

このセットアップにより、ローカル開発環境でも OpenRouter の豊富なモデルを自由に選んで Cursor で利用できます。

9. 次のステップ:VPS での本格運用

9.1. ngrok の制限を超える

現在のセットアップは個人開発に最適ですが、以下のような要件が出てくると制限に当たります:

9.2. LiteLLM の Docker イメージを活用

LiteLLM は公式の Docker イメージが公開されており、VPS や Kubernetes などの本格的なインフラでの導入は想像以上に簡単です。

9.3. VPS + HTTPS で常時接続が可能

Xserver VPS や AWS Lightsail など、常時稼働する VPS に LiteLLM を立ち上げ、Nginx でリバースプロキシして HTTPS で公開すると:

固定 URL: https://api.example.com/v1 のような安定した URL で Cursor から接続可能です

ngrok 不要: トンネリング層を削除でき、レイテンシが改善されます

複数マシンからのアクセス: どの開発マシンからでも同じエンドポイントで接続可能です

セキュリティ向上: HTTPS と API Key による認証で、ローカル公開より安全です

スケーラビリティ: モデルの追加、設定変更が VPS 側で管理され、開発マシンへの影響がありません

9.4. 運用の観点

LiteLLM の Docker イメージ活用により:

バージョン管理が簡単: 環境変数や設定ファイルだけで管理でき、アップグレードは Docker イメージを更新するだけです

ログ集約が可能: 複数の LiteLLM インスタンスをオーケストレーションできます

メトリクス収集対応: Prometheus など、監視システムとの統合が容易です

複数プロバイダの一元管理: OpenRouter だけでなく、OpenAI、Anthropic など複数プロバイダを同時管理可能です

このように、LiteLLM は個人開発から本番運用まで、スケーラブルに対応できるツールとなっています。

10. FAQ

connection to private IP is blocked というエラーが出ます。なぜですか?
Cursor のアーキテクチャ上の仕様です。Cursor はリクエストを一度 Cursor 社のサーバーを経由して処理するため、セキュリティ(SSRF対策)の観点から localhost や 127.0.0.1 などのプライベート IP への接続をブロックしています。これを回避するために ngrok で外部公開 URL を発行する必要があります。
最初は動いていたのに、数時間後に接続できなくなりました。
ngrok の無料プランを使用している場合、一定時間でセッションがタイムアウトするか、再起動時に URL が変更されます。ngrok を再起動し、新しく発行された https://....ngrok-free.app の URL を Cursor の設定画面に入力し直してください。
ターミナルを閉じても動きますか?
いいえ、動きません。LiteLLM(プロキシサーバー)と ngrok(トンネル)のプロセスは常にバックグラウンドで起動している必要があります。これらを停止すると接続は切断されます。
OpenRouter 以外のモデル(ローカルの Ollama など)も使えますか?
はい、可能です。LiteLLM は Ollama や LocalAI など多数のプロバイダに対応しています。litellm_config.yaml の model 指定を ollama/llama3 のように変更し、LiteLLM がそのローカルサーバーにアクセスできるようにすれば、同様の構成で Cursor から利用できます。
Cursor の「Base URL」には正確に何を入力すれば良いですか?
ngrok が発行した HTTPS の URL の末尾に /v1 をつけたものです。 例: https://xxxx-xxxx-xxxx.ngrok-free.app/v1 末尾の /v1 が抜けていると、パス解決ができずエラーになる場合が多いのでご注意ください。
litellm_config.yaml の model_name は何でも良いのですか?
はい、好きな名前を付けられます。ここで設定した名前(例: my-claude)を Cursor 側の「Model Name」欄に入力して呼び出すことになります。覚えやすい名前をつけるのがおすすめです。
複数のモデルを切り替えて使うにはどうすれば良いですか?
litellm_config.yaml の model_list に複数のモデル定義を追加してください。その後、LiteLLM を再起動すれば、Cursor 側でモデル名を入力し直すだけで切り替えて使用できます。
ローカル環境を ngrok で公開してセキュリティ的に大丈夫ですか?
ngrok の URL は推測困難ですが、一時的に外部からアクセス可能になるリスクはあります。LiteLLM 側で master_key(API Key)を設定し、Cursor からの接続時に必ず認証を通すように設定(記事内の設定例は対応済み)することで、不正利用を防ぐことを強く推奨します。
LiteLLM 自体の利用に料金はかかりますか?
LiteLLM はオープンソースソフトウェアであり、ツール自体の利用は無料です。費用が発生するのは OpenRouter などの LLM プロバイダへの API 利用料のみです。
OpenRouter の利用上限に達したらどうなりますか?
設定したクレジット残高がなくなるか、設定した利用上限(Limit)に達すると API リクエストが 402 エラーなどで拒否されます。Cursor 上ではエラーメッセージが表示されるため、OpenRouter のダッシュボードでチャージまたは上限緩和を行う必要があります。
毎回 ngrok の URL を書き換えるのが面倒です。回避策はありますか?
ngrok の有料プランを契約して固定ドメインを取得するか、Cloudflare Tunnel を使う、または記事の「次のステップ」にあるように VPS 上に構築して固定 IP/ドメインを持たせる方法があります。
レスポンス速度は遅くなりませんか?
ursor → Cursorサーバー → ngrok → 自宅PC(LiteLLM) → OpenRouter という長い経路を辿るため、直接接続に比べると若干のレイテンシ(遅延)は発生します。ただ、チャットの用途であれば体感できるほどの大きな劣化は少ない場合が多いです。