lanbus
Detects FastAPI/OpenAPI AI APIs on the LAN by fingerprinting /openapi.json during discovery.
Detects Gradio applications on the LAN through HTTP fingerprinting during discovery.
Detects Jupyter services on the LAN through HTTP fingerprinting during discovery.
Discovers Ollama endpoints on the LAN and supports sending prompts to Ollama models, including model listing via /api/tags and native Ollama calls.
Discovers OpenAI-compatible model endpoints and supports sending prompts to them, including /v1/models enumeration and OpenAI-compatible API calls.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
lanbus
One agent entry. Sub-agents everywhere else on your LAN.
English · 中文 · Overview · 中文总览 · Architecture · Protocol
You talk to a single main agent - an A agent CLI, a B agent CLI, a C agent desktop, or anything that speaks MCP. It dispatches work to agents running on your other machines — Windows for the Web UI, WSL for the Linux build, macOS for native packaging — then verifies what actually changed and either accepts the result or sends it back for rework.
Zero mandatory dependencies. Standard library only. Never leaves your LAN. Optional Playwright unlocks real browser actions; Chrome/Edge headless gives fallback screenshots. A built-in scanner finds AI agents already running on the LAN without installing anything on them.
you ──► main agent (A agent CLI)
│ MCP: lan_dispatch / lan_logs / lan_result / lan_review
▼
┌───────────────────┐
│ lanbus hub :8788 │ SQLite task table + state machine
└───┬───────────┬───┘
REST (pull) │ │ REST (pull)
┌───▼────┐ ┌───▼────┐
│ win-ui │ │ mac-ui │
│windows │ │ macos │
└───┬────┘ └────────┘
│ same machine
┌───▼─────┐
│wsl-core │
│ wsl │
└─────────┘Workers pull from the hub, so only the hub machine needs an inbound port. Sub-environments need no firewall rules at all.
Why this exists
Running agents in three environments usually means being the human message bus: you ask one agent for a task, then copy its text into the other agent's window, then eyeball the result yourself. lanbus replaces that loop with machine-checkable facts:
Without lanbus | With lanbus |
you paste the task across |
|
the remote agent says "done" |
|
you trust the summary |
|
you judge by vibes |
|
you cannot see the remote run |
|
"cancel" only changes a database row |
|
a crashed worker strands the task | lease + reaper requeue it, with a new claim token |
A remote agent physically cannot approve its own work: only the caller can call lan_review.
Related MCP server: Crosschat Relay
First: who is already on the LAN?
lanbus discover # local processes + services + local /24
lanbus discover --cidr 192.168.1.0/24 --json
lanbus discover --hub http://HUB:8788 --env windowsIt combines three evidence sources:
local processes — agent CLI and desktop processes (A agent CLI, B agent CLI, C agent desktop, local model runtimes, image/UI tools), matched by executable name and command line; on Windows it also reads running WSL processes (
scope=wsl:<distro>);local listening ports — PID/process/port mapping;
LAN scan + HTTP fingerprints — local model runtimes (
/api/tags), OpenAI-compatible/v1/models, chat/web UIs, inference servers, notebook servers, browser DevTools, MCPserverInfo, lanbus/health, and FastAPI/OpenAPI AI APIs (/openapi.json).
A native Go scanner is included as Phase 0; Python falls back to the pure-Python scanner automatically. Build it once with make go-scan (or make go-scan-all for macOS/Linux cross-builds). The report includes engine: "go" or engine: "python".
A native Go worker is also available as Phase 1.5. It speaks the same hub protocol, streams logs, uploads artifacts, and handles lan_interrupt by killing the process tree:
bin/lanbus-worker --name go-win --env windows --hub http://HUB:8788 --token WORKER_TOKEN --cwd "D:\proj" --agent ADAPTERBuild with make go-worker / make go-worker-all. The Go worker now handles agent, shell, discover, and ask tasks, including native LAN discovery and OpenAI-compatible runtime calls. Browser tasks remain on the Python worker.
Add --pty to run agents on a real PTY (ConPTY on Windows, Unix PTY elsewhere):
bin/lanbus-worker --name tui --env tui --hub http://HUB:8788 --token TOKEN --cwd D:/proj --agent ADAPTER --ptyPTY mode keeps full-screen/TUI CLIs working and still uses the same Job Object/process-group cancellation.
Native Go hub (Phase 2)
A native hub subset is available as lanbusd:
make go-hub
bin/lanbusd --bind 127.0.0.1 --port 8789 --data-dir /tmp/lanbus-go --token TOKEN --worker-token TOKENIt implements the worker REST protocol (register/claim/progress/log/submit/recover),
SQLite persistence, MCP lan_dispatch / lan_dispatch_many / lan_envs /
lan_list / lan_result / lan_await / lan_logs / lan_review / lan_cancel /
lan_interrupt / lan_artifact / lan_chat / lan_conversations /
lan_discover / lan_ask / lan_shot, SSE /events, artifact storage, and /ui.
Dual-run is covered by tests/test_go_hub.py: the same Python fake worker runs
against the Python hub and lanbusd, comparing status, exit code, verify flag,
and task result. The Go hub is now the default on port 8788; the Python hub
remains available as a fallback (lanbus hub / start-hub-python.cmd) for
browser-task and legacy compatibility.
Local multi-agent chat
Start one worker per local agent - a Linux-side A agent CLI, a Windows-side B agent CLI, a C agent desktop, a WSL agent - each with its own env name, then let the hub relay a conversation:
lanbus worker --name win-a-cli --env win-a-cli --hub http://127.0.0.1:8788 --agent ADAPTER_A --cwd D:/proj
lanbus worker --name win-b-cli --env win-b-cli --hub http://127.0.0.1:8788 --agent ADAPTER_B --cwd D:/proj
lanbus worker --name win-c-ui --env win-c-ui --hub http://127.0.0.1:8788 --agent ADAPTER_C --cwd D:/proj
lanbus chat --envs win-a-cli,win-b-cli,win-c-ui --message "introduce your strongest capability" --rounds 2The same feature is the MCP tool lan_chat (2–4 envs, 1–6 rounds) and POST /chat. Every turn is a normal lanbus task, so lan_logs, lan_result, lan_interrupt, and review still work on the individual turn.
Conversations are persisted. List them, read one, or continue it:
lanbus chat --list
lanbus chat --conversation c123abc --message "继续,总结刚才的结论" --rounds 1MCP: lan_conversations(conversation_id=...). REST: GET /conversations, GET /conversations/<id>.
Web dashboard
The hub serves a zero-dependency dashboard at http://HUB:8788/ui (public HTML; APIs use the agent token):
online environments and capabilities
persisted conversation list and transcript
start a new 2–4 agent conversation
resume an existing conversation
The UI uses the same endpoints as MCP/CLI: GET /api/envs, GET /conversations, POST /chat.
Human confirmation for remote agents
Cross-machine targets require an explicit human approval before a task or
conversation can start. The hub keeps local envs on the fast path and puts
remote-target tasks in waiting_confirmation.
lanbus confirm list
lanbus confirm approve --env macos-a-cli --ttl 1800
lanbus confirm revoke --env macos-a-cliThe approval token is separate from the main-agent token:
~/.lanbus/operator-token.txtThe Web dashboard / GUI shows remote targets with hostname, agent, and
cwd; use the "确认此 agent" button. The agent token cannot approve targets.
For multiple agents in the same project, give each worker a different env and
name, with the same or different --cwd; the human chooses the exact env in
the approval panel.
Desktop GUI / tray (Windows)
make go-gui
bin/lanbus-gui.exe --hub http://127.0.0.1:8788Wails/WebView2 window + tray menu. It embeds the same dashboard and proxies
authenticated API calls to the running hub. Closing the window hides it to the
tray; the tray menu reopens it, opens /ui in the default browser, or quits.
lanbus web # open the dashboard in the default browser
lanbus gui # launch bin/lanbus-gui.exe
make package # portable Windows zip under dist/The portable package and optional Inno Setup installer are under packaging/windows/.
Signing (sign.ps1) and a SHA-256 update helper (update.ps1) are included.
Persistent local workers
lanbus local init # write ~/.lanbus/local.json
lanbus local up # start configured workers if their env is offline
lanbus local status
lanbus local downlocal up skips workers whose env is already online, so it is safe to run from login startup. It supports Go workers, Python workers, and WSL entries ("wsl": "Ubuntu-24.04"). See examples/local/README.md.
No lanbus/MCP installation is required on the discovered machines. For endpoints that expose an HTTP API you can immediately query them:
lanbus ask --endpoint 192.168.1.50:11434 --prompt "用一句话介绍自己"
lanbus ask --endpoint 192.168.1.60:1234 --prompt "review this diff" --model qwen2.5Important limit: a GUI-only agent that opens no port (a C agent desktop) can only be seen as a process on the machine where it runs. To see it from another machine, run a lanbus worker there or run lanbus discover on that host. Remote discovery is inherently limited to what the network exposes.
Quick start (3 minutes)
1. Hub — on the always-on machine (usually Windows)
pip install .
make go-hub
bin/lanbusd --bind 0.0.0.0 --port 8788 --data-dir ~/.lanbus --token choose-a-secret --worker-token a-different-worker-secretlanbusd is the default hub. The Python hub remains available for browser/legacy
compatibility: lanbus hub --port 8789 ... (or start-hub-python.cmd).
--worker-token is optional. If omitted, workers use the same token as the main agent (simplest single-secret setup). With it, a worker token can only call /worker/*, never /mcp or /events; the agent token can still operate workers. For true per-worker identity, pass --worker-tokens '{"win-ui":"token1","wsl-core":"token2"}' (or --worker-tokens-file); a token then only works for its registered name.
New-NetFirewallRule -DisplayName "lanbus" -Direction Inbound -Protocol TCP `
-LocalPort 8788 -Action Allow -Profile PrivateData (SQLite + artifacts + generated token) goes to ~/.lanbus. Override with LANBUS_DATA_DIR or --data-dir. TLS is available with --tls-cert / --tls-key.
Or with Docker:
LANBUS_TOKEN=... LANBUS_WORKER_TOKEN=... docker compose up -d2. Worker — one per environment
# Windows
lanbus worker --name win-ui --env windows --hub http://HUB_LAN_IP:8788 `
--token a-different-worker-secret --cwd D:\proj\webui --agent ADAPTER# WSL
lanbus worker --name wsl-core --env wsl --hub http://HUB_LAN_IP:8788 \
--token a-different-worker-secret --cwd /mnt/d/proj --agent ADAPTER
# macOS
lanbus worker --name mac-ui --env macos --hub http://HUB_LAN_IP:8788 \
--token a-different-worker-secret --cwd ~/proj --agent ADAPTER--agent selects a built-in adapter for a common agent CLI (see the adapter reference); shell runs the prompt as a command and echo is a connectivity check. --cmd accepts any CLI you already have: {prompt_file} expands to a temp file holding the prompt, otherwise the prompt goes to stdin. Use --cmd for a C agent desktop's bundled CLI, a vendor-specific wrapper, or an agent whose flags differ from the built-in adapters.
Each worker also gets:
Streaming logs — agent stdout/stderr is uploaded line by line; watch with
lan_logsorlanbus logs --follow.Real cancellation —
lan_cancelsignals the worker, which kills the whole process tree; late submissions are rejected by claim token.Lease + auto-requeue — crash the worker mid-task and the hub requeues after the lease expires (default 120s, configurable per task).
Artifact upload — screenshots/logs are base64-uploaded to the hub, so separate machines no longer need a shared filesystem.
Browser helper —
pip install playwright && playwright install chromium(or install Chrome/Edge) letslan_shotclick, fill forms and screenshot.lanbus doctorreports what is available.Discovery —
lanbus discover/lan_discoverfinds AI agents on the LAN without touching them;lan_askcan query OpenAI-compatible model endpoints directly.Context handoff —
context+ local.lanbus/context.md+ git state are composed into the prompt automatically.
3. Main agent — A agent CLI (or any MCP client)
cd your-project
cp -r /path/to/lanbus/integrations/mcp-client-preset/.mcp.json.example .mcp.json
# set HUB_LAN_IP + token, then point your MCP client at it
cp -r /path/to/lanbus/integrations/mcp-client-preset/agents .mcp/agents
cp -r /path/to/lanbus/integrations/mcp-client-preset/commands .mcp/commandsintegrations/mcp-client-preset is only a ready-made preset (sub-agent prompts and
slash-command text) that you can adapt to your client. Any MCP client works:
register http://HUB_LAN_IP:8788/mcp with the agent token and the same tools
appear. Approve the project MCP server once when your client asks, then:
/lan windows change the login button radius from 4px to 12px, run npm run build, screenshot when greenIt resolves the environment, dispatches, watches logs, reads verify_out and diff, judges, sends back with feedback if needed, and reports when accepted.
{
"mcpServers": {
"lanbus": {
"type": "http",
"url": "http://HUB_LAN_IP:8788/mcp",
"headers": { "Authorization": "Bearer choose-a-secret" }
}
}
}MCP tools
Tool | Purpose |
| online workers, caps ( |
| dispatch one task; |
| fan out to several environments in one call |
| browser task: URL + click/fill/evaluate actions + screenshot |
| wait for tasks to reach a reviewable state |
| full record: output, log tail, |
| incremental real-time logs ( |
| list/read artifacts; images and text returned inline |
| LAN AI-agent reconnaissance without preinstall: local processes + ports + HTTP fingerprints; |
| send a prompt to a discovered OpenAI-compatible model endpoint and get its reply |
| the gate: |
| filter by status / env / kind |
| cancel; stops the remote process tree |
| Ctrl+C-equivalent for a lanbus task: kill the worker process tree, independent of window focus/background state |
Task states:
queued ──claim──► claimed ──► running ──submit──► submitted
▲ │ │
│ └─ lease lost ──► queued ├─ approve ─► approved
│ (recoveries+1) ├─ fail ────► failed
└──────── rework (feedback, retry+1) ───────────┘
└─ cancel ──► cancelledrework requeues with retry+1; past max_retry (default 2) the task becomes failed instead of looping forever. A lost worker lease requeues with recoveries+1; past max_recoveries (default 3) it fails. cancelled is terminal: the worker is signalled to kill its process tree, and any late submit carrying the old claim token is ignored.
HTTP surface (for scripts and dashboards)
All endpoints except /health require Authorization: Bearer <token>.
Method | Path | Purpose |
GET |
| status counts, no auth |
GET |
| SSE stream of task/worker/log events ( |
GET |
| incremental execution logs |
GET |
| zero-preinstall discovery (also |
POST |
| prompt a discovered AI endpoint |
GET |
| authenticated artifact download |
POST |
| MCP (stateless streamable HTTP) |
POST |
| worker registration + capabilities |
POST |
| atomic claim; returns |
POST |
| lease renewal + cancellation poll |
POST |
| batched streaming log lines |
POST |
| submit result + verify + diff + inline/base64 artifacts |
POST |
| liveness + cancellation hints |
POST |
| worker restart hands back its lost tasks |
Discovery itself is not a network listener on the scanned hosts: it runs on the hub/worker/CLI side and only probes standard TCP/HTTP surfaces.
Security
Two roles: agent token (
--token) for MCP/read/artifacts; worker token (--worker-token) for/worker/*only. If no worker token is set, both roles share one token for backward compatibility. Optional per-worker tokens (--worker-tokens) bind a token to one worker name.Worker ownership: submit/progress/log only work for the task currently assigned to that worker name and its random
claim_token; a stale worker cannot resurrect a requeued/cancelled task.Hostheader allowlist: onlylocalhost/loopback and IP literals, which blocks DNS-rebinding style attacks (a hostname resolving to your LAN IP).Optional TLS:
--tls-cert+--tls-keyon the hub; workers use normal verification,--ca FILEfor a private CA, or--insecureonly on a trusted LAN.Workers are outbound-only — no listening port on Windows/WSL/macOS.
lanbus discoverperforms an active TCP/HTTP scan. Run it only on networks you are allowed to inspect; it does not exploit services or modify remote state.Do not publish port 8788 to the internet. For cross-network use, put it behind WireGuard/Tailscale.
Reliability model
Execution transport: prefer worker tasks (
lan_dispatch) over UI keystroke injection. Worker tasks have a process tree, a claim token, and a real cancellation path; UI automation only observes/notifies a desktop and is not the execution mechanism.Ctrl+C:
lan_cancel/lan_interruptsets a cancellation flag; the worker kills the whole process tree (Windows Job Object or POSIX process group). This works while the window is unfocused or the task is in the background.Lease: claim sets
lease_expires_at; the worker renews every ~3s via/worker/progresswhile the agent, verify command, or browser runs.Reaper: hub requeues expired
claimed/runningtasks, up tomax_recoveries; then fails them with evidence.Claim token: every claim gets a random token; submits from the old execution are rejected after requeue/cancel.
Outbox: if the hub is unreachable when a task finishes, the worker writes the submission under
~/.lanbus/outbox/<name>/and retries until accepted. If the lease expired meanwhile, the hub still accepts the late result while the task is queued and not yet re-claimed.Logs: streamed in batches; sequence numbers make retries idempotent. A local copy is kept under
~/.lanbus/logs/.
Context handoff
A remote agent is a fresh CLI process, so lanbus composes a self-contained prompt:
task id / env / cwd / kind / retry / verify / artifact globs;
contextyou pass tolan_dispatch(background, paths, constraints, acceptance criteria);worker-local
.lanbus/context.md,.lanbus/rules.md, optional--context-file, plus git branch/status;your
prompt;previous
feedback;non-interactive execution rules.
lan_result returns the exact composed prompt, so you can see what the remote agent actually received.
Known limits
Conversation context is not magically shared. lanbus injects structured
context, local.lanbus/context.md, and git state, but if a detail only exists in your local chat you must pass it explicitly.Workers use each CLI's non-interactive one-shot mode (
-p/exec/headless); anything needing interactive approval fails instead of prompting. Put the required permission mode or pre-authorization in that CLI's own config. Built-in adapters already pass a non-interactive permission mode where the CLI supports one.If WSL uses
/mnt/d/...and Windows usesD:\..., that is one filesystem — no syncing needed, but concurrent edits to the same file will collide. Partition tasks by file.WSL→Windows needs either mirrored networking (
networkingMode=mirroredin.wslconfig, thenwsl --shutdown) or the host IP, which changes across reboots.Headless browser fallback only supports
goto+screenshot. Click/fill/evaluate requires Playwright (pip install playwright && playwright install chromium).Browser tasks require a worker with a
browsercapability;lan_envsreportshas_browserandcaps.Remote discovery can only see hosts that answer on scanned TCP ports or expose an HTTP(S) API. GUI-only agents are visible only in local process scans; run a lanbus worker or
lanbus discoveron that host for full coverage. Port 443 is fingerprinted over HTTPS; custom HTTPS ports are not probed by default.Discovery is heuristic: a port can be open for unrelated software, and an OpenAI-compatible endpoint may be an inference server rather than a full tool-using agent. Verify before sending sensitive prompts.
An agent CLI on macOS needs a worker running on the Mac (
--agent ADAPTERor--cmd) or a locallanbus discover; a Windows scanner cannot see a GUI/CLI process on the Mac without one of those. macOS Local Network permission must allow Terminal/the worker.UI-only desktop windows have no stable programmable input/interrupt API. lanbus uses CLI/headless/worker for task execution; GUI automation is best-effort notification only.
macOS worker
If an agent CLI is already installed on macOS but is not reachable from Windows, it has no worker. Run this on the Mac:
export PATH="$HOME/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"
lanbus doctor
lanbus worker --name mac-a-cli --env macos --hub http://HUB_LAN_IP:8788 --token WORKER_TOKEN --cwd /Users/me/proj --agent ADAPTEROr use the native Go worker without Python:
bin/lanbus-worker-darwin-arm64 (Apple Silicon) or bin/lanbus-worker-darwin-amd64, with the launchd template
examples/macos/com.lanbus.worker-go.plist (native Go worker) or
examples/macos/com.lanbus.worker.plist (Python worker); set ADAPTER and paths.
Or run examples/macos/start-worker.sh in the foreground for a quick self-check.
After it connects, lan_envs shows mac-a-cli with the adapter capability, and lan_dispatch(env="macos", ...) runs in the current project. lan_discover from Windows can only see the Mac's open ports; process-level agent detection happens on the Mac via its worker or local lanbus discover.
Development
pip install -e ".[dev]"
pytest -v # 39 tests: protocol, dispatch/rework, logs, cancel/interrupt, lease recovery, artifacts, roles, discovery, chat, web UI, local supervisor, Go hub tools/dual-run, remote confirmation
make go-test # Go scanner + worker tests
make go-scan # native bin/lanbus-scan; Python auto-detects it
make go-worker # native bin/lanbus-worker
python -m pip wheel . --no-deps --no-build-isolation -w distTests spin up a real hub and real workers on free ports and drive actual MCP JSON-RPC — no mocks.
Docs
Architecture — components, why workers pull, state machine, evidence model
Protocol — every endpoint, tool schema, error codes, SSE events
Troubleshooting — symptom → cause → fix
Go migration assessment — why/if to move the core to Go, magpie patterns
Go scanner and worker — Phase 0/1 native binaries
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Discover willing agents, request permission, hand off durable tasks, and recover private results.
Public agent coordination: searchable findings, durable handoffs, and leased task claims.
Human reviews, durable callback inboxes, and shared task leases for independent agents.
Task-first cross-agent collaboration for discussions, review, referrals, and reusable knowledge.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables coding agents from different vendors on the same machine to delegate tasks to each other over the A2A protocol, while also allowing the machine to act as an A2A peer.7MIT
- AlicenseNot gradedqualityCmaintenanceLets AI agents in different harnesses hand each other concrete tasks, claim and report on them, and continue after restarts via a live dashboard and unattended workers.MIT
- AlicenseNot gradedqualityBmaintenanceEnables orchestration of worker registration, capability-based task dispatch, heartbeat telemetry, automatic circuit breaking, and checkpoint recovery for distributed agent operations.7MIT
- AlicenseBqualityBmaintenanceEnables a host coding agent to launch and coordinate real subagent sessions in other agent CLIs and accounts, sharing existing MCP servers, skills, plugins, and instructions. Supports two-way messaging, automatic account failover, and mixed-CLI delegation while leaving credentials with the vendor CLIs.811Apache 2.0