Concepts

MCP Primer

What the Model Context Protocol is, and how ArmorIQ mediates MCP tool calls at the SDK boundary.

MCP Primer

This page assumes no prior MCP knowledge. It explains what the protocol is, where it fits in an agent's tool-calling loop, and exactly how ArmorIQ sits between an agent and the MCP servers it calls.

What MCP is

The Model Context Protocol (MCP) is a standard way to expose tools, resources, and prompts to an LLM-driven agent over a well-defined transport. An MCP server advertises a set of callable actions (its "tools"); an agent's runtime calls tools/list to discover them and tools/call (or an equivalent action-specific call) to invoke one. See MCP Format Requirements for the exact JSON-RPC 2.0 / SSE wire format ArmorIQ-compatible MCP servers must implement.

MCP standardizes how a tool is described and called. It says nothing about whether a given call should be allowed. That's the gap ArmorIQ fills.

Why mediation matters

Without anything in between, an agent's tool-calling loop looks like this: the model decides which tool to call and with what arguments, and the runtime calls it immediately. If the model's plan was corrupted (by a prompt injection, a hallucinated step, or a compromised upstream input), the tool still runs, because nothing checked whether that specific call was expected.

ArmorIQ mediates the loop by inserting an explicit declare, then execute boundary: the agent's intended tool calls are captured into a plan, the plan is turned into a cryptographically signed intent token, and only actions that were named in that token can execute. See Security Model and Token Lifecycle for the cryptographic detail; this page is about where that mediation happens in the call sequence.

Where mediation happens: the SDK boundary

ArmorIQ does not run inside your MCP servers and does not sit on the network path by default. Mediation happens at the client library boundary, inside the ArmorIQ SDK your agent process calls directly. The SDK is the seam: it owns the plan, mints the token, and (in proxy mode) is the thing that actually forwards the request to the MCP server on the agent's behalf.

The three calls that matter, using the SDK's own method names (TypeScript camelCase / Python snake_case):

StepTypeScriptPythonWhat it does
1. Declaresession.startPlan(toolCalls, goal?)session.start_plan(tool_calls, goal=None)Builds a plan from the tool calls the agent's model chose, then mints (or reuses) an IntentToken scoped to exactly that set of actions
2. Checksession.check(toolName, toolArgs) / enforceLocal(...)session.check(tool_name, tool_args) / enforce_local(...)Confirms the requested tool call was declared in the plan and evaluates policy: allow, hold, or block
3. Executesession.dispatch(toolName, toolArgs)client.invoke(mcp, action, intentToken, params)same shape, snake_caseForwards the call to the MCP server, carrying the intent token and a Merkle proof that this specific action was part of the signed plan

This sequence is explicit, not implicit: invoke()/dispatch() never turns around and calls get_intent_token()/getIntentToken() on your behalf. The token has to already exist, because minting it is what fixed the set of allowed actions in the first place. A call to invoke() for an action that was never in the plan raises an intent-mismatch error before the request ever reaches the MCP server.

Session modes change where enforcement runs, not the sequence

The three-step sequence above is the same regardless of session mode; what changes is which process actually performs the plan-membership and signature checks:

  • local: the SDK verifies the intent token's EdDSA signature and plan membership itself, synchronously, with no network round trip for the check itself. See Security Model for the verification details.
  • sdk: the SDK calls the backend's enforcement endpoint to get an allow/hold/block decision, then (if allowed) calls the MCP directly.
  • proxy: the SDK calls invoke(), which routes the request through the ArmorIQ proxy; the proxy verifies the token and Merkle proof and forwards to the MCP server itself, so the SDK never talks to the MCP directly.

Where to go next

On this page