{"slug": "how-to-connect-maref-to-your-agent-via-mcp-step-by-step", "title": "How to Connect MAREF to Your Agent via MCP — Step-by-Step", "summary": "MAREF Engineering published a step-by-step tutorial showing how to connect MAREF to AI agents via the Model Context Protocol (MCP), covering both MAREF as an MCP client to govern external tools and as an MCP server to govern agent hosts like Claude Code, Cursor, and Windsurf. The tutorial details using the MCPBridge to wrap every tool invocation in a security gate, emitting governance events for audit logs, and exposes a ~15-line stdio launcher for the MCPServer API.", "body_md": "# How to Connect MAREF to Your Agent via MCP — Step-by-Step\n\nBy MAREF Engineering\n\n**Model Context Protocol (MCP)** has become the universal interface for agent-to-tool communication. Claude Code, Cursor, and Windsurf all speak it. The question isn't whether your agent will use MCP — it's whether anyone is watching the tools it calls. MAREF speaks MCP on both sides of that conversation, so governance is a layer, not a bolt-on.\n\nThis tutorial is written against the real MAREF API (`maref.integration.mcp_client`\n\nand `maref.integration.mcp_bridge`\n\n). Everything below runs on a stock `pip install maref`\n\n.\n\n## Two roles, one protocol\n\nMAREF works in two directions over MCP, and understanding which one you need is the whole setup:\n\n**MAREF as MCP client**— MAREF reaches out to external MCP servers (file, shell, browser, email, or a third-party tool server), lists their tools, and runs every invocation through its security gate before the call goes through.**MAREF as MCP server**— Claude Code / Cursor / Windsurf connect to MAREF as a tool server. Every tool the agent would call becomes a governed tool in MAREF's registry.\n\nMost teams start with the first and graduate to the second. Both are covered below.\n\n## 1. MAREF as an MCP client — governing external tools\n\nThe entry point is `MCPClient`\n\n. You register an external server with an `MCPServerConfig`\n\n, and MAREF manages the connection lifecycle — initialize, capability negotiation, reconnects — for you:\n\n``` python\nfrom maref.integration.mcp_client import MCPClient, MCPServerConfig\n\nclient = MCPClient()\n\nconfig = MCPServerConfig(\n    command=[\"npx\", \"-y\", \"@some/tool-server\"],\n    transport_type=\"stdio\",          # or \"sse\" with url=\n    server_name=\"my-tool-server\",\n    env={\"TOOL_API_KEY\": \"...\"},\n)\n\nconn = client.register_server(config)   # returns an MCPConnection\ntools = client.list_tools(conn)         # list[MCPToolDef]\n```\n\nNow the interesting part. A raw `MCPClient.call_tool`\n\nskips governance. The safe path is `MCPBridge`\n\n, which wraps every call in the security gate:\n\n``` python\nfrom maref.integration.mcp_bridge import MCPBridge\n\nbridge = MCPBridge(client)               # optional: pass your own MCPSecurityGate\n\n# watch governance events\nbridge.on(\"maref.mcp.invoke\", lambda e: print(\"governed:\", e.data))\n\nbridge.discover_tools(conn)              # security-check each tool once\n\nresult = bridge.invoke_tool(\n    conn,\n    tool_name=\"create_file\",\n    args={\"path\": \"/tmp/demo.txt\", \"content\": \"hello\"},\n)\n# if the security gate returns DENY, invoke_tool returns\n# {\"error\": \"Tool blocked by security gate\", \"tool\": ...} — the\n# external server is never even contacted.\n```\n\nThat one line — `bridge.invoke_tool`\n\n— is the difference between \"an agent that can call any tool\" and \"an agent that can call tools its policy allows.\" Every invocation emits a `maref.mcp.invoke`\n\nevent you can route to your audit log, SIEM, or dashboards.\n\n## 2. MAREF as an MCP server — governing Claude Code / Cursor\n\nIf your agent host already speaks MCP, expose MAREF's own tool registry as an MCP server. The `MCPServerAdapter`\n\nbridges MAREF's `ToolRegistry`\n\nto the MCP wire protocol — `list_tools`\n\nand `handle_tool_call`\n\nare the two methods the protocol needs:\n\n``` python\nfrom maref.mcp.router import MCPServerAdapter\nfrom maref.tools import ToolRegistry\n\nregistry = ToolRegistry()                # your governed tools live here\nadapter = MCPServerAdapter(registry)\n\n# MCP JSON-RPC requests come in, governed responses go out\nadapter.handle_tool_call(\"send_email\", {\"to\": \"[email protected]\"})\n```\n\nIn practice you usually mount this behind the full `MCPServer`\n\nimplementation (`maref.integration.mcp_server`\n\n), which gives you resources, prompts, and sampling callbacks on top of tools. MAREF doesn't ship a built-in `maref mcp serve`\n\nCLI command — the stdio entrypoint is a ~15-line launcher wired straight to the real `MCPServer`\n\nAPI:\n\n``` python\nimport json, sys\nfrom maref.integration.mcp_transport import JSONRPCRequest\nfrom maref.integration.mcp_server import MCPServer\n\nserver = MCPServer(name=\"maref-mcp-server\", security_gate=gate)  # gate: your security gate\n# ... server.register_tool(...) register your governed tools ...\n\nfor line in sys.stdin:                     # newline-delimited JSON-RPC 2.0\n    msg = json.loads(line)\n    req = JSONRPCRequest(method=msg[\"method\"], params=msg.get(\"params\"), id=msg.get(\"id\", 0))\n    resp = server.handle_request(req)\n    sys.stdout.write(json.dumps({\"jsonrpc\": resp.jsonrpc, \"result\": resp.result, \"error\": resp.error, \"id\": resp.id}, ensure_ascii=False) + \"\n\")\n    sys.stdout.flush()\n{\n  \"mcpServers\": {\n    \"maref\": {\n      \"command\": \"python3\",\n      \"args\": [\"/path/to/mcp_stdio.py\"]\n    }\n  }\n}\n```\n\nFrom that point on, when Claude Code or Cursor calls any tool, the call passes through MAREF's governance state machine — policy decision tree, safety gates, and audit trail — before it touches the world.\n\n## 3. What governance actually blocks\n\nGovernance isn't a suggestion. It's a decision, and it's made four ways in the policy tree — **Rule → Mode → SafetyGate → User**:\n\n- A\n**hard rule**(never touch`/etc`\n\n) blocks instantly, no model consultation. - The\n**current mode**(read-only, triage, full) narrows what's permitted. - The\n**safety gate** catches risky operations — high blast radius, untrusted targets, anomalous patterns. **Human escalation** fires for the genuinely dangerous cases, with a named approver and an audit line.\n\nAnd because every decision is signed per-agent (Ed25519) and written to the audit log, \"which agent did this?\" is never a debate.\n\n## Try it now\n\nThe fastest way to see the loop working is the local demo — it boots a governed toy agent and a live dashboard so you can watch BLOCK/ALLOW decisions stream in:\n\n```\npip install maref\nmaref demo --port 8080\n# open http://localhost:8080 — the dashboard shows the 8-layer\n# defense pipeline, trust scores, and the audit log, all live.\n```\n\n*🛡️ Sources: MAREF source — src/maref/integration/mcp_client.py (MCPClient, MCPServerConfig, register_server), src/maref/integration/mcp_bridge.py (MCPBridge.discover_tools / invoke_tool), src/maref/integration/mcp_server.py (MCPServer), src/maref/mcp/router.py (MCPServerAdapter). *\n\n[See all integration options](/en/integrations/).", "url": "https://wpnews.pro/news/how-to-connect-maref-to-your-agent-via-mcp-step-by-step", "canonical_source": "https://maref.cc/en/blog/mcp-integration-tutorial", "published_at": "2026-08-14 00:00:00+00:00", "updated_at": "2026-08-14 04:35:27.549388+00:00", "lang": "en", "topics": ["ai-tools", "ai-agents", "ai-safety", "developer-tools"], "entities": ["MAREF", "Claude Code", "Cursor", "Windsurf", "MCPClient", "MCPBridge", "MCPServerAdapter", "ToolRegistry"], "alternates": {"html": "https://wpnews.pro/news/how-to-connect-maref-to-your-agent-via-mcp-step-by-step", "markdown": "https://wpnews.pro/news/how-to-connect-maref-to-your-agent-via-mcp-step-by-step.md", "text": "https://wpnews.pro/news/how-to-connect-maref-to-your-agent-via-mcp-step-by-step.txt", "jsonld": "https://wpnews.pro/news/how-to-connect-maref-to-your-agent-via-mcp-step-by-step.jsonld"}}