Connect an Agent

Point a coding agent — Claude Code, Codex, or pi.dev — at your locally loaded models with one click, using either the Anthropic-compatible shim or the OpenAI-compatible router directly.

What it does

LlamaForge exposes two HTTP surfaces a coding agent can talk to:

Shim auth (backend/routes.py _shim_auth_ok(), called from server.py) accepts either header an Anthropic client might send: x-api-key: <key> or Authorization: Bearer <key>. It is skipped while router_host is 127.0.0.1 or no router_api_key is set. The panel itself remains loopback-only. Network Access requires a usable router key for every newly configured LAN router; the shim forwards the configured credential to the router where needed.

Agent setup (backend/agentsetup.py) generates the config each agent needs to point at LlamaForge, and can optionally write it in place:

AgentConfig fileFormatEndpoint it's given
claude-code~/.claude/settings.jsonJSON (env block)The loopback Anthropic endpoint, http://127.0.0.1:<panel_port> — always local, never the LAN.
codex~/.codex/config.tomlTOML (appended provider block)Direct mode uses the router's OpenAI-compatible endpoint, http://<host>:<router_port>/v1; injected mode uses the loopback panel endpoint http://127.0.0.1:<panel_port>/v1.
pi~/.pi/agent/models.jsonJSON (providers block)The same direct-router or injected-loopback choice as Codex.

Claude Code's generated settings.json sets ANTHROPIC_BASE_URL to the shim endpoint, ANTHROPIC_AUTH_TOKEN to the router key (your router_api_key, else the key LlamaForge generated for its own local router, else the literal string llamaforge — the shim needs a non-empty token even when auth is effectively open), ANTHROPIC_MODEL, and ANTHROPIC_SMALL_FAST_MODEL. Codex's TOML block declares a [model_providers.llamaforge] section with wire_api = "chat" and, if a router key exists (yours or the generated local one), an env_key pointing at a LLAMAFORGE_API_KEY environment variable the user must set — the key itself is never written to the TOML file. pi's models.json sets api: "openai-completions" with the key embedded directly in the config.

Codex and pi can optionally be routed through the loopback panel proxy with inject=true — this is how those two agents pick up wiki context injection (see Context Wiki). An injected endpoint is local-machine-only; direct Codex/pi configuration uses the router endpoint instead.

Preview generation returns config content and a human-readable target path/instructions without touching disk (used for "copy this into your config" display). Apply writes it — JSON targets are deep-merged into any existing file (_deep_merge(), so unrelated existing keys survive), and the Codex TOML target is appended only if the [model_providers.llamaforge] block isn't already present, commenting out any conflicting top-level model/model_provider line rather than deleting it. Apply backs up the target once, to <path>.llamaforge.bak, before its first write.

The preview may deliberately contain the Claude Code or pi credential needed for that agent's native file. Treat it like Client Config: it is shown only after the explicit POST request. Apply may use the stored key to write a file, but its response never returns the key.

How to use it

  1. Open the Setup tab, find the Connect an agent card, and pick Claude Code, Codex, or pi.dev under Agent.
  2. Choose a Model from the active llama-family engine (and, for Claude Code, a Small model). vLLM agent setup is deferred.
  3. Press Show configuration. This is the only preview action: it is an explicit POST and is not fetched on render or selection change. For Codex or pi.dev, tick Inject local context through the panel (this machine only) only when the agent runs on this same machine.
  4. Review or copy the preview, then click Apply only to write the config into the agent's real local config file.
  5. Launch the agent. Claude Code must run on the same machine as LlamaForge — its endpoint is always 127.0.0.1.

The same card carries a pi coding agent section and an MCP server section. Install pi fetches pi's published npm package into LlamaForge's own agents/pi folder with your Node.js (22.19 or newer; Install Node.js is offered when it is missing), Update reinstalls it and Remove deletes only that copy; LlamaForge uses pi_bin from config.json first, then its own copy, then pi on PATH. The MCP section gives copy-paste snippets that let Claude Code, Codex or any MCP client drive LlamaForge itself; see MCP Server.

Reference

ConceptSourceBehavior
Anthropic request translationbackend/anthropic_shim.py to_openai_request()Anthropic Messages body -> OpenAI chat body (system, messages incl. tool_use/tool_result, tools, tool_choice, stop_sequences).
Anthropic response translationbackend/anthropic_shim.py to_anthropic_response() / stream_anthropic_events()OpenAI response/SSE -> Anthropic message / streaming content-block events.
Token estimatebackend/anthropic_shim.py count_tokens_estimate()Advisory only: len(text) // 4 over the translated prompt.
Shim authbackend/routes.py _shim_auth_ok()Accepts x-api-key or Authorization: Bearer <key>; skipped when router_host is 127.0.0.1 or no router_api_key is set.
Endpoint per agentbackend/routes.py _agent_endpoint_for()Claude Code -> loopback Anthropic endpoint; direct Codex/pi -> router at <host>:router_port/v1; injected Codex/pi -> loopback panel at 127.0.0.1:panel_port/v1.
Config previewPOST /api/agent/configExplicit POST with {agent, model, backend, small, inject}; may deliberately contain Claude/pi credentials and does not write files.
Config applyPOST /api/agent/applySame targeting fields; writes to the real target path, JSON is deep-merged and Codex TOML appended if absent, original is backed up once. Apply never returns a key.

Troubleshooting

If Claude Code can't reach LlamaForge, confirm it's running on the same machine — the shim endpoint is hardcoded to 127.0.0.1 and never the LAN IP, by design (routes._agent_endpoint_for() always returns the loopback panel address for Claude Code). If Codex or pi.dev requests fail auth after changing router_host, make sure LLAMAFORGE_API_KEY (Codex) or the embedded apiKey (pi) actually matches the current router_api_key in config — a stale key set before you edited config will keep failing. If re-applying a config seems to have no effect, check <path>.llamaforge.bak next to the target file: it holds the original from before LlamaForge ever touched it, since the backup is only ever written once.

See also Context Wiki for how injected context reaches requests that go through the shim or router proxy.