Skip to main content
Glama

mcp-drone-os

An Arch-based, LAN-only disposable agent runner. The project builds a bootable USB image with hardened SSH, per-agent Unix identities, isolated SMB shares, an MCP bridge, and a local control-plane dashboard.

Architecture

Run one coordinator on the laptop where the host agent lives. Booted machines are drones. The host agent connects to one local MCP server; the coordinator keeps fleet state and later maintains one persistent SSH control connection per drone. Drones run one-shot jobs or durable services.

host agent -> local mcp-drone-mcp -> coordinator state -> SSH -> drones

Job submission is batched. A twelve-variant experiment is one MCP call, not twelve independent shell conversations. A drone advertises available slots and capabilities; placement can be explicit or capability-aware.

Related MCP server: Awaitless

Features

This repository contains the contracts and safe host-side tooling needed for the first image profile:

  • mcp-drone-os validate validates an agent manifest without network access.

  • mcp-drone-os devices lists removable block devices.

  • mcp-drone-os write requires --yes, an exact device confirmation, and a removable-disk check before writing.

  • mcp-drone-os events appends and reads the legacy JSONL event format.

  • mcp-drone-mcp provides a local JSON-RPC stdio MCP gateway.

  • mcp-drone-agent provides a persistent JSON-lines worker protocol for launching, inspecting, and reading logs from transient systemd tasks.

  • mcp_drone_os.ssh_transport.SSHDrone keeps one SSH worker stream alive and uses OpenSSH connection multiplexing for repeated operations.

  • The coordinator stores drones, tasks, artifacts, and audit events in SQLite.

  • The MCP gateway exposes registration, batch submission, status, bounded logs, artifact listing/fetching, cancellation, reconciliation, persistence promotion, and user-event recording.

  • run_jobs accepts many variants in one call. Each job can select a drone; otherwise placement uses available slots. Jobs support one-shot work, durable services, and long-lived provisioning work.

  • Each drone uses a persistent JSON-lines SSH worker stream plus OpenSSH connection multiplexing. The host agent sends coarse batch operations rather than starting a new SSH process for every command.

  • Drones use per-agent Unix accounts, transient systemd units with CPU, memory, and process limits, and rootless Podman/Quadlet for durable services.

  • Enrollment supports agent keys, a separate controller key, and an OpenSSH host certificate signed by a coordinator-held CA. Password and root SSH are disabled.

  • A preconfigured image boots without a framebuffer login: it creates declared agent accounts, installs the controller key, derives a unique mcp-drone-<NIC> hostname, records IP/CPU/memory in /run/mcp-drone/identity, and advertises _ssh._tcp over mDNS.

  • runner/profile/ is an ArchISO profile with the minimal runtime package set, SSH hardening, first-boot enrollment hook, and systemd target.

  • tools/test-image.sh boots a built image in QEMU with SSH forwarded to port

Install and use

python3 -m venv .venv
. .venv/bin/activate
pip install -e '.[test]'
mcp-drone-os validate examples/manifest.json
mcp-drone-os devices

# Start the local MCP gateway for an MCP client
mcp-drone-mcp

# The coordinator can also be inspected directly
mcp-drone-os fleet --state /var/lib/mcp-drone/coordinator.db

Launch mcp-drone-mcp as a local stdio MCP server for the host agent. The dashboard is optional and defaults to localhost; view it remotely through SSH port forwarding. Use TLS and a network boundary before exposing it on a LAN.

USB-only operation

After the ISO is built, the runtime does not need this repository, Python packages, or an internet connection. Boot the USB and use the bundled commands:

/usr/local/bin/mcp-drone-os fleet --state /var/lib/mcp-drone/coordinator.db
/usr/local/libexec/mcp-drone-mcp

An MCP client on another computer can use the USB-hosted coordinator over SSH by launching /usr/local/libexec/mcp-drone-mcp as its SSH stdio command. The dashboard is available through ssh -L 8787:127.0.0.1:8787 ...; it is not exposed on the LAN by default. Enrollment and remote multi-drone jobs still need LAN connectivity to the other machines, but the USB itself is the complete control-plane/runtime artifact.

Build an image after installing Arch’s archiso package:

tools/build-image.sh out
tools/test-image.sh out/mcp-drone-os-0.1.0-x86_64.iso

For a dedicated machine, boot the ISO and run the guarded persistent installer from the live shell. It repartitions the selected whole disk, creates a LUKS2-encrypted root, installs the runner filesystem, and configures BIOS and UEFI GRUB boot paths:

/usr/local/bin/mcp-drone-install \
  --device /dev/sda --confirm-device /dev/sda --yes

The installer asks for the device path a second time and prompts for the disk passphrase. Verify the target carefully: this operation destroys all existing partitions on that disk. The live image remains the recommended disposable mode when a machine should be reset by rebooting.

The image configures wired Ethernet and USB Ethernet for DHCP through systemd-networkd. Wi-Fi credentials are intentionally not baked into the generic image; configure the appropriate network profile on machines that need wireless operation.

To bake a runner enrollment bundle into the image, set both MCP_DRONE_MANIFEST and MCP_DRONE_ENROLLMENT. The enrollment JSON must reference /etc/mcp-drone/manifest.json; the builder copies the selected manifest to that path. Enrollment tokens are secrets and should not be committed to the repository.

To make a USB immediately accept work from one controller, also provide its public key at build time. It is copied into the image but is not committed:

MCP_DRONE_MANIFEST=manifest.json \
MCP_DRONE_ENROLLMENT=enrollment.json \
MCP_DRONE_CONTROLLER_PUBLIC_KEY="$HOME/.ssh/id_ed25519.pub" \
tools/build-image.sh out-ready

The enrollment manifest declares the agent IDs that become drone-<id> Unix accounts. Discover a runner with avahi-browse -rt _ssh._tcp, then register its advertised hostname and SSH account with the coordinator. register_drone accepts ssh_user for hosts whose SSH username differs from the default mcp-control.

For an offline/preconfigured runner, start with examples/enrollment.json; add coordinator_url and a one-time token when the coordinator is available on the LAN.

Enrollment URLs must use HTTPS by default. For a temporary isolated lab only, allow_insecure: true can be set in the enrollment bundle. The dashboard supports --tls-cert and --tls-key when it must be reachable from a LAN; otherwise keep its localhost default and use SSH forwarding.

For authenticated host enrollment, configure the coordinator with MCP_DRONE_ENROLL_TOKEN and MCP_DRONE_SSH_CA_KEY. The drone generates its own host key on first boot and receives an OpenSSH host certificate; the CA private key never goes into the image.

SMB is intentionally optional. Install samba in a custom profile, generate /etc/samba/mcp-drone-shares.conf with mcp_drone_os.shares.render_shares, then enable mcp-drone-smb.service. Agent homes remain accessible over SFTP without enabling Samba.

Parallel example: 12 experiments on 3 machines

Register three runners with four slots each. Submit one batch through MCP:

{
  "agent_id": "research-agent",
  "mode": "once",
  "defaults": {"limits": {"cpu_quota": "200%", "memory_max": "2G", "tasks_max": 256}},
  "jobs": [
    {"command": ["./run-test", "--variant", "0"]},
    {"command": ["./run-test", "--variant", "1"]},
    {"command": ["./run-test", "--variant", "2"]}
  ]
}

Continue the array through variant 11. The coordinator persists all tasks, dispatches up to the available slots, and fills slots as work finishes. Use fleet_snapshot or reconcile_running for progress, then task_artifacts and fetch_artifact to collect results. The laptop handles coordination and metadata; the three drones perform the CPU and I/O work.

For scripts or repositories, call stage_bundle once per destination drone, then have the batch commands reference /var/lib/mcp-drone/staging/<bundle-id>. Jobs submitted for agent_id=alpha run as the provisioned drone-alpha Unix account, so the manifest must declare that agent on each target runner.

Current boundaries

This is a small v1 runner, not a general cluster scheduler. It does not flash media automatically, provide browser login, or implement remote HTTP MCP. Persistence promotion still expects an already-mounted data volume; the separate persistent installer handles whole-disk installation and LUKS2 root encryption. SMB, Kubernetes, and remote MCP transport remain optional future work.

USB writes are destructive and are never part of the build step. The image enrollment hook is intentionally explicit: it only registers when given a coordinator URL and one-time token.

Security defaults

The image profile disables root/password SSH, accepts only declared public keys, binds services to the private interface, and creates one Unix identity and share root per agent. The host builder never guesses a target disk.

Repository layout

schemas/manifest.schema.json   manifest contract
src/mcp_drone_os/              coordinator, MCP gateway, and state
runner/profile/                bootable ArchISO profile
runner/systemd/                service templates
tools/                         image build and QEMU test entrypoints
tests/                         unit and contract tests

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables SSH command execution, file uploads/downloads, and multi-server management with zero-config inline credentials, supporting async jobs and AI-readable output.
    15 npm
    2
    AGPL 3.0
  • A
    license
    A
    quality
    A
    maintenance
    Durable MCP server for managing long-running jobs locally, over SSH, or on Slurm clusters. Jobs survive client disconnects and return exit codes, bounded logs, and JSON artifacts.
    11
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to safely run bounded, sandboxed tasks on remote machines with persistent state and reviewable artifacts.
    Apache 2.0
  • A
    license
    A
    quality
    A
    maintenance
    Runs commands on machines you cannot SSH into by publishing steps to a transport the far side already reaches (git, file share, S3, relay), then reads back a log with every line timestamped in UTC. Seven tools cover send, status, logs, stall detection and a pre-flight check.
    7
    MIT