You watched the eight-minute ADK video, opened your terminal, and hit the part every video skips: where does this project actually live, and how does Google ADK find your agent? That gap is why so many first agents never start. This Google ADK tutorial closes it — you’ll go from an empty folder to a running agent, with the setup gotchas spelled out instead of glossed over.
Most AI agents tutorials skip straight to the code and leave you stuck at the terminal. By the end of this one you’ll have a working agent you can chat with in your browser, a version that checks its own work, and one that reaches into an MCP server for real tools.
- ADK is a code-first Python toolkit: you write a
root_agentwith an instruction and tools, and ADK runs the loop for you. - The setup that actually works:
uvfor the environment,adk createfor the layout, a Gemini key in.env, thenadk web. - You’ll go beyond “hello agent”: a self-correcting validation loop and a live MCP connection, not just a single prompt.
What Google ADK Is — and Where It Fits
Google ADK (Agent Development Kit) is an open-source Python toolkit for building AI agents, and it hit version 2.0 GA in 2026. The idea is simple: you describe an agent as a normal Python object — a name, a model, an instruction, and a list of tools — and ADK runs the agent loop, the tool calling, and the session state for you.
That diagram is the whole mental model. You own the box on the left; ADK owns the runtime in the middle. Where it fits against other frameworks comes down to taste: ADK is the most opinionated of the popular options, with a built-in dev UI and first-class Gemini support, where LangGraph, CrewAI, and AutoGen trade that polish for more control or a different agent model. If you’re already in the Google ecosystem, ADK removes the most setup friction. If you want to understand what any of them do underneath, that’s a plain Python loop — which is exactly what an AI agent is once you strip the framework away.
Setup That Actually Works
Here is the setup the videos rush past. I use uv (a fast Python package manager) because it creates the environment and installs in seconds, but plain pip works the same way.
# 1. Create and activate a virtual environmentuv venvsource .venv/bin/activate # Windows: .venv\Scripts\activate# 2. Install ADKuv pip install google-adk
You need Python 3.10 or newer. With ADK installed, let it scaffold the project for you instead of guessing the layout:
adk create my_agent
That command creates a small package — the layout that trips up beginners:
my_agent/├── __init__.py # makes the folder importable; imports the agent├── agent.py # your agent lives here, in a variable named root_agent└── .env # your API key, loaded automatically
Now the one step the video left open: the API key. Create a free key in Google AI Studio, then put it in my_agent/.env — inside the package, not next to it:
GOOGLE_GENAI_USE_VERTEXAI=FALSEGOOGLE_API_KEY=your_key_here
ADK loads that .env automatically when the agent runs, so you never call load_dotenv yourself. The USE_VERTEXAI=FALSE line tells ADK to use the simple AI Studio key path rather than a full Google Cloud project — that one line is the difference between “works in five minutes” and “fights IAM for an hour.”
Your First Agent: Instruction, a Tool, and the Web UI
Open my_agent/agent.py and replace it with a real agent. A tool in ADK is just a Python function with a docstring — ADK reads the docstring and type hints to tell the model what the tool does.
from google.adk.agents import Agentdef get_exchange_rate(base: str, target: str) -> dict:"""Get the exchange rate between two currencies.Args:base: The 3-letter code to convert from, e.g. "USD".target: The 3-letter code to convert to, e.g. "INR"."""rates = {("USD", "INR"): 83.4, ("USD", "EUR"): 0.92}rate = rates.get((base, target))if rate is None:return {"status": "error", "message": f"No rate for {base} to {target}."}return {"status": "success", "base": base, "target": target, "rate": rate}root_agent = Agent(name="currency_agent",model="gemini-2.5-flash",description="Answers questions about currency exchange rates.",instruction="Convert currencies for the user. Always call get_exchange_rate; never invent a rate.",tools=[get_exchange_rate],)
Two details matter. The variable must be named root_agent — that exact name is how ADK discovers your agent. And returning a dict with a status field is the ADK convention: it gives the model a clean signal for success or failure. Now run the dev UI from the parent folder (the one that contains my_agent, not inside it):
adk web
Open http://localhost:8000, pick my_agent from the dropdown, and ask “What’s 100 USD in INR?” You’ll watch the model call your function and answer 8,340 — and the web UI shows the tool call and its result, which is the fastest way to see what your agent is actually doing.
Add a Validation Loop (an Agent That Self-Corrects)
A single agent answers once. The pattern that makes ADK worth learning is the LoopAgent — a write → review → fix → repeat loop where one agent produces work and another checks it until it passes. This is how you get output that corrects itself instead of shipping the first draft.
from google.adk.agents import Agent, LoopAgentfrom google.adk.tools import ToolContextdef exit_loop(tool_context: ToolContext) -> dict:"""Call this only when the draft is approved, to stop the loop."""tool_context.actions.escalate = True # signal: we're donereturn {"status": "approved"}writer = Agent(name="writer",model="gemini-2.5-flash",instruction="Write or revise a one-line product tagline using any feedback in the session.",output_key="draft", # saves the result into shared state)critic = Agent(name="critic",model="gemini-2.5-flash",instruction=("Read the latest draft. If it is punchy and under 10 words, call exit_loop. ""Otherwise reply with one concrete improvement."),tools=[exit_loop],)root_agent = LoopAgent(name="tagline_refiner",sub_agents=[writer, critic],max_iterations=4,)
Here is the mechanism. The writer saves its draft to shared session state via output_key; the critic reads it and either approves or returns a fix; the loop repeats. The loop ends when the critic calls exit_loop — which sets escalate = True — or when max_iterations is hit. That max_iterations guard is not optional: without it, a critic that’s never satisfied loops forever and burns tokens. I cap every loop agent, every time.
The first time I built one of these, I forgot the output_key and the critic kept reviewing an empty draft. If your loop behaves strangely, check that each agent is reading and writing the same state key — that’s the usual culprit.
Connect It to MCP Servers (What the Video Teased)
The breakout video ended on “next: connecting to MCP servers” and stopped. Here’s that step. MCP (Model Context Protocol) is a standard way to give an agent prebuilt tools — file access, GitHub, a database — without writing each integration yourself. If the term is new, the complete guide to MCP servers covers the why; here we just plug one in.
ADK connects through McpToolset. This example wires in the official filesystem server so your agent can read local files:
from google.adk.agents import Agentfrom google.adk.tools.mcp_tool import McpToolset, StdioServerParametersfilesystem = McpToolset(connection_params=StdioServerParameters(command="npx",args=["-y", "@modelcontextprotocol/server-filesystem", "./project"],),tool_filter=["read_file", "list_directory"], # expose only what you need)root_agent = Agent(name="file_agent",model="gemini-2.5-flash",instruction="Help the user read and list files in their project folder.",tools=[filesystem],)
The tool_filter is the part I’d insist on. An MCP server can expose dozens of tools, and every tool definition costs tokens on every request — so I filter down to the two or three the agent actually needs. Run adk web again and your agent can now list and read files, using tools you never had to write.
Quick Recap
Everything you just built, in five points:
- Setup:
uv venv→uv pip install google-adk→adk create my_agent→ key in.env→adk web. - A tool is a Python function with a docstring; the agent variable must be
root_agent. adk webgives you a local chat UI and a live view of every tool call.LoopAgentadds a writer/critic self-correction loop, always capped withmax_iterations.McpToolsetplugs in prebuilt MCP tools — filter them down to save tokens.
Conclusion
You went from an empty folder to a running Google ADK agent, then added a self-correcting loop and a real MCP connection — the two steps most first tutorials never reach. ADK’s job is to handle the plumbing so you spend your time on the instruction and the tools, which is where an agent’s quality actually lives.
Before you go, the four mistakes that account for most “it won’t run” messages:
- Agent doesn’t appear in
adk web: you ran it from inside the package — run it from the parent folder. - “Where does the project live?“: anywhere you like, as long as it’s a package with
__init__.pyand aroot_agentinagent.py. - Key errors: the
.envmust sit inside the agent package, and keepGOOGLE_GENAI_USE_VERTEXAI=FALSEfor the AI Studio path. - Behavior changed overnight: you didn’t pin the model — set
model=explicitly.
What’s the first tool you’d give your ADK agent — a database query, a web search, a file reader? Tell me in the comments; I’m collecting the ones people reach for first.
Read next: The AI Agent Loop in Python — build the exact loop ADK runs for you, by hand, so the framework holds no mysteries.








