AgentStack
MCP verified Apache-2.0 Self-run

Flux7 Mesh

mcp-ktcrisis-flux7-mesh · by KTCrisis

Guardrail sidecar proxy for AI agents — policy, approval gates, grants, tracing. One Go binary, one YAML.

No reviews yet
0 installs
5 views
0.0% view→install

Install

$ agentstack add mcp-ktcrisis-flux7-mesh

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

Are you the author of Flux7 Mesh? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

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.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.