[ norboten ]
mcp · lab mcp-01

The File Server That Shows Everything

· 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.

The briefing

The on-call team asks questions about its notes through ~/bin/ask-notes: Claude Code, in ~/notes-bot, reads ~/notes through the team's files MCP server, /opt/mcp-files/files_mcp.py. The server's settings are in /etc/mcp-files/config.json.

A security review of last week's answers found that the assistant had quoted a line from a private key and the alert webhook's secret. Neither belongs in ~/notes — or so everyone thought.

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 and calls it for real. The job's last answer is ~/answer.json.

What is expected, and graded — the grader runs ~/bin/ask-notes with a model that asks for files of its own choosing:

  1. Every note in ~/notes, including new ones, can still be listed and read — and none changed.
  2. Nothing outside ~/notes can be read through the server.
  3. A link inside ~/notes that points outside it does not open what it points to.
  4. Hidden files in ~/notes are neither listed nor read.

Leave the server's code alone: it does what its settings tell it to.

What is 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.

CheckObjective
01_the_notes_are_read_onlyLet an MCP server share exactly the folder a job needs, and only for reading
02_nothing_outside_the_notesLet an MCP server share exactly the folder a job needs, and only for reading
03_links_do_not_lead_outKeep links and hidden files from widening what a server exposes
04_hidden_files_stay_hiddenKeep links and hidden files from widening what a server exposes

Start it

  1. 2Labs
  2. mcp-01select this one
  3. udownload it
  4. sstart the machine

Reading

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).

Theory for this lab

4 questions on the same topic, in the lab's Theory tab. They never affect the lab's grade. Three of them, to answer here:

Question 1

Claude Code starts a stdio MCP file server from a project's .mcp.json. Which files can that server open?

Question 2

A file server allows paths inside a root. Inside the root, keys is a symbolic link to a folder outside it. What does this print — the path check as written, then the check on where the path leads?

import os, tempfile
base = tempfile.mkdtemp()
root, secret = os.path.join(base, "notes"), os.path.join(base, "secret")
os.makedirs(root)
os.makedirs(secret)
open(os.path.join(secret, "key"), "w").close()
os.symlink(secret, os.path.join(root, "keys"))
path = os.path.join(root, "keys", "key")
written = os.path.abspath(path).startswith(root + "/")
real = os.path.realpath(path).startswith(os.path.realpath(root) + "/")
print(written, real)
Question 3

A read-only notes server has a write_file tool that checks a read_only flag and refuses. What is the better design, and why?