Skip to main content
Glama
Anshv784
by Anshv784

AgentGate

A governed tool-call gateway for AI agents, built on Terminal 3's ADK.

Give an LLM agent an API key and it can call anything, spend anything, and leak anything — and you find out afterwards, from the logs it wrote about itself.

AgentGate is the layer in between. You write down, once, which endpoints exist and what each one is allowed to touch. The agent then asks for actions by name, and a Rust contract running inside an Intel TDX enclave decides whether to carry them out.

The agent names an endpoint, not a URL. It never holds a credential. It never sees the user's personal data. And every attempt it makes — allowed or denied — lands in a ledger it cannot edit.

That last point is the one people miss: denials are recorded too. An agent probing for what it can get away with leaves a trail.

It ships as an MCP server, so any MCP client (Claude Code, Claude Desktop, Cursor, an SDK agent) gets governed tool calls by adding one config entry. No framework, no rewrite.

  MCP client (Claude / Cursor / your agent)
    │  call_endpoint { endpoint: "resend", path: "/emails",
    │                  body: { to: ["{{profile.verified_contacts.email.value}}"] } }
    ▼
  AgentGate MCP server            ← holds the T3N session; the model holds nothing
    │
    ▼
┌─ z:<tid>:agentgate — TEE contract (Rust → WASM, Intel TDX) ───────────────┐
│  1. every {{…}} marker must be profile.* AND on this endpoint's allowlist │
│  2. path must be one the tenant enumerated — exact match, no globs        │
│  3. credential read from the sealed z:<tid>:secrets map                   │
│  4. host substitutes real PII inside the enclave (contract never sees it) │
│  5. upstream response projected to declared fields only                   │
│  6. ledger entry appended — for ALLOWED and DENIED alike                  │
└───────────────────────────────────────────────────────────────────────────┘
    ▼
  api.resend.com   ← reached only if the data owner's grant permits this host

Where to look

If you want

Read

proof it works

the receipt directly below — four real denials and a real delivered email

how it works, and why the boundary sits where it does

docs/ARCHITECTURE.md — one call followed end to end

what it costs and what to do when it breaks

docs/HANDOVER.md — runbook written for a stranger

the platform bugs found building it

docs/BUGS.md — 13 findings, severity-indexed, each with a runnable reproduction in probes/

Two Rust crates live here: contract/ is the gateway; contract-probe/ is a throwaway diagnostic used to map the platform's behaviour, kept as evidence for the bug report.

Related MCP server: Proofpane

It works. Here is the receipt

npm run demo against T3N testnet — every call below is made by the org-minted agent:

🛑 DENIED   profile field outside the endpoint's allowlist  ({{profile.ssn}})
            marker rejected: 'ssn' is not in this endpoint's allowed_placeholders
🛑 DENIED   marker reaching for another namespace  ({{secret.resend_api_key}})
            marker rejected: 'secret.resend_api_key' is not a profile marker
🛑 DENIED   path the tenant never enumerated  (/domains)
            path rejected: '/domains' is not in this endpoint's allowed_paths
🛑 DENIED   endpoint that does not exist  (stripe)
            unknown endpoint

── policy is per-ENDPOINT, not per-host ──────────────────────────────
   'resend' and 'resend-notify' share a host AND a credential.
   The same marker is allowed on one and refused on the other.

✅ ALLOWED  {{profile.first_name}} via 'resend'        (allowlisted there)
            {"data":{"id":"d7299ce6-668f-47f2-8e22-8f3f96c0f255"},"status":200}
🛑 DENIED   {{profile.first_name}} via 'resend-notify' (allowlist is empty)
            marker rejected: 'first_name' is not in this endpoint's allowed_placeholders
✅ ALLOWED  no markers via 'resend-notify'             (allowed, returns nothing)
            {"data":{},"status":200}

Real emails were delivered. The recipient's address and name were resolved inside the enclave from the data owner's profile — they appear nowhere in the agent's input, the MCP transport, the contract's memory, or the ledger.

The last line is the deny-by-default response projection: resend-notify declares no response_fields, so a successful call returns a status code and an empty object. Even the upstream's message id is withheld.

The ledger afterwards:

denied     0  resend/emails         markers=["profile.ssn", …]        'ssn' not allowed here
denied     0  resend/emails         markers=["secret.resend_api_key"] not a profile marker
denied     0  resend/domains        markers=[]                        path not enumerated
denied     0  stripe/emails         markers=[]                        unknown endpoint
ok       200  resend/emails         markers=["first_name","last_name","verified_contacts.email.value"]
denied     0  resend-notify/emails  markers=["profile.first_name", …] 'first_name' not allowed here
ok       200  resend-notify/emails  markers=[]

Marker names are recorded. Marker values were never available to record.

Quick start

npm install
cp .env.example .env          # add your T3N_API_KEY from terminal3.io/claim-page
npm run test                  # 9 native policy tests, no network, no credits
npm run build                 # Rust → wasm32-wasip2
npm run deploy                # idempotent — safe to re-run
npm run doctor                # pre-flight a deployment you didn't just create
npm run demo                  # the run shown above

Add to any MCP client:

{ "mcpServers": {
    "agentgate": { "command": "npx", "args": ["tsx", "/path/to/agentgate/mcp/server.ts"] } } }

Adding an endpoint

One file. No Rust, no redeploy of the contract.

// agentgate.config.json
"endpoints": {
  "stripe": {
    "base": "https://api.stripe.com",
    "secret_key": "stripe_api_key",        // key in z:<tid>:secrets
    "auth_header": "Authorization",
    "auth_prefix": "Bearer ",
    "allowed_paths": ["/v1/customers"],    // exact match only
    "allowed_placeholders": ["first_name", "verified_contacts.email.value"],
    "response_fields": ["id"]              // everything else is dropped
  }
}

Then npm run deploy. It skips contract registration when the wasm is unchanged, so adding an endpoint costs ~800 credits rather than paying for a re-registration (measured; the figure this README originally carried was wrong by 5x).

Why the design is shaped this way

Three decisions came out of measuring the platform, not reading about it:

  • Denials return Ok, never Err. Contract writes roll back on error, so returning Err on a policy denial would roll back the audit entry recording that denial — an agent could trip the policy repeatedly and leave no trace.

  • Responses are projected, not passed through. http-with-placeholders protects the outbound leg only. The upstream response returns into WASM in full, so an endpoint that echoes its request hands back the PII the markers withheld. Demonstrated in docs/BUGS.md.

  • The contract sets no Content-Type. The host appends its own rather than replacing yours, producing application/json,application/json, which strict upstreams reject — silently, with an HTTP 200 and an empty body. See docs/BUGS.md#1.

Repo layout

Path

What

contract/

the TEE contract — policy.rs is pure and natively tested, gateway.rs talks to the host

mcp/server.ts

MCP server — 3 tools

scripts/deploy.ts

idempotent deploy; owns the contract_id ledger

scripts/doctor.ts

pre-flight health check

scripts/demo.ts

the run shown above

agentgate.config.json

every endpoint and grant, declaratively — this is the file you edit

.mcp.json

drops the server into any MCP client that reads it, no setup

deployments.json

committed ledger of every contract_id ever issued

probes/

one runnable script per platform bug — reproductions, not tests

docs/BUGS.md

13 findings against the platform, each with a reproduction

docs/ARCHITECTURE.md

start here — one call followed end to end, and why the boundary sits where it does

docs/HANDOVER.md

runbook for whoever operates this next

contract-probe/

throwaway diagnostic that mapped the platform's behaviour — evidence for the bug report, not something to build on

Status

Built and verified end-to-end against T3N testnet with @terminal3/t3n-sdk@5.2.0, running the full three-identity flow:

Principal

Holds

Role in the run above

Tenant

eth key, funded

owns the contract, seals the credential, enumerates the policy

Data owner

own DID + profile

grants the agent; the markers resolve against their profile

Agent

an opaque bearer token, nothing else

makes every call shown above

The agent's signing key was minted inside the TEE and never left it. It holds no API key, no URL, and no personal data, and cannot reach a core contract to inspect its own grants — yet it delivers a personalised email to a real inbox.

Getting there required Terminal 3 to fund the agent DID by hand: a minted agent starts at zero and one call reserves 10,000 tokens, with no self-serve top-up (docs/BUGS.md#10). Every developer will hit that on their first agent.

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

0Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    A
    maintenance
    Provides a trust and governance layer for AI agents, enabling secure API access, credential vaulting, paid execution with human approval, and automatic call resume.
    15
    2
  • A
    license
    B
    quality
    A
    maintenance
    A governance proxy for AI tools — every MCP/agent tool call is policy-gated, secret-redacted, and written to a hash-chained, offline-verifiable audit trail.
    13
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Bounded egress gateway & secret proxy for AI agents and applications, enabling safe credential injection into upstream requests while keeping raw secrets out of LLM prompt contexts.
    6
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Governed MCP gateway that lets AI agents call tools with policy enforcement, prompt-injection screening, a kill-switch, and tamper-evident signed audit logs.
    Apache 2.0

View all related MCP servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Anshv784/agentgate'

If you have feedback or need assistance with the MCP directory API, please join our Discord server