# claude-bridge
A **subscription-safe bridge** that lets a primary **Claude Code (Opus 4.8, on Pro/Max)**
session drive a **secondary Claude agent running a different model** via its own
`ANTHROPIC_BASE_URL` — without ever putting a proxy on the primary session.
Sibling of [`crush-bridge`](https://git.ltms.dev/systems/vms) (which drives a headless
**Crush** worker on GX10 DeepSeek). `claude-bridge` keeps the worker a *real Claude Code
process*, so it inherits `CLAUDE.md`, hooks, skills, and MCP — just pointed at a
cheaper/local model.
## Leading approach — herdr-centric message server (`bridged`)
A small always-on message server, **`bridged`**, controls
[herdr](https://herdr.dev) (an agent multiplexer) over its Unix-socket API and exposes a
clean 2-way messaging API as an **MCP server that both the primary and the workers mount** —
one unified Claude setup (REST/SSE stays for non-Claude clients, plus an optional broker).
herdr owns the PTYs, multiplexing, persistence, and **agent-status events**; `bridged` owns
policy (subscription boundary, session lifecycle, status-gated delivery) and the client
contract. The worker `claude` launches with `ANTHROPIC_BASE_URL=https://ollama.ltms.dev` + a
bearer token; the primary Opus stays env-clean and calls `bridged`'s MCP tools.
```mermaid
flowchart LR
OPUS["Opus — primary
(Claude Code, env CLEAN)"]
BD["bridged
message server
(not a claude process)"]
HERDR["herdr
panes · agent-status"]
W["worker claude
ANTHROPIC_BASE_URL set"]
M["ollama.ltms.dev
(worker model)"]
OPUS -->|"MCP bridge_send (blocks)"| BD
W -.->|"MCP bridge_reply"| BD
BD -->|"Unix socket
send_text · events.subscribe"| HERDR
HERDR -->|"drives PTY"| W
W -->|"inference"| M
classDef ext fill:#2b6cb0,stroke:#1a365d,color:#ffffff;
classDef core fill:#2f855a,stroke:#22543d,color:#ffffff;
class OPUS ext
class BD,HERDR core
```
- **Subscription boundary:** the *primary* never sets `ANTHROPIC_BASE_URL` (stays on
Pro/Max). Only the *secondary* process is off-subscription — and `bridged` itself is a
plain daemon (no Anthropic quota), so it may poll/subscribe freely.
- **Unified MCP setup:** both the primary and the workers mount `bridged` as an MCP server
(one `claude mcp add` line, same on each side). Claude ↔ Claude runs over MCP tools —
`bridge_send` / `bridge_reply` / `bridge_ask` / `bridge_status` — with no `curl` or bespoke
client. MCP tool I/O never sets `ANTHROPIC_BASE_URL`, so mounting the bridge is
subscription-safe by construction.
- **How the primary consumes a reply:** a single **blocking MCP call** (`bridge_send`);
`bridged` holds it open until the worker calls `bridge_reply` or its turn hits
`agent_status=done`, then returns the reply as the tool result. No cross-turn busy-poll, so
no quota burn. SSE is an optional side-channel for humans/dashboards watching status.
Long/detached work uses the async broker path instead.
- **Worker → primary** rides `bridged`'s **MCP rendezvous** — the reply resolves the primary's
blocking call, so *no keystroke into the primary pane is needed, even single-host*.
Fallbacks: a single-host non-MCP primary can be typed into by herdr (subscription-safe
simulated typing); a split-host primary gets it via the **broker + its own `Stop`-hook**.
See the wiki for the two topologies.
- **Different model per process** sidesteps Claude Code's lack of per-subagent provider
routing — the worker isn't a subagent, it's its own configured process.
- **AgentAPI** ([`coder/agentapi`](https://github.com/coder/agentapi)) is retained only as a
swappable *fallback injector* behind the same interface. See the wiki for the full
design, comparison, and rationale.
## Docs
Full design, setup, and operations live in the **[wiki](https://git.ltms.dev/lms/claude-bridge/wiki)**,
vendored here as a submodule under [`wiki/`](./wiki):
```bash
git clone --recurse-submodules ssh://git@git.ltms.dev:2224/lms/claude-bridge.git
# or, after a plain clone:
git submodule update --init
```
Edit docs in `wiki/`, then `cd wiki && git commit && git push` to publish them to the
Gitea wiki.
## Status
🟢 Design — herdr-centric **`bridged`** message server selected as the primary approach
(2026-07-11), superseding the AgentAPI plan (2026-07-08). AgentAPI retained as fallback
injector.