Gate an agent's MCP tool call
Ask the MCP gateway for Intralock's verdict on an agent's tool call, read the reason, and list the callers it has seen.
mcp.enforce
Ask the MCP gateway for Intralock's verdict on an agent's tool call, read the reason, and list the callers it has seen.
mcp.enforcePut admission in front of your MCP servers, repositories, SaaS tools and cloud accounts. Every agent gets a lease or a reason – and you keep the lever to stop any of them.
An agent calls tools on an MCP server and you want each call decided before it reaches the tool. The gateway returns the verdict with no model on the path.
The code reads the key from INTRAMEDIAL_KEY. Keep it in your shell or your secret store, never in a file you commit. Calls that need a signed-in person cannot use a key: the console makes them.
Send the agent's DID and the tool name. A mutation-shaped name such as fs.write is admitted as a write whatever else is sent.
mcp.enforcemcp-enforce
curl -sS -X POST https://api.intramedial.com/api/v1/acp/mcp/enforce \
-H "Authorization: Bearer $INTRAMEDIAL_KEY" \
-H "Content-Type: application/json" \
-d '{
"actorDid": "did:web:acme.example:agent:support",
"tool": "fs.write"
}'const res = await fetch("https://api.intramedial.com/api/v1/acp/mcp/enforce", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INTRAMEDIAL_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
actorDid: "did:web:acme.example:agent:support",
tool: "fs.write",
}),
});
console.log(res.status, await res.json());import os, requests
res = requests.post(
"https://api.intramedial.com/api/v1/acp/mcp/enforce",
headers={"Authorization": "Bearer " + os.environ["INTRAMEDIAL_KEY"]},
json={
"actorDid": "did:web:acme.example:agent:support",
"tool": "fs.write",
},
timeout=30,
)
print(res.status_code, res.json())allow and reason are Intralock's answer. mode is the stored gateway mode.
{
"mode": "observe",
"shadow": false,
"event": { "actorDid": "did:web:acme.example:agent:support", "tool": "fs.write" },
"advise": null,
"allow": false,
"reason": "no_grant",
"action": "write",
"llm": false,
"protocolVersion": "2026-07-28"
}Every request through the gateway appends an mcp.shadow event to the ledger, naming the DID, the tool and the mode. This route returns the newest 50. It does not say whether a caller is enrolled, so compare the callers with your identity list to find the ones nobody registered.
curl -sS https://api.intramedial.com/api/v1/acp/mcp/shadow \
-H "Authorization: Bearer $INTRAMEDIAL_KEY"const res = await fetch("https://api.intramedial.com/api/v1/acp/mcp/shadow", {
headers: { Authorization: `Bearer ${process.env.INTRAMEDIAL_KEY}`, },
});
console.log(res.status, await res.json());import os, requests
res = requests.get(
"https://api.intramedial.com/api/v1/acp/mcp/shadow",
headers={"Authorization": "Bearer " + os.environ["INTRAMEDIAL_KEY"]},
timeout=30,
)
print(res.status_code, res.json())Copied from: /docs/mcp-enforce
instructionShaped flag is a heuristic on text.The ledger is append-only and sealed under Merkle roots. The time on an entry is Intramedial's own clock, and a signed bundle can be checked offline with the published key.
Read the callers the MCP gateway has seen, then sanction one as an identity or keep it tracked as a shadow.
mcp.shadowidentity.enrollAsk the plane whether an agent may act on a connected SaaS source, and read the verdict before anything is sent.
saas.admitAdmit an agent's write to a repository through Intralock and post the verdict to the commit as a check run or status.
github.enforceOne short email when we add recipes to the cookbook. No other mail, and you can unsubscribe from any message.
No key or account: Try it on the coordination.admit module page runs the real kernel in your browser. Use a workspace key for your own workspace.