fix(testing/ci/tooling): consistent unittest, venv guidance, runnable lab commands
- #9: standardize the test chain on stdlib unittest (nothing-to-install, which keeps M13's claims true and its planted bug intact). Aligned M5/M14/M16 prose, M14 lab/test_tasks.py, and ci/gitlab starters; ruff stays the only pip install. - #20: add venv / PEP 668 / which-python guidance to M20 (+ M14/M15 local installs); point MCP config at the venv's absolute python. - #21: replace M21 Part D's empty `git diff HEAD~1` with `git log -p` (no .gitignore added — device preserved). - #22: add a dependency-install step before M23's green baseline on a fresh clone. - #23: M24 reviewer/triage now tolerate code-fence-wrapped JSON (stdlib only); feature.patch trap untouched. - #28: fix M27 Part D CI snippet path (working-directory) and require the gate to target a varying candidate; swapped_model regression kept as the fixture. Closes #9 Closes #20 Closes #21 Closes #22 Closes #23 Closes #28 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:
@@ -239,10 +239,40 @@ is the one that lands the concept.
|
||||
- Your agentic coding tool from Module 4, which is the **MCP client**. Find, in its docs, *where it
|
||||
reads MCP server configuration* and *how it shows that a server is connected* (often a list of
|
||||
connected servers or available tools).
|
||||
- Python 3.10+ and the official MCP Python SDK: `pip install "mcp[cli]"`.
|
||||
- Python 3.10+ and the official MCP Python SDK, installed into a virtual environment — read the
|
||||
**Python packages and which `python`** note just below *before* you run `pip`.
|
||||
- The starter files in this module's `lab/` folder: `tasks_mcp_server.py` and
|
||||
`mcp-config-example.json`.
|
||||
|
||||
> **Python packages and which `python`.** This lab's one dependency is the MCP SDK, and *how* you
|
||||
> install it decides whether the server ever connects. Two things bite people:
|
||||
>
|
||||
> - **PEP 668 ("externally-managed-environment").** On modern Debian/Ubuntu and Homebrew Python, a
|
||||
> global `pip install` is refused on purpose. The clean fix is a virtual environment per project:
|
||||
>
|
||||
> ```bash
|
||||
> cd ~/workflow-course/tasks-app
|
||||
> python3 -m venv .venv # one-time
|
||||
> source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||
> python3 -m pip install "mcp[cli]"
|
||||
> ```
|
||||
>
|
||||
> (If you'd rather not manage a venv: `pipx`, or `pip install --break-system-packages` — but a venv
|
||||
> is the clean default and keeps this lab's dependency out of your system Python.)
|
||||
> - **The install interpreter must match the config's launch command.** Your MCP client starts the
|
||||
> server by running the `"command"` in its config — *not* your activated shell — so activating a
|
||||
> venv does nothing to help the client find the SDK. You must point `"command"` at the venv's
|
||||
> **absolute** python path (e.g. `~/workflow-course/tasks-app/.venv/bin/python`, or
|
||||
> `...\.venv\Scripts\python.exe` on Windows). If they don't match, the server dies on `import mcp`
|
||||
> and your tool just says "not connected" with no obvious reason — the exact failure this lab is
|
||||
> about avoiding.
|
||||
>
|
||||
> Before wiring anything, verify with the *same* interpreter the config will launch:
|
||||
>
|
||||
> ```bash
|
||||
> ~/workflow-course/tasks-app/.venv/bin/python -c "import mcp; print('mcp ok')"
|
||||
> ```
|
||||
|
||||
### Part A — Connect an existing server (warm-up, ~10 min)
|
||||
|
||||
Before building anything, prove the plumbing works by connecting a server someone else already
|
||||
@@ -291,8 +321,8 @@ That's the entire client/server loop, end to end, with zero code you wrote. Now
|
||||
2. Sanity-check it starts. From inside `tasks-app`:
|
||||
|
||||
```bash
|
||||
pip install "mcp[cli]" # once
|
||||
python tasks_mcp_server.py # it will sit there waiting for a client — that's correct
|
||||
python3 -m pip install "mcp[cli]" # into the venv from the note above, once
|
||||
python tasks_mcp_server.py # it will sit there waiting for a client — that's correct
|
||||
```
|
||||
|
||||
It looks like it's hanging. It isn't — a stdio server waits for a client on its stdin/stdout.
|
||||
@@ -301,20 +331,26 @@ That's the entire client/server loop, end to end, with zero code you wrote. Now
|
||||
### Part C — Wire it into your agentic tool
|
||||
|
||||
3. Open `lab/mcp-config-example.json`. Copy the `tasks` entry into wherever your tool reads MCP
|
||||
config, and replace the path with the **absolute** path to your `tasks_mcp_server.py`. (Use
|
||||
`python3` or a venv's python if that's what runs the SDK on your system.)
|
||||
config. Set `"command"` to the **absolute path of the python that has `mcp` installed** — the venv
|
||||
python from the note above, *not* a bare `python` — and set `args` to the **absolute** path to
|
||||
your `tasks_mcp_server.py`:
|
||||
|
||||
```json
|
||||
"tasks": {
|
||||
"command": "python",
|
||||
"command": "/ABSOLUTE/PATH/TO/workflow-course/tasks-app/.venv/bin/python",
|
||||
"args": ["/ABSOLUTE/PATH/TO/workflow-course/tasks-app/tasks_mcp_server.py"]
|
||||
}
|
||||
```
|
||||
|
||||
(On Windows the venv python is `...\.venv\Scripts\python.exe`.) A bare `"command": "python"` is the
|
||||
single most common reason the server "won't connect": the client launches whatever `python` is on
|
||||
*its* PATH, which is usually not the interpreter that has the SDK.
|
||||
|
||||
4. Reload your agentic tool and confirm it shows the `tasks` server **connected**, with `list_tasks`
|
||||
and `add_task` among its available tools. If it doesn't connect, the usual culprits are a wrong
|
||||
path, the wrong `python`, or the SDK not installed for that interpreter — check the tool's MCP
|
||||
logs.
|
||||
path, the wrong `python`, or the SDK not installed for that interpreter — re-run the
|
||||
`... .venv/bin/python -c "import mcp"` check from the note above against the *exact* path you put
|
||||
in `"command"`, then check the tool's MCP logs.
|
||||
|
||||
### Part D — Watch the AI use its new hands
|
||||
|
||||
|
||||
Reference in New Issue
Block a user