Skip to main content
Glama
evavai

evav-gateway

Official
by evavai
README.md
# evav-gateway

**The open-source governed MCP gateway.** Point any AI agent (Claude, Cursor, ChatGPT, your own) at one endpoint; every tool call it makes is **governed** — policy-checked, screened for prompt-injection/exfiltration, haltable by a kill-switch — and written to a **signed, tamper-evident audit log** *before* it reaches the real tool.

Built on [FastMCP](https://github.com/jlowin/fastmcp) for the wire (federation, pooled sessions, auth, transport); the governance layer is ours.

> Status: **v0.1, early.** The governed proxy + signed audit + injection screening work and are tested. OAuth brokering, an OPA policy backend, the one-command client-setup, and packaging are on the roadmap below.

## Why

Every OSS MCP gateway governs *the wire*. Most log unsigned, have no native injection screening, and no approval gate. `evav-gateway`:
- **Signs its audit log** (Ed25519, hash-chained) — tamper-evident. No surveyed gateway does this.
- **Screens every call for prompt-injection / exfiltration** on the way in *and* the way out — native, not a bolt-on.
- **Fails closed**: a policy error, an injected argument, a poisoned upstream output, or an engaged kill-switch stops the call. It never silently allows.

## Governance pipeline (per tool call)

```
kill-switch → policy (block / require-approval) → injection screen (input)
  → forward to upstream (pooled session) → injection screen (output, withhold)
  → signed audit record
```

## Use as a library

```python
from fastmcp import Client
from evav_gateway import build_gateway, Policy

gw, audit = build_gateway(
    {"mcpServers": {"slack": {"url": "https://mcp.slack.com/mcp"}}},
    policy=Policy(approval_tools=("payments.transfer",),
                  block_patterns=(r"\bssn\b",)),
)
# every call through `gw` is governed; audit.verify() checks the signed chain
```

## Config-as-code

```yaml
# evav-gateway.yaml
name: "Acme Gateway"
injection_on: true
upstreams:
  - name: slack
    url: https://mcp.slack.com/mcp
    auth_env: SLACK_MCP_TOKEN        # secret from env, never inlined
policy:
  approval_tools: [payments.transfer]
  block_patterns: ["\\bssn\\b", "password"]
  param_limits:
    payments.transfer: { amount: 1000 }
```

```
evav-gateway run --config evav-gateway.yaml
```

## Quickstart

```bash
pip install evav-gateway          # or: uvx evav-gateway ...
cp evav-gateway.example.yaml evav-gateway.yaml     # edit upstreams + policy
evav-gateway run --config evav-gateway.yaml        # serves http://127.0.0.1:8000/mcp
evav-gateway client-setup --client cursor --url http://127.0.0.1:8000/mcp   # point your agent here
```

Or with Docker:

```bash
docker build -t evav-gateway .
docker run -p 8000:8000 -v "$PWD/evav-gateway.yaml:/config/evav-gateway.yaml" evav-gateway
```

## Roadmap

- [x] Governed proxy on FastMCP (policy · injection in/out · kill-switch · signed audit)
- [x] `evav-gateway client-setup` — one command to point Claude/Cursor/VS Code/Windsurf here
- [x] Docker image + `uvx`/pip install
- [x] OPA (Rego) policy backend for enterprise param/context authz (opt-in; see `examples/policy.rego`)
- [x] Brain-injection: inject the org's rules/skills into any agent (`evav_rules` / `evav_skill`)
- [x] Persistent signed audit (SQLite + stable key) — retrieve via `evav_audit`, verify offline via `evav-gateway verify-audit`
- [x] Hardened injection screen (decode pass: base64/URL/control-char obfuscation)
- [ ] OAuth 2.1 + upstream token brokering (agents never hold upstream creds)
- [ ] Shared multi-replica audit (Postgres + shared key)
- [ ] Async endpoint + tuned connection pooling under load
- [ ] Rule/skill/memory **context injection** (inject the org's relevant rules into any agent)
- [ ] Helm chart

## License

Apache-2.0.