Mapping your tools
Verb inference handles most MCP tools well (get_* is READ, send_* is COMMUNICATION, delete_* is DELETE). For tools you rely on, an explicit mapping is better. It is faster to reason about, it can’t be fooled by a misleading name, and it tells AgentsFence which arguments carry recipients, URLs and paths.
Check what AgentsFence thinks
Section titled “Check what AgentsFence thinks”agentsfence classify mcp_crm_update_contact '{"email": "ann@corp.com", "notes": "…"}'{ "tool_name": "mcp_crm_update_contact", "capability": "crm.write", "risk": "EXTERNAL_WRITE", "source": "inferred", "targets": {"recipients": ["ann@corp.com"], "domains": [], "urls": [], "paths": [], "command": null}}Add a mapping
Section titled “Add a mapping”tools: mcp_crm_update_contact: capability: crm.write risk: EXTERNAL_WRITE recipient_args: [email]
mcp_tickets_run_query: # name says "run", but it's a read-only query capability: tickets.read risk: READ
mcp_wallet_get_quote_and_pay: # name starts with "get", but it pays capability: payment.pay risk: FINANCIAL
mcp_notes_manage: # one tool, several actions capability: notes.write risk: LOCAL_WRITE arg_risk: action: {list: READ, read: READ, delete: DELETE}| Key | Meaning |
|---|---|
capability |
the name used in policies and the audit log; keep <domain>.<verb> |
risk |
one of the risk classes |
arg_risk |
override the risk class by the value of one argument |
recipient_args |
arguments holding people or channels (checked against allowed recipients) |
domain_args |
arguments holding URLs (checked against allowed domains and the exfiltration heuristic) |
path_args |
arguments holding file paths (checked against allowed paths and protected paths) |
Patterns for tool families
Section titled “Patterns for tool families”patterns: - {match: "mcp_internalwiki_*", capability: wiki.read, risk: READ} - {match: "mcp_*", risk: infer} - {match: "*", risk: infer}The first match wins. Keep the two infer catch-alls at the end.