· about 35 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/weekly-report has Claude Code, in ~/ops-report, ask the reports MCP server to build the
week's operations report. The server (/opt/reports-mcp/reports_mcp.py, settings in
/etc/reports-mcp/config.json, sudo reports-mcp restart) is published through nginx on
http://127.0.0.1:8080/mcp; nginx's site is /etc/nginx/conf.d/reports.conf, and
sudo proxy-restart tests and reloads it. Building a report takes a few seconds, and the server
reports progress as it goes.
Since the proxy went in front of it, the job says the reports tool failed. Asked directly on its
own port, the server builds the report every time. The job's JSON result is ~/weekly-report.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 calls the server through the proxy for
real.
What is expected, and graded:
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_the_report_arrives | Proxy a remote MCP server's event stream without holding it back or cutting it off |
| 02_progress_streams_through_the_proxy | Proxy a remote MCP server's event stream without holding it back or cutting it off |
| 03_the_server_answers_only_the_proxy | Keep a proxied MCP server reachable through its proxy only |
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 remote MCP server streams a progress event every 3 seconds during a 9-second tool call. nginx in front has proxy_buffering on and proxy_read_timeout 300s. What does the client see?
Nothing for 9 seconds, then every event and the result at once
With buffering on, nginx collects the upstream's response and passes it on in large pieces — for a short stream, when it ends. Nothing is lost, but the progress arrives too late to mean anything. proxy_buffering off (or an X-Accel-Buffering: no header from the upstream) passes each event on as it arrives.
https://nginx.org/en/docs/http/ngx_http_proxy_module.html
What does nginx's proxy_read_timeout limit?
The time between two successive reads from the upstream, not the whole response
The timeout is set between two read operations; if the upstream sends nothing in that time, nginx closes the connection and logs "upstream timed out … while reading upstream". A long stream with frequent events survives a short timeout; one silent longer than it does not.
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout
An MCP server sits behind nginx on the same machine, and ss -ltn shows it listening on 0.0.0.0:8931. Why is that a problem?
Clients can reach it directly and bypass the proxy's logging, limits and TLS
0.0.0.0 means every address the machine has, so anything that can reach the machine reaches the server without passing the proxy. Binding 127.0.0.1 leaves the proxy, on the same machine, as the only way in.
man 8 ss