af-filesystem-mcp
An MCP server that gives an AF (Analysis Facility) user browse/read access to
their own files on the AF's shared NFS home (/home/<unixname>) and Ceph data
area (/data/<unixname>) — nothing more. Designed to sit behind
af-mcp-platform's credential broker so an LLM session can look at a user's own
analysis outputs, condor logs, and scratch files without a human copying paths
around.
What it does
| Tool | Does | Read/write |
|---|---|---|
fs_list |
List a directory | read-only |
fs_read |
Read a file, by byte range or line range, including head/tail | read-only |
fs_stat |
Stat a path — size, mtime, type, permissions | read-only |
fs_grep |
Search for a pattern across files under a directory, capped in files scanned and matches returned | read-only |
That is the entire v1 tool surface: all four tools are read-only
(read_only_hint=true in their MCP tool annotations) and confined to the
caller's own two AF roots (open_world_hint=false). There is deliberately no
write tool, no delete, no chmod, no arbitrary command execution, and no
full-tree walk (directory-size, duplicate-finder). See CLAUDE.md for the
design rationale and phase-2 (write) plan.
Security model
Every filesystem operation for user alice runs in a short-lived helper
subprocess impersonating alice's real uid/gid — the server process itself
(running as root, holding only CAP_SETUID/CAP_SETGID) never reads or writes
a byte of user data directly. This means the kernel (and, for the NFS-mounted
homes, the NFS server) enforces every permission check against the real
identity: even a bug in this server's own path-pinning logic can only let alice
reach what alice's real uid could already reach. See CLAUDE.md § "Security
model" and src/af_filesystem_mcp/paths.py for the full design rationale, and
maniaclab/af-mcp-platform#188
for the workplan and the (rejected) alternatives this design was chosen over.
Installation
Or with pixi:
Quick start (local development, stdio)
In stdio mode there is exactly one caller (you), so no impersonation happens —
the server operates directly as your own uid/gid, confined to your own $HOME
and a configurable data root:
Broker mode (production, HTTP)
af-filesystem-mcp serve --transport http \
--broker-url https://mcp.af.uchicago.edu \
--broker-audience af-filesystem-mcp \
--home-root /home --data-root /data
Bearers are broker-issued identity JWTs (aud=af-filesystem-mcp) carrying
uid/gid/unixname POSIX claims (af-mcp-platform's
identityProviders[].targetOptions.af-filesystem-mcp.includePosix: true).
Requires the broker extra: pip install af-filesystem-mcp[broker].
See Contributing for development setup.