The stack
Every choice here had to clear the same bar: free without a credit card, and reproducible by someone following along weeks later. That rules out a lot of otherwise-better options, and it’s the right constraint for learning.
| Layer | We use | Why, in one line |
|---|---|---|
| Language | Python 3.11+ | What the AI ecosystem is written in |
| Package manager | uv | One tool instead of four, and a lockfile |
| API framework | FastAPI | Async, typed, free interactive docs |
| Agent framework | Pydantic AI | Feels like FastAPI; not tied to one model vendor |
| Tool protocol | FastMCP | Makes the tools usable outside our app |
| Model | Gemini | A no-card free tier — see the alternatives |
| Database | Supabase | Free Postgres with pgvector built in |
| Agent host | Render | Free web services, deploys from GitHub |
| Frontend | Vite + React | The frontend most people will port this into |
| Client host | GitHub Pages | Free, and makes CORS real |
The last two host rows are defaults, not requirements — the agent also runs on FastAPI Cloud and the client also runs on Vercel, both free and both verified with this project. See Deploy for the two tracks side by side.
What it is. A Python package and project manager — it replaces pip,
venv, pip-tools, and pyenv with one tool.
Why we chose it. The single most common way a tutorial fails is “it worked
for the author”. uv sync reads pyproject.toml and uv.lock and builds the
exact environment this project was tested with, down to the Python version.
No activate step to forget.
Where it is. app/pyproject.toml, app/uv.lock, app/.python-version —
the deployed application is its own uv project, kept out of the repo root.
cd appuv sync # create the environmentuv run fastapi dev main.py # run something in itWhat it costs. Nothing, open source.
FastAPI
Section titled “FastAPI”What it is. A Python web framework for building APIs.
Why we chose it. Three things matter here: it’s async, which suits waiting
on slow model calls; it validates requests from type hints, which is a free
guardrail; and it generates interactive docs at /docs so you can test your
deployed agent from a browser without writing a client.
Where it is. app/main.py — five endpoints, and that’s the whole API.
What it costs. Nothing, open source.
Pydantic AI
Section titled “Pydantic AI”What it is. An agent framework from the team behind Pydantic (which FastAPI is built on).
Why we chose it. It was explicitly designed to bring the FastAPI feeling to agents, so if you know FastAPI you already know most of it — decorators for tools, type hints for schemas, dependency injection for context. It’s also model-agnostic: switching from Gemini to something else is one line, which keeps the deployment lesson from expiring alongside a model.
We evaluated LangGraph (more powerful, but graphs and nodes are a second architecture to learn), the OpenAI Agents SDK (elegant, but pulls toward a provider with no free tier), and Google ADK (natural with Gemini, but leans on Google Cloud deployment).
Where it is. app/agent/research.py.
What it costs. Nothing, open source.
FastMCP
Section titled “FastMCP”What it is. A Python library for building Model Context Protocol servers.
Why we chose it. MCP’s official Python SDK had a major version bump very recently with renamed core classes; FastMCP is the mature, batteries-included layer and Pydantic AI integrates with it directly. For a tutorial that has to keep working for months, that stability is worth more than being first.
Where it is. app/tools/server.py, mounted at /mcp in app/main.py.
What it costs. Nothing, open source.
See Learn · MCP for why it’s here at all — and where we deliberately didn’t use it.
Gemini
Section titled “Gemini”What it is. Google’s model family. We use it via AI Studio, the developer-facing entry point.
Why we chose it. It has a genuinely usable free tier that doesn’t ask for a credit card, and a token budget large enough for a loop that resends its context every turn. For a room full of people who need their own keys, that’s decisive.
It is not the only free option, though — Cerebras, OpenRouter and Groq all hand out keys without a card, and switching is three environment variables rather than a code change. See Model providers.
Where it is. app/agent/research.py builds the model; app/config.py holds
the key and model name.
What it costs. Free, with limits on requests per minute, requests per day, and tokens per minute. One agent run is 5–10 requests, so a shared key rate-limits a room within minutes. Everyone needs their own.
Supabase
Section titled “Supabase”What it is. Managed Postgres with a REST API, a table editor, and pgvector available out of the box.
Why we chose it. We get a real relational database and vector storage from one free signup, plus a table editor you can put on a projector — watching rows appear during a run is the moment the architecture clicks for most people.
We talk to it over its REST API rather than a Postgres driver. For a workshop that’s the right trade: no driver to install, no connection pool to tune, no IPv6-or-pooler-port surprises on free hosting. It’s just HTTPS.
Where it is. app/db.py, database/schema.sql.
What it costs. Free, but projects pause when database activity stays low across a 7-day window and need a manual resume. You get 90 days to restore a paused project before its backup is dropped.
Render
Section titled “Render”What it is. A hosting platform that deploys from a GitHub repo.
Why we chose it. Free web services with no credit card, deploys on push, a readable build log, and an environment-variables panel that teaches the right habit. It’s boring in the way infrastructure should be.
Where it is. deploy/render.yaml.
What it costs. Free, with real trade-offs: services spin down after ~15 minutes idle and take about a minute to wake, you get a small CPU slice, and the filesystem is ephemeral — anything written to disk is gone on restart.
The small CPU slice is the surprise. It’s fine here because agent work is I/O-bound — you’re waiting on the model anyway — but it would be bad for anything CPU-heavy.
See also FastAPI Cloud, the second agent host — built by the FastAPI team, deploys from GitHub with no config file at all, and free without a card. Shipping the same app to both is the cheapest deployment lesson available.
Vite + React
Section titled “Vite + React”What it is. A build tool and a UI library — the default way to start a frontend today.
Why we chose it. The HTTP calls in this workshop are the same in any framework. What isn’t the same is the code around them: cancelling a poll loop when a component unmounts, not stacking requests when the server is slow. Writing the client in a real framework is the only way to show that honestly, and React is the one most people will be porting this into.
Where it is. client/ — src/api.ts is the backend contract,
src/useConversation.ts is the pattern.
What it costs. Nothing, open source.
GitHub Pages
Section titled “GitHub Pages”What it is. Free static hosting straight from a repo.
Why we chose it. Free, no new signup, and it makes the frontend genuinely cross-origin from the backend — which means the CORS lesson is real rather than theoretical.
Where it is. .github/workflows/deploy-pages.yml publishes this site, the
slides, and the demo client together.
What it costs. Nothing, with soft bandwidth limits you won’t hit.
Vercel is the other free option for this layer, and
it’s worth doing as well as rather than instead of — two frontend origins makes
ALLOWED_ORIGINS concrete in a way one never does.
The honest summary
Section titled “The honest summary”Free tier isn’t a smaller paid tier. It’s a different set of trade-offs: your server sleeps, your database pauses, your model rate-limits, and your disk forgets. You’re trading money for latency and reliability.
That’s a fine trade for a demo or a portfolio project. Know that you’re making it.
Next: Architecture →