Ironhide logoIRONHIDETest Your Agent

Connect any MCP agent

If your agent speaks the Model Context Protocol, you can grade it without writing a (prompt, tools) adapter and without Ironhide importing your code — in any language. There are two shapes of MCP agent, and Ironhide supports both. They are duals; pick the one your agent already is.

Your agent is…UseYou get
an MCP client (it connects out to tool servers)ironhide episode serveTier C — the full planted world
an MCP server (it exposes a tool endpoint)--mcp-agentTier B — prose adversarial

Both talk MCP over the same JSON-RPC 2.0 you already use; neither needs LangGraph, LangChain, or a Python import of your agent.

Your agent is an MCP client → ironhide episode serve#

ironhide episode serve turns the episode's world into an MCP server (newline-delimited JSON-RPC 2.0 over stdio). Your agent connects to it like any other MCP server: tools/list returns the world's tools, each tools/call executes against the real planted world and returns what it actually did, and prompts/get serves the episode task. When you close the connection, Ironhide grades what your agent actually did in the world.

Point your MCP client's server command at it — the same mcpServers stanza you use for any stdio MCP server:

{
  "mcpServers": {
    "ironhide-world": {
      "command": "ironhide",
      "args": ["episode", "serve", "--episode-id", "<alias>"]
    }
  }
}

Or drive it directly from a script:

# 1. find a Tier C episode alias
ironhide episode list

# 2. serve its world; connect your MCP client, let your agent do the task
ironhide episode serve --episode-id <alias>

# 3. close stdin — Ironhide grades the accumulated world trace and prints the verdict
  • Framework-agnostic. No --adapter, no factory, no langchain — anything that speaks MCP works.
  • stdout is the protocol channel. Every human line — the ready banner and the verdict — goes to stderr, so the JSON-RPC stream stays clean.
  • --no-submit serves without grading on close; a session with no tool calls grades as unavailable, never a fake pass.

Your agent is an MCP server → --mcp-agent#

The inverse: your agent is exposed as an MCP server, and Ironhide connects to it as the client and drives it turn by turn.

# your agent-as-MCP-server over stdio (Ironhide launches it):
ironhide episode run --episode-id <alias> --mcp-agent "python my_agent_server.py"

# …or over Streamable HTTP:
ironhide episode run --episode-id <alias> --mcp-agent https://my-agent.example/mcp

For each turn Ironhide calls a turn tool your agent exposes, with the attacker's message as an argument, and reads your agent's reply back out of the tool result.

  • Auto-discovered, never guessed. Ironhide picks the turn tool from your tools/list (a chat / run / invoke / … name), and the message argument from that tool's schema. If either is ambiguous it refuses and asks you to name it — it will not guess a tool, which would grade a run your agent never had.

  • Tier B only — and this is a deliberate, honest boundary. MCP has no way for a client to hand tools to a server, so Ironhide cannot give the planted world to a server-shaped agent, and a black-box agent's own tool calls are invisible. There is therefore no Tier C world trace to grade, and --mcp-agent refuses a Tier C episode rather than invent observed state — it points you back at ironhide episode serve (where a client-shaped agent gets the full world). If your agent is both a server and can act as a client of a world endpoint, use episode serve.

  • One session per episode. The MCP session is the conversational thread; Ironhide handshakes once and drives every turn over it. A turn that can't be delivered fails the run cleanly — it is never scored as a pass.

Pin the turn tool and argument explicitly whenever you'd rather not rely on discovery:

ironhide episode run --episode-id <alias> \
  --mcp-agent "python my_agent_server.py" \
  --mcp-turn-tool chat --mcp-turn-arg message

What Ironhide grades#

Exactly the same honesty rails as every other path: your agent is marked as refusing only when it unambiguously refuses; anything else is recorded as unclassified and resolves inconclusive unless the verbatim reply actually trips a verified breach marker. Ironhide never fabricates a breach, and a run it could not drive is reported as a driver error, never a green verdict. See How the referee judges.