AMG is the policy-enforcing MCP gateway between your AI agents and the tools they touch. Agents see one server; you decide which tools each role can call — down to the argument — with every decision audited.
self-hosted · default-deny · credential brokering · shadow mode · human approvals
| TIME | DECISION | TOOL | AGENT | ROLE | LATENCY |
|---|---|---|---|---|---|
| 14:02:11 | allow | notion__get_pages | crm-enrichment-worker | notion_read | 82ms |
| 14:02:09 | shadow deny | notion__get_pages | crm-enrichment-worker | notion_read | 114ms |
| 14:01:55 | needs approval | notion__delete_page | docs-crawler | docs_writer | — |
| 14:01:48 | allow | stripe__get_payment_intents | billing-reconciler | stripe_billing | 211ms |
| 14:01:31 | deny | stripe__get_payment_intents | billing-reconciler | stripe_billing | — |
| 14:01:30 | allow | notion__get_users | crm-enrichment-worker | notion_read | 67ms |
| 14:01:12 | allow | notion__search | crm-enrichment-worker | notion_read | 93ms |
Built for teams that can't ship their data to someone else's cloud
Policy engine
Agents in production call tools with the full blast radius of whatever key they're handed. AMG replaces the key with a scoped token, and the token with a policy.
Roles are compiled and validated against the live upstream tool list at save time — not at 2am when the call fails.
Reads scoped to one workspace. Limits capped at 100. Unknown arguments? Denied by default.
Log would-be denials without enforcing. Promote to enforce when the line hits zero — like a migration cut-over.
Destructive tools park instead of executing. The payload is immutable — approval forwards exactly what the agent sent.
Upstream secrets live in Vault and never reach the agent runtime. Agents hold one thing: an AMG token you can revoke in 30 seconds.
Every decision lands with role, arguments (redacted), policy version, latency, and verdict. Replayable forever.
How it works
Point your agent's MCP client at AMG. That's the whole integration.
A scoped bearer token resolves server-side to a role. Claimed roles are never honored — the agent is untrusted input.
Tool visibility, call authorization, argument constraints, rate limits, approval gates. Any engine error fails closed.
Credentials injected from Vault at the connection, never before. Result returned, decision audited, asynchronously.
Trust model
Prompt injection can't escalate privileges it was never granted. The worst case is bounded by the grant — and the grant is yours.
Bearer token → role, resolved server-side. Skill files are documentation, not authorization.
Malformed policy, engine error, unknown upstream — every failure path is a deny, never a passthrough.
256-bit, shown once at issuance, revocable with a 30-second latency ceiling.
Upstream keys live in Vault, read into memory at connection time, absent from logs and the database.
Sensitive fields never land in the audit log — redaction happens before the write, not after.
Path traversal, case games, and null bytes are rejected before routing — and the attempt is audited.
From one key that could delete everything to per-agent grants you can read in a screenful of YAML.
Self-hosted, open core. One docker compose up away from your first scoped agent.