Level 0 — Connect-Everything
This is the default state after following any “getting started” MCP tutorial. You ran npx @modelcontextprotocol/server-filesystem or dropped in the Anthropic desktop config. The agent can now read and write files, run shell commands, or query your database—depending on which server you wired up. There is no logging, no scope, no differentiation between the agent you run for internal research and the one you’re testing with external users.
The signature risk is not exotic. It is boredom plus power. A model running a long agentic task will occasionally produce a tool call that makes perfect sense within its local context but is catastrophic at the system level. “Clean the tmp directory” that targets /var/tmp instead of your project’s .tmp/. A file_write call that overwrites a config file. An API call to your billing provider because the tool description said “manages account settings.” You will not catch any of this because nothing is logged.
The upgrade move is not to add any controls yet. The first move is pure inventory: open every MCP config, list every tool, and label each one as R (read-only, reversible), W (write, reversible), or D (destructive, irreversible). This takes 30-60 minutes on a typical setup. Without this list, every decision in L1 through L4 is guesswork.
Level 1 — Tool Inventory
At L1 you know what you have. The tool manifest is checked into version control alongside your agent configuration. Every tool has a classification (R/W/D), an owner, and the date it was added. New tools go through a PR that requires the classification to be explicit before merge.
Teams at L1 often think they are further along than they are. The inventory looks rigorous in the PR. But shared MCP servers—especially filesystem and HTTP-fetch servers—expose dynamically scoped capabilities. A filesystem server that points to /home/user today silently gains access to new directories as the user creates them. The manifest shows “filesystem (W)” but the actual scope has grown. This is the L1 trap: static documentation of a dynamic surface.
Practical L1 output looks like this. A file called agent-tools.yaml in your repo root. Each entry: name, server, classification, scope description, date added, reviewer. PR rule: any change to an MCP config file must also update this manifest or the PR is blocked by a CI check. That CI check is three lines of shell that diffs the config against the manifest and exits non-zero on divergence.
Level 2 — Scoped Exposure
At L2 you stop treating all agents as equal consumers of a shared tool pool. Each agent role—customer support, internal research, code generation, data pipeline—gets its own explicit tool allow-list. A customer-support agent can call order_lookup, refund_initiate, and ticket_create. It cannot call db_query, file_write, or send_email directly. These constraints are enforced by the server or middleware, not by the system prompt.
The system-prompt approach is what most teams try first: “You are a customer support agent. Do not use database tools.” This fails because it relies on the model to enforce the constraint. Models are not access control systems. A sufficiently clever prompt injection, a confused multi-step reasoning chain, or a simple model upgrade that changes the fine-tuned safety behaviour can all defeat prompt-level constraints. L2 requires the constraint to be structural.
In a Model Context Protocol setup, structural scoping means running separate MCP server instances per agent role, each configured with a filtered tool list. In function-calling APIs it means generating the tools array at call time from a role-to-tools map, not passing the full registry. Either way the model never receives a tool definition for what it is not allowed to call—it cannot call what it cannot see.
The boundary between L1 and L2 is measurable: at L1, can a customer-facing agent invoke a destructive tool if the model reasons its way there? If yes, you are at L1 regardless of what the system prompt says.
Level 3 — Observed Calls
Scoping reduces blast radius. Observation catches what scoping misses. At L3, every tool invocation produces a structured log event before the call is made and after the result is returned. Minimum fields: timestamp, agent ID, task ID, tool name, arguments (sanitised for secrets), result status, latency in milliseconds.
The “before the call” part matters. Post-call logging misses the case where the tool call itself causes an outage before returning. Pre-call logging also enables a confirm-before-execute pattern for D-classified tools: log the intended call, check it against policy, proceed or block. This is not a full human-in-the-loop approval flow (that would break automation). It is a policy check that can block obviously wrong calls in milliseconds.
Structured JSON logs are non-negotiable at L3. Unstructured log lines like 2026-06-18 12:34 Tool called: file_write look like logging but are not. You cannot write a Datadog monitor, a Kibana query, or a Python anomaly detector against a free-text log. Every field must be a first-class key in a JSON object, and the schema must be stable across agent versions. Changing field names is a breaking change—version your log schema.
The L3 alert baseline to start with: (1) any D-classified tool called more than N times per hour, where N is 2x the historical max; (2) any tool call whose argument includes strings matching secret patterns (API keys, connection strings); (3) any agent task that calls more than 50 tools—this usually signals a loop. Three monitors cover 80% of the real-incident patterns seen in production MCP deployments.
Level 4 — Least-Privilege Audited
L4 is not a state you reach and stay in by default. It requires a maintenance cycle. The definition of least-privilege for tool access is: each agent role has exactly the tools it used in the last 90 days, minus any tools it used only once (candidates for removal) and minus any tools that no active task type requires. Permissions that were added for a one-time project and never revoked are not least-privilege, even if they look harmless.
The quarterly audit is the mechanism. Pull the structured logs from L3. For each agent role, list every distinct tool called in the last 90 days with a call count. Cross-reference against the current allow-list from L2. Any tool on the allow-list with zero calls in 90 days is flagged for review—either the task type is deprecated (remove the tool) or there is a bug in the logging (investigate before deciding). Any tool called from a role that is not on the allow-list is a critical finding: your L2 scoping is broken.
Automating the permission-usage report prevents the audit from being skipped. A cron that runs weekly, compares the L2 allow-list against the L3 usage log, and opens a GitHub Issue or Slack alert when the two diverge costs four hours to build and prevents the drift that makes L4 collapse back toward L2 over time. Human attention is only required when the automated check fires.
One genuine challenge at L4: agents that run rare but critical tasks. An agent that handles end-of-quarter finance exports runs four times a year. Its tool permissions will always look “unused” for 80 of every 90 days. The solution is task-type tagging at the point of invocation. Log every tool call with a task_type field. The audit logic becomes: “zero calls in 90 days AND no scheduled task of this type” rather than just the call count. This requires discipline in tagging but is the only way to avoid false-positive revocations on seasonal workflows.
Self-Assessment: Where Does Your Setup Sit Today?
Work through this table honestly. The highest level where you answer “No” to any question is your current level minus one. You need to resolve every “No” at a level before claiming it.
| Level |
Assessment Question |
Yes / No |
| L0 → L1 |
Can you list every tool exposed to every agent in your system right now, from memory or a live document? |
|
| L0 → L1 |
Is every tool classified as read-only, write, or destructive? |
|
| L1 → L2 |
Is the tool manifest version-controlled and enforced by CI (not just a wiki page)? |
|
| L1 → L2 |
Do different agent roles have different tool subsets—enforced at the server or middleware layer, not just in a system prompt? |
|
| L2 → L3 |
Is every tool invocation logged before it executes, with task ID, tool name, and arguments? |
|
| L2 → L3 |
Are those logs structured (machine-readable JSON), queryable, and retained for at least 90 days? |
|
| L3 → L4 |
Do you have at least one automated alert on anomalous tool-call patterns (volume, call type, argument content)? |
|
| L3 → L4 |
In the last 90 days, has any unused-permission been revoked from any agent role? |
|
| L4 check |
Do you have an automated report that flags divergence between the allow-list and the usage log, on a weekly or monthly schedule? |
|
| L4 check |
Do seasonal or low-frequency agent tasks have a task-type tag that prevents false-positive revocation in the audit? |
|
If you answered “No” to the first two questions, you are at L0. That is not a failure—it is the starting condition for almost every team that deployed an MCP server in the first year of the ecosystem. The inventory exercise that moves you to L1 is the highest-ROI security action available to an agent team right now.
Common Upgrade Mistakes at Each Transition
Teams moving from L0 to L1 frequently build the inventory in a spreadsheet that only one person maintains. When that person is unavailable, the inventory is stale within two sprint cycles. Put the manifest in the repository, not in Notion or Google Sheets. The data format does not matter—YAML, JSON, TOML—but the version-control history and the CI check that compares it to the MCP config are non-negotiable.
The L1-to-L2 mistake: scoping in the system prompt instead of at the server. “Only use tools relevant to the user’s request” is not a scope boundary. Tool call filtering middleware that strips tools from the request before it reaches the model—that is a scope boundary. If you build prompt-only scoping and call it L2, the first adversarial prompt or model upgrade will demonstrate why you were still at L1.
The L2-to-L3 mistake: logging only errors. A tool call that returns a success code but writes unexpected data to a database is not an error from the tool’s perspective. Full-spectrum observability means logging every call, not just the ones that throw. The storage cost of structured JSON tool-call logs is trivial—a busy agent system producing 10,000 tool calls per day generates roughly 50 MB of logs before compression. Store everything.
The L3-to-L4 mistake: the manual quarterly review that gets skipped. The L4 audit works only when it is automated enough to be frictionless. If reaching L4 requires a two-hour meeting every quarter, it will be de-prioritised the moment the team has a delivery deadline—which is always. Automate the report generation. Automate the alert. Reserve the human decision for the exceptional case, not the routine check.
ATGM and MCP Specifically
The Model Context Protocol specification does not mandate governance. It is a transport and capability-advertisement protocol. MCP makes it easy to expose tools; it makes no opinions about who should see which tools, how calls should be logged, or how permissions should expire. That design is intentional—the protocol is meant to be minimal. But it means the governance layer is entirely the operator’s responsibility.
The ATGM maps to MCP’s architecture cleanly. L1 inventory corresponds to the tools/list response—that is your canonical tool registry. L2 scoping corresponds to running separate server processes per role or using an MCP gateway that filters tools/list per client identity. L3 observation corresponds to intercepting tools/call requests at the transport layer before forwarding to the server. L4 auditing is out-of-band process, but it reads from the L3 log and writes back to the L2 allow-list configuration.
If you are building tools for others to browse and use, the WOWHOW tools directory is structured with exactly this kind of capability taxonomy—each tool is scoped, described, and categorised so you can see what it does before connecting it to an agent. For deeper agent infrastructure resources, the full product catalog includes MCP server templates, agent scaffolding kits, and observability starters that implement L2 and L3 patterns out of the box.
Timeline Expectations
For a solo developer or two-person team: L0 to L2 in one focused day. The inventory takes 60-90 minutes. The CI check takes two hours to write and test. Scoping at the server layer takes a half-day if you are using standard MCP servers (filesystem, fetch, database). Total: one eight-hour day to move from zero governance to structural tool scoping.
L2 to L3 takes one sprint (two weeks). Structured logging middleware is the core implementation work. Choosing a log destination (CloudWatch, Loki, Datadog, even a Postgres table for small setups) and writing the ingest code takes most of the time. The three anomaly alerts described above take another day once the log schema is stable.
L3 to L4 takes one quarter to execute the first audit cycle and one sprint to automate the report. The first audit is always manual—you are establishing the baseline of what “normal usage” looks like per agent role before you can automate detection of deviations from it.
Teams with existing DevSecOps practices and a CI/CD pipeline already in place will move faster. Teams that are currently running agents in a notebook with no deployment process will take longer—not because the ATGM steps are harder, but because they will need to establish deployment hygiene alongside the governance work.
A Note on the Risk Gradient
Not every agent deployment needs L4. An agent that only calls read-only tools against non-sensitive data—a research assistant that calls a web search API and a Wikipedia fetch—carries materially lower risk than an agent with database write access and billing API permissions. The model is a gradient: you calibrate target level to the actual risk profile of the tools in scope.
A practical heuristic: if any tool in your allow-list can cause an irreversible state change to user data, financial records, or production infrastructure, target L3 at minimum. If any of those tools can be reached by an agent that accepts arbitrary external input (a user-facing chatbot, a code agent processing PRs, an email-processing agent), target L4. The cost of operating at L4 for a team already at L3 is low. The cost of a critical incident from an under-governed tool is not.
The ATGM is a WOWHOW framework. The five-level structure, the classification scheme (R/W/D), the assessment questions, and the upgrade-move format are original to this publication. Teams building on the framework should cite this post. Practitioners who find gaps or want to extend the model for specific deployment contexts—multi-tenant SaaS agents, healthcare data agents, financial trading agents—should approach each extension by adding constraints to the existing levels rather than adding new levels. The power of a maturity model is comparability across teams and over time; extending by addition preserves that property while expanding the applicability.
Your highest-impact action right now: open your MCP config, list every tool, and write the R/W/D label next to each one. That single exercise, done in the next hour, moves you from L0 to halfway through L1 and gives you the foundation to make every subsequent governance decision with the right information. Visit WOWHOW Pro Vault for agent infrastructure templates that ship with L2 scoping and L3 logging already wired in.
People Also Ask
What is the ATGM framework for AI agent tool governance?
ATGM (Agent Tool-Governance Maturity Model) is a five-level framework created by WOWHOW that maps how well an AI agent deployment controls tool access. Level 0 is the default “connect everything” state with no logging or scoping. Level 4 is least-privilege access with quarterly audits and automated permission-usage reports. Each level has one upgrade move.
How is ATGM different from SOC 2 or OWASP for securing AI agents?
SOC 2 and OWASP were designed for humans operating software, not for software deciding which tools to call autonomously. ATGM addresses three gaps those frameworks miss: a dynamic attack surface (tools added at runtime), an opaque intent chain (no change ticket for agent actions), and compounding blast radius (one agent calling ten tools hitting thirty external services per task).
How long does it take to move from ATGM Level 0 to Level 2?
For a solo developer or two-person team, Level 0 to Level 2 takes one focused eight-hour day. Tool inventory and R/W/D classification takes 60–90 minutes. The CI check that enforces the manifest takes two hours. Server-layer scoping with standard MCP servers takes a half-day. Level 2 to Level 3 (structured logging) takes one two-week sprint.
Why is scoping AI agent tools in the system prompt not enough?
System-prompt scoping relies on the model to enforce access constraints. Models are not access-control systems — a sufficiently crafted prompt injection, a multi-step reasoning error, or a model upgrade that changes fine-tuned behaviour can all bypass prompt-level rules. ATGM Level 2 requires structural enforcement: the model never receives a tool definition for what it is not allowed to call, so it cannot call what it cannot see.
When does an agent deployment need ATGM Level 4 versus Level 3?
Target Level 3 if any tool in your allow-list can cause an irreversible state change to user data, financial records, or production infrastructure. Target Level 4 if any of those tools can be reached by an agent that accepts arbitrary external input — a user-facing chatbot, a code agent processing pull requests, or an email-processing agent. The cost of operating at Level 4 from Level 3 is low; the cost of a critical incident from an under-governed tool is not.
Comments · 0
Beta: comments are stored locally on your device and not visible to other readers.
No comments yet. Be the first to share your thoughts.