agent-relay

module
v0.9.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2026 License: AGPL-3.0

README

agent-relay

ci docs Go Reference

A self-hosted, authenticating inference relay that fronts agent CLIs (v1: the claude CLI) behind standard HTTP APIs:

  • POST /v1/messages — Anthropic Messages API (streaming SSE and non-streaming)
  • POST /v1/chat/completions — OpenAI Chat Completions API
  • POST /a2aAgent2Agent tasks (opt-in), with a public Agent Card
  • GET /health — unauthenticated liveness probe
  • GET /v1/metrics — minimal JSON metrics

The relay spawns one supervised CLI subprocess per request, translates its stream-json output into the requested wire format, and enforces a hard security invariant: there is no configuration in which an unauthenticated caller on a non-loopback interface reaches a backend.

Two execution modes

Inference (default) Agentic (opt-in)
What a request can do produce text, spend tokens also create/edit files, run granted commands
CLI permission flags none, ever operator-chosen, per authorized request
Working directory static ephemeral per request, auto-deleted
Extra credential X-Agentic-Authorization header

In inference mode the CLI's tools hit a permission wall that nothing in a non-interactive subprocess can lift — callers get text, never side effects. Agentic mode deliberately lifts that wall behind four layers of consent: an operator flag, startup guards, an optional per-request credential, and a backend re-check. These control who may trigger agentic execution — they are authorization, not containment. The subprocess still runs as your user, with your HOME, so whatever RELAY_AGENTIC_ARGS grants can reach any file that user can (including the subscription credentials); the per-request throwaway directory isolates requests from each other, not from the host. Real containment is OS-level (a dedicated low-privilege account, a filesystem namespace, or one container per request) — see Security & threat model and docs/execution-modes.md.

Quick start

go build -o relay ./cmd/relay

# loopback, no auth required
./relay

# on a private network interface (e.g. Tailscale), auth is mandatory
RELAY_BIND=100.64.0.5:18082 RELAY_TOKENS=$(openssl rand -hex 32) ./relay

Call it with any Anthropic- or OpenAI-compatible client:

curl -N http://127.0.0.1:18082/v1/messages \
  -H "x-api-key: <token>" \
  -d '{"model":"sonnet","max_tokens":1024,"stream":true,
       "messages":[{"role":"user","content":"hello"}]}'

Security

Read SECURITY.md before exposing the relay off loopback. It states the threat model, the trust boundaries, what the relay does not defend against (TLS, sandboxing, prompt injection, per-caller quotas), why a TLS-terminating reverse proxy is mandatory off loopback, and why sharing a caller token means sharing your identity, your subscription's reputation, and — in agentic mode — your host.

Documentation

Development

go test ./...        # full suite, subprocess tests use a stub CLI
go test -race ./...  # run before committing
go vet ./...

Versioning follows Semantic Versioning; notable changes are tracked in CHANGELOG.md.

Disclaimer — terms of service

This is an independent, self-hosted tool. It is not affiliated with, endorsed by, or supported by Anthropic or any other model provider.

  • Requests relayed to the claude CLI are subject to the terms that govern your Anthropic account — the Consumer or Commercial Terms of Service and the Usage Policy — exactly as if you had run the CLI yourself.
  • Consumer subscriptions (Pro/Max) are personal. This relay is designed for your own scripts and devices on a private network (e.g. a Tailnet). Do not expose it to third parties, share access to your account through it, or use it to resell access. If several people or a service need access, use an API key under commercial terms instead.
  • Providers may restrict automated or programmatic use of consumer subscriptions; review the current terms before deploying. Violations can lead to rate limiting, suspension, or termination of your account.
  • You are solely responsible for how you deploy and use this software. It is provided under the AGPL without any warranty (see LICENSE).

AI usage disclosure

Portions of this project (code, tests, and documentation) were developed with the assistance of AI tools, under human direction and review.

License

This project is licensed under the GNU Affero General Public License, version 3 or (at your option) any later version — see LICENSE.

Directories

Path Synopsis
cmd
relay command
Command relay is the self-hosted agent relay: an authenticating inference proxy that fronts agent CLIs (v1: claude) behind Anthropic- and OpenAI-compatible HTTP APIs.
Command relay is the self-hosted agent relay: an authenticating inference proxy that fronts agent CLIs (v1: claude) behind Anthropic- and OpenAI-compatible HTTP APIs.
internal
api/a2a
Package a2a exposes the relay as an Agent2Agent (A2A) agent: a third wire adapter alongside the Anthropic and OpenAI ones.
Package a2a exposes the relay as an Agent2Agent (A2A) agent: a third wire adapter alongside the Anthropic and OpenAI ones.
api/anthropic
Package anthropic translates the Anthropic Messages wire format to and from the neutral core model (REQ-API-01).
Package anthropic translates the Anthropic Messages wire format to and from the neutral core model (REQ-API-01).
api/openai
Package openai translates the OpenAI Chat Completions wire format to and from the neutral core model (REQ-API-03).
Package openai translates the OpenAI Chat Completions wire format to and from the neutral core model (REQ-API-03).
backend/claude
Package claude adapts the `claude` CLI to the neutral core.Backend interface.
Package claude adapts the `claude` CLI to the neutral core.Backend interface.
backend/ollama
Package ollama adapts a local Ollama server to the neutral core.Backend interface.
Package ollama adapts a local Ollama server to the neutral core.Backend interface.
config
Package config loads and validates the relay configuration.
Package config loads and validates the relay configuration.
core
Package core defines the neutral request/event model that sits between the wire-format API layer and the agent backends.
Package core defines the neutral request/event model that sits between the wire-format API layer and the agent backends.
obs
Package obs provides request IDs, structured request logging, and a minimal JSON metrics snapshot (REQ-API-06, DQ-4: minimal JSON over Prometheus for v1).
Package obs provides request IDs, structured request logging, and a minimal JSON metrics snapshot (REQ-API-06, DQ-4: minimal JSON over Prometheus for v1).
outputs
Package outputs retains the artifacts of agentic requests for later retrieval.
Package outputs retains the artifacts of agentic requests for later retrieval.
ratelimit
Package ratelimit implements a per-caller token bucket: the relay's concurrency cap bounds simultaneous work, this bounds sustained rate, so one caller cannot drain the operator's subscription.
Package ratelimit implements a per-caller token bucket: the relay's concurrency cap bounds simultaneous work, this bounds sustained rate, so one caller cannot drain the operator's subscription.
server
Package server wires the HTTP mux: routing, auth, and the handlers that bridge wire decoding to core dispatch.
Package server wires the HTTP mux: routing, auth, and the handlers that bridge wire decoding to core dispatch.
toolbridge
Package toolbridge lets a backend agent call the *caller's* tools.
Package toolbridge lets a backend agent call the *caller's* tools.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL