Model Context Protocol
Add AGP governance to any MCP server. Every tool call gets a policy decision, capability check, and immutable audit entry — regardless of which model or agent runtime is driving it.
MCP is a standard for exposing tools to agent runtimes. AGP is the governance layer that sits underneath those tools. Every call — regardless of which model, framework, or runtime is driving it — gets a capability check, a policy decision, and an immutable audit entry.
MCP client (any model or agent runtime)
↓ tool call: "approve_payment"
AGP governance layer
├─ Register task (risk_tier: high)
├─ Check capability token
├─ Run policy evaluation → require_approval
├─ Wait for human sign-off
└─ Submit action envelope → 201 + ledger entry
↓
Tool executes (or is blocked if any step fails)AGP is model-agnostic. It does not matter whether the MCP client is Claude, GPT-4, Gemini, a LangChain agent, an AutoGen workflow, or a custom runtime you built yourself. The governance contract is between the tool server and the AGP server — not between AGP and any specific model.
There are two integration points. Choose based on whether you want the agent runtime to participate in the governance workflow, or whether you want governance to fire transparently behind your tool surface.
Approach A — AGP as an MCP server
Expose AGP's governance tools to the agent runtime via MCP. The agent registers tasks, evaluates policy, and submits action envelopes as part of its own reasoning loop. Best when the runtime supports tool use and you want full transparency into governance decisions.
Approach B — AGP behind your MCP server
Wrap each tool handler in your existing MCP server with the AGP pipeline. The agent runtime calls your tools normally — governance fires server-side. Best for protecting an existing tool surface without changing the agent's behaviour or prompts.
Approach A — AGP as an MCP server
The agp-mcp package is a ready-made MCP server that exposes the full AGP
lifecycle as MCP tools. Any MCP-compatible agent runtime can connect to it — the
agent can then register tasks, evaluate policy, and submit action envelopes as
native tool calls, with no direct HTTP calls to the AGP server required.
Install
pip install agp-mcpStart the server
Two transport modes — stdio for local agent runtimes, SSE for remote or networked hosts:
# stdio — for local runtimes (Claude Desktop, local LangChain agent, etc.)
AGP_BASE_URL=https://your-agp-server \
AGP_CLIENT_ID=my-agent \
AGP_CLIENT_SECRET=s3cr3t \
python -m agp_mcp
# SSE — for remote MCP hosts, multi-agent networks, or cloud deployments
AGP_BASE_URL=https://your-agp-server \
AGP_CLIENT_ID=my-agent \
AGP_CLIENT_SECRET=s3cr3t \
python -m agp_mcp --sseConnect your agent runtime
Point any MCP-compatible client at the server. Examples for common runtimes:
{
"mcpServers": {
"agp": {
"command": "python",
"args": ["-m", "agp_mcp"],
"env": { "AGP_BASE_URL": "https://your-agp-server", "...": "..." }
}
}
}# using langchain-mcp-adapters
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient({
"agp": {"url": "http://localhost:8765/sse", "transport": "sse"}
})
tools = await client.get_tools() # AGP tools available to any LangChain agent# stdio transport
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
server_params = StdioServerParameters(
command="python", args=["-m", "agp_mcp"],
env={"AGP_BASE_URL": "https://your-agp-server"},
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools() # all AGP tools availableAvailable tools
| Tool | What it does |
|---|---|
run_governed_task | One-call lifecycle wrapper — registers task, evaluates policy, and executes. Use for straightforward governed actions. |
create_task | Register a new task with risk tier, principal, and outcome. |
bind_liability | Attach a sponsoring entity and accountable owner. Required before a decision can be recorded. |
issue_capability | Issue a capability token scoped to specific permitted actions. |
record_decision | Record the agent's reasoning, selected action, and uncertainty score. |
evaluate_policy | Record a policy verdict: allow / require_approval / deny / quarantine. |
create_approval | Record a human approval decision for APPROVAL_PENDING tasks. |
create_escalation | Raise an escalation notice when the agent is uncertain or detects an ethical concern. |
submit_action | Submit the action envelope through the fail-closed execution gate. |
validate_action | Dry-run validation — checks all gate conditions without executing or writing to the ledger. |
replay_audit_log | Retrieve the full hash-chained audit trail for a task. |
Simple governed action — one tool call
For straightforward low-risk actions, any agent runtime can use
run_governed_task to complete the full AGP lifecycle in a single tool call:
Agent calls run_governed_task(...)
run_governed_task(principal_id="my-agent", requested_outcome="Summarise Q3 sales report", risk_tier="low", policy_verdict="allow", ...)
AGP registers the task, binds liability, issues a capability token, evaluates policy, submits the action envelope, and returns a receipt with the ledger entry — in one round-trip. Works the same whether the agent is Claude, a LangChain ReAct agent, an AutoGen workflow, or a custom runtime.
High-risk action with human approval
For high-risk actions, the agent runtime uses the individual tools to walk the
pipeline step by step, pausing at APPROVAL_PENDING until a human approves. The
agent can surface the task ID to the user and wait:
# Agent runtime calls these tools in sequence
# 1. Register intent
create_task(
principal_id="finance-agent",
requested_outcome="Approve $125k payment to Acme Corp",
risk_tier="high",
sponsoring_entity="finance-team",
jurisdictions=["EU"],
regulatory_frameworks=["EU_AI_ACT_2024"],
)
# → { "task_id": "tsk_01HX...", "status": "CREATED" }
# 2. Bind accountability
bind_liability(task_id="tsk_01HX...", sponsoring_entity="finance-team",
accountable_owner="cfo@acme.com", jurisdiction="EU")
# 3. Issue capability token
issue_capability(subject_agent="finance-agent", issuer="finance-team",
principal_id="finance-agent",
permitted_actions=["approve_payment"])
# → { "capability_id": "cap_01HA..." }
# 4. Record reasoning
record_decision(task_id="tsk_01HX...", agent_id="finance-agent",
selected_action="approve_payment",
rationale="Vendor verified, amount within delegated limit",
uncertainty_score=0.12)
# 5. Policy evaluation → high-risk triggers require_approval
evaluate_policy(task_id="tsk_01HX...", verdict="require_approval",
rationale="Amount > $100k threshold",
decision_ref="dec_01HB...")
# → task status: APPROVAL_PENDING
# Agent reports back to user: "Action registered, awaiting CFO approval.
# Task ID: tsk_01HX... Resume once approved."
# 6. After human approves out-of-band (via your approval UI or AGP API):
create_approval(task_id="tsk_01HX...", approver_id="cfo@acme.com",
decision="approved", rationale="Confirmed with procurement",
policy_evaluation_ref="pol_01HC...")
# 7. Execute — fail-closed gate fires here
submit_action(task_id="tsk_01HX...", agent_id="finance-agent",
tool_id="approve_payment",
operation={"vendor": "Acme Corp", "amount_usd": 125000},
capability_token_ref="cap_01HA...",
decision_ref="dec_01HB...",
policy_decision_ref="pol_01HC...")
# → 201 Created. Signed receipt + immutable ledger entry.Remote / SSE transport
For use with a remote MCP host (not Claude Desktop), start the server in SSE mode:
AGP_BASE_URL=https://your-agp-server \
AGP_CLIENT_ID=my-agent \
AGP_CLIENT_SECRET=s3cr3t \
python -m agp_mcp --sseApproach B — AGP behind your MCP server
If you already have an MCP server exposing tools, wrap each handler with the AGP
pipeline. The agent runtime calls your tools exactly as before — governance
fires server-side, invisibly. The agent sees a normal tool result, or a
ToolError if the action was blocked or requires human approval. No changes to
the agent's prompts, tool definitions, or client configuration.
Install
pip install agp-sdk mcpRisk classification
Define how your tools map to AGP risk tiers. This determines whether a tool call
auto-approves (allow) or requires human sign-off (require_approval):
from agp import AGPClient
RISK_MAP = {
# Read-only, no side effects
"search_docs": "low",
"read_database": "low",
# Writes to internal systems
"send_email": "medium",
"update_record": "medium",
# Consequential external actions
"approve_payment": "high",
"delete_records": "high",
"deploy_code": "critical",
}
def policy_verdict(risk_tier: str) -> str:
return "allow" if risk_tier in ("low", "medium") else "require_approval"Governance wrapper
Wrap your tool handler with a helper that runs the full AGP pipeline before the
tool executes. Low and medium risk tools complete in a single round-trip.
High-risk tools return an APPROVAL_PENDING response; the real tool only fires
once create_approval is called and the wrapper is resumed.
import functools
from mcp.server.fastmcp import FastMCP
from mcp.server.fastmcp.exceptions import ToolError
from agp import AGPClient
from agp.exceptions import AGPPolicyDeniedError, AGPApprovalRequiredError
agp = AGPClient("https://your-agp-server",
client_id="my-mcp-server", client_secret="s3cr3t")
server = FastMCP("my-tools")
def governed(tool_name: str, agent_id: str = "mcp-server",
entity: str = "my-org", owner: str = "owner@example.com"):
"""Decorator: wrap any tool handler with AGP governance."""
def decorator(fn):
@functools.wraps(fn)
async def wrapper(*args, **kwargs):
risk = RISK_MAP.get(tool_name, "medium")
verdict = policy_verdict(risk)
try:
with agp.task_session(
principal_id=agent_id,
requested_outcome=f"MCP tool call: {tool_name}",
risk_tier=risk,
) as session:
session.bind(sponsoring_entity=entity,
accountable_owner=owner, jurisdiction="EU")
session.issue_capability(subject_agent=agent_id, issuer=entity,
principal_id=agent_id,
permitted_actions=[tool_name])
session.decide(agent_id=agent_id, selected_action=tool_name,
rationale="MCP tool call", uncertainty_score=0.1)
session.evaluate(verdict=verdict)
if verdict == "require_approval":
# Return task_id — caller must approve before execution
raise ToolError(
f"Action requires human approval. "
f"Task ID: {session.task_id}. "
f"Approve via POST /agp/decision/approvals."
)
session.execute(agent_id=agent_id, tool_id=tool_name,
operation=kwargs)
return await fn(*args, **kwargs)
except AGPPolicyDeniedError as e:
raise ToolError(f"Blocked by governance policy: {e}")
return wrapper
return decorator
# Apply to your tools — Claude sees no difference
@server.tool()
@governed("send_email")
async def send_email(to: str, subject: str, body: str) -> str:
"""Send an email."""
# Your real implementation here
...
@server.tool()
@governed("approve_payment")
async def approve_payment(vendor: str, amount_usd: float) -> str:
"""Approve a vendor payment."""
# Only reached after AGP clears the action envelope
...What the agent runtime sees
For low/medium risk tools, the agent calls the tool and gets a normal result —
no change in behaviour. For high-risk tools, the agent receives a ToolError
containing the task ID and approval instructions. The runtime can surface this
to the user, pause, and retry once a human has approved via the AGP approval
endpoint. This works with any MCP client regardless of the underlying model.
What you get
Auditable tool calls
Every tool the agent calls creates an immutable ledger entry. You can replay the full sequence of events for any task — what the agent intended, what it decided, what policy said, who approved, what executed.
Automatic risk gating
Low-risk tools execute freely. High-risk tools are blocked until a human signs off. The same workflow handles both — no separate approval UI needed beyond the AGP approval endpoint.
Revocable authority
Capability tokens can be revoked at any time. If the agent's session token is revoked, all pending and future actions under that capability are immediately blocked — even mid-workflow.
EU AI Act compliance evidence
Each task provides: risk classification (Art. 9), decision rationale and uncertainty score (Art. 13), human oversight record (Art. 14), and an append-only audit ledger (Art. 12) — out of the box.
Next steps
AGP works across the full agent stack. If your agent is orchestrating other agents or calling microservices, governance extends there too:
Overview
AGP is the governance layer, not the transport — integrate it with MCP, A2A, AP2, UCP, and microservices.
Agent-to-Agent (A2A)
Govern multi-agent workflows with AGP. Sub-token delegation, liability chains, and cascade revocation across orchestrators and worker agents — model and framework agnostic.