· about 30 minutes · runs on ubuntu-26.04-claude · unrated
An unrated lab. It runs on your machine with no account and no network, and everything about it — the faults, the checks, the hints and the reference solution — is in the repository. An attempt on it is recorded on your profile and never moves a rating: only rated labs do. Rated and unrated labs.
~/bin/ask-handbook answers questions from the team handbook: Claude Code, in ~/handbook-bot,
searches it through the docs MCP server that the repository's .mcp.json declares — edition 3,
the current one. The server needs the handbook service's key, which the job reads from
~/.config/handbook/env.
People keep getting last year's answers: credentials rotated yearly by whoever is on call, deploys
encouraged on Friday afternoons. The .mcp.json in the repository is right; everyone has checked.
While they were looking, someone also noticed the service key sitting in that same file, committed.
The job's JSON result is ~/handbook.json.
This lab runs in a container, as learner with sudo. claude here is the real Claude Code
2.1.270, talking to a scripted model on this machine; it starts the MCP server for real.
What is expected, and graded:
.mcp.json is the only place a docs server is defined for this project.This lab runs in a container — Docker or Podman, no VM — so there is no boot to survive: the checks run once, against the state you left.
| Check | Objective |
|---|---|
| 01_answers_come_from_the_current_edition | Find which of Claude Code's MCP scopes a server's definition comes from |
| 02_one_docs_server_defined | Find which of Claude Code's MCP scopes a server's definition comes from |
| 03_the_key_is_not_in_the_repository | Keep an MCP server's secret out of the repository that configures it |
Where the lab's hints send you, level by level, as you ask for them (h, then l opens a journal section in the TUI).
3 questions on the same topic, in the lab's Theory tab. They never affect the lab's grade. Here they are, to answer in place:
A server named docs is defined in a project's .mcp.json and, for that project, in the local scope. Which definition does Claude Code use in the project?
The local one: local beats project, and project beats user
For a name defined in several scopes the most personal wins for that project: local, then project, then user. claude mcp list reports the conflict and names both commands; claude mcp get shows which scope the one in effect came from.
https://code.claude.com/docs/en/mcp
Where does `claude mcp add` store a server added without a --scope option?
In ~/.claude.json, under the current project's entry: the local scope
The default scope is local: private to you, for this project, kept in ~/.claude.json and never committed. --scope project writes .mcp.json; --scope user makes it available in every project.
https://code.claude.com/docs/en/mcp
A key was committed in .mcp.json last month. It is replaced by ${DOCS_API_KEY} today and committed. What remains to be done?
Rotate the key at the service: it is still in the repository's history and every clone
Removing a secret from the current tree does not remove it from history, forks, clones or backups; git log -S shows the commit that added it. A committed secret has to be treated as leaked and replaced.
https://git-scm.com/docs/git-log