n4nAI

Routing Claude Code and Cursor requests through n4n.ai

Engineer-focused tutorial: set up claude code cursor n4n.ai routing via OpenAI-compatible endpoint, env vars, and a minimal Anthropic-to-OpenAI proxy.

n4n Team4 min read858 words

Audio narration

Coming soon — every post will get a voice note here.

Setting up claude code cursor n4n.ai routing lets you centralize model access, get automatic fallback when providers degrade, and meter token usage without modifying agent internals. Cursor speaks the OpenAI chat protocol natively; Claude Code speaks the Anthropic Messages protocol. Because the gateway is OpenAI-compatible, Claude Code needs a thin local translation proxy—this guide builds one and wires both tools end to end.

Step 1: Provision credentials and record the endpoint

n4n.ai exposes a single OpenAI-compatible endpoint that fronts 240+ models. Grab an API key from your dashboard and note the base URL (typically https://api.n4n.ai/v1—substitute your actual tenant URL). Export them so later steps and the proxy can read them:

export N4N_API_KEY="sk-your-real-key"
export N4N_BASE_URL="https://api.n4n.ai/v1"

Keep the key out of shell history in shared environments. The gateway honors client routing directives (e.g., x-routing-pref) and forwards provider cache-control hints, but those are opt-in headers we’ll touch on later.

Step 2: Configure Cursor to use the OpenAI-compatible gateway

Cursor lets you override the OpenAI base URL and key through its settings JSON. On Linux/macOS this lives at ~/.cursor/config.json. The relevant keys are openaiApiKey, openaiBaseUrl, and model.

{
  "openaiApiKey": "sk-your-real-key",
  "openaiBaseUrl": "https://api.n4n.ai/v1",
  "model": "anthropic/claude-3.5-sonnet",
  "openaiOrg": ""
}

If you prefer the GUI, open Settings → Models → OpenAI Compatible, paste the base URL and key, and select a model from the dropdown. Because the gateway aggregates many providers, you can switch model to any supported ID (e.g., openai/gpt-4o, meta/llama-3.1-70b) without leaving Cursor.

Verify Cursor routing

Run a trivial prompt inside Cursor (“echo the word pong”). Then check your gateway usage log for a chat.completions call with the expected model ID. If you see 401s, the key or base URL is wrong; 404s mean the model string isn’t recognized by the gateway.

Step 3: Build a minimal Anthropic-to-OpenAI proxy for Claude Code

Claude Code reads ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY, then posts to /v1/messages. We stand up a local FastAPI service that accepts that shape, translates to /v1/chat/completions, and maps the response back. This is not a full Anthropic emulation—it covers single-turn prompt and basic params, which is enough for interactive coding sessions.

# proxy.py
from fastapi import FastAPI, Request
import httpx, os

app = FastAPI()
UPSTREAM = os.environ["N4N_BASE_URL"]
KEY = os.environ["N4N_API_KEY"]

@app.post("/v1/messages")
async def messages(req: Request):
    body = await req.json()
    # Anthropic prompt is a string; OpenAI wants messages
    openai_req = {
        "model": body["model"],
        "messages": [{"role": "user", "content": body["prompt"]}],
        "max_tokens": body.get("max_tokens", 1024),
        "temperature": body.get("temperature", 1.0),
        "stream": body.get("stream", False),
    }
    async with httpx.AsyncClient(timeout=60) as c:
        r = await c.post(
            f"{UPSTREAM}/chat/completions",
            headers={"Authorization": f"Bearer {KEY}"},
            json=openai_req,
        )
        data = r.json()
    # Map back to Anthropic's minimal message shape
    return {
        "id": data.get("id", "msg_local"),
        "type": "message",
        "role": "assistant",
        "content": [{
            "type": "text",
            "text": data["choices"][0]["message"]["content"]
        }],
        "model": data.get("model", body["model"]),
        "stop_reason": "end_turn",
    }

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8080)

Install deps:

pip install fastapi uvicorn httpx

Run it:

python proxy.py

Handling streaming and system prompts

Production Claude Code uses streaming and often sends a system field. Extend the proxy by mapping system to a leading {"role":"system"} message and by piping upstream SSE chunks back as Anthropic’s text deltas. For a quick start, disabling streaming in Claude Code’s config ("stream": false) avoids that work. Tool-use blocks require similar shape translation but are out of scope for a first deploy.

Step 4: Point Claude Code at the local proxy

Claude Code only needs the base URL; the key is ignored by our proxy but must be non-empty.

export ANTHROPIC_BASE_URL="http://127.0.0.1:8080"
export ANTHROPIC_API_KEY="local-dummy"
claude-code  # or your launcher

If you run Claude Code inside a container, point the base URL at the host gateway (e.g., http://host.docker.internal:8080). Test with a single command:

echo "explain the function main in main.c" | claude-code --print

You should see a completion sourced from the upstream model. The proxy logs will show the translated request hitting N4N_BASE_URL.

Step 5: Verify end-to-end routing and metering

Two checks matter: (1) both tools actually route through the gateway, and (2) token usage is recorded per request.

For Cursor, watch the gateway’s request log or call the usage endpoint if your plan exposes one. For Claude Code, curl the proxy directly to isolate translation bugs:

curl -s http://127.0.0.1:8080/v1/messages \
  -H "content-type: application/json" \
  -d '{"model":"anthropic/claude-3.5-sonnet","prompt":"say hi","max_tokens":16}' \
  | python -m json.tool

A well-formed Anthropic-style response confirms the proxy. Then inspect the gateway side: because the upstream is the OpenAI-compatible endpoint, you should see a corresponding chat.completions entry with the same model ID and a usage object. That object feeds per-token metering, so your finance or platform team can attribute cost to the agent without instrumenting the agents themselves.

Routing directives and cache hints

If you want to force a specific provider or enable prompt caching, pass headers in the proxy before forwarding:

headers = {
    "Authorization": f"Bearer {KEY}",
    "x-routing-pref": "provider=anthropic",  # if gateway supports
    "x-cache-control": "ephemeral",
}

Claude Code sends cache_control in its native body; map that to the gateway’s cache hint so repeated repo context isn’t re-billed. The gateway forwards those hints to the underlying provider where supported.

Step 6: Harden the setup for daily use

The local proxy is a single point of failure. Run it as a systemd user service or a background container:

# /etc/systemd/user/claude-proxy.service
[Unit]
Description=Anthropic-to-OpenAI proxy for Claude Code
[Service]
Environment=N4N_BASE_URL=https://api.n4n.ai/v1
Environment=N4N_API_KEY=sk-your-real-key
ExecStart=/usr/bin/python /opt/proxy.py
Restart=on-failure

Then systemctl --user enable --now claude-proxy. For teams, bake the proxy into a shared image so every engineer uses identical translation logic. Keep the proxy stateless—no caching, no key storage beyond env—so the gateway remains the source of truth for auth and fallback.

Common failure modes

  • Model not found (404): Cursor or proxy sends a model ID the gateway doesn’t map. Use the gateway’s /v1/models list to confirm the exact string.
  • Timeout on large diffs: Claude Code can emit huge prompts. Raise the proxy’s httpx timeout and the gateway client timeout; consider truncating context at the proxy if you hit provider limits.
  • Streaming mismatch: If Claude Code hangs, ensure stream is either fully implemented or disabled on both sides. Mismatched stream:true upstream with a non-streaming local response will stall the CLI.
  • Key leakage: Never log N4N_API_KEY in proxy logs. Redact before shipping containers.

What you get

After these steps, Cursor and Claude Code share one authenticated egress point. You gain automatic fallback when a provider is rate-limited, centralized cache-control, and per-token metering without maintaining separate Anthropic and OpenAI keys in every tool. The translation proxy is ~40 lines; treat it as internal infrastructure, not a product, and extend only the fields your agents actually send.

Tagsclaude-codecursorn4n-airouting

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All autonomous coding agents: claude code, devin, cursor posts →