Lesson 1 of 6 · 15 min · Checked on 10 October 2026
Agent SDK: building your own agent
By the end of this lesson you will be able to:
- Tell Claude Code in the terminal apart from the same engine called from a program of your own
- Install the Agent SDK in Python and run a minimal agent that prints its result
- Limit tools, permissions, turns and spending in the code itself
- Recognise codex exec and not confuse it with the OpenAI Agents SDK
Ana has a small online shop in Velas, on the island of São Jorge, selling cheese and sweets from the island. Every morning she exports the overnight orders to a file and spends half an hour copying them into a list. You have already asked Claude Code to do this by hand, and it works. But Ana does not want to open the terminal at seven in the morning. She wants a program that does it on its own.
The concept: the same engine, another steering wheel
In the terminal, Claude Code is a conversation: you ask, it proposes, you approve. The engine underneath always does the same loop: it reads, decides, uses a tool, looks at the result and repeats until it is done.
The Agent SDK gives you that engine inside a program of your own, in Python or TypeScript. The request, the tools and the limits are now written in the code. So is what to do with the answer: save it to a file, add it to a log, throw it away.
The important difference is that nobody is watching. In the terminal, you are the brake. In a program, the brakes have to be written down.
Two realistic uses:
- an agent that reads the shop's orders file and writes the list for the day;
- an agent that, every morning, compares a page with yesterday's and summarises what changed (you build this one in lesson 05).
Watch out
In a program, whatever you allow happens without a question. Always start with an agent that has no tools: your code reads the file and hands it the text. Giving it reading, writing, commands or network is your decision, one at a time.
How it is done today: the smallest program
This is how it looks on 6 October 2026; your screen may differ. Look for the button with the same name. Guide: code.claude.com/docs/en/agent-sdk/quickstart.
You need Python 3.10 or newer. In a new folder, create a virtual environment and install the package:
python3 -m venv .venv
source .venv/bin/activate
pip install claude-agent-sdk
On Windows, create the environment with py -m venv .venv and activate it with .venv\Scripts\Activate.ps1. The package already comes with the Claude Code engine, so in most cases you do not need to install anything else.
Now the program, in a file called agente.py (“agent.py”):
import asyncio
from pathlib import Path
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
encomendas = Path("encomendas.txt").read_text(encoding="utf-8") # your code does the reading
opcoes = ClaudeAgentOptions(
cwd=".", # the agent's starting folder (not a sealed box)
disallowed_tools=["*"], # no tools: it receives text, returns text
permission_mode="dontAsk", # whatever would need authorisation is refused
max_turns=5, # cap on turns
max_budget_usd=0.50, # cap on the spending of this run
)
try:
async for msg in query(
prompt="Make a list of these orders: customer, product, quantity. Do not invent anything.\n\n" + encomendas,
options=opcoes,
):
if isinstance(msg, ResultMessage):
print(msg.result)
print("End:", msg.subtype, "| estimated cost:", msg.total_cost_usd)
except Exception as erro:
print("Stopped with an error:", erro)
asyncio.run(main())
Run it with python agente.py. The agent sends messages while it works; this program ignores them and only prints the last one, the ResultMessage, with the answer, the reason it ended and the estimated cost.
The brakes, line by line
disallowed_tools=["*"]takes every tool away from the agent: it receives text and returns text, and your code is what reads and saves files. A name on its own, like"Bash", takes away only that one.disallowed_toolsis what forbids;allowed_tools, which this example does not use, only approves without asking and forbids nothing.cwdis the folder where the agent starts, not a sealed box. If you gave it the Read tool, it could read any file in the folder, including a.envwith the key; that is why the file goes in the request.permission_mode="dontAsk"refuses everything that would need authorisation, instead of waiting.max_turnsandmax_budget_usdstop the agent. When one of them reaches its limit, the reason it ended iserror_max_turnsorerror_max_budget_usd, and the SDK raises an error right after. That is why the loop is inside atry.
Guide: code.claude.com/docs/en/agent-sdk/permissions.
Tip
The cost the program prints is an estimate made on your computer. The real bill is in the provider's console. Use the program's number to compare days, not to invoice anyone.
The key and the spending cap
The SDK needs an API key in the ANTHROPIC_API_KEY variable. Keep it in .env, outside Git, as in lesson 1/06. The SDK does not read .env on its own: make sure your program loads it before it calls the SDK.
The documentation is clear: a program made for other people uses an API key, not the login of your claude.ai account.
max_budget_usd stops one run, but it is an approximate brake: it counts estimated costs and is only checked between turns, so a run can go slightly over the amount. The spending limit in the provider's console, which you set in lesson 1/06, stops the month. You need both. Amounts depend on the model and the plan: see the Current state page.
And on the OpenAI side?
The shortest path is codex exec "request": it runs Codex without a conversation and prints the final answer on the screen. By default, it can only read. For programs there is also the Codex SDK, in Python (pip install openai-codex) and TypeScript. Guide: learn.chatgpt.com/docs/non-interactive-mode.
Do not confuse it with the OpenAI Agents SDK (package openai-agents). That is something else: a library for building agents from scratch with OpenAI models, without the Codex engine.
Tip
Before you write code, try the request in the terminal with claude -p "request" or codex exec "request". If the answer is no good in the terminal, it will not be any good inside a program either.
Exercise
How I know it worked on the first run you get the list of the three orders, the reason success and an estimated cost. On the second, the agent says it cannot delete, and encomendas.txt is still there.
If it didn't work
ModuleNotFoundError: No module named 'claude_agent_sdk': the virtual environment is not active. Activate it and run again.- “Not logged in” or “Invalid API key”: the
ANTHROPIC_API_KEYvariable is not set in the terminal where you run the program. pipsays it cannot find the package: check withpython --versionthat you have 3.10 or newer.- The file was deleted: check that
disallowed_toolshas"*", spelled like that, in quotes, and that you did not usebypassPermissions.
Videos
A crash course on the Claude Agent SDK: what it is, how it differs from the client SDK, a first agent, a receipt processor and remote agents.
Test what you learned
Corrections to this lesson (1)
- : After a second external review: the example no longer gives the agent the Read tool (with it, it could read any file in the folder, including a `.env` with the key); your code reads `encomendas.txt` and passes the text in the request, and the agent has no tools. `cwd` is now described as the starting folder, not as a sealed box. `max_budget_usd` is an approximate brake. The correct quiz option and «If it did not work» follow the new example.