sdl-lab-hostops

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.

Category
Visit Server

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 with sudo -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 from C:\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 unless HOSTOPS_TOKEN is set; clients send Authorization: Bearer <token>. Network reachability is additionally gated by Tailscale ACLs, per the lab's v1 auth posture (STATUS_SPEC §11). Exception: GET /status is unauthenticated — it serves a read-only STATUS_SPEC v1.2 envelope (read-only conformance clause, §9) so the dashboard can register the instance in equipment.yaml and monitor the watchers. Primary operation: none (ops service) — activity is permanently idle; claims/allowed_actions are 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:

  1. http, minimal: skip the [serial] extra, keep the whitelist tiny.

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

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.

Official
Featured
TypeScript
Audiense Insights MCP Server

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.

Official
Featured
Local
TypeScript
Magic Component Platform (MCP)

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.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

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.

Official
Featured
TypeScript
Kagi MCP Server

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.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

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.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured