sdl-lab-hostops
MCP server for SDL2 lab machines providing host operations: service status, log tailing, whitelisted service restarts, serial port listing, and local status probing. It is strictly whitelisted with no arbitrary command execution.
README
sdl-lab-hostops
Whitelisted host-operations MCP server for SDL2 lab machines. It answers "is the service up, what did it log, did the USB adapter come back, is the local device API answering" — the class of incident (boot USB-enumeration races, corrupt-venv locks, silent partial syncs) that a network client can see but not diagnose.
Deliberate non-goals: no shell tool, no arbitrary commands, and no path
to any device /control/* endpoint. Hardware control belongs to the
lab-skills SDK and its MCP server (ac-organic-lab — AGENT_RULES §1.1).
The tool surface below is the complete surface; every target must be
whitelisted in config.toml, so a service or port not listed cannot be
touched at all.
Tools
| Tool | Mutates? | Notes |
|---|---|---|
host_info() |
no | hostname, OS, uptime, disk free, loadavg, backend |
service_status(service) |
no | systemd unit / Windows service state |
tail_service_log(service, lines) |
no | journald (Linux) or NSSM .out/.err logs (Windows); 10–400 lines |
restart_service(service) |
yes | only services in the smaller restartable list; Windows path runs nssm restart + the mandatory sc continue quirk; audited (see below) |
list_serial_ports() |
no | pyserial ([serial] extra) or /dev glob fallback |
probe_local_status(port) |
no | GET http://127.0.0.1:<port>/status for whitelisted ports |
Backends
Selected automatically by platform:
-
systemd (Linux, Raspberry Pi):
systemctl/journalctl. Restarts can be prefixed withsudo -n(use_sudo = true) — grant only the exact units, e.g./etc/sudoers.d/sdl-lab-hostops:sdl2 ALL=(root) NOPASSWD: /usr/bin/systemctl restart plateloc.service -
nssm (Windows device PCs):
sc query,nssm restart+sc continue(DEVICE_PC_SETUP §7 quirk), log tails fromC:\SDL_Logs\<svc>.{out,err}.log.
Transports & auth
stdio(default): the MCP client spawns the process per connection. No daemon, no token. This is also the daemonless "lite" mode — see the Pi section.http(streamable-http): long-lived service. A non-loopback bind refuses to start unlessHOSTOPS_TOKENis set; clients sendAuthorization: Bearer <token>. Network reachability is additionally gated by Tailscale ACLs, per the lab's v1 auth posture (STATUS_SPEC §11). Exception:GET /statusis unauthenticated — it serves a read-only STATUS_SPEC v1.2 envelope (read-only conformance clause, §9) so the dashboard can register the instance inequipment.yamland monitor the watchers. Primary operation: none (ops service) —activityis permanentlyidle; claims/allowed_actionsare N/A because there is no control surface.
Environment
| Var | Meaning |
|---|---|
HOSTOPS_CONFIG |
path to config.toml (or pass --config) |
HOSTOPS_TOKEN |
bearer token, required for non-loopback http binds |
HOSTOPS_INGEST_URL |
e.g. http://sdl2-server:8001 — enables audit rows |
Audit: every restart_service posts a hostops_action event to the
dashboard's POST /api/ingest/events (best-effort, never blocks the
restart). Reads are not audited. Register the hostops_action event type in
ac-organic-lab/docs/LAB_MONITORING.md §4 when the first instance ships.
Install — Windows device PC (NSSM)
Follow ac-organic-lab/docs/DEVICE_PC_SETUP.md §3 with:
cd C:\Users\sdl2\Projects
git clone <this-repo> sdl-lab-hostops
cd sdl-lab-hostops
Copy-Item config.example.toml config.toml # edit whitelists for this PC
C:\SDL_Tools\uv.exe sync --extra serial
nssm install sdl-lab-hostops C:\SDL_Tools\uv.exe run --project C:\Users\sdl2\Projects\sdl-lab-hostops lab-hostops-serve --transport http
nssm set sdl-lab-hostops AppDirectory C:\Users\sdl2\Projects\sdl-lab-hostops
nssm set sdl-lab-hostops AppEnvironmentExtra HOSTOPS_TOKEN=<token> HOSTOPS_INGEST_URL=http://sdl2-server-gaia.tail6a1dd7.ts.net:8001
# ... stdout/stderr logs, auto-start, run-as user: exactly as DEVICE_PC_SETUP §3
nssm start sdl-lab-hostops
sc continue sdl-lab-hostops
Note the service account needs rights to restart the other services
(sc sdset per service, or run sdl-lab-hostops under an account that has them).
A permission failure is reported truthfully in the tool result.
Install — Linux / Raspberry Pi (systemd)
git clone <this-repo> /opt/sdl-lab-hostops && cd /opt/sdl-lab-hostops
cp config.example.toml config.toml # edit
uv sync # base deps only — no extras needed
sudo cp deploy/sdl-lab-hostops.service /etc/systemd/system/
sudo systemctl enable --now sdl-lab-hostops
Pi Zero 2W "lite" mode
The base install is small (mcp + httpx/starlette/uvicorn, all pure-Python or
armv8 wheels) and idles at a few tens of MB — the same footprint class as the
sense-every-zone gateway already running on sdl2-pi0-environ-01. Two ways
to run it lighter:
-
http, minimal: skip the
[serial]extra, keep the whitelist tiny. -
daemonless stdio-over-SSH — zero resident footprint; the central Hermes spawns it on demand and SSH is the auth (no token, no open port):
# Hermes mcp_servers entry on the central server hostops-pi0-environ: command: ssh args: [sdl2@sdl2-pi0-environ-01, /opt/sdl-lab-hostops/.venv/bin/lab-hostops-serve, --transport, stdio, --config, /opt/sdl-lab-hostops/config.toml]Requires key-based SSH from the central server. Prefer this on the Pis; prefer the http service on the Windows PCs (no SSH daemon there).
Client registration
Register each instance in the lab's reviewed MCP registry
(ac-organic-lab/mcp/servers.yaml) with the full 6-tool include list, and
mirror that allowlist in the client config (e.g. the Hermes lab-ops
profile's mcp_servers.<name>.tools.include). A new tool added here should
only reach an agent after both lists are updated — that's the point.
Tests
uv run pytest -q
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.