style(no-slop): remove every em-dash + banned words across all modules + capstone

Apply the no-ai-slop standard (now binding in AGENTS.md): the em-dash character is
banned outright (restructured, not blind-replaced), plus the banned word/phrase
list (delve, leverage, robust, seamless, truly, unlock, etc.). 0 em-dashes remain
in modules + capstone; the only "robust" left is the planted M10 ai-change.patch
trap. Module H1 titles use a colon separator.

All deliberate teaching devices preserved; labs compile/parse (py/sh/yaml/json);
no junk. AGENTS.md updated with the hard no-slop rules.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfzV5QvtPDz8LJS3Pu5VLT
This commit is contained in:
2026-06-22 23:21:09 -04:00
parent 513d7e7ac8
commit 389ac2e460
99 changed files with 1324 additions and 1315 deletions
@@ -1,4 +1,4 @@
# Module 20 MCP Servers: Giving the AI Hands
# Module 20: MCP Servers, Giving the AI Hands
> **Until now the AI could read and write files in your repo and nothing else. MCP lets it reach
> your real tools, data, and systems (your task tracker, your database, your docs, your APIs)
@@ -23,7 +23,7 @@ Helpful but not required: **Module 16** (containers) and **Module 17** (secrets)
we talk about *where* a server runs and *what it's allowed to touch*. You can read this module
without them.
This is the opener of **Unit 4 Extend the AI into your systems.** Units 13 got the AI safely
This is the opener of **Unit 4: Extend the AI into your systems.** Units 13 got the AI safely
editing your code and shipping it. Unit 4 is about giving it reach beyond the repo.
---
@@ -115,17 +115,17 @@ server to a client," and it's the same skill everywhere.
An MCP server can offer three kinds of things. You'll mostly care about the first:
- **Tools** *actions the AI can take.* A tool is a named function with typed arguments and a
- **Tools** are *actions the AI can take.* A tool is a named function with typed arguments and a
description: `add_task(title)`, `run_query(sql)`, `create_issue(title, body)`. The AI reads the
description, decides to call it, supplies the arguments, and gets a result. This is the "hands"
half of the module title; tools are how the AI *does* things. (Tools can have side effects: they
write to your database, hit your API, change real state. That power is exactly why Module 22
exists.)
- **Resources** *data the AI can read.* Read-only context the server makes available: a file, a
- **Resources** are *data the AI can read.* Read-only context the server makes available: a file, a
database record, a docs page, the contents of a config. Where tools *do*, resources *inform*:
they're how the AI gets eyes on a system, the parallel to "durable memory it can read" from
Module 2, extended past your repo.
- **Prompts** *reusable prompt templates the server offers* for common operations against it (e.g.
- **Prompts** are *reusable prompt templates the server offers* for common operations against it (e.g.
"summarize this incident from these logs"). Useful, but the least-used of the three; don't worry
about them while you're learning.
@@ -279,7 +279,7 @@ is where the idea sticks.
> /home/you/ai-workflow-course/tasks-app/.venv/bin/python -c "import mcp; print('mcp ok')"
> ```
### Part A Connect an existing server (optional warm-up, ~10 min)
### Part A: Connect an existing server (optional warm-up, ~10 min)
This part is **optional**: it proves the plumbing works by connecting a server someone else already
wrote, but it's a warm-up. Parts B/C carry the real lesson on the Python SDK you already installed.
@@ -308,7 +308,7 @@ That's the entire client/server loop, end to end, with zero code you wrote. Now
> will run with your permissions; vetting that is **Module 22's** job, and it's not optional. For
> now, stick to first-party reference servers or the one you write next.
### Part B Build a one-tool server over the tasks-app
### Part B: Build a one-tool server over the tasks-app
1. Have Claude Code (or sub your own agent) copy this module's `lab/tasks_mcp_server.py` into your
`tasks-app` folder, next to `tasks.py` and `cli.py`, and confirm it landed there:
@@ -348,7 +348,7 @@ That's the entire client/server loop, end to end, with zero code you wrote. Now
there's nothing to print and no prompt to return to until a client connects. That waiting *is*
the correct behavior. You don't run it by hand for real; the client launches it.
### Part C Wire it into your agentic tool
### Part C: Wire it into your agentic tool
3. Have the agent write the `tasks` config entry. It already knows both absolute paths (the venv
python it just reported and the server file it just copied), so let it fill them in. Point it at
@@ -381,7 +381,7 @@ That's the entire client/server loop, end to end, with zero code you wrote. Now
`... .venv/bin/python -c "import mcp"` check from the note above against the *exact* path in
`"command"`, then check the tool's MCP logs.
### Part D Watch the AI use its new hands
### Part D: Watch the AI use its new hands
5. In the AI chat, **don't** mention files or `tasks.json`. Ask in terms of the *system*:
@@ -411,8 +411,8 @@ That's the entire client/server loop, end to end, with zero code you wrote. Now
history. No copy-paste, no script you ran by hand, no pasting `tasks.json` into a chat. That's
"hands."
7. (Optional, to feel the discovery point.) Edit the docstring on `add_task` to be vague change it
to just `"""Adds something."""` reload, and try the same request. Notice the AI gets *less*
7. (Optional, to feel the discovery point.) Edit the docstring on `add_task` to be vague; change it
to just `"""Adds something."""`, reload, and try the same request. Notice the AI gets *less*
reliable about choosing the tool. The description is part of the interface; the model reads it to
decide. Restore the good docstring.