Skip to content

Request flow

This page traces a single tools/call from your MCP client to the upstream service and back. Understanding the order of checks explains every error you can encounter — and why a denied call never touches the upstream.

The flow

client ──► 1 authenticate ──► 2 agent & membership checks ──► 3 resolve service
──► 4 build resource ──► 5 evaluate policies ──► 6 audit ──► 7 forward ──► 8 stream back

1. Authenticate

The client calls POST https://mcp.wicket.sh/mcp with Authorization: Bearer <member-key>. The key resolves — via a server-side digest, never a stored plaintext — to exactly one member of one agent. Unknown key → 401. The request is also counted against the key’s rate limit (429 when exceeded).

2. Agent and membership checks

The agent must be active and the membership approved. Either failing → 403, before anything else happens. Disabling an agent is therefore an instant kill switch for all of its traffic.

3. Resolve the service and tool

Aggregated tool names carry their service as a prefix: github__get_file_contents is the github connector’s get_file_contents. The service must be in the agent’s enabled-connector list — a member can’t call a service the owner hasn’t turned on, even by crafting the name manually.

4. Build the resource

The connector maps the tool call’s arguments to the resource it targets — a repository, a channel, a Linear issue — and enriches it with harvested attributes (visibility, labels, state, …) where available. This is what resource conditions evaluate against.

5. Evaluate policies

Wicket loads the agent’s enabled policies — agent-wide for trusted agents, per-member for untrusted ones (see Trust model) — and evaluates them with the Cedar engine against four inputs:

InputContents
PrincipalThe calling member
ActionThe tool, namespaced per service
ResourceFrom step 4, with harvested attributes
ContextTool arguments, current time, and the session’s history (tool counts, per-policy allow/deny counts)

The decision rule is simple: deny unless a permit matches; a matching forbid always wins.

6. Audit

The decision is recorded before forwarding — member, tool, resource, decision, matched policy versions, deny message if any, and duration. Denied calls stop here and return a JSON-RPC error to the client; the upstream never sees them.

7. Forward

For allowed calls, Wicket decrypts the member’s own OAuth token for that service — unlockable only with the member key presented in this request — strips the service prefix from the tool name, and forwards the JSON-RPC call to the connector’s upstream MCP server. Expired managed tokens are refreshed automatically; upstream sessions are established and reused per conversation.

8. Stream back

The upstream response — including streaming responses — passes through to the client unmodified. Upstream timeout (30 s) → 504; upstream unreachable → 502.

Session correlation

Calls from one client conversation are correlated into a tool session using the session ID most MCP clients send (with a privacy-safe fingerprint as fallback). The session’s running counters — which tools ran, which policies fired — feed back into step 5 as context, which is what makes session conditions possible.

Example: one call, both outcomes

The client sends a tools/call for the aggregated tool name:

{
"jsonrpc": "2.0",
"id": 12,
"method": "tools/call",
"params": {
"name": "github__delete_file",
"arguments": { "owner": "my-org", "repo": "api", "path": "README.md" }
}
}

Allowed — the upstream’s result passes through unchanged:

{
"jsonrpc": "2.0",
"id": 12,
"result": { "content": [{ "type": "text", "text": "" }] }
}

Denied at step 5 — the upstream never sees the call:

{
"jsonrpc": "2.0",
"id": 12,
"error": {
"code": -32600,
"message": "Authorization denied: tool 'delete_file' is not permitted for agent 'my-first-agent'"
}
}

Both outcomes produce an audit entry; the denied one carries the matched policy and its deny message.

Why this order matters

  • Policy denial is free. Denied calls cost you no upstream quota and leak nothing to the provider.
  • Audit is unconditional. There is no path to the upstream that bypasses step 6.
  • Authorization precedes credentials. A call that fails policy never has tokens decrypted for it (you’ll see a credentials error only after a call is authorized but no connection exists — that’s the 412).