# ๐ŸŽญ Setting Up Claude Code Agent with 9Router: Free Anthropic-Compatible Inference

**Date:** July 16, 2026  
**Tags:** AI, Claude Code, 9Router, Coding Agent, Self-Hosted, MCP, AI Agents

---

## ๐ŸŽฏ Overview

[Claude Code](https://github.com/anthropics/claude-code) is Anthropic's terminal **AI coding agent**. Out of the box it expects the official Anthropic API โ€” but it can be pointed at **any Anthropic-compatible endpoint** by overriding two environment variables. That's exactly how we run it for **free** through **9Router**, our LAN model router that exposes an Anthropic-compatible Messages API at `/v1/messages`.

This guide focuses on the **9Router integration**: Claude Code becomes a *first-class coder* in the stack without paying per token, auto-rotating through 9Router's free models (including `Free`, the default we pin).

### Why Claude Code + 9Router?

| Feature | Benefit |
|---------|---------|
| **๐Ÿ’ธ Free** | 9Router serves Anthropic-compatible models at no cost |
| **๐Ÿ”Œ Drop-in** | Only two env vars to override (`ANTHROPIC_BASE_URL`, `ANTHROPIC_API_KEY`) |
| **๐Ÿ” Auto-rotate** | 9Router picks healthy free models automatically |
| **๐ŸŒ OpenRouter Fallback** | One `OPENROUTER_API_KEY` for paid overflow |
| **๐Ÿ”Œ MCP Ready** | GBrain + any MCP server |
| **๐Ÿง  Reasoning** | `NINE_ROUTER_ENABLE_REASONING=true` |

---

## ๐Ÿ—๏ธ Architecture Overview

```
   Terminal / Telegram / tmux
            โ”‚
            โ–ผ
   claude  (coding agent)
     env: ANTHROPIC_BASE_URL=http://192.168.51.115:20128/v1
     env: ANTHROPIC_API_KEY=
     env: model=Free
            โ”‚
            โ–ผ
   9Router  http://192.168.51.115:20128/v1/messages
   (Anthropic-compatible Messages API, free models)
            โ”‚
   claude โ”€โ”€ MCP โ”€โ”€โ–บ GBrain (shared memory / Postgres)
```

---

## ๐Ÿ“‹ Prerequisites

- Linux VM with the Claude Code CLI installed (binary at `~/.local/bin/claude`).
- A running **9Router** (see the [9Router guide](/blog/9router-setup/)) exposing `/v1/messages`.
- (Optional) GBrain MCP server for shared memory.
- A non-root user (`ryan` in examples).

> โš ๏ธ **Security note:** Every secret below is a ``. Never commit real keys.

---

## ๐Ÿ“ฆ Step 1 โ€” Install Claude Code

```bash
# Claude Code installs as a global CLI; on this VM:
# /home/ryan/.local/bin/claude ->
#   /home/ryan/.local/share/claude/versions//claude

# Verify
which claude
claude --version
```

---

## โš™๏ธ Step 2 โ€” Point Claude Code at 9Router (the core trick)

Claude Code reads two env vars to locate its API. Override them to hit 9Router's Anthropic-compatible endpoint:

```bash
# The two variables that make it work:
export ANTHROPIC_BASE_URL="http://192.168.51.115:20128/v1"
export ANTHROPIC_API_KEY=""

# Optional: enable 9Router reasoning passthrough
export NINE_ROUTER_ENABLE_REASONING="true"

# Optional: OpenRouter fallback key
export OPENROUTER_API_KEY=""

# Pin the model Claude Code requests
export CLAUDE_CODE_MODEL="Free"   # or pass --model Free
```

These can be baked into Claude Code's `settings.json` so they apply automatically:

```json
// ~/.claude/settings.json (sanitized)
{
  "env": {
    "PATH": "/home/ryan/.bun/bin:/home/ryan/.local/bin:/usr/local/bin:/usr/bin:/bin",
    "ANTHROPIC_BASE_URL": "http://192.168.51.115:20128/v1",
    "ANTHROPIC_API_KEY": "",
    "NINE_ROUTER_ENABLE_REASONING": "true",
    "OPENROUTER_API_KEY": ""
  },
  "effortLevel": "medium",
  "theme": "dark",
  "model": "Free"
}
```

> ๐Ÿ’ก With `ANTHROPIC_BASE_URL` set, Claude Code sends its `POST /v1/messages` calls to 9Router instead of `api.anthropic.com` โ€” fully transparent to the agent.

---

## ๐Ÿงฉ Step 3 โ€” Env Helper Scripts

Two helper scripts on this VM manage the 9Router wiring. The preferred one reads the key from the central env file (no hardcoded secret):

```bash
# ~/.claude/ninerouter-env.sh (preferred โ€” reads key from ~/.hermes/.env)
if [ -f "$HOME/.hermes/.env" ]; then
  NINEROUTER_API_KEY="$(python3 - <<'PY'
from pathlib import Path
for line in Path('/home/ryan/.hermes/.env').read_text().splitlines():
    if line.startswith('NINE_ROUTER_API_KEY='):
        print(line.split('=', 1)[1].strip().strip('"'))
PY
  )"
fi
export ANTHROPIC_BASE_URL="http://192.168.51.115:20128/v1"
export ANTHROPIC_API_KEY="$NINEROUTER_API_KEY"
export NINE_ROUTER_ENABLE_REASONING="true"
```

```bash
# ~/.claude/start-claude-9router.sh (launches claude with 9Router env)
#!/usr/bin/env bash
source /home/ryan/.claude/9router-env.sh
export ANTHROPIC_BASE_URL ANTHROPIC_API_KEY NINE_ROUTER_ENABLE_REASONING OPENROUTER_API_KEY
exec claude "$@"
```

Launch a long-lived session:

```bash
# From tmux / Telegram bridge
source /home/ryan/.claude/9router-env.sh
claude --dangerously-skip-permissions
```

> ๐Ÿ” Prefer `ninerouter-env.sh` over the variant that hardcodes the key in the script. Keep secrets in `~/.hermes/.env`, not inline.

---

## ๐Ÿงฉ Step 4 โ€” Wire GBrain via MCP

Claude Code supports MCP servers via `~/.claude/mcp.json` (same GBrain server as the other agents):

```json
{
  "mcpServers": {
    "gbrain": {
      "command": "/home/ryan/.bun/bin/gbrain",
      "args": ["serve"],
      "env": {
        "GBRAIN_DATABASE_URL": "",
        "GBRAIN_DIRECT_DATABASE_URL": ""
      }
    }
  }
}
```

Verify:

```bash
/home/ryan/.bun/bin/gbrain get_health
# -> healthy
```

---

## ๐Ÿš€ Step 5 โ€” Usage

```bash
# Interactive session (env already sourced)
claude

# One-shot (non-interactive) with a prompt
claude -p "Refactor src/auth.py to use env vars instead of hardcoded config"

# Pin a model explicitly
claude --model Free

# Skip permission prompts for long-lived/automation sessions
claude --dangerously-skip-permissions
```

---

## ๐Ÿงช Step 6 โ€” Smoke Test

```bash
# 1. Claude binary resolves
which claude

# 2. Env points at 9Router
echo "$ANTHROPIC_BASE_URL"   # -> http://192.168.51.115:20128/v1

# 3. 9Router reachable with key (placeholder)
curl -s --max-time 8 -H "Authorization: Bearer " \
  http://192.168.51.115:20128/v1/models | head -c 200

# 4. A trivial Claude call works (uses ANTHROPIC_BASE_URL)
claude -p "Say: claude online via 9router"

# 5. GBrain MCP healthy
/home/ryan/.bun/bin/gbrain get_health
```

Expected: `/v1/models` returns JSON, Claude prints `claude online via 9router`, GBrain is healthy.

---

## ๐Ÿฉบ Troubleshooting

| Symptom | Likely cause | Fix |
|---------|-------------|-----|
| Claude hits `api.anthropic.com` | `ANTHROPIC_BASE_URL` not set | `export ANTHROPIC_BASE_URL=http://192.168.51.115:20128/v1` |
| 401 from 9Router | Wrong/expired key | Re-source `ninerouter-env.sh`, re-test `/v1/models` |
| `model not found` | Model ID not served by 9Router | Use `Free` or check `/v1/models` |
| MCP tools missing | gbrain down / bad env | `gbrain get_health`, fix `` |
| Reasoning ignored | Flag off | Set `NINE_ROUTER_ENABLE_REASONING=true` |

---

## ๐Ÿ” Security Checklist

- [ ] `ANTHROPIC_API_KEY` is `` (the 9Router key), injected via env, never committed.
- [ ] Prefer `ninerouter-env.sh` (reads from `~/.hermes/.env`) over any script that hardcodes the key.
- [ ] `OPENROUTER_API_KEY` is a ``, used only as fallback.
- [ ] GBrain Postgres URLs are placeholders; DB user is least-privilege.
- [ ] `--dangerously-skip-permissions` only for trusted automation sessions.

---

## โœ… Summary

You now have **Claude Code** running on **9Router** for free:

- Installed as a global CLI (`~/.local/bin/claude`).
- **Anthropic-compatible endpoint override**: `ANTHROPIC_BASE_URL=http://192.168.51.115:20128/v1` + `ANTHROPIC_API_KEY=`.
- Model pinned to `Free`; reasoning enabled via `NINE_ROUTER_ENABLE_REASONING=true`.
- Helper scripts (`ninerouter-env.sh`, `start-claude-9router.sh`) for clean launches + OpenRouter fallback.
- Connected to **GBrain** via MCP for shared memory across all agents.

Claude Code rounds out the coding roster alongside [Pi](/blog/pi-coding-agent-setup/), [OpenCode](/blog/opencode-agent-setup/), and [Codex](/blog/codex-agent-setup/) โ€” all behind [OpenClaw](/blog/openclaw-setup/) (gateway), orchestrated with [Hermes](/blog/hermes-setup/), leaning on [9Router](/blog/9router-setup/) for inference. ๐Ÿš€

---

*No API keys, tokens, or secrets are included in this guide โ€” every value is a `` you supply locally. Built with Astro, GitHub, and Cloudflare Pages.*