Skip to main content
Glama

MCP Fleet Orchestrator

A FastMCP server that lets a central agent such as Hermes manage a fleet of edge nodes in natural language:

  • Onboard new nodes: SSH checks, packages, Docker access, app clone, generated credentials.

  • Install skills on nodes from the app's skill-catalog.json.

  • Deploy the Multimodal Weld Defect Detection app and its MCP server with make up_agentic MCP=true. Deployment follows the shipped multimodal-deploy skill: preflight, deploy, status, and smoke check.

  • Work with each node's MCP server (describe, start_pipeline, list_insights_data, run_agent, …), one node at a time or across the fleet.

 "Onboard 192.168.1.23 as weld_node3 and deploy the weld app with its MCP server"
                                   │
┌──────────────── central host ────┼───────────────────────────┐
│ Hermes ── skill: fleet-orchestrator                          │
│   └─ mcp_servers.fleet ─► fleet-orchestrator (127.0.0.1:8765)│
│                             ├ inventory.db (SQLite)          │
│                             ├ skill cache (sparse git clone) │
│                             ├ certs/, secrets.env (mode 600) │
│                             └ ssh / ssh -L tunnels           │
└──────────────────────────────┼───────────────────────────────┘
                 SSH (key-based)│              tunnel 1400N ─► node 127.0.0.1:3000
        ┌───────────────────────▼──────────────────────────────┐
        │ node: ~/.fleet/skills/multimodal-deploy               │
        │       ~/manufacturing-ai-suite/industrial-edge-…      │
        │       make up_agentic MCP=true                         │
        │       nginx (127.0.0.1:3000) ─► /mcp ─► multimodal-mcp-server │
        └───────────────────────────────────────────────────────┘

No agent daemon runs on the nodes. The orchestrator uses plain key-based SSH. Each node keeps HOST_IP=127.0.0.1, so its UI and /mcp endpoint stay on loopback and are reached only through an SSH tunnel owned by the orchestrator.

Tools

Tool

What it does

register_node

Add a node (name, host, SSH user/port, tags) and test key-based SSH

list_nodes, node_status, remove_node

Inventory, live status (make status, MCP reachability), forget a node

onboard_node (job)

Install missing packages (passwordless sudo only) and check Docker. Clone the app. Fill empty .env credentials with random valid values and pin HOST_IP=127.0.0.1. Store the node's MCP login centrally

list_skills, install_skill

Read the app's skill catalog; copy a skill to ~/.fleet/skills/<skill> on the node and verify its SHA-256

stage_models (job)

Download the vLLM base model and the weld LoRA adapter as in the app's user guide. Requires accept_model_license=true

deploy_app (job), deploy_fleet

Run the skill's deploy flow for a variant: default, vllm, agentic, or agentic_mcp (= make up_agentic MCP=true). With agentic_mcp, the job also connects the node's MCP server

teardown_app (job)

make down MCP=true (requires confirm=true)

get_job, list_jobs

Poll long-running jobs; returns the result and log tail

connect_node_mcp

(Re)open the tunnel, pin the node's current nginx certificate, wait for tools/list

list_node_tools, call_node_tool, fleet_call_tool

Use a node's own MCP server. start_pipeline/stop_pipeline require confirm=true

register_node_in_hermes

Optional: add the node's MCP server directly to Hermes as mcp__<node>__<tool>

Long operations return a job_id right away, so tool calls don't hit agent timeouts. The fleet-orchestrator skill tells the agent to poll get_job.

Related MCP server: Latitude.sh MCP Server

Install on the central host

Requirements: Linux, Python 3.11+, ssh, git, and key-based SSH to every node. Each node needs an apt-based OS, a deployment account in the docker group (or passwordless sudo so onboarding can install packages), and the app's hardware requirements.

git clone https://github.com/vkb1/mcp-fleet-orchestrator.git
python3 -m venv ~/.local/share/fleet-orchestrator/venv
~/.local/share/fleet-orchestrator/venv/bin/pip install ./mcp-fleet-orchestrator

Run it as a long-lived service, so jobs and tunnels survive between chat sessions:

install -D -m 0644 mcp-fleet-orchestrator/deploy/fleet-orchestrator.service ~/.config/systemd/user/fleet-orchestrator.service
systemctl --user daemon-reload
systemctl --user enable --now fleet-orchestrator
loginctl enable-linger "$USER"

The HTTP endpoint binds to 127.0.0.1:8765 and requires a bearer token. On first start the token is written to ~/.fleet-orchestrator/api-token (mode 600); fleet-orchestrator token prints its path. The service runs without your SSH agent, so the node SSH key it uses must be readable without a passphrase, or set SSH_AUTH_SOCK in ~/.config/fleet-orchestrator.env.

Configuration

Set these in the environment or in ~/.config/fleet-orchestrator.env:

Variable

Default

Purpose

FLEET_REPO_URL

https://github.com/open-edge-platform/manufacturing-ai-suite.git

Repository cloned on nodes and used as the skill source

FLEET_REPO_BRANCH

main

Branch for both

FLEET_SKILLS_REPO

(unset)

Use a local checkout as the skill source instead of cloning

FLEET_REMOTE_ROOT

manufacturing-ai-suite

Clone location under the node user's home

FLEET_HOME

~/.fleet-orchestrator

Inventory, logs, certificates, secrets

FLEET_TUNNEL_BASE_PORT

14000

Node N gets local port 14000+N (kept clear of the 1300N tunnels from hermes-setup-v2.md)

FLEET_DEPLOY_TIMEOUT

3600

Seconds allowed for one deployment

FLEET_STRICT_HOST_KEYS

false

true: only connect to nodes whose host key is already in $FLEET_HOME/known_hosts (otherwise trust on first use)

FLEET_API_TOKEN

(generated)

Bearer token for HTTP mode (32+ characters)

FLEET_HERMES_BIN, HERMES_HOME

hermes, ~/.hermes

Used by register_node_in_hermes

Connect Hermes

Store the token in Hermes's .env without echoing it, then register the server and install the skill:

printf 'FLEET_API_TOKEN=%s\n' "$(cat ~/.fleet-orchestrator/api-token)" >> ~/.hermes/.env
chmod 600 ~/.hermes/.env
hermes config set mcp_servers.fleet.url "http://127.0.0.1:8765/mcp"
hermes config set mcp_servers.fleet.headers.Authorization 'Bearer ${FLEET_API_TOKEN}'
install -d ~/.hermes/skills/devops
cp -r mcp-fleet-orchestrator/skills/fleet-orchestrator ~/.hermes/skills/devops/
hermes mcp test fleet

Stdio also works (command: ~/.local/share/fleet-orchestrator/venv/bin/fleet-orchestrator, args: ["serve", "--transport", "stdio"]). In that mode, running jobs and tunnels stop when the Hermes session ends.

Use it

hermes -s fleet-orchestrator chat

Register 192.168.1.21 as weld_node1 and 192.168.1.22 as weld_node2, both tagged line1, user deploy. Onboard them.

Install the multimodal-deploy skill on both and deploy the agentic app with the MCP server on line1.

What tools does weld_node1's MCP server have? Describe every node.

Start the weld pipeline on weld_node2 with vision on GPU and time series on CPU. (The agent asks you to confirm.)

Show the latest 10 insights from weld_node2, run the agent over the last 1m and fetch the results.

Tear down weld_node1. (The agent asks you to confirm.)

If key-based SSH is not set up for a node, register_node returns the ssh-copy-id command to run in your own terminal. Passwords never go through the chat.

Security model

  • No new network exposure. Node MCP endpoints stay on loopback and are reached through SSH tunnels. The orchestrator binds to loopback and requires a bearer token. Binding elsewhere needs --allow-remote plus --ssl-certfile/--ssl-keyfile.

  • SSH host keys. The orchestrator uses its own $FLEET_HOME/known_hosts. By default a node's key is trusted on first use. For stricter setups, set FLEET_STRICT_HOST_KEYS=true and add verified keys first, for example ssh-keyscan -H <node> >> ~/.fleet-orchestrator/known_hosts after checking the fingerprint out of band.

  • Untrusted tool input. Every argument that reaches SSH, a path, or a config key is validated against a strict pattern. Remote commands are fixed scripts bundled with this package, with each argument shell-quoted. The agent cannot pass free-form shell.

  • Secrets stay out of chats and command lines. Generated .env values are sent over SSH stdin. Node MCP logins are stored in ~/.fleet-orchestrator/secrets.env (mode 600) and are never returned by a tool.

  • Pinned TLS. Each node's self-signed nginx certificate is fetched over the authenticated SSH channel and is the only trust anchor for that node. nginx regenerates the certificate on every deploy, so the pin is refreshed the same way. Only Python 3.13's strict X.509 profile is relaxed, because the app's certificate has no keyUsage extension.

  • Allow-listed node tools. Only the app's known MCP tools can be called. start_pipeline and stop_pipeline need confirm=true, and so do teardown_app and remove_node. stage_models needs explicit license acceptance. These flags are set by the agent, so they guard against accidental calls, not against a compromised agent. Node tool output is data from the node, and the bundled skill tells the agent to act only on what the user asked.

  • Least privilege on nodes. Onboarding uses sudo -n only, so it never prompts. The deployment user's Docker access is root-equivalent, so use a dedicated account with key-only SSH.

  • One orchestrator per FLEET_HOME. A lock file enforces it, because per-node job locks and tunnels live in the process. Tunnels left behind by a crash are detected through their pidfiles and replaced. Cancelling a job stops the local ssh client. A remote make that is already running may still finish on the node.

Development

python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
.venv/bin/ruff check . && .venv/bin/ruff format --check .
.venv/bin/pytest
# Run the end-to-end test against the real multimodal-deploy skill:
FLEET_TEST_SKILLS_REPO=/path/to/manufacturing-ai-suite .venv/bin/pytest tests/test_e2e_fake_node.py

tests/test_e2e_fake_node.py runs the full flow: register, onboard, skill install, deploy with MCP=true, node MCP calls with Basic auth over a tunnel with a pinned CN=localhost certificate, and teardown. It runs against a fake node built from fake ssh and docker binaries, a stand-in Makefile, and an HTTPS FastMCP server.

License

Apache-2.0

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    B
    maintenance
    Enables deploying and managing infrastructure via natural language, including project/domain management, compute nodes, image deployment, and CI/CD integration.
    70
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables natural language management of Latitude.sh infrastructure, allowing users to list, create, and delete servers, projects, and SSH keys through MCP-compatible clients.
    15 npm
    4
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables server operations and AI application deployment via 16 MCP tools, including container management, disk diagnostics, and GitHub repository search with one-click deployment, through natural language.
    9
    MIT