Integrating LangGraph with MAREF — Protocol-Level Governance That Works Today

By MAREF Engineering

LangGraph tutorial A2A integration agent governance

If you're building production agents in 2026, there's a good chance they're a LangGraph state graph. Nodes, edges, conditional routing — elegant, testable, and — until you add a governance layer — completely unsupervised. This guide shows the two ways to govern a LangGraph app with MAREF, and it's honest about which is ready today.

TL;DR: the protocol-level path (MCP + A2A) is live and tested; the native LangGraphAdapter documented in the quickstart is on the roadmap, with the AutoGen sidecar adapter already shipped.


The honest status, first

MAREF's quickstart documents a sidecar.adapters.langgraph.LangGraphAdapter with three methods — evaluate_node_safety, observe_transition, and inject_governance. We want to be direct with you: that adapter is specified but not yet merged. The AutoGen adapter (sidecar.adapters.autogen.AutoGenAdapter) is live; LangGraph's native adapter is being built to the same contract.

What that means for you: you should not block on the adapter. The protocol-level integration below uses only shipped, tested code paths and gives you the same governance guarantees today.

Path 1 — Govern tool calls inside a LangGraph node (MCP)

LangGraph nodes call tools. Those tools are where the blast radius lives. Wrap them with MCPBridge and every call from any node goes through the security gate — with the same event stream you can feed your audit log:

LangGraph node behind the MAREF security gate
from langgraph.graph import StateGraph
from maref.integration.mcp_client import MCPClient, MCPServerConfig
from maref.integration.mcp_bridge import MCPBridge

client = MCPClient()
conn = client.register_server(MCPServerConfig(
    command=["npx", "-y", "@your/tool-server"],
    transport_type="stdio",
    server_name="tool-server",
))
bridge = MCPBridge(client)                      # wraps calls in the security gate

def tool_node(state):
    # every node that touches the world goes through governance
    return bridge.invoke_tool(
        conn,
        tool_name=state["tool"],
        args=state["args"],
    )

graph = StateGraph(dict)
graph.add_node("tools", tool_node)
graph.add_edge("__start__", "tools")

A DENY verdict returns {"error": "Tool blocked by security gate", ...} — the external server is never called, and the node's __error__ edge or fallback logic can route around it. Your LangGraph topology stays exactly as designed; MAREF just sits at every tool boundary.

Path 2 — Govern whole tasks across agents (A2A)

For multi-agent LangGraph deployments — several graphs, maybe a supervisor — the A2ABridge makes MAREF itself an A2A-governed agent that creates, delegates, and halts tasks across the federation:

MAREF as the governed agent in an A2A federation
from maref_lite.state_machine import GovernanceStateMachine
from maref.governance.audit import AuditLogger
from maref.integration.a2a_bridge import A2ABridge

bridge = A2ABridge(
    state_machine=GovernanceStateMachine(),
    audit_logger=AuditLogger(log_path="maref-audit.jsonl"),
    agent_name="langgraph-supervisor",
)

task_id = bridge.create_task("Summarize Q3 report")    # governed lifecycle
# another agent can delegate into us:
bridge.delegate_task(task_id, "https://other-agent.local:8000")

# any authorized human can halt a task outright:
bridge.force_halt_task(task_id, reason="scope change")

Every create_task, delegation, and state change is HMAC-signed into the audit log and runs through the same governance state machine — OBSERVE → ANALYZE → EVALUATE → DECIDE → ACT → VERIFY → STABILIZE → REPORT, with HALT reachable by any authorized human or the circuit breaker.

The result: your LangGraph graphs keep their orchestration logic, while MAREF owns the "is this safe?" decision at every boundary — tool calls, inter-agent handoffs, and task lifecycle.

Which path should you pick?

  • Single graph, several tools → Path 1 (MCP bridge on tool calls). Minimal change, immediate audit trail.
  • Multiple graphs / supervisor pattern → Path 2 (A2A). You get task lifecycle governance, delegation, and a kill-switch across the whole fleet.
  • Both → They compose. MAREF governs tool calls and task orchestration simultaneously — that's the 8-layer architecture working as designed.

🛡️ Sources: MAREF source — src/maref/integration/mcp_bridge.py (MCPBridge.invoke_tool), src/maref/integration/a2a_bridge.py (A2ABridge.create_task / delegate_task / force_halt_task), src/sidecar/adapters/autogen.py (shipped sidecar adapter). LangGraph adapter contract defined in docs/quickstart.md §3.3 (roadmap — AutoGen adapter shipped). Quickstart · Integrations.