Open Source · Apache-2.0 · eunolabs/euno

Policy proxy for
MCP AI agents

One YAML file enforces what every agent is allowed to do — before the tool call reaches your backend. Drop-in. No infrastructure. No code changes to your agent or your server.

Get started in 60 seconds → Star on GitHub

Block a bad tool call in real time

An agent tries to read a .pem key, drop a database table, and DM an external recipient. The proxy fires before the upstream is ever contacted — every decision is signed and audited.

euno-mcp proxy
📄 euno.policy.yaml
# euno.policy.yaml — AgentCapabilityManifest
# Validate: npx @euno/mcp validate ./euno.policy.yaml

agentId: filesystem-agent
name:    Filesystem Agent
version: 0.1.0

requiredCapabilities:
  - resource: read_file
    actions: [call]
    conditions:
      - type: allowedExtensions
        extensions: [".csv", ".json", ".txt"]
      - type: maxCalls
        count: 50
        windowSeconds: 60

  - resource: query
    actions: [call]
    conditions:
      - type: allowedOperations
        operations: [SELECT]

  - resource: send_dm
    actions: [call]
    conditions:
      - type: recipientDomain
        domains: [company.com]

Everything you need to ship agents safely

The current release ships the full CapabilityCondition matrix, in-process LangChain.js enforcement, a tamper-evident OCSF audit log, and reference policies for the most popular MCP servers.

Full condition matrix

maxCalls, allowedOperations, allowedExtensions, allowedTables, argumentSchema, ipRange, recipientDomain, redactFields, policy, custom — all enforced before the upstream is contacted.

OCSF audit log

Every tool call — allowed or denied — is recorded as a cryptographically signed OCSF API Activity event at ~/.euno/audit.jsonl. Verify, rotate, summarise with euno-mcp stats.

Drop-in for every host

Wraps Claude Desktop, Cursor, Windsurf, and any stdio MCP client with a one-line config change. HTTP transport for LangChain.js and other in-process agents.

LangChain.js companion

@euno/langchain places the same enforcement engine inside the LangChain tool wrapper — no proxy process, no transport hop. Same YAML policy.

Reference policies

Ship-ready YAML for filesystem, Postgres, GitHub, Slack, and fetch — including a lexical SSRF guard. Drop one in your repo and run euno-mcp validate.

Custom backends

Plug in OPA, Cedar, or a bespoke rules engine via --policy-backend. Add domain-specific guards via --custom-condition. Both are repeatable flags, both fail-fast on load.

Zero infra. Zero cloud.

Runs entirely on your machine. No sign-up, no API key, no telemetry. npx away.

Proxy sits between host and server

The MCP proxy is transparent to both sides — it speaks the MCP protocol on both ends and evaluates policy in the middle. See the full architecture →

📝

Write policy

Define allowed tools and argument constraints in a single euno.policy.yaml.

🔀

Wrap your server

Pass npx @euno/mcp proxy as the command in your MCP host config. No agent or server changes.

Enforce at runtime

Every tools/call is evaluated against the policy before it reaches the upstream.

🔍

Inspect the log

Stream a live audit feed and aggregate denials with euno-mcp stats.

Zero-infra. Ships in 60 seconds.

No sign-up. No cloud account. Runs entirely on your machine.

1 — run the proxy
npx -y @euno/mcp proxy --policy ./euno.policy.yaml \
-- npx -y @modelcontextprotocol/server-filesystem /data
2 — tail the audit log
tail -F ~/.euno/audit.jsonl | jq
npx -y @euno/mcp stats   # ASCII histogram of denials
Claude Desktop · mcpServers in claude_desktop_config.json
"my-server": {
"command": "npx",
"args": ["-y", "@euno/mcp", "proxy", "--policy", "./euno.policy.yaml",
"--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"]
}