Sidecar — Cross-Cutting Concerns Layer
Auto-injected Go binary that handles tracing, cost attribution, guardrails, A2A, and MCP for every deployed agent.
Sidecar — Cross-Cutting Concerns Layer
The sidecar is a single Go binary auto-injected next to every AgentBreeder agent. The agent talks to it over localhost; the sidecar handles all of the boring-but-mandatory infrastructure work — tracing, cost attribution, guardrails, A2A, MCP, and bearer-token auth — so language SDKs stay thin.
One binary, every language, every cloud.
When the sidecar is injected
The deploy pipeline auto-injects rajits/agentbreeder-sidecar:<version> whenever your agent.yaml declares any of:
guardrails:— a list of egress rules (PII, content filter, custom)- MCP
tools:— anytools:entry that resolves to an MCP server a2a:— an A2A peer block
If none of these are present the sidecar is not injected — the agent runs alone, and there's no overhead for simple agents.
Auto-injection coverage in v2.0
v2.0 wires sidecar auto-injection into Docker Compose, GCP Cloud Run, and AWS ECS Fargate deployers. AWS App Runner, Azure Container Apps, and Kubernetes deployers will land auto-injection in v2.x — for those targets today, run the sidecar as a separate task/container and point AGENTBREEDER_SIDECAR_AGENT_URL at your agent. Tracking issue: open one at agentbreeder/agentbreeder/issues if you need a specific target prioritised.
To override behaviour locally, set AGENTBREEDER_SIDECAR=disabled in the environment. The injection helper short-circuits and the agent runs solo regardless of agent.yaml.
name: support-agent
version: 1.0.0
team: customer-success
owner: alice@company.com
model:
primary: claude-sonnet-4
framework: langgraph
# Any of these three triggers sidecar injection
guardrails:
- pii_detection
- content_filter
tools:
- ref: tools/zendesk-mcp # MCP tool — triggers injection
# (a2a:) block also triggers injectionTopology
┌──────── Pod / Task / Cloud Run revision ─────────┐
│ │
│ ┌─────────────┐ localhost ┌──────────────┐ │
│ │ user agent │ ◄───────────► │ sidecar │ │
│ │ (any lang) │ :8080 in │ (Go binary) │ │
│ │ │ :9090 a2a │ │ │
│ │ │ :9091 mcp │ → OTel │ │
│ └─────────────┘ :9092 cost │ → cost svc │ │
│ ▲ │ → guardrail │ │
│ │ inbound :8080 └──────────────┘ │
└───────┼──────────────────────────────────────────┘
│
external traffic (deployer ingress → sidecar → agent)External traffic hits the sidecar on :8080. The sidecar:
- Validates the bearer token (
AGENT_AUTH_TOKEN) - Runs egress guardrails on the request body
- Forwards the (possibly redacted) request to the agent on
:8081
The agent uses localhost helper endpoints to send A2A calls, talk to MCP servers, and emit cost events without re-implementing any of that logic per language.
Endpoints
Inbound (:8080)
| Path | Method | Auth | Description |
|---|---|---|---|
/health | GET | open | Liveness probe |
/openapi.json | GET | open | Self-describing schema |
/* | * | bearer | Forwarded to the agent on AGENTBREEDER_SIDECAR_AGENT_URL after guardrails |
Local helpers (127.0.0.1:9090)
| Path | Method | Description |
|---|---|---|
/a2a/{peer} | POST | JSON-RPC 2.0 send to a configured A2A peer |
/mcp/{server} | POST | JSON-RPC passthrough to a configured MCP server (HTTP / SSE) |
/cost | POST | Record a cost/token event in the AgentBreeder API (writes both costs + audit_log tables) |
/health | GET | Liveness for the local helpers |
Guardrails
The sidecar ships with built-in PII rules — SSN, credit-card, email — that run on every egress. You can extend them by mounting a YAML file at /etc/agentbreeder/sidecar.yaml:
guardrails:
- name: ssn-block
type: regex
pattern: '\b\d{3}-\d{2}-\d{4}\b'
action: block # block | redact | warn (default redact)
- name: profanity
type: keyword
pattern: "darn,heck"
action: redact
replace: "[CENSORED]"Actions:
block— short-circuits and returns 403; the agent never sees the request.redact— rewrites the request body before forwarding (default).warn— records a violation but lets the request through.
The default rules run first; user rules run after and can layer on top.
Calling A2A peers
Configure peers in sidecar.yaml:
a2a_peers:
research-agent: https://research.run.app
# Per-peer bearer token: peer-token@@<url>
finance-agent: finance-tok@@https://finance.run.appThen from your agent, regardless of language, just POST to localhost:
import httpx
resp = httpx.post(
"http://127.0.0.1:9090/a2a/research-agent",
json={"method": "tasks/send", "params": {"message": "summarise X"}},
)
result = resp.json()["result"]The wire format matches engine/a2a/protocol.py exactly so Python and Go peers interoperate without a shim.
Calling MCP servers
mcp_servers:
docs:
transport: http
url: https://docs.example.com/mcpresp = httpx.post(
"http://127.0.0.1:9090/mcp/docs",
json={"method": "tools/list", "params": {}},
)v1 supports HTTP / SSE upstream MCP servers. Stdio transport is deferred to a follow-up — see the TODO in sidecar/internal/mcp/mcp.go.
Cost events
Every LLM call should emit a cost event so the registry stays attribution-accurate. Either call the local sidecar helper:
httpx.post("http://127.0.0.1:9090/cost", json={
"model": "claude-sonnet-4",
"input_tokens": 1024,
"output_tokens": 256,
"cost_usd": 0.0038,
"trace_id": current_trace_id(),
})…or rely on language-SDK middleware to emit it for you (Python / TS SDK ship this; Go / Kotlin / Rust SDKs ship in Track I).
The sidecar writes one row to the costs table and a corresponding cost.recorded entry to the audit log per event.
Environment variables
| Var | Required | Default | Notes |
|---|---|---|---|
AGENT_NAME | ✅ | — | Canonical agent identifier |
AGENT_VERSION | — | Populated automatically by the deployer | |
AGENT_AUTH_TOKEN | ✅ | — | Bearer token validated on inbound :8080 |
AGENTBREEDER_SIDECAR | enabled | Set to disabled / off / false / 0 to skip injection | |
AGENTBREEDER_SIDECAR_AGENT_URL | http://127.0.0.1:8081 | Where to forward inbound traffic | |
OTEL_EXPORTER_OTLP_ENDPOINT | — | OTLP/HTTP base URL. When unset, span export is a no-op | |
OTEL_EXPORTER_OTLP_HEADERS | — | Comma-separated k=v pairs | |
AGENTBREEDER_API_URL | — | API base for cost emission | |
AGENTBREEDER_API_TOKEN | — | Bearer token used when calling the AgentBreeder API |
Local development
To run an agent without the sidecar:
export AGENTBREEDER_SIDECAR=disabled
agentbreeder deploy --target localThe deployer's should_inject() helper honours this env var and the sidecar container is skipped entirely.
To run the sidecar locally with an agent:
docker run --rm \
-e AGENT_NAME=demo \
-e AGENT_AUTH_TOKEN=$(openssl rand -hex 16) \
-e AGENTBREEDER_SIDECAR_AGENT_URL=http://host.docker.internal:8081 \
-p 8080:8080 \
rajits/agentbreeder-sidecar:latestA complete docker-compose example lives at sidecar/examples/compose/.
Source
The sidecar source is in the top-level sidecar/ directory of the agentbreeder repo. It's a self-contained Go module — no Python dependency.
Build:
cd sidecar
go test ./... -cover
go build -o sidecar ./cmd/sidecar
# Multi-arch image
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag rajits/agentbreeder-sidecar:dev \
-f Dockerfile .The sidecar binary is built in CI and published as rajits/agentbreeder-sidecar:<version> on each AgentBreeder platform release.