flux7-mesh: Governance Mesh for AI Agents
The problem
You're deploying agents. They call tools such as file writes, emails, API calls and database queries. You need to answer three questions before going to production:
- Which agent can call which tool? Frameworks don't enforce boundaries. An agent can call anything it discovers.
- Who approved that action? The developer clicked "yes" in a terminal prompt 3 weeks ago. That decision is gone.
- What happened? You have stdout logs somewhere. They are neither structured nor queryable, so they cannot serve as an audit trail.
These problems belong to the infrastructure rather than to the agent framework. Service meshes solved them for microservices a decade ago with policy enforcement, observability and access control at the network layer. Agents need the same thing at the tool call layer.
What flux7-mesh is
flux7-mesh is a sidecar proxy that sits between agents and their tools. It ships as one Go binary with one YAML config and zero dependencies.
Agent (Claude, LangChain, script)
│
└──► flux7-mesh (sidecar)
├── policy: allow / deny / human_approval
├── rate limiting + loop detection
├── temporal grants (sudo for agents)
├── approval queue (async, non-blocking)
├── traces (JSONL + OTEL)
└──► tools (MCP servers, OpenAPI, CLI binaries)
Agents don't know the proxy exists. They call tools and get results. The operator sees the governance layer, whereas the agent does not.
Transports: MCP stdio (Claude Code, Cursor) · MCP Streamable HTTP at POST /mcp (Anthropic Managed Agents, remote clients) · HTTP REST (POST /tool/{name})
Where it sits
flux7-mesh is the first of up to four layers a call can meet. A rule decides most calls on the spot. When a rule sends a call to approval, precedents in flux7-memory can settle it, then flux7-supervisor, and only then a human. Only the mesh is required. See How it works.
Every tool call is a trace, and every decision can be kept as a fact in flux7-memory. Both are queryable.
What makes it different
Three properties set flux7-mesh apart. The other features are standard capabilities, well executed.
1. The enforcement point is protocol-agnostic. A policy attaches to a tool's identity, not to the transport carrying it. The same rule governs a stdio MCP server, an imported OpenAPI operation and a local binary, in one catalog. Change your agent framework or your tool protocol and the rule survives both.
2. The audit trail is causal, not chronological. A trace carries parent_trace_id and grant_id. GET /traces/{id}/why walks the chain back, so the answer is not "allowed by rule X" but "allowed by grant G, which came from approval A, which came from call T". Most systems record what happened, whereas flux7-mesh also records why the call was permitted, back to the human decision.
3. Enforcement is decoupled from proxying. POST /decide evaluates policy without executing anything. A PreToolUse hook asks "would you allow this?" and enforces locally, which means flux7-mesh governs tools that never transit it, including a harness's built-in tools. Hence flux7-mesh acts as a policy authority rather than only as a proxy.
| API Gateways (Kong, Apigee) | Agent Frameworks (LangChain, CrewAI) | flux7-mesh | |
|---|---|---|---|
| Traffic | North-south (user → LLM) | Internal (agent runtime) | East-west (agent → tools) |
| Policy | API keys, rate limits | None or coarse allow/ask | Semantic YAML rules per agent per tool |
| Approval | None | Framework-specific | Async queue, non-blocking, with memory |
| Identity | API consumer | Single agent | Per-agent (agent:claude, agent:worker-3) |
| Decision persistence | None | None | Facts in flux7-memory, queryable, auditable |
| Deployment | Heavy infrastructure | Embedded in code | Single binary sidecar, zero config to start |
The closest comparable is Microsoft Agent Governance Toolkit. However, that toolkit is a middleware, whereas flux7-mesh is a sidecar and requires zero changes to agent code.
Current state (September 2026)
- v0.17.2: 454 Go test functions across 18 packages, plus 80 Python SDK tests
- Import: MCP servers over stdio, SSE and Streamable HTTP (
transport: streamable-httpfor hosted upstreams); OpenAPI specs (URL or file); CLI binaries whosedefault_actionacts as a tightening-only floor under the dispatcher - Export: MCP stdio + MCP Streamable HTTP + HTTP REST
- Governance: YAML policies, glob patterns, numeric conditions and string operators (
contains,not_contains,starts_with,not_starts_with) on arguments, per-agent policy files, specificity sort, hot-reload - Policy API:
POST /decideevaluates policy without executing,GET /policiesexposes active rules with the file each came from (source_file);mesh7-hook, a Claude Code PreToolUse hook, asksPOST /decidebefore every tool call, including the harness's built-in tools that never transit the proxy - Auth: JWT validation against external IdPs (Cloudflare Access, Auth0, Keycloak), JWKS cached with background refresh.
auth.jwt.user_claimrecords the human the agent acts for, exported asenduser.id. The legacyBearer agent:<name>form is opt-in and off by default once JWT is configured. An MCP Streamable HTTP session is bound to the identity that opened it: another caller presenting itsMcp-Session-Idgets a403 - Approval: async queue, routing via
queue | tty | tty-fallback, temporal grants that record their origin, supervisor protocol, flux7-memory auto-approve - Content safety: raw parameters can be withheld from an external resolver, and a prompt-injection tripwire suppresses auto-approval so the call escalates to a human instead
- Observability: JSONL traces with rotation, OTEL export (batched, retried on network errors, 429 and 5xx, GenAI semantic conventions, custom headers and TLS options), session tracking, Prometheus metrics, token accounting that distinguishes real provider counts from estimates. Each trace line is hash-chained to the previous one (HMAC-SHA256 when
MESH_TRACE_KEYis set);mesh7 trace verifychecks files offline andGET /traces/verifychecks the running store (Trace Integrity) - Lineage: traces carry
grant_idandparent_trace_id, grants carry theapproval_idandtrace_idthey came from;GET /traces/{id}/whywalks the chain from a call back to the human approval that authorised it - Durable state: approvals and grants persisted in SQLite, survive restarts (
storage_path: state.db) - Auto-proxy: in MCP mode, detects a running instance and becomes a thin stdio→HTTP shuttle (zero config change, removes the port conflict between clients)
- Daemon mode:
mesh7 serveruns as a persistent daemon, MCP clients auto-proxy to it - Python SDK:
pip install flux7-meshv0.6.1 providesAgentMesh(token=...)for JWT identity, GovernedToolkit (namespace-qualified tool names), MeshHooks (Anthropic Agent SDK), andmesh7-hookfor the Claude Code CLI - Integrations: flux7-memory (decision persistence + auto-approve), flux7-console (dashboard + governance UI), flux7-supervisor (L1 evaluation agent)
- Next: claim-based policy conditions, semantic conditions beyond text matching
Known limits
These limits are stated plainly, because a governance tool that oversells itself is worse than none.
- Policy conditions match text, case-sensitively. Denying
rm -rfdoes not stopRM -RFor a base64 payload. - Injection detection is a regex tripwire wired to auto-approval, not a defence.
- CLI positional arguments are metacharacter-filtered but not allowlisted; the allowlist governs flags.
- Rate-limit counters live in memory and reset with the daemon. Approvals and grants do not.
- The
--mcpauto-proxy probes localhost, so it is a same-host mechanism.
Claude ecosystem integration
flux7-mesh and flux7-memory cover every Claude surface with a native integration path.
| Surface | flux7-mesh | flux7-memory |
|---|---|---|
| Claude Code / Cursor | MCP stdio (auto-proxy if daemon running) | MCP stdio (auto-proxy if daemon running) |
| Claude Platform / Console | MCP Streamable HTTP (POST /mcp) |
Via flux7-mesh (tools memory.*) |
| Managed Agents | MCP connector URL → POST /mcp |
Via flux7-mesh (tools memory.*) |
| Claude API (raw) | Python SDK + POST /decide |
Python SDK (pip install flux7-memory) |
| Agent SDK (custom) | HTTP direct (/tool/{name}, /decide) |
HTTP direct (/rpc) |
flux7-memory access from Platform, Console, and Managed Agents goes through flux7-mesh policy, without direct exposure. Therefore governance is enforced at every layer, and not only in local development.
Gaps (tracked): MCP registry listing, memory_context system prompt helper for Platform, claim-based policy conditions.
Get started
# Install (mesh7 and the mesh approval CLI)
curl -fsSL https://raw.githubusercontent.com/KTCrisis/flux7-mesh/main/install.sh | sh
# Add to Claude Code
claude mcp add mesh7 -- mesh7 --mcp --config config.yaml
# Or run standalone
mesh7 --config config.yaml
Apache 2.0 licensed. github.com/KTCrisis/flux7-mesh