MCP Bridge — 4 Tools (Tier 2)
iris intermediate 5 min read
ELI5
MCP (Model Context Protocol) is like a universal remote control for AI assistants. The IRIS MCP server is a small adapter that lets Claude (or any MCP-compatible client) create sprites, validate them, form councils, and run chains — all by speaking a standard language that the client already understands.
Technical Deep Dive
MCP Architecture
flowchart TB subgraph client["MCP Client"] claude["Claude Desktop or MCP Client"] end subgraph bridge["Tier 2 — Bridge"] mcp["iris-mcp-server<br/>stdio / SSE transport"] end subgraph core["Tier 1 — Core"] iris["iris-service FastAPI"] end claude --> mcp mcp --> irisTransport: MCP uses stdio (for local clients like Claude Desktop) or SSE (Server-Sent Events) for remote connections. The iris-mcp-server currently implements stdio transport.
Deployment: The server is built for Cloudflare Workers using Wrangler (wrangler.toml). It can also run locally with Node.js.
The 4 MCP Tools
flowchart TB subgraph Tools["MCP Tools"] A["create_sprite_in_iris"] B["validate_sprite"] C["create_council"] D["run_chain"] end subgraph Delegation["Delegates to iris-service"] E["POST /v1/sprites"] F["Client-side validation"] G["POST /v1/councils"] H["POST /v1/chains/execute"] end A --> E B --> F C --> G D --> HTool 1: create_sprite_in_iris
Purpose: Create a sprite in the IRIS registry, optionally documenting it in Choco.
Input schema (JSON Schema):
{ "name": "SOL-FORGE-01", "version": "1.0.0", "role": "architect", "capabilities": [{"name": "generate_code", "description": "..."}], "system_prompt": "You are a senior software architect...", "protected": false, "gate_authority": false, "metadata": {"author": "dev", "tags": ["core"]}, "document_in_choco": false, "choco_workspace": null}Output:
{ "sprite": { /* full Sprite object with id + fingerprint */ }, "documented": false, "choco_page_url": null}Key design: Sprite creation always happens in IRIS. Choco documentation is optional and currently a stub (always returns documented: false).
Tool 2: validate_sprite
Purpose: Dry-run validation against iris.schema.json without persisting.
Input: sprite_definition (object), optional format (json or yaml)
Output:
{ "valid": true, "errors": [], "schema_version": "1.0.0", "fingerprint_preview": "a1b2c3d4..."}Validation checks:
- Name matches
SOL-[A-Z]+-\d+pattern - Version is valid semver
- Role is one of 6 valid roles
- Capabilities array has ≥1 item with name and description
- System prompt is non-empty string
Note: YAML format is not yet supported in the MCP server (returns an error). The fingerprint preview is a placeholder hash, not real Blake3.
Tool 3: create_council
Purpose: Group existing sprites under a domain with governance.
Input:
{ "domain": "engineering", "sprite_ids": ["uuid1", "uuid2"], "gate_agent_ids": ["uuid1"], "chains": [ /* optional Chain definitions */ ], "rules": [ /* optional Rules */ ]}Field name translation: The MCP client uses descriptive names (sprite_ids, gate_agent_ids) while the REST API uses concise names (sprites, gate_agents). The MCP server translates between them.
Output: Full council object with server-generated id and timestamps.
Tool 4: run_chain
Purpose: Synchronous chain execution per DEC-002.
Input:
{ "council_id": "uuid", "chain_id": "uuid", "input": { "task": "Generate a REST API for user management", "context": {"language": "python", "framework": "fastapi"} }}Output: Full ChainExecutionResult including execution_id, status, steps, gates, and timing.
Error Handling
flowchart TD A["MCP Tool Call"] --> B{"IrisServiceError?"} B -->|Yes| C["Return {isError: true, content: [{type: text, text: error_json}]}"] B -->|No| D["Return {content: [{type: text, text: result_json}]}"] D --> E{"Generic error?"} E -->|Yes| C E -->|No| F["Success ✓"]All errors are returned as MCP text content with isError: true, containing the full JSON error response from iris-service.
Key Terms
- MCP → Model Context Protocol; a standard protocol for AI assistants to discover and call tools
- stdio transport → MCP over standard input/output streams (used by Claude Desktop)
- Tool schema → JSON Schema defining each tool’s inputs, used by MCP clients for auto-discovery
- Field name translation → MCP uses descriptive names (
sprite_ids) while REST uses concise names (sprites) - Choco integration → Optional documentation sync; currently a stub in the MCP server
- Dry-run validation →
validate_spritechecks constraints without persisting to the registry
Q&A
Q: Do I need Choco to use the MCP server? A: No. The MCP server works standalone. Choco documentation is optional. Sprite creation, validation, council creation, and chain execution all work without Choco.
Q: Can the MCP server run outside Cloudflare Workers?
A: Yes. While wrangler.toml configures it for Workers, the server is standard TypeScript/Node.js and can run anywhere Node 18+ is available.
Q: How does Claude discover the available tools?
A: The MCP server implements ListToolsRequestSchema, returning the JSON Schema for all 4 tools. Claude (or any MCP client) calls this on connection to learn what tools are available.
Q: Why does validate_sprite not use real Blake3?
A: The MCP server is designed to be lightweight with zero heavy dependencies. Real fingerprinting requires the blake3 Python library or WebAssembly module. The preview hash is a deterministic placeholder for quick validation feedback.
Q: Can I use the MCP server with clients other than Claude? A: Yes. Any MCP-compatible client can connect. The protocol is transport-agnostic (stdio, SSE, HTTP).
Examples
The MCP bridge is like a restaurant’s phone ordering system:
- create_sprite_in_iris = “I’d like to place a new item on the menu” (the kitchen always receives the order; optionally the PR team writes a press release)
- validate_sprite = “Can you check if my recipe will work before I cook it?” (tastes the sauce, doesn’t serve it to customers)
- create_council = “I’d like to book a private dining room for my team with one designated person who can cancel the reservation”
- run_chain = “Start the tasting menu course by course” (each course comes out sequentially; if the designated taster says “this is bad,” the kitchen stops immediately)
neighbors on the map
- GRACE Session Structure & Context Lifecycle starting a new GRACE session
- STRATT Protocol Overview learning STRATT for the first time