Use casesAIAI agents10 / 12
How it fits together

One core, two doors: the agent gets what the app gets, and no more

An agent connects to the MCP server with a key or by signing in through your identity provider. It sees only the tools its grant allows, and a dictionary of what the columns mean, with masked ones marked. Its calls run through the same checks as a REST call. Ad-hoc SQL is read-only and capped, and a write waits for a person. Every call is in its usage, by agent.

1core behind REST and MCP
200rows at most per tool call
0database passwords given to the agent
Who asks
Two doors
The governed core
Your data, and what agents did
Your identity provider↗
OAuth 2.1 · issues the tokens
A person approvesStable↗
Console → Approvals
↗ An AI agent support-agent Claude, or any MCP client close_ticket → done · 1 row
↗ Your app orders-app 200 · 12 rows
↗

MCP

/mcp · :5001 key or OAuth 2.1✓Stable tools: only what's granted✓ a wrong credential: 401
↗

REST

/q/<name> · :5000 the same checks, in the same order
The governed corethe same code for both doors↗

01 · Same rules

Rate limit, sign-in, grants: in REST's order.

support-agent ✓ 429 rate_limited

02 · Tables

Ad-hoc SQL: read-only, only allowed tables.

payroll ✗ table_not_allowed

03 · Masking

As over REST. Masked columns are marked for the agent.

email → hash mask_unresolvable

04 · Writes

Only queries marked for agents, each approved by a person.

approved ✓ own_write
Recorded transport: mcp · support-agent · close_ticket · approved Every run in run history, as for REST: the caller, the transport, the rows.
↗

PostgreSQL

warehouse
orders customers tickets payroll
customers.ltv_90dsource: database "Revenue in the customer's first 90 days, EUR"
↗

What agents did

GET /api/v1/usage/agents agent_unusual_volume support-agent calls 4 · rows 212 · errors 1 · masked_calls 1 · adhoc 2 refusals {table_not_allowed: 1} · writes {done: 1}
What the agent seesonly what its key grants
tools orders_by_customer · revenue_by_region · list_tables · describe_table · execute_sql (read-only) · close_ticket (approval) resource queryapigate://connections/warehouse/dictionary dictionary customers.ltv_90d BIGINT "Revenue in the customer's first 90 days, EUR" · customers.email masked: hash
Stablecompatibility promise With Redis, a key's rate limit is one count across REST and MCP.
An AI agentA key, or signed in through your identity providerAny MCP client, at /mcp.
Two doors, one coreMCP and REST run the same checksAn agent is never governed less because of its protocol.
The governed coreRules → tables → masking → writesAd-hoc SQL is read-only, on allowed tables, at most 200 rows. A write waits for a person.
Your warehouseDescribed for the agent, masked where you sayA dictionary of what each column means, with masked ones marked.
What agents didCalls, rows, refusals and writes, per agentAn alert when one reads ten times its usual hour, above a floor you set.

The same governed core as the full architecture.

For AI agents

Let an agent query your data, governed like an app

An agent with a database password is an agent with everything. Through the MCP server it gets saved queries as tools, ad-hoc SQL only where you allow it, descriptions of what tables mean, and writes only with a person approving.

✓Any MCP client connects to /mcp, with an API key or OAuth 2.1 through your identity provider.
✓The same grants, limits and masking as REST. An agent cannot be governed less because of its protocol.
✓Descriptions imported from the database's own comments tell the agent what ltv_90d is, so it writes the right SQL first time.
✓Per-agent usage, and an alert when one reads ten times its usual hourly volume, above a floor you set.
AI agents
# claude_desktop_config.json, or any MCP client
{
  "mcpServers": {
    "warehouse": {
      "url": "https://data.example.com/mcp",
      "headers": {"X-API-Key": "sk_live_…agent"}
    }
  }
}

# what the agent sees
tools: orders_by_customer, revenue_by_region, list_tables,
       execute_sql (read-only, allowed tables only)
resources: queryapigate://connections/warehouse/dictionary
           (masked columns marked)
write tools: close_ticket → waits for a person's approval
More use casesAll twelve →

Not sure which fits?

The example APIs ship with a generated database and one scoped key per scenario, so you can try each of these in a few minutes without connecting anything of your own.

Run the examplesCompare alternatives