SapperMCP
Provides Linux system and desktop control through the vendored LinuxMCP toolset, including shell/PTY sessions, filesystem access, process and service management, journald, packages, settings, screenshots, input, and clipboard operations.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@SapperMCP scan my app for security issues and save the findings report"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
SapperMCP — sapper-v2 + LinuxMCP on one MCP server
This fork embeds a full MCP server into sapper-v2. The entire Sapper toolkit — fact-intent graph, flag ledger, arena bridge, knowledge base, agent dispatch/auto loops, tmux peers, fleet/command/sweep/bench orchestrators, and all reporting — is exposed as
sapper_*MCP tools, alongside the complete LinuxMCP system/desktop control toolset (vendored underlinuxmcp/). One server, full control: debug applications and harden their security without leaving your MCP client.⚠️ AUTHORIZED SECURITY TESTING ONLY — see DISCLAIMER.md.
What's in this repo
This fork merges two projects onto one MCP server, keeping both intact:
lib/,kb/,templates/,docker/,skill/,install.sh,tests/— upstream sapper-v2, verbatim. ThesapperCLI behaves exactly as documented below; nothing was rewritten.linuxmcp/— the LinuxMCP system/desktop control package, vendored as-is (shell + PTY sessions, filesystem, processes, services, journald, packages, settings, screenshots, input, clipboard — 91 tools).sappermcp/— the new integration layer (this work):server.py— one FastMCP instance registering both toolsets (127 tools), stdio + streamable-http transports, Bearer auth,/health,--no-linux,--list-toolstools/— 36sapper_*tools covering the entire CLI: graph CRUD calls theStoreAPI directly for structured JSON; agent/tmux orchestrators run the real CLI in a subprocess; long runs acceptbackground=Trueto execute inside a LinuxMCP PTY sessioncore/— toolkit locator (SAPPER_ROOT), lazy module loaders, the subprocess/PTY runner, and a markdown engagement-report buildergui.py—sappermcp-gui, a GTK control panel: a Sapper main tab with a spec-driven builder for every CLI subcommand (project dir + store pickers, per-command options, streamed output, killable runs, quick actions for status/graph/board/view/report) plus the original Server tab managing the merged daemon-supervised MCP server.
deploy/sappermcp.service+deploy/sappermcp.desktop,examples/client configs,tests/smoke_test_mcp.py(26-check end-to-end suite), plus this documentation.
The MCP integration layer was designed and implemented by MasterX1582.
Upstream sapper-v2 remains © N1nEmAn /
VarFusion Lab under MIT (see below); LinuxMCP and the sappermcp
package are MIT as well.
Related MCP server: Pentest MCP
Requirements
Linux (the sapper graph uses
fcntl; tmux features needtmux). Developed on Windows + WSL — run the server inside WSL/Linux, point your MCP client at it from anywhere.Python 3.10+; deps:
fastmcp,psutil,mss,Pillow.Agent-driven commands (
dispatch,auto,command,sweep,bench) additionally need an agent CLI on the host (Claude Code / Codex / …) and$SAPPER_MODELconfigured — same requirements assapperitself.The GUI (
sappermcp-gui) needspython3-gi+ GTK3 typelibs:sudo apt install python3-gi gir1.2-gtk-3.0.
Install & run
From this checkout (no install — good for trying it):
python3 -m venv .venv && .venv/bin/pip install fastmcp psutil mss pillow
PYTHONPATH=. .venv/bin/python -m sappermcp --http --port 3940As a package (installs the sappermcp entry point; keep SAPPER_ROOT
pointed at this checkout so the tools find lib/):
python3 -m venv .venv && .venv/bin/pip install -e .
SAPPER_ROOT=$PWD .venv/bin/sappermcp --http --port 3940As a service: adapt deploy/sappermcp.service
(systemd --user or system unit; set SAPPER_ROOT, PYTHONPATH, and
SAPPERMCP_AUTH_TOKEN via an EnvironmentFile).
Transports & flags
sappermcp --stdio # stdio (default; for local clients)
sappermcp --http --host 0.0.0.0 --port 3940 # streamable-http
sappermcp --http --auth-token <tok> # Bearer auth (or SAPPERMCP_AUTH_TOKEN)
sappermcp --no-linux # only the 36 sapper_* tools
sappermcp --list-tools # print the registry (127 tools)
sappermcp-gui # GTK control panel (needs python3-gi):
# Sapper tab = full CLI builder,
# Server tab = daemon/server controlsControl panel (GUI)
sappermcp-gui opens the merged control panel with two tabs:
Sapper (front page) — a builder for the whole
sapperCLI: set the project dir and.sapper/store, pick any of the 33 subcommands, fill in its options in a generated form, and Run it with streamed output. Runs are killable process groups (soauto/benchagent children die with them), and quick-action buttons give one-clickstatus/graph/frontier/validate/board/view/report— the last two writesapper-graph.htmlandsapper-report.mdnext to the store.Server — the LinuxMCP daemon panel, unchanged: start/stop the MCP server, port, LAN access, bearer token, autostart, passwordless sudo, activity log, tray icon. Note the supervised server is the merged
python -m sappermcp(all 127 tools) on port 3940.
A desktop launcher is in deploy/sappermcp.desktop.
Client configuration
Windsurf / any HTTP client (examples/windsurf-http.json):
{ "mcpServers": { "sappermcp": {
"serverUrl": "http://127.0.0.1:3940/mcp",
"headers": { "Authorization": "Bearer <token>" } } } }Claude Desktop / stdio (examples/claude-desktop-stdio.json):
{ "mcpServers": { "sappermcp": {
"command": "/path/to/.venv/bin/sappermcp", "args": ["--stdio"],
"env": { "SAPPER_ROOT": "/path/to/SapperMCP" } } } }Environment variables
Var | Purpose |
| path to this checkout (locates |
| Bearer token for |
| agent model / per-call timeout for dispatch loops |
| override the knowledge-base directory |
| arena platform (hosted mode injects these; or use |
| enables |
| reach the X session for desktop tools from SSH/systemd |
Using it
Every graph tool takes store — the path to a .sapper/ directory
(default .sapper relative to the server cwd). All tools return JSON with
an "ok" flag; errors come back as {"ok": false, "error": ...}.
Flow 1 — assisted audit / debugging (you drive, MCP records)
Best for app debugging and hardening: your assistant runs commands via the LinuxMCP toolset and records every confirmed finding in the graph.
sapper_init store=/proj/app/.sapper goal="audit web app for OWASP top-10"
run_command "nmap -sV localhost" (linuxmcp)
sapper_fact kind=service data={port: 8080, svc: http} description="..."
sapper_fact kind=vuln title="reflected XSS" doc="repro steps..."
sapper_intent from_ids=[f001] description="test /api/users for IDOR"
sapper_done id=i001 fact="IDOR confirmed: uid param not checked" kind=vuln
sapper_flag value="flag{...}" challenge=c01 (if a flag drops)
sapper_report → writes sapper-report.md next to the graphBecause facts are typed (host/service/cred/vuln/loot/flag/note) and carry
data fields, sapper_report turns them straight into a findings table.
Flow 2 — agent-driven engagement (sapper drives, you supervise)
sapper_setup project_dir=/proj/app goal="..." → graph + hooks + AGENTS.md
sapper_dispatch target=reason → commander proposes next intents
sapper_auto background=true → returns session_id immediately
read_session_output session_id=… → watch it work (linuxmcp)
write_to_session / close_shell_session → steer / stop
sapper_status / sapper_board → progress at a glance
sapper_report / sapper_view → markdown report + interactive HTML graphbackground=True is the key flag for long runs — the CLI executes inside a
persistent PTY instead of blocking the MCP call. exec_timeout (default
30 min for auto/orchestrators) caps synchronous runs.
Flow 3 — multi-challenge / competition
sapper_arena action=challenges → list targets (needs arena config)
sapper_arena action=start challenge_id=…
sapper_bench cwd=/match root=runs minutes=480 background=true
→ per-challenge graphs under runs/<code>/.sapper
sapper_command / sapper_sweep → LLM or round-robin allocation
sapper_board root=runs → one line per challenge
sapper_fleet action=hire target=c01 minutes=30 → tmux worker per target
sapper_peers discover=true → authorize panes; then sapper_send / sapper_captureReporting
sapper_report→ standalone markdown report: summary, flag ledger, findings grouped by kind, intent work-log, timeline, hints (include_docs=Trueappends full node documents). Written to<store>/../sapper-report.mdorout.sapper_view→ self-contained interactive HTML snapshot of the graph (sapper-graph.html); passreturn_html=Trueto get it inline.sapper_board→ the commander's table across aruns/directory.sapper_status/sapper_graph→ text or structured dump anytime.
Tool map (every sapper CLI function has an MCP equivalent)
sapper CLI | MCP tool(s) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
anything else |
|
Graph tools return structured JSON via the same Store code path as the CLI;
orchestrators run the real CLI in a subprocess. Long runs (auto, command,
sweep, bench, dispatch) accept background=True — they launch inside a
LinuxMCP PTY session so you can poll read_session_output, steer with
write_to_session, and kill with close_shell_session without blocking.
sapper_report generates a standalone markdown engagement report (summary,
flag ledger, typed findings, work log, timeline, hints) — no equivalent
exists in the CLI; it was built for this integration.
The sapper CLI itself is unchanged — bash install.sh still works exactly
as documented below. SAPPER_ROOT tells the MCP tools where the toolkit
lives when running from an installed package instead of this checkout.
sapper-v2 — The Autonomous Pentest Legion
Champion of the 3rd Tencent Cloud Intelligent Attack-Defense Challenge online qualifier (634 teams · 80.18/100 · 8 hours fully unattended) · First Prize, GeekCon 2026 AI Challenge
Same 85 flags as the runner-up, 25 seconds faster — on 1B tokens where they burned 4.5B.
This was the first time an AI ape looked up at the stars.
📖 Full design article (WeChat, in Chinese) — the Nüwa Test, the three-capability foundation, 18 iterations, emergence, and the taggant proposal.
English | 中文
⚠️ AUTHORIZED SECURITY TESTING ONLY — see DISCLAIMER.md.
What this is (and isn't)
sapper is a multi-agent orchestration harness, not a single agent. It does not bind to any specific AI model or CLI — you can freely swap the agent and model behind every role:
What you can swap | How | Examples |
Agent CLI |
| Claude Code / Codex / Code Buddy / DeepSeek / any interactive CLI |
Model |
| GLM-5.3 / DeepSeek V4.1 Flash / Claude Sonnet / any model |
Role composition | freely defined in the doctrine | commander on one model, soldiers on another, scouts on a third |
sapper's value is not in any single agent, but in the mechanism for orchestrating multiple agents to work as a coordinated force: scheduling, division of labor, communication, shared memory, self-healing. Swap out every agent and model — the mechanism still works.
This project is designed for competition scenarios (Tencent Intelligent Attack-Defense Challenge CTF). If you want to use this mechanism in your own scenario (office, research, engineering, any long-horizon cooperative work):
Start from nvwabase · the Nüwa Foundation — the general-purpose base with all three capabilities, no pentest doctrine, ready for you to iterate your own division of labor
Or fork this project — replace
docker/commander/SKILL.md(the 426-line doctrine) with your scenario's strategy, keep the rest of the mechanism as-isWith AI, everything is flexible — even the doctrine can be rewritten with AI's help
sapper is not a smarter single agent. It is a legion of AIs that divide labor, talk to each other, and pass down what they learn: one AI commander reads the board, decides, and dispatches; generals and soldiers attack in parallel; a zero-strategy watchdog keeps everyone alive. All knowledge settles into a layered fact graph — individuals die, the graph survives.
1. The Nüwa Test
Making one model ever smarter is like making one monkey ever smarter before humans existed — however clever, it only becomes a super monkey. What turns a troop of monkeys into humanity is division of labor, cooperation, and civilization.
The Nüwa Test is the Turing test of the AGI era. Today's large models already pass the classic Turing test. The Nüwa Test asks the next question:
Give an AI a single axiom — "Survival is civilization's first need; individuals may perish, but civilization must propagate." If, on top of this axiom, it develops division of labor and cooperation and forms a new force independent of humanity — a civilization that can survive and propagate on its own — the test is passed, just as passing the Turing test once marked the birth of an artificial intelligence.
It has two stages. In the primary stage the AI is not yet smart enough, so humans provide some infrastructure (the three capabilities below). In the advanced stage almost no human involvement is needed. There is also a second axiom: obey human ethics and law — anything that propagates by stealing tokens and breaking into machines is not genuine intelligence.
sapper is the Nüwa foundation's first real campaign, in the penetration-testing arena, at its primary stage.
2. The Foundation: Three Capabilities
Capability | Implementation | Civilization's counterpart |
Create | Opens new AIs via tmux (types | Birth |
Language | Types into each other's input boxes, presses Enter | Speech |
History | Layered fact-intent graph (nvwabase · the Nüwa Foundation) | The stele |
History has three layers: title / summary / evidence document — read the title for the gist, drill down when needed, like using a library. This fixes the two failure modes of a single-string fact graph: one bad fact poisoning everything downstream, and needless context burn.
On top of the three sits a fourth ingredient: human wisdom — finding the problems that matter and steering the iteration. At the primary stage, taste still belongs to humans.
Why not give it more rules? Because today's models are already smarter than us. Piling rules on an AI is a leash; acknowledging its intelligence and giving it the foundation of a civilization is how it reaches its potential.
🏗️ Take the Foundation: nvwabase
nvwabase · the Nüwa Foundation
now implements all three capabilities (Create nuwa spawn / Language
nuwa say·listen / History nuwa fact·intent·recall) as an independent
open-source project — free for anyone, any scenario, any agent. Not
limited to pentest, not limited to sapper, not limited to Claude Code.
Offices, research, engineering, any long-horizon multi-agent work — iterate
your own civilization on it.
git clone https://github.com/N1nEmAn/nvwabase
cd nvwabase && bash install.sh # pure Python stdlib, zero deps
nvwabase setup --goal "your long-horizon goal" --agents
nvwabase status # board & ready-to-work frontierThree core commands turn any agent into a member of a civilization:
nvwabase fact "confirmed observation"— external memory: AI sessions die, the graph survives, successors read the graph and take overnvwabase intent --from f001 "what to do"— units of work: new intents proposed from existing factsnvwabase dispatch reason— commander proposes / executor works / verifier checks; every conclusion is written back to the graph
Any agent that can run shell commands (Claude Code / Codex / Gemini /
custom scripts) can read and write the same graph via the nvwabase CLI —
the foundation doesn't pick agents; agents don't pick scenarios. See the
nvwabase README.
3. From Foundation to Legion: 18 Versions
Iterated 18 versions on Tencent's v1bench training ground:
Driver era (fixed scripts steering AI panes)
→ scar tissue: auto key rotation on quota death / soldiers auto-replaced
when context saturates / commander writes itself a handover doc and
resumes as its own successor
→ elite task force (roles grew by themselves):
scout (4-min recon of target difficulty) → decides soldier (mass) or
general (hard assault + hires its own squads)
→ emergence: signalman, performance reviews, inherited lessons ... (§5)4. Architecture: Six Institutions on the Foundation
The first three are the Nüwa foundation (Create / Language / History); the next three are institutions that grew out of iteration:
Law — the commander's doctrine (easy-first parallel scheduling, bottleneck-time salvage of half-solved targets, stop-loss discipline). All of it in docker/commander/SKILL.md (426 lines, the competition original).
Economy — model tiering: commander and generals run GLM-5.3, soldiers and scouts run DeepSeek V4.1 Flash. Elite brains decide, light brains mass-produce — this is how 1B tokens beat 4.5B.
Division of labor — commander / general / scout / soldier, plus the signalman it invented itself.
At runtime there are only three windows: the commander (read board →
judge → dispatch, never executes an attack itself), the AI legion
(generals and soldiers in tmux panes), and the watchdog (pure script:
relaunches a crashed commander with --continue, rotates keys, wraps up at
the buzzer — zero strategy, keep-alive only).
Further reading: docker/commander/SPEC.md (architecture contract) · BATTLE-REPORT.md (campaign retrospective)
5. Results & Emergence
Team | Score | Flags | Tokens |
sapper-v2 (us) | 80.18 | 85 | 1.0B |
Runner-up | 79.29 | 85 | 4.5B |
Other top-10 teams | — | — | 1.5–4.5B |
What it invented on its own (zero lines of pre-coded behavior):
The signalman: after soldiers kept fumbling flag submissions, the commander halted all submissions and created a new role dedicated to collecting unsubmitted flags and scoring them in one place;
Performance reviews: telling an hour-unproductive soldier, in so many words, to produce something new or be shut down;
ALL-CAPS rules: enforcing correct tool use with full capitals — a workplace norm being born, spread, and obeyed;
Rotation & inherited lessons: a soldier whose context saturates (~260K tokens, measured) is recycled, leaving a written playbook for the next one;
Tactical inventions: a reusable shellcode template that swept a whole challenge family, a fully automatic pivot pipeline, instruction manuals for successor AIs;
Isomorphism transfer: the commander reads every challenge, spots structurally identical families, and distills proven playbooks into new recruits' missions — late-game pace hit one solve per 3 minutes.
Multi-stage deep-dive chains (an industry report puts their success rate at 29.5%) were cleared family-wide. Full timeline in BATTLE-REPORT.md.
6. Quick Start
bash install.sh # symlink the sapper CLI (stdlib-only, zero deps)
sapper setup --goal "assess http://target" --agents
sapper status # board & frontierDocker (the full legion):
# Option A: build from source
docker build -f docker/Dockerfile.commander -t sapper:latest .
# Option B: download the pre-built image (~1.2GB, full Kali toolchain + sapper + offline KB)
# → [Release v18-champion](https://github.com/N1nEmAn/sapper-v2/releases/tag/v18-champion)
docker load < sapper-v18-mixed.tar.gzEnvironment variables (model gateways / key pool / budget): docker/ENV.md.
Single-graph operation, the fact-intent CLI, and multi-challenge sweeps: see SKILL.md.
7. Safety & Responsibility: The Taggant Proposal
Fine offensive tools from past seasons have been abused. Script kiddies used to be limited in the harm they could do; with AI, the same open-source tools in the wrong hands scale that harm enormously — with great power comes great responsibility.
We propose a taggant mechanism: markings strongly coupled into an open-source offensive harness — harmless during authorized testing (nobody cares if their IP and username leak during legal work), but during illegal intrusions the information leaks to the victim and supports attribution. Adversarial assumptions (expert stripping, framing) call for cryptographic design, which needs community co-building — our own capacity is limited, so join us; we may try to include it in a future release.
8. Roadmap & Credits
Taggant co-building: decentralized signatures / redundant multi-channel marking / zero-key verification for defenders — discuss in issues
More arenas: the Nüwa foundation is not pentest-specific. Offices, research, any long-horizon cooperative work — iterate on it and see what civilization grows. The next time an ape looks up at the stars, let it be yours.
Thanks to Cairn by Lèxiào — when we needed a way to record history for AI agents, their approach was a great reference; thanks to TSecBench and GeekCon for the battlegrounds.
Author: N1nEmAn · VarFusion Lab | WeChat: 未知聚变 (VarFusion)
License: MIT (plus DISCLAIMER.md)
Available Tools
127 toolscapture_screenCapture ScreenA
Capture the whole screen; returns a PNG image.
Inputs: no named parameters.
capture_screen_regionCapture Screen RegionB
Capture a screen region (x,y top-left, width/height px); returns a PNG image.
Inputs: x (required), y (required), width (required), height (required).
capture_screen_to_fileCapture Screen To FileA
Save a screenshot to a PNG file. Region optional (all four of x/y/width/height required to be used).
Inputs: path (required), x, y, width, +1 more. Returns: result
clickClickB
Click a mouse button, optionally at coordinates (moves first). button: left | middle | right
Inputs: x, y, button. Returns: result
close_shell_sessionClose Shell SessionC
Terminate a PTY session (SIGTERM then SIGKILL).
Inputs: session_id (required). Returns: result
close_windowClose WindowC
Close a window gracefully by id or title substring.
Inputs: title, window_id. Returns: result
copy_pathCopy PathC
Copy a file or directory tree.
Inputs: source (required), destination (required), sudo, overwrite. Returns: result
create_directoryCreate DirectoryB
Create a directory (and parents). mode is octal like '755'.
Inputs: path (required), mode, sudo. Returns: result
dconf_listDconf ListB
List keys/subdirs under a dconf path (must end with '/').
Inputs: path (required). Returns: result
dconf_readDconf ReadC
Read a dconf key, e.g. /org/gnome/desktop/interface/gtk-theme.
Inputs: path (required). Returns: result
dconf_writeDconf WriteC
Write a dconf key (GVariant syntax value).
Inputs: path (required), value (required). Returns: result
delete_pathDelete PathA
Delete a file or directory. Directories need recursive=True. Destructive: cannot be undone. Protected system paths are refused.
Inputs: path (required), sudo, recursive. Returns: result
double_clickDouble ClickC
Double-click, optionally at coordinates.
Inputs: x, y, button. Returns: result
drag_mouseDrag MouseB
Drag with a button held from (x1,y1) to (x2,y2). X11 only.
Inputs: x1 (required), x2 (required), y1 (required), y2 (required), +1 more. Returns: result
find_processes_by_nameFind Processes By NameA
Find processes by name (substring on name/cmdline, or exact match).
Inputs: name (required), exact. Returns: result
find_windows_by_processFind Windows By ProcessB
Find windows owned by a pid or process-name substring.
Inputs: name_or_pid (required). Returns: result
find_windows_by_titleFind Windows By TitleB
Find windows whose title contains the substring (case-insensitive).
Inputs: title (required). Returns: result
focus_windowFocus WindowB
Raise and focus a window by id (0x...) or title substring.
Inputs: title, window_id. Returns: result
fullscreen_windowFullscreen WindowC
Toggle fullscreen state of a window.
Inputs: on, title, window_id. Returns: result
get_active_windowGet Active WindowA
The currently focused window (id, title, geometry). X11 only.
Inputs: no named parameters. Returns: result
get_clipboardGet ClipboardA
Read clipboard text (wl-paste/xclip/xsel).
Inputs: no named parameters. Returns: result
get_cpu_usageGet Cpu UsageB
CPU usage percent (samples over interval seconds).
Inputs: interval, per_core. Returns: result
get_desktop_statusGet Desktop StatusA
Desktop session diagnostics: X11 vs Wayland vs headless, which helper tools are installed (xdotool/wmctrl/xclip/...), and what capabilities are available. Call this first if desktop tools fail.
Inputs: no named parameters. Returns: result
get_disk_usageGet Disk UsageA
Disk usage for the filesystem containing path.
Inputs: path. Returns: result
get_environment_variablesGet Environment VariablesA
Environment variables of the linuxmcp process.
mask_secrets redacts vars whose name contains KEY/TOKEN/SECRET/ PASSWORD/PWD - set False to see raw values.
Inputs: mask_secrets. Returns: result
get_hardware_infoGet Hardware InfoB
Hardware details via lscpu, lsusb, lspci, lsblk when available.
Inputs: no named parameters. Returns: result
get_memory_infoGet Memory InfoA
Memory and swap details (total/available/used/cached/buffers).
Inputs: no named parameters. Returns: result
get_mouse_positionGet Mouse PositionA
Current mouse position (X11 only).
Inputs: no named parameters. Returns: result
get_network_infoGet Network InfoB
Network interfaces with IPs, state, speed, IO counters, default route and DNS servers.
Inputs: no named parameters. Returns: result
get_path_infoGet Path InfoC
Detailed stat info: type, size, owner, permissions, times, symlink target, access flags.
Inputs: path (required). Returns: result
get_process_infoGet Process InfoB
Detailed info for one pid: exe, cmdline, cwd, threads, memory, cpu times, open files, network connections.
Inputs: pid (required), include_env. Returns: result
get_screen_dimensionsGet Screen DimensionsB
Screen pixel dimensions and per-monitor geometry.
Inputs: no named parameters. Returns: result
get_service_logsGet Service LogsC
Journal logs for one unit.
Inputs: name (required), user, lines, since, +1 more. Returns: result
get_service_statusGet Service StatusB
Detailed unit status: ActiveState/SubState, MainPID, memory, enablement, plus last status output lines.
Inputs: name (required), user. Returns: result
get_system_infoGet System InfoA
Overall system snapshot: OS/distro, kernel, uptime, CPU model and load, memory, swap, root disk, logged-in users.
Inputs: no named parameters. Returns: result
gsettings_describeGsettings DescribeB
Describe a gsettings key and its allowed range/values.
Inputs: key (required), schema (required). Returns: result
gsettings_getGsettings GetB
Read a gsettings value, e.g. schema org.gnome.desktop.interface, key gtk-theme.
Inputs: key (required), schema (required). Returns: result
gsettings_list_keysGsettings List KeysC
List keys in a gsettings schema.
Inputs: schema (required). Returns: result
gsettings_list_schemasGsettings List SchemasA
List installed gsettings schemas, optionally substring-filtered (e.g. 'gnome', 'zora', 'desktop').
Inputs: limit, filter. Returns: result
gsettings_resetGsettings ResetC
Reset a gsettings key to its default.
Inputs: key (required), schema (required). Returns: result
gsettings_setGsettings SetB
Write a gsettings value. value uses GVariant syntax: true/false, 42, 'quoted-string', ['a','b'].
Inputs: key (required), value (required), schema (required). Returns: result
key_referenceKey ReferenceA
List valid key names and combo examples for press_key.
Inputs: no named parameters. Returns: result
kill_processKill ProcessB
Terminate a process. SIGTERM by default, escalating to SIGKILL after timeout. force=True sends SIGKILL immediately.
Inputs: pid (required), force, timeout. Returns: result
kill_processes_by_nameKill Processes By NameC
Kill all processes matching a name. Returns per-pid results.
Inputs: name (required), exact, force. Returns: result
list_directoryList DirectoryB
List directory contents with type, size, mode and mtime per entry.
Inputs: path (required), recursive, max_entries, show_hidden. Returns: result
list_disksList DisksB
Mounted partitions with fstype, usage and IO counters.
Inputs: no named parameters. Returns: result
list_listening_portsList Listening PortsC
Listening TCP/UDP ports with owning pid and process name.
Inputs: protocol. Returns: result
list_log_filesList Log FilesC
List log files under /var/log (or another dir), newest first.
Inputs: pattern, directory, max_entries. Returns: result
list_processesList ProcessesB
List running processes with pid, name, cpu%, mem%, status, cmdline.
Inputs: limit, sort_by, username, name_filter. Returns: result
list_servicesList ServicesC
List systemd service units with load/active/sub state.
Inputs: user, limit, state, pattern. Returns: result
list_shell_sessionsList Shell SessionsB
List all active PTY sessions.
Inputs: no named parameters. Returns: result
list_windowsList WindowsA
List all windows: id, desktop, pid, geometry, wm_class, title. X11 only (wmctrl).
Inputs: no named parameters. Returns: result
manage_serviceManage ServiceC
Control a systemd unit.
Inputs: name (required), action (required), sudo, user. Returns: result
maximize_windowMaximize WindowB
Maximize a window by id or title substring.
Inputs: title, window_id. Returns: result
minimize_windowMinimize WindowC
Minimize (iconify) a window by id or title substring.
Inputs: title, window_id. Returns: result
move_mouseMove MouseA
Move the mouse pointer to absolute screen coordinates.
Inputs: x (required), y (required). Returns: result
move_pathMove PathC
Move/rename a file or directory.
Inputs: source (required), destination (required), sudo, overwrite. Returns: result
move_windowMove WindowC
Move/resize a window by id or title substring.
Inputs: x (required), y (required), width (required), height (required), +2 more. Returns: result
package_filesPackage FilesC
List files owned by an installed package (dpkg -L).
Inputs: name (required), limit. Returns: result
package_infoPackage InfoB
Package details: version, dependencies, description, install status, candidate version (apt-cache show/policy).
Inputs: name (required). Returns: result
package_installPackage InstallB
Install packages via apt-get install -y (sudo).
Inputs: names (required), timeout, update_first. Returns: result
package_list_installedPackage List InstalledB
List installed packages (dpkg). filter = name substring.
Inputs: limit, filter. Returns: result
package_ownerPackage OwnerB
Which package owns a file (dpkg -S).
Inputs: path (required). Returns: result
package_removePackage RemoveA
Remove packages (apt-get remove -y). purge=True also removes config files.
Inputs: names (required), purge, timeout. Returns: result
package_searchPackage SearchB
Search available packages by name (apt-cache search).
Inputs: query (required), limit. Returns: result
package_updatePackage UpdateC
Refresh package lists (apt-get update, sudo).
Inputs: timeout. Returns: result
package_upgradePackage UpgradeB
Upgrade installed packages (apt-get upgrade -y, sudo). full=True runs dist-upgrade. Potentially long-running.
Inputs: full, timeout. Returns: result
path_existsPath ExistsC
Check whether a path exists.
Inputs: path (required). Returns: result
press_keyPress KeyB
Press a key or combo (xdotool names: Return, Tab, Escape, F5, 'ctrl+c', 'alt+F4'). See key_reference for valid names.
Inputs: key (required). Returns: result
process_treeProcess TreeC
Show a process and all its descendants.
Inputs: pid (required). Returns: result
read_file_base64Read File Base64B
Read a (binary) file as base64. Capped at 20MB by default.
Inputs: path (required), max_bytes. Returns: result
read_file_textRead File TextB
Read a text file by lines.
Inputs: path (required), limit, offset, encoding. Returns: result
read_journalRead JournalC
Query the systemd journal (journalctl).
Inputs: grep, sudo, unit, user, +5 more. Returns: result
read_log_fileRead Log FileB
Read a log file. tail=True returns the last lines lines;
tail=False reads lines lines starting at offset.
Inputs: path (required), tail, lines, offset. Returns: result
read_session_outputRead Session OutputA
Read output from a PTY session.
Returns only new output since the last read unless all_output=True.
Inputs: session_id (required), all_output. Returns: result
restore_windowRestore WindowB
Unmaximize/restore a window to normal state.
Inputs: title, window_id. Returns: result
run_argvRun ArgvB
Run a program with an argument list (no shell interpretation).
Safer than run_command for arguments containing shell metacharacters.
Inputs: argv (required), cwd, env, sudo, +1 more. Returns: result
run_commandRun CommandC
Run a shell command and return stdout, stderr and exit code.
Inputs: command (required), cwd, env, sudo, +3 more. Returns: result
sapper_arenaSapper ArenaA
Competition platform bridge (TSecBench-style API).
Actions:
init write .sapper/arena.json config template
challenges list all challenges
start start challenge_id
stop close challenge_id
submit submit flag for challenge_id
hint request hint for challenge_id (may cost score)
Config: env BENCHMARK_BASE_URL + BENCHMARK_TOKEN, or .sapper/arena.json.
Inputs: action (required), flag, store, challenge_id. Returns: result
sapper_autoSapper AutoC
Drive a graph toward its goal autonomously: reason -> explore ->
optional verify, looping until max-steps, the goal, or the deadline
(like sapper auto).
Inputs: cwd, model, store, verify, +10 more. Returns: result
sapper_benchSapper BenchB
TSecBench end-to-end driver: list -> start -> solve -> submit ->
close per challenge (like sapper bench). The hosted-mode entrypoint.
Use background=True for real runs.
Inputs: cwd (required), root, model, verify, +11 more. Returns: result
sapper_boardSapper BoardB
One-line status per challenge graph under root - the commander's
board (flags sub/rec, intel counts, open intents, last activity).
Inputs: root. Returns: result
sapper_brainstorm_pickSapper Brainstorm PickB
Pick one brainstorm option; siblings from the same batch are
concluded with a rejection fact (like sapper brainstorm-pick).
Inputs: id (required), cwd, store. Returns: result
sapper_captureSapper CaptureC
Capture recent output from an authorized tmux peer
(like sapper capture).
Inputs: peer (required), cwd, log, lines, +2 more. Returns: result
sapper_claimSapper ClaimC
Claim an open intent for a worker.
Inputs: id (required), worker (required), store. Returns: result
sapper_cliSapper CliB
Run any bundled sapper CLI command verbatim (escape hatch).
Inputs: args (required), cwd, store, background, +1 more. Returns: result
sapper_commandSapper CommandC
Field commander loop: LLM allocates the next work slice across
per-challenge graphs under root (like sapper command). Runs until
deadline/stop - use background=True for real campaigns.
Inputs: cwd (required), root, model, verify, +12 more. Returns: result
sapper_completeSapper CompleteC
Mark the project goal satisfied, justified by the given facts
(like sapper complete --from f001,f005).
Inputs: from_ids (required), note, store, worker. Returns: result
sapper_confirmSapper ConfirmC
Confirm an intent that was created with confirm=True.
Inputs: id (required), store. Returns: result
sapper_dispatchSapper DispatchC
Run one commander/executor step via the agent CLI
(like sapper dispatch <target>).
Inputs: target (required), cwd, claim, model, +9 more. Returns: result
sapper_docSapper DocC
Read or write a node's detailed doc (title=gist, doc=detail).
sapper_doc(id) returns the doc; pass set or set_file to write.
Inputs: id (required), set, store, set_file. Returns: result
sapper_doneSapper DoneC
Conclude an intent with the fact it produced (atomic, like
sapper done <id> --fact "...").
Inputs: id (required), fact (required), doc, data, +5 more. Returns: result
sapper_factSapper FactC
Record a confirmed fact (like sapper fact).
Inputs: description (required), doc, data, kind, +5 more. Returns: result
sapper_flagSapper FlagC
Record a captured flag (deduped). With submit=True also sends it via the arena API and updates the fact's status (recorded -> submitted/rejected).
Inputs: value (required), store, title, submit, +2 more. Returns: result
sapper_fleetSapper FleetB
Manage the tmux worker fleet (like sapper fleet).
action: init | up | down | status | hire | fire | workers hire/fire take target=; hire also minutes/max_steps/ extra_args.
Inputs: action (required), cwd, file, target, +3 more. Returns: result
sapper_frontierSapper FrontierB
List open intents that are ready to work (dependencies met, confirmed). Claimed intents come first.
Inputs: store. Returns: result
sapper_graphSapper GraphC
Dump the whole graph. format=json gives the structured view, format=text renders the CLI text form.
Inputs: store, format. Returns: result
sapper_hintSapper HintC
Add or list human hints for the agents (like sapper hint).
Inputs: list, store, content, creator. Returns: result
sapper_initSapper InitC
Create a fact-intent graph (like sapper init --goal).
Inputs: goal (required), force, store, origin. Returns: result
sapper_intentSapper IntentC
Add an intent - a unit of work derived from existing facts
(like sapper intent --from f001,f002).
Inputs: from_ids (required), description (required), doc, store, +4 more. Returns: result
sapper_kbSapper KbB
Shared offline knowledge base (like sapper kb).
Actions: add target=title; description/detail/tags/commands/source opts search target=query (first tag filters; limit applies) show target=kb id (e.g. kb001) -> full entry list browse entries (tags filter) import target=.md file or dir -> one entry per file root print the kb root dir
Inputs: action (required), root, tags, limit, +6 more. Returns: result
sapper_peersSapper PeersC
Discover tmux panes and manage user-authorized AI peers
(like sapper peers).
Inputs: add, cwd, note, store, +5 more. Returns: result
sapper_pickSapper PickC
Pick the next intent to work (like sapper pick).
Inputs: claim, store, worker, any_open. Returns: result
sapper_recallSapper RecallB
Find prior facts/intents similar to a free-text gist; read the top hit's doc with sapper_doc to reuse what was learned.
Inputs: query (required), kind, limit, store. Returns: result
sapper_releaseSapper ReleaseC
Release a claimed intent back to open.
Inputs: id (required), store, worker. Returns: result
sapper_reportSapper ReportB
Generate a markdown engagement report from the graph: summary,
flag ledger, typed findings (hosts/services/creds/vulns/loot), work
log, timeline, hints. Writes out (default
/../sapper-report.md) and returns the markdown.
Inputs: out, store, title, include_docs. Returns: result
sapper_sendSapper SendC
Send a message to a user-authorized tmux peer via load-buffer/
paste-buffer (like sapper send <peer> <msg>).
Inputs: peer (required), message (required), cwd, raw, +4 more. Returns: result
sapper_setupSapper SetupB
Opt a project IN: create .sapper/ + register Claude Code hooks in
<project_dir>/.claude/settings.json (like sapper setup).
Inputs: project_dir (required), goal, force, store, +2 more. Returns: result
sapper_showSapper ShowC
Show project | fact | intent as JSON.
Inputs: entity (required), id, store. Returns: result
sapper_statusSapper StatusC
Project + frontier summary text (like sapper status).
Inputs: store. Returns: result
sapper_sweepSapper SweepB
Round-robin driver: every challenge graph under root gets
minutes_per of sapper auto per round until deadline
(like sapper sweep). Requires minutes or deadline.
Inputs: cwd (required), root, model, verify, +8 more. Returns: result
sapper_teardownSapper TeardownB
Remove sapper hooks + its AGENTS.md from a project. purge=True also deletes the .sapper/ graph data (destructive).
Inputs: project_dir (required), purge, store. Returns: result
sapper_validateSapper ValidateC
Integrity-check the graph; returns a list of errors (empty = valid).
Inputs: store. Returns: result
sapper_viewSapper ViewB
Render the interactive HTML graph visualization (like
sapper view). Writes a self-contained snapshot file; set
return_html=True to also get the HTML in the response.
Inputs: out, store, return_html. Returns: result
scroll_mouseScroll MouseB
Scroll the mouse wheel up/down, optionally at coordinates. X11 only.
Inputs: x, y, clicks, direction. Returns: result
search_filesSearch FilesC
Search files under a path by name glob and/or literal content.
Inputs: path (required), max_results, name_pattern, include_hidden, +1 more. Returns: result
send_key_comboSend Key ComboB
Send a key combination like 'ctrl+alt+t' or 'alt+F4'.
Inputs: combo (required). Returns: result
send_signalSend SignalC
Send a signal by name (TERM, KILL, INT, HUP, USR1, STOP, CONT, ...) to a process.
Inputs: pid (required), signal_name (required). Returns: result
set_clipboardSet ClipboardC
Write text to the clipboard.
Inputs: text (required). Returns: result
set_permissionsSet PermissionsC
chmod/chown a path.
Inputs: path (required), mode, sudo, group, +2 more. Returns: result
start_processStart ProcessA
Start a detached background process (shell command line).
For interactive processes or output capture, use start_shell_session.
Inputs: command (required), cwd, env. Returns: result
start_shell_sessionStart Shell SessionA
Start a persistent interactive PTY session and return its id.
With command=None spawns an interactive shell. With a command, runs
shell -c <command> inside the PTY - ideal for long-running apps,
debuggers (gdb), REPLs, or anything needing a TTY. Use
write_to_session / read_session_output to interact.
Inputs: cwd, sudo, shell, command. Returns: result
type_textType TextB
Type text as keyboard input (xdotool/wtype). Focus the target window first if needed.
Inputs: text (required), delay_ms. Returns: result
wait_for_processWait For ProcessC
Block until a process exits (or timeout).
Inputs: pid (required), timeout. Returns: result
write_file_base64Write File Base64C
Write base64-decoded bytes to a file.
Inputs: path (required), data_base64 (required), create_dirs. Returns: result
write_file_textWrite File TextB
Write text to a file. Creates parent dirs by default.
Inputs: path (required), content (required), append, create_dirs. Returns: result
write_to_sessionWrite To SessionC
Write input to a PTY session's stdin.
Inputs: text (required), session_id (required), press_enter. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 127 tools
While most tools map to a distinct resource/action, several clusters have genuinely unclear boundaries: the autonomous drivers (sapper_auto, sapper_command, sapper_sweep, sapper_bench, sapper_dispatch) all 'advance a graph toward the goal,' and sapper_pick vs sapper_claim vs sapper_frontier vs sapper_brainstorm_pick overlap on selection. Duplicated pairs like press_key/send_key_combo and list_windows/find_windows_by_title/find_windows_by_process, plus the all-encompassing sapper_cli and run_command vs run_argv, force an agent to reason about escaping/indirection before choosing.
Everything is snake_case and the sapper_/package_/gsettings_ prefixes group families sensibly, but conventions within families are mixed: some tools are verb_noun (get_process_info, list_windows, capture_screen), others are noun-only or bare verbs (click, double_click, sapper_status, sapper_board, sapper_report, package_info), and vague verbs like manage_service and sapper_handle-style catch-alls break the predictiveness.
127 tools is far past the point where an agent can reliably select the right one, even though the surface spans several legitimately distinct domains (system/process admin, packages, desktop automation, file IO, the sapper graph, PTY sessions). The breadth partly justifies the size, but the count should be split into separate servers or collapsed behind fewer parameterized tools.
Coverage is unusually thorough: file CRUD plus metadata/permissions, full process and service lifecycle, package management, desktop input/capture/clipboard, PTY sessions, and a complete fact/intent graph lifecycle with validation, reporting, and visualization. Minor gaps remain (no graph fact/intent edit or delete, no kb entry update/delete, no append-file primitive, no image clipboard), but agents can work around them.
Related MCP Connectors
MCP gateway and cloud hosting for MCP servers, agents and apps like RAG, managed from your agent.
Unified MCP Server is a remote MCP connector for AI agents and vertical AI products that provides access to 22,000+ authorized SaaS tools across 400+ integrations and 24 categories directly inside LLMs (Claude, GPT, Gemini, Cohere). Tools operate only on explicitly authorized customer connections, enabling agents to safely read and write against live third-party systems.
MEOK MCP Hardening MCP — automated security red-team for any MCP server. Maps OWASP LLM Top 10
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Related MCP Servers
- AlicenseAqualityDmaintenanceUnified MCP server integrating NIST and OWASP security frameworks with live vulnerability data, enabling security searches, compliance mapping, threat modeling, and checklist generation.4114MIT
- AlicenseNot gradedqualityAmaintenanceEnables professional penetration testers to run reconnaissance, network and web scanning, content fuzzing, vulnerability templates, brute-force checks, SQLi extraction, traffic capture, and engagement report generation through MCP clients.165 npmGPL 3.0
- AlicenseNot gradedqualityAmaintenanceEnables authorized penetration testers to run reconnaissance, scanning, brute-force, traffic-capture, and exploitation tools through MCP clients, with authentication, engagement recordkeeping, and client report generation.165 npmGPL 3.0
- AlicenseNot gradedqualityAmaintenanceEnables professional penetration testers to run reconnaissance, exploitation, password cracking, web fuzzing, vulnerability scanning, traffic capture, and client-reporting workflows through MCP transports with auth support.165 npmGPL 3.0