Install
$ agentstack add mcp-ktcrisis-flux7-mesh ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
______ ____ __
/ __/ //_ /_____ _ ___ ___ / /
/ _// /__/ /___/ ' \/ -_|_-(tools)"]
RL["Rate limiter+ loop detect"]
POL["Policy engine(glob, conditions)"]
FWD["Forward"]
APP["Approval store"]
GRT["Grant store(sudo for agents)"]
TRC["Trace store(JSONL + sessions)"]
OTEL["OTEL exporter(file / stdout / OTLP)"]
REG --> RL --> POL --> FWD
POL -.approval.-> APP
POL -.bypass.-> GRT
FWD --> TRC
TRC --> OTEL
end
subgraph Upstream["Upstream tools"]
U1["MCP servers(stdio + SSE)"]
U2["REST APIs(OpenAPI specs)"]
U3["CLI binaries(terraform, gh, docker)"]
end
subgraph Observability["Observability"]
O1["Jaeger / Tempo /Datadog / OTLP HTTP"]
O2["traces-otel.jsonl"]
end
A4["Anthropic Managed Agents"]
A1 -- "MCP stdio" --> Mesh
A2 -- HTTP --> Mesh
A3 -- HTTP --> Mesh
A4 -- "MCP streamable HTTP" --> Mesh
FWD --> U1
FWD --> U2
FWD --> U3
OTEL --> O1
OTEL --> O2
Import: OpenAPI specs (URL or file) · MCP servers (stdio + SSE) · CLI binaries Export: MCP server (stdio) · MCP Streamable HTTP (POST /mcp) · HTTP proxy (:port) · OTLP traces
The problem
When you connect tools directly to an AI agent, the agent gets unguarded access — no policy, no trace, no control.
The solution
Put Agent Mesh between the agent and its tools:
claude mcp add mesh7 -- mesh7 --mcp --config config.yaml
The agent sees a normal tool surface. Agent Mesh enforces policy and records traces on every call.
Install
Binary (recommended)
VERSION=$(curl -s https://api.github.com/repos/KTCrisis/flux7-mesh/releases/latest | grep tag_name | cut -d '"' -f4)
# Linux amd64
curl -L "https://github.com/KTCrisis/flux7-mesh/releases/download/${VERSION}/mesh7_${VERSION#v}_linux_amd64.tar.gz" | tar xz
sudo mv mesh7 /usr/local/bin/
# macOS Apple Silicon
curl -L "https://github.com/KTCrisis/flux7-mesh/releases/download/${VERSION}/mesh7_${VERSION#v}_darwin_arm64.tar.gz" | tar xz
sudo mv mesh7 /usr/local/bin/
All releases: github.com/KTCrisis/flux7-mesh/releases
From source
Requires Go 1.24+:
git clone https://github.com/KTCrisis/flux7-mesh.git
cd flux7-mesh
make install # builds to ~/go/bin/mesh7 with version metadata
mesh7 --version
# mesh7 v0.10.1 (827c457) built 2026-05-08T...
Python SDK
pip install flux7-mesh # core client
pip install flux7-mesh[anthropic] # with Claude API support
Govern tool calls from any Python code — Claude API, LangChain, or plain HTTP:
from mesh7 import GovernedToolkit
toolkit = GovernedToolkit(agent="my-agent")
@toolkit.tool
def get_weather(city: str) -> str:
"""Get current weather for a city."""
return fetch_weather(city)
# Generate tools[] for Claude API — names are namespace-qualified
# e.g. "my-agent.get_weather"
response = client.messages.create(
model="claude-sonnet-4-6",
tools=toolkit.schemas(),
messages=[...],
)
# Execute with governance (policy + trace)
results = toolkit.process_response([b.model_dump() for b in response.content])
Or use the client directly:
from mesh7 import AgentMesh
mesh = AgentMesh("http://localhost:9090", agent="my-agent")
decision = mesh.call_tool("filesystem.write_file", {"path": "/tmp/x", "content": "hello"})
print(decision.action) # allow | deny | human_approval
Agent SDK hooks
from mesh7 import MeshHooks
hooks = MeshHooks(agent="my-agent")
# Pass to ClaudeAgentOptions(hooks=hooks.agent_sdk_hooks())
See [sdk/python/](sdk/python/) for full docs and examples.
Quick start
1. Write a config
# config.yaml
mcp_servers:
- name: filesystem
transport: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/me/projects"]
policies:
- name: claude
agent: "claude"
rules:
- tools: ["filesystem.read_*", "filesystem.list_*", "filesystem.search_*"]
action: allow
- tools: ["filesystem.write_file", "filesystem.edit_file"]
action: human_approval
- tools: ["filesystem.*"]
action: deny
- name: default
agent: "*"
rules:
- tools: ["*"]
action: deny
Or auto-generate one:
mesh7 discover --config config.yaml --generate-policy
mesh7 discover --openapi https://petstore.swagger.io/v2/swagger.json --generate-policy
2. Plug into Claude Code
claude mcp add mesh7 -- mesh7 --mcp --config config.yaml
3. Use normally
Restart Claude Code. The agent sees the tools. Agent Mesh enforces the rules. Every call is traced.
Config reference
All features are declared in a single YAML config.
MCP servers
mcp_servers:
- name: filesystem
transport: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/me"]
- name: remote-service
transport: sse
url: "https://mcp-server.example.com/sse"
headers:
Authorization: "Bearer "
OpenAPI specs
Import REST APIs as governed tools — persisted across restarts.
openapi:
# From URL
- url: https://date.nager.at/swagger/v3/swagger.json
# From local file
- file: ./specs/internal-api.json
backend_url: http://localhost:3001
Each endpoint becomes a tool (e.g. get_public_holidays). Same policy, same traces as MCP tools.
CLI tools
Wrap any CLI binary behind policy, approval, and tracing:
cli_tools:
- name: gh
bin: gh
default_action: allow
- name: terraform
bin: terraform
default_action: human_approval
commands:
plan:
timeout: 120s
- name: kubectl
bin: kubectl
strict: true # only declared commands, everything else denied
commands:
get:
allowed_args: ["-n", "--namespace", "-o"]
- name: jq # binary without subcommands
bin: jq
default_action: allow
bare:
allowed_args: ["-r", "--compact-output"]
Agents call CLI tools like any MCP tool — terraform.plan, kubectl.get, gh.pr. A bare binary registers a single .run tool. Every CLI tool accepts an optional stdin param, piped to the process as data (never shell-interpreted). See [docs/cli-tools.md](docs/cli-tools.md).
Policies
YAML-based, first-match-wins, glob patterns for agents and tools.
policies:
- name: support-agent
agent: "support-*"
rate_limit:
max_per_minute: 30
max_total: 1000
rules:
- tools: ["*.read_*", "*.list_*", "*.get_*"]
action: allow
- tools: ["create_refund"]
action: allow
condition:
field: "params.amount"
operator: " policies/temp.yaml
# Remove it — reverts immediately
rm policies/temp.yaml
Hot-reload covers policies and rate limits only. Changes to MCP servers, CLI tools, or OpenAPI specs require a restart.
Supervisor mode
supervisor:
enabled: true # hide approval tools from agents
expose_content: false # redact raw params → structural metadata
supervisor_agents: # agent IDs (glob) allowed to see approval tools
- "supervisor-*"
When enabled, approval.resolve and approval.pending are hidden from agents — only an external supervisor can resolve approvals. See [docs/supervisor-protocol.md](docs/supervisor-protocol.md).
Agents matching supervisor_agents globs are whitelisted: they see and can call approval tools even in supervisor mode. This enables a Managed Agent (e.g. Claude via MCP Streamable HTTP) to act as a cloud supervisor — connecting to POST /mcp with Authorization: Bearer agent:supervisor-claude and resolving approvals with Claude's judgment.
Memory integration
Persist approval decisions as queryable facts in mem7. Fire-and-forget — a failing mem7 never blocks approvals.
memory:
url: http://localhost:9070 # mem7 daemon URL
token: "" # optional Bearer token
When configured, every approval resolve (approve, deny, timeout) is written to mem7 as a fact with tags [decision, approved|denied, , agent:].
Auto-approve from past decisions — when memory.url is set, mesh7 queries mem7 before submitting to the approval queue. If a tool+agent pattern has 3+ consistent approvals with 0 rejections, it is auto-approved (traced as supervisor:mem7). Governance gets less intrusive over time without getting less safe.
supervisor:
auto_approve: true # default true when memory.url is set
min_approvals: 3 # threshold for auto-approve (default 3)
The auto-approve is a pre-filter (Level 1). If it can't resolve, the request proceeds to the external supervisor (if running) or human. If mem7 is down, the request is escalated — never blocked. See [docs/mem7-auto-approve.md](docs/mem7-auto-approve.md) for a step-by-step example.
Authentication
Two planes, two guards:
auth:
# Control plane (traces, grants, approvals, policies, sessions, metrics).
# When set, these endpoints require `Authorization: Bearer `.
# When empty, they are restricted to loopback callers only.
# MESH_ADMIN_TOKEN env overrides this value.
admin_token: "a-long-random-secret"
# Data plane: validate agent identity via JWT against an external IdP.
jwt:
jwks_url: https://idp.example.com/.well-known/jwks.json
issuer: https://idp.example.com # optional
audience: mesh7 # optional
agent_claim: sub # claim used as agent id (default: sub)
allow_legacy: false # keep plaintext "agent:" off when JWT is on
# Reject data-plane requests with no credentials (401) instead of letting
# them resolve to "anonymous" and fail closed at the policy engine.
require_authentication: false
| Setting | Guards | Default behavior when unset | |---------|--------|------------------------------| | admin_token | Control plane — a caller here can mint grants and resolve approvals, overriding what policies enforce | Loopback-only | | jwt | Data-plane identity — cryptographic agent id instead of the spoofable agent: header | Plaintext identity accepted | | require_authentication | Anonymous access to /tools and /mcp-servers enumeration | Anonymous allowed, governed by policy |
The data plane (tool calls, /decide, /mcp, /health) is never gated by admin_token. Details: control-plane auth and JWT authentication.
Other settings
port: 9090 # HTTP port (default 9090)
storage_path: state.db # SQLite durable state (approvals, grants survive restarts)
trace_file: traces.jsonl # JSONL persistence
otel_endpoint: /path/to/traces-otel.jsonl # or "stdout" or "http://localhost:4318"
approval:
timeout_seconds: 300 # approval TTL (default 5 min)
notify_url: https://hooks.slack.com/... # webhook on new pending approval
Features
Human approval
When a policy requires human_approval, the flow is non-blocking:
Claude calls filesystem.write_file
→ mesh7 returns: "Approval required (id: a1b2c3d4)"
→ Claude calls approval.resolve(id: a1b2c3d4, decision: approve)
→ mesh7 replays the original tool call
→ Result returned to Claude
Virtual MCP tools: approval.resolve, approval.pending. Also via CLI (mesh approve ) or HTTP API (POST /approvals/{id}/approve).
Temporal grants
Like sudo for agents — temporary override for repeated approvals:
"Grant filesystem.write_* for 30 minutes"
→ grant.create {tools: "filesystem.write_*", duration: "30m"}
→ All filesystem.write_* calls bypass approval for 30m
→ Traced as "grant:a1b2c3d4"
Virtual MCP tools: grant.create, grant.list, grant.revoke.
Grants only bypass human_approval. Tools marked deny remain blocked — policy edit required.
Rate limiting
Per-agent call limits with automatic loop detection:
| Protection | What it stops | |------------|--------------| | max_per_minute | Runaway loops | | max_total | Budget exhaustion | | Loop detection | Same tool + same params > 3x in 10s |
Tracing & sessions
Every tool call is logged: agent, tool, params, policy decision, latency, approval metadata.
curl http://localhost:9090/traces?agent=claude&tool=filesystem.write_file
curl http://localhost:9090/sessions # list sessions
curl http://localhost:9090/sessions/abc123 # session detail
Session IDs are propagated via X-Session-Id header or --mcp-session-id flag.
OpenTelemetry export
otel_endpoint: /path/to/traces-otel.jsonl # file
otel_endpoint: stdout # debug
otel_endpoint: http://localhost:4318 # Jaeger, Tempo, Datadog
Each span includes agent.id, tool.name, policy.action, approval.*, and llm.token.* attributes. See [docs/otel.md](docs/otel.md).
Supervisor protocol
External supervisor agents can poll GET /approvals?status=pending, evaluate with full context (recent traces, active grants, injection risk), and resolve with structured verdicts (reasoning, confidence). See [docs/supervisor-protocol.md](docs/supervisor-protocol.md).
Commands & flags
mesh7 (main binary)
mesh7 [flags] # run proxy (HTTP or MCP mode)
mesh7 serve [flags] # run as persistent daemon
mesh7 discover [flags] # discover tools + generate policy
mesh7 --version # print version
| Flag | Default | Description | |------|---------|-------------| | --config | config.yaml | Path to YAML config | | --openapi | | OpenAPI spec URL (ephemeral, for quick tests) | | --backend | | Backend base URL override | | --port | from config or 9090 | Port override | | --mcp | false | MCP mode (stdio JSON-RPC — auto-proxies to daemon if running) | | --mcp-agent | claude | Agent ID for MCP-mode policy evaluation | | --mcp-session-id | auto-generated | Session ID for MCP traces |
serve flags: --config , --port . Runs as a persistent HTTP daemon. MCP clients auto-proxy to it via --mcp.
discover flags: --openapi , --config , --generate-policy, --backend .
mesh (approval CLI)
mesh pending # list pending approvals
mesh show # full details
mesh approve # approve
mesh deny # deny
mesh watch # interactive poll + prompt
Set MESH_URL to override the default http://localhost:9090.
API
| Method | Path | Description | |--------|------|-------------| | POST | /decide | Evaluate policy without executing (returns allow/deny/human_approval) | | POST | /tool/{name} | Proxy a tool call through policy | | POST | /mcp | MCP Streamable HTTP transport (JSON-RPC) | | DELETE | /mcp | Terminate MCP HTTP session | | GET | /tools | List all registered tools | | GET | /mcp-servers | List connected MCP servers | | GET | /traces | Query traces (?agent=...&tool=...) | | GET | /sessions | List sessions (id, agent, event count, timespan) | | GET | /sessions/{id} | Session detail | | GET | /otel-traces | OTLP JSON spans (?agent=...&tool=...&limit=...) | | GET | /approvals | List approvals (?status=pending&tool=filesystem.*) | | GET | /approvals/{id} | Approval detail with context | | POST | /approvals/{id}/approve | Approve (optional: reasoning, confidence) | | POST | /approvals/{id}/deny | Deny (optional: reasoning, confidence) | | GET | /policies | List all policies (sorte
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: KTCrisis
- Source: KTCrisis/flux7-mesh
- License: Apache-2.0
- Homepage: https://docs.flux7.art
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.