AI Agent Autonomy Levels: A Small TypeScript Approval Gate A developer published a TypeScript approval-gate pattern that assigns autonomy levels 0 through 4 to individual tools rather than whole agents, classifying each tool as read, write or irreversible and routing calls to allow, ask or deny accordingly. The reference implementation, run via an AUTONOMY environment variable against the Anthropic SDK, lets reads run freely while irreversible actions like deletion require human approval below level 4. The author argues autonomy is a policy the code enforces, not a trait of the model. An agent with a delete tool and a loose prompt can read “clean up my old entries” as permission. Nothing malfunctions. The message allows that reading and the tool allows the action. What's missing is a rule about when the tool may run. This post continues my series on building agents. The previous one covered MCP https://zahidhasantonmoy.vercel.app/blog/what-is-mcp-model-context-protocol . An agent's autonomy is how much it may do on its own before a human has to approve, review or step in. It is a policy your code enforces, not a trait of the model. No standard defines these levels. This is my own working scale. | Level | Meaning | |---|---| | 0 | No tools. A plain chatbot | | 1 | Read-only tools | | 2 | Writes, each approved by a human | | 3 | Routine writes run alone inside limits, irreversible actions still ask | | 4 | Full autonomy, rarely justified | A level belongs to a tool, not to the whole agent. The same agent can run reads at Level 4 and deletes at Level 2. A read tool changes nothing. A write tool changes something you can undo. An irreversible tool can't be taken back: deleting data, sending a message, moving money. The class comes from the cost of a wrong call, not the tool's name. php flowchart TD A Model requests a tool -- B{Tool risk class} B -- |read| C Run it B -- |write| D{Autonomy level} B -- |irreversible| E{Autonomy level} D -- |1| F Refuse D -- |2| G Ask a human D -- |3 or 4| C E -- |1| F E -- |2 or 3| G E -- |4| C G -- |approved| C G -- |declined| I Send an error result to the model F -- I C -- H Send the result to the model Run it with AUTONOMY=2 npx tsx agent/autonomy.ts and change the value to compare levels. python // agent/autonomy.ts import Anthropic from '@anthropic-ai/sdk'; import { createInterface } from 'node:readline/promises'; const client = new Anthropic ; const rl = createInterface { input: process.stdin, output: process.stdout } ; type Risk = 'read' | 'write' | 'irreversible'; type Decision = 'allow' | 'ask' | 'deny'; const LEVEL = Number process.env.AUTONOMY ?? 2 ; const expenses = { id: 1, item: 'tea', amount: 40 } ; let nextId = 2; const risks: Record