Building agents and MCP servers
In Module 07 you watched the agent loop from the outside. Now you write it: about twenty lines of code, a few well-described tools, and the limits that keep it safe. Then you turn your own system into an MCP server, so every agent from Module 10 can use it.
1. The idea
In code, those four parts are:
- Brain: a model API call with a clear system prompt (Modules 05 and 14).
- Hands: tools, each a name, a description and an input schema, backed by your function (Module 06).
- Loop: call the model; if it asks for tools, run them and send the results back; repeat until it answers.
- Leash: a maximum number of turns, a token or cost budget, read-only tools by default, approval for risky actions, and logs of every step.
Start with the simplest thing that works. Anthropic's advice in Building effective agents is to use a single call or a fixed workflow when the steps are predictable, and a full agent only when they aren't.
2. How it works
Here is the whole loop with the Claude API. The other providers' versions have the same shape.
import anthropic
client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY
def run_agent(task, max_turns=10):
messages = [{"role": "user", "content": task}]
for turn in range(max_turns): # leash: turn budget
reply = client.messages.create(
model="claude-sonnet-5-5", max_tokens=2048,
system=SYSTEM_PROMPT, tools=TOOLS, messages=messages,
)
messages.append({"role": "assistant", "content": reply.content})
if reply.stop_reason != "tool_use": # no tool requested: done
return next(b.text for b in reply.content if b.type == "text")
results = []
for block in reply.content:
if block.type == "tool_use":
output = run_tool(block.name, block.input) # your code, your checks
results.append({"type": "tool_result", "tool_use_id": block.id,
"content": output})
messages.append({"role": "user", "content": results})
raise RuntimeError("Turn budget exhausted") # stop, don't loop forever
3. Try it yourself
The leash: turn budgets
A task needs a certain number of tool calls. Some runs go wrong and repeat themselves. See what the budget does.
Write an MCP server tool
Fill in one tool and get a working MCP server in Python (official SDK, v2). Any MCP client, including all five coding tools from Module 10, can then call it.
4. Why it matters at work
- Design tools for the model, not for your API. Fewer, task-shaped tools ("get_order_status") beat thin wrappers over every endpoint. Clear names, descriptions with examples, and short, useful outputs.
- Return errors the model can act on. "Order A-1042 not found; order numbers look like A-1234" lets it recover. A stack trace doesn't.
- Read-only first. Add tools that change things only when needed, and put approval in front of anything irreversible (sending, paying, deleting).
- Treat tool output as untrusted. A web page or ticket can contain instructions aimed at your agent (prompt injection, Module 18). Your code, not the prompt, enforces permissions.
- Log every turn: the model's request, the tool input and output, tokens and time. You'll need it to debug and to evaluate (Modules 17 and 19).
- Use an SDK once the basics are clear. SDKs give you the loop plus context management, sessions, subagents, tracing and permission handling.
5. Agent SDKs and protocols
Checked against vendor documentation, October 2026.
| SDK | Install | What it gives you |
|---|---|---|
| Claude Agent SDK | pip install claude-agent-sdk | The same agent harness as Claude Code: built-in file and shell tools, hooks, subagents, MCP, permissions, sessions, skills |
| OpenAI Agents SDK | pip install openai-agents | Agents, handoffs between agents, guardrails, sessions, tracing |
| Agent Development Kit (ADK) | see docs | Google's open-source framework for agents and multi-agent systems; model-agnostic |
| Antigravity SDK | pip install google-antigravity | The Antigravity agent runtime in Python: custom tools, MCP, policies and approvals, subagents |
| MCP SDKs | uv add "mcp[cli]" | Build MCP servers (and clients) in Python, TypeScript and other languages |
MCP and A2A: tools vs teammates
6. Remember it
How this hook works: what “Brain, hands, loop, leash” means
What the slogan means, word by word
- “Brain”
- The model and its system prompt. It decides what to do next, but can't do anything by itself.
- “hands”
- The tools: name, description, schema, and your function behind them. They are the only way the agent affects the world.
- “loop”
- Call, run requested tools, return results, repeat, until the model answers without asking for a tool.
- “leash”
- Turn and cost budgets, least-privilege tools, approval for risky actions, and logs. Enforced in your code.
Why this picture fits: the four words are also the four places to look when an agent misbehaves: a bad decision (brain), a confusing tool (hands), a run that never ends (loop), or an action it shouldn't have taken (leash).
The story → the concept
| The assistant | The agent |
|---|---|
| Their judgement | The model + system prompt |
| The keys and logins you give them | Tools (and MCP servers) |
| Working until the job is done | The while-tool-use loop |
| "Ask me before spending over £100" | Approval for risky tools |
| "Stop by 5pm either way" | max_turns, token budget |
| Their notebook of what they did | Logs and traces |
| Calling another firm's assistant | A2A |
Watch it on an example
- Brain: "Where is order A-1042?" → the model decides it needs the order status.
- Hands: it calls
get_order_status(order_id="A-1042"); your function queries the database read-only. - Loop: the result goes back; the model answers "Out for delivery, arriving today."
- Leash: when a customer asks for a refund, the
issue_refundtool waits for a human to approve.
The trap it saves you from
Shipping the brain, hands and loop without the leash: an agent that loops forever, spends without limit, or acts on instructions hidden in a web page.
It still works when…
You use an SDK: it provides the loop, and you still choose the brain, design the hands and set the leash (allowed tools, permission mode, budgets).
7. Common mistakes
8. Hands-on lab (roadmap week 18)
- Write the loop yourself with two read-only tools (for example: search notes, read a note). Cap it at 8 turns and log every step.
- Break it on purpose: a tool that errors, a vague tool description, a task that can't be done. Watch how the agent reacts and improve the tool messages.
- Rebuild it with an SDK (Claude Agent SDK or OpenAI Agents SDK) and compare: what did the SDK add for free?
- Build an MCP server exposing one tool from your own system, test it with the MCP Inspector, then connect it to your coding tool.
- Add the leash: one tool that changes something, gated by an approval step.
9. Self-check quiz
When does the agent loop finish normally?
stop_reason is no longer "tool_use"; the model has given its answer.Where should "the agent may not delete records" be enforced?
Where should a stdio MCP server write its logs?
Your agent needs to hand a task to another company's agent. Which protocol fits?
10. Go deeper
| Resource | Time | Why |
|---|---|---|
| Building effective agents (Anthropic) | 30 min | Workflows vs agents, and when to use which. |
| Writing effective tools for agents (Anthropic) | 25 min | How to design, test and improve tools. |
| Build an MCP server (modelcontextprotocol.io) | 45 min | The official tutorial, in several languages. |
| Agent SDK overview (Claude) and Agents SDK (OpenAI) | 1 h | The two SDKs in the code tabs above. |
| A2A protocol | 20 min | Agent Cards and how agents hand off tasks. |