Overview
This page explains what the Gateway is, the terms used throughout the rest of these guides, and what actually happens when an AI calls a tool. You don’t need to have read the MCP specification to follow it.
The Big Picture
MCP (Model Context Protocol) is how an AI client discovers and calls tools. An MCP server publishes a set of tools - “list S3 buckets”, “run this SQL”, “create a Jira issue” - and an MCP client calls them on the model’s behalf.
Normally the client connects to each MCP server directly, and each server holds whatever credential it needs to do its job. That credential is standing access: it exists before anyone asks for it and remains after they stop.
The Gateway changes the shape. Clients connect to the Gateway, and the Gateway connects to the backend MCP servers. Because every call passes through one place, that place can decide, credential, inspect, and record.
flowchart LR
Human["Assistant driven by a person<br/>(Claude Desktop, Claude Code, Codex)"]
Agent["Autonomous agent or workload<br/>(CI job, scheduled agent)"]
Gateway["Britive MCP Gateway"]
Britive["Britive platform<br/>(policy, checkouts, audit)"]
B1["Backend MCP server<br/>(AWS, database, Jira…)"]
Human -->|"tool call over HTTPS"| Gateway
Agent -->|"tool call over HTTPS"| Gateway
Gateway <-->|"may they? credential please"| Britive
Gateway -->|"call + temporary credential"| B1
Gateway -->|"audit event"| Britive
Two Kinds of Caller
The Gateway treats both as first-class, and the audit trail distinguishes them.
| Person using an assistant | Autonomous agent or workload | |
|---|---|---|
| How it signs in | Browser OAuth flow against your tenant | Presents a Britive token on the request |
| Credential type | Their own Britive identity | AI identity, workload token, or API token |
| Enabled by default | Yes | No - Accept agent tokens must be turned on for the gateway pool |
| Can act for someone else | No | Yes, with X-On-Behalf-Of, if your tenant authorizes the delegation |
Everything else in this documentation - policy, credential injection, inspection, audit - applies identically to both. Where behaviour differs, it is called out.
See Agent tokens and delegation for the settings.
Key Concepts
These terms appear constantly in the rest of the documentation. Skim them once and refer back as needed.
| Term | What it means |
|---|---|
| Backend | An MCP server the Gateway proxies to. Backends are defined on your Britive tenant, and so are the Gateway’s own settings - there is no configuration file. |
| Tool prefix | A short name that namespaces one backend’s tools. A backend with prefix aws publishes aws_list_buckets, aws_get_caller_identity, and so on, so two backends can both offer a “list” tool without colliding. |
| Tool catalogue | The set of tools one caller can see. Built from that identity’s Britive policy, and from nothing else. |
| Auth strategy | How a credential reaches the backend. Either britive_checkout (the Gateway injects temporary credentials) or downstream_oauth (the caller authorizes the backend once and the platform manages the token). |
| MCP endpoint | A routable URL - /mcp/<path> - exposing a curated subset of backends. /mcp always exposes everything the caller is entitled to. |
| Pool token | The credential the Gateway uses for its own calls to Britive: syncing backends, publishing tools, forwarding audit. Never used for anything on a caller’s behalf. |
| Inspection | Scanning tool arguments and tool responses for prompt injection, secrets, and obfuscation. Records verdicts in audit mode; blocks or redacts in enforce mode. |
| Relay | A small process that runs on a user’s own computer so Claude Desktop can reach a Gateway that isn’t publicly routable. |
How a Tool Call Travels
Every call follows the same path, whoever the caller is.
sequenceDiagram
participant C as MCP client
participant G as Gateway
participant P as Britive platform
participant B as Backend MCP server
C->>G: tools/call aws_list_buckets
G->>G: Is the caller authenticated?
G->>P: Does this identity's policy allow this tool?
P-->>G: Allowed
G->>G: Inspect the arguments
G->>P: Obtain a credential for this identity
P-->>G: Temporary credential
G->>B: tools/call + credential in headers
B-->>G: Result
G->>G: Inspect the response
G-->>C: Result
G->>P: Audit event
Any stage can stop the call, and the error names which one did - see When a call fails.
The Catalogue Is Policy, and Only Policy
The list of tools a client receives reflects the caller’s Britive policy - never the state of a connection. If a backend needs authorizing, or is temporarily unreachable, its tools stay in the list and the call is what fails.
This matters more than it sounds. MCP clients bind a tool list at the start of a conversation and hold it. A catalogue that shrank when a backend went unhealthy would leave the client calling names the Gateway had legitimately offered it moments earlier, and getting “tool not found” - a message that says the tool doesn’t exist when in fact it does and simply needs a sign-in.
So: a name that appears is a real tool. Whether this call succeeds is a property of the call.
When a Call Fails
A failed tool call carries a machine-readable code alongside its human-readable reason, so the model can tell the difference between “ask the user to sign in” and “stop trying”.
| Code | Meaning | What resolves it |
|---|---|---|
AUTH_REQUIRED | The tool is real and allowed, but the backend needs authorizing first. | The caller opens the connect URL carried in the error, authorizes the backend on the platform, then retries the same call. |
POLICY_DENIED | The caller’s Britive policy does not permit this tool. | A policy change on the tenant. |
BACKEND_UNAVAILABLE | The backend MCP server could not be reached or errored. | Backend availability; check the admin console. |
RATE_LIMITED | Too many calls too quickly from this identity. | Wait. The error tells the model to stop retrying. |
TOOL_UNKNOWN | No such tool in this caller’s catalogue. | Genuinely absent - check the name and the policy. |
Every code except TOOL_UNKNOWN asserts that the tool exists and the call was
well-formed.
What the Gateway Records
Three pieces of context are captured from the model itself on every call, because the Gateway cannot derive them from the request:
| Field | What it holds |
|---|---|
_user_prompt | The prompt that led to the call - what was actually asked for. |
_llm_intent | Why the model chose this tool and these arguments. |
_llm_session_id | An identifier the model holds constant across one chat or agent run, so a series of calls reads as one episode instead of unrelated rows. |
These are injected into the tool schema the model sees, stripped out before the call reaches the backend, and written to the audit trail. They are never shown as callable parameters in the admin console’s tool list, and each can be turned off.
_user_prompt and _llm_intent are content - they may contain anything the
caller supplied. They stay inside your deployment unless you explicitly opt in to
forwarding content to your tenant. See
Audit & SIEM.
Two Ways a Backend Gets Its Credential
This is the single most useful distinction in these docs, because it determines what a caller has to do before a tool works.
The Gateway injects temporary credentials. On each call it performs a Britive checkout for that identity and passes the result to the backend in HTTP headers. The backend stores nothing - it reads the credential from the request, uses it, and forgets it.
Use this for backends you run: a database MCP server, an AWS adapter, an internal service. The caller does nothing beyond having the right Britive policy.
See Britive checkout.
What Runs Where
The Gateway is a single container image plus a Postgres database you supply.
flowchart TB
subgraph client["Callers"]
C["MCP client"]
R["Relay<br/>(Claude Desktop only)"]
A["Agent / workload"]
C -.-> R
end
subgraph yours["Your network"]
LB["Load balancer / TLS edge"]
G1["Gateway"]
G2["Gateway"]
DB[("Postgres")]
LB --> G1
LB --> G2
G1 --> DB
G2 --> DB
end
T["Britive tenant"]
B["Backend MCP servers"]
C --> LB
R --> LB
A --> LB
G1 --> T
G1 --> B
The transport is always stateless
The Gateway serves MCP over Streamable HTTP and holds no per-client session in
memory. There is no Mcp-Session-Id kept between requests, and this is not
configurable.
That single property is what makes everything above work: any replica can serve any request, so a restart drops nothing, a rolling upgrade needs no draining, and the load balancer needs no session affinity. All state that must persist - stored tokens, cached policy answers, the audit trail - lives in Postgres, which every replica shares.
It also explains why _llm_session_id has to come from the model: with a
stateless transport and a conversation spanning many requests, the Gateway has
nothing of its own to correlate a series of calls by.
What is stored, and what is encrypted, is covered in Production.