Deck: mcp-factory-intro-deck.html · 14 slides · ~12 minutes at a steady pace (plus Q&A).
How to use this: one entry per slide, in order. The Cue line is a rough timing/intent marker; the paragraph beneath it is what to say — paraphrase it, don't read it. Advance with the arrow keys (or number keys 1–9 to jump). Press O in the deck for the slide overview, F for fullscreen.
On screen: MCP Factory
Cue: ~45s · warm open
MCP Factory is scaffolding for building MCP servers. If you've ever wired an API into an AI assistant by hand, you know the boilerplate repeats every time — HTTP client, response formatting, tool registration. MCP Factory turns that repetition into a factory line: a clean, SOLID foundation where every API you add is a self-contained "plugin." Drop the plugin in, and its tools appear automatically in Cursor, Claude Desktop, or any MCP client — with zero changes to existing code. Today I'll show what it is, how it's built, and the exact repeatable process for spinning up a brand-new MCP.
On screen: Every new API means the same wiring — again
Cue: ~50s
Quick context. MCP — the Model Context Protocol — is the open standard that lets an AI agent call tools and read data through a simple interface. It's great, but here's the catch: every server repeats the same plumbing. An async HTTP client. Try/except error handling. Turning JSON into readable Markdown. Registering each tool so the agent can discover it. You rewrite that for every API. MCP Factory's whole premise is on the right: one API becomes one plugin. The framework owns the repetitive plumbing; you write only what's genuinely specific to your API. That's the shift — from re-plumbing to plugging in.
On screen: An extensible MCP server, ready to be extended or forked
Cue: ~55s
So what actually ships? Four things worth knowing. One — the architecture: every API is a plugin folder under services/, holding its own config, HTTP client, formatter, validation, and tools. Nothing leaks between services. Two — it's built on FastMCP and Python 3.13, async httpx for I/O, stdio transport, managed with uv. Three — it comes with two reference services on purpose: NASA's APOD, a classic REST API, and Code Guardian, a local code scanner — proving the pattern works for HTTP calls and local logic. Four — you can fork the whole thing as a template: rename it, delete the sample, and you've got your own clean MCP scaffold.
On screen: Add a plugin. The tools appear. Existing code never changes.
Cue: ~50s · the "aha"
This is the one slide to remember. On the left: plugins — APOD, Weather, and a new one you're adding — all feed into a single ServiceRegistry. The registry collects them and applies them to the FastMCP server, which exposes every tool to every client. On the right is the punchline in code: to light up a whole new API, you import your service and add one line — registry.add(YourService()). That's it. You never touch the registry, the server loop, or any other service. That's the Open/Closed Principle in the wild: the system is open to extension but closed to modification. New capability, zero risk to what already works.
On screen: From launch command to live tools
Cue: ~55s
Here's the whole machine in one line. main.py is a thin entry point. It hands off to server.py, which builds the FastMCP instance and a ServiceRegistry. The registry holds the plugins; each plugin's register() wires its tools onto FastMCP, which then talks to MCP clients. Underneath, the boot runs in four phases: Import the plugin classes, Build the registry by adding each service, Apply them all — which calls every plugin's register — and finally Serve the stdio loop. The key insight for extending it: when you add a new API, you only touch phases one and two. Apply and Serve are generic; they never change. That's why adding a service is safe and boring — exactly what you want in infrastructure.
On screen: Small contracts you inherit, extend, and plug in
Cue: ~55s
Four small contracts do all the load-bearing work. BaseAPIClient — an abstract class; you subclass it and implement one method, fetch, which returns a dict or None and never throws. BaseFormatter — also abstract; implement format, a pure function that turns data into a Markdown string, with no I/O. ServicePlugin — this one's a Protocol, structural typing: any class with a register(mcp) method counts, no inheritance needed. And ServiceRegistry — the little factory that collects plugins and applies them. Notice how thin these are. A plugin is asked for exactly one method and nothing more — that's Interface Segregation — and any client can stand in for any other, which is Liskov. Small contracts, big leverage.
On screen: Five small files, one clear job each
Cue: ~50s
Open any service and you'll always see the same five files — that predictability is the point. config.py: constants only — base URL, timeout, and the API key loaded from an environment variable, never hardcoded. client.py: the one and only place HTTP happens; it returns a dict or None. formatter.py: a pure function, data in and Markdown out, trivially testable because it does no I/O. validation.py: optional — date checks, ID checks — so your tools stay thin. And init.py: the service class that composes the client and formatter and defines the actual tools inside its register method. Single Responsibility, file by file: if the output format changes, you know exactly which file to open.
On screen: Eight steps to a new MCP service
Cue: ~60s · the centerpiece
This is the recipe — memorize the shape, not the details. One: make a folder under services/. Two: add config — URL, key from an env var, timeout. Three: the client, extending BaseAPIClient. Four: the formatter, extending BaseFormatter. Five: the service class with your tools inside register. Six: register it — that one line in server.py, highlighted in amber because it's the only existing file you touch. Seven: tests, unit and end-to-end. Eight: uv run pytest -v. For a simple REST API this is a 30-to-60-minute job. And crucially — steps one through five and seven all create brand-new files. The blast radius on existing code is a single line.
On screen: Validate → fetch → format → return
Cue: ~55s
Zoom into one tool call. First, the agent chooses the tool by reading its docstring — so the docstring is a real API surface, not a comment. Write it for the model. Then the tool body follows a fixed rhythm: validate the input and bail out with a friendly string if it's wrong; call client.fetch, which gives you a dict or None; if None, return an error message; otherwise hand the data to format and return the Markdown. The iron rule, bottom-left: a tool always returns a string and never raises. The agent should get a helpful message, never a stack trace. And one distinction to keep straight — a tool is an action the agent calls; a resource is read-only reference data it reads at a URI, like a curated list.
On screen: Copy the template, fill the TODOs
Cue: ~45s
You don't write those five files from a blank page. The repo ships templates/service_template/ — the exact same five files, pre-stubbed with TODO markers, correct imports, and the right method signatures. So the real workflow is: cp -r the template into a new service folder, then go file by file replacing TODOs and renaming the Template classes to your own. Set your URL and env var in config, implement fetch, implement format, add validation if you need it, and define your tools in the service class. Then the two-line hookup in server.py and uv run pytest. You're editing a working skeleton, not architecting from scratch — that's what keeps it a 30-minute task.
On screen: Tested at two levels, always green
Cue: ~45s
Two levels of testing keep the factory trustworthy. Unit tests hit each module in isolation, with HTTP mocked by respx so there's never a real network call — you test the client's success and failure paths, the formatter's output, and your validation. End-to-end tests boot a real FastMCP-plus-registry-plus-service stack and call your tools through the actual MCP interface; that suite is the contract test for "no breaking changes." The gate is simple: uv run pytest -v, and everything — old and new — has to be green before you merge. If it's green, the external interface is intact and you can ship.
On screen: Fork it as a template for a brand-new MCP
Cue: ~55s
Beyond adding a service, you can fork the whole repo as the seed for your own MCP product. Four moves: rename the package and fix imports; update the project name and SERVER_NAME; delete the APOD sample and its tests; then build your first real service with the same 8-step process. Everything reusable — base classes, registry, server wiring, entry point, and the test harness — you inherit for free. The pattern travels: a Weather MCP wrapping OpenWeather, or a database MCP over Postgres where you add a sibling BaseQueryClient. And don't assume it's only for REST — Code Guardian, the second bundled service, scans local files with no external API at all. Same plugin-and-registry shape, different guts.
On screen: Two worked examples in the box
Cue: ~45s
The best documentation is the two services that ship with it. NASA APOD is the canonical reference — a clean REST plugin with three tools (today's photo, by-date, random) and one resource, that curated list of famous space dates. It's the thing you copy when your API looks like a normal REST call. Code Guardian is deliberately different — five tools that scan a local codebase for secrets, OWASP-style vulnerabilities, quality and style problems, and known CVEs through an analyzer registry backed by OSV.dev. No external REST call at its core. Having both in the box is intentional: one proves the HTTP path, the other proves local logic, and together they show the plugin pattern generalizes well past "wrap an API."
On screen: Copy · fill 5 files · add 1 line · test · tools appear
Cue: ~50s · close
Let me collapse the whole thing into one sentence: copy the template, fill in five files, add one line, run the tests, and your tools go live in every MCP client. That loop is the product. Three things to take with you. It's SOLID by design — every file has one job, and new work only extends the system, it never rewrites what already works. It's built for AI agents — the CLAUDE.md, the Cursor rules, and the templates mean a coding agent can scaffold a correct service almost unattended. And it's yours to fork — there's a production-ready MCP scaffold hiding inside a NASA photo demo. From here, jump into the docs site: the architecture, the step-by-step guides, and the two reference services in full detail. Thank you.
Estimated speaking time: ~11 min 55s across the 14 slides. Trim slides 5, 6, and 12 first if you need to come in under 10 minutes.