Local-first MCP gateway and homelab control plane with CLI, HTTP API, and web UI.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent — or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag — we're steadily working through the catalog.
💡 Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)

Rust MCP gateway with Code Mode, authentication, setup, logs, CLI, HTTP API, and operator web UI.
Canonical remote: git@github.com:dinglebear-ai/labby.git.
The root README is the public entrypoint. The topic docs in docs/ own the detailed contracts; when this file and a topic doc disagree, fix the topic doc first and then refresh this summary.
Labby is centered on the current gateway/operator surface:
search and
execute.labby proxy /path/to/dist.js and expose its unmodified MCP surface over
loopback or an owned Tailscale Serve HTTPS port with tailnet, bearer, OAuth,
or explicit no-auth policy.$LABBY_HOME.~/.labby, provision the host service, and
run a health audit across env, reachability, auth, and versions.labby serve log stream.The registered services on this branch are exactly doctor, fs, gateway,
lab_admin, server_logs, setup, and snippets. The older
marketplace/stash/acp/nodes/deploy/logs/device product services
were removed by the "Slim labby gateway host" pass; their domain types survive
in labby-runtime/labby-apis but are no longer registered services and have
no CLI commands. Use the generated catalogs below for the current surface
instead of copying command or action lists by hand.
After installing Labby, configure proxy defaults once and launch a JavaScript stdio server without proxy flags:
The built-in zero-flag policy is Tailscale Serve plus tailnet authorization on a random high port. Child flags follow the first child token unchanged, and an explicit separator is available for unusual commands:
Use labby proxy --local --auth none ... for explicit loopback-only
development. Bearer and OAuth setup, exact-port resource audiences, safe Serve
ownership, configuration precedence, output modes, and recovery are covered in
the stdio MCP proxy guide.
Linux/macOS:
MCP clients that prefer npm launchers can run Labby through the Node wrapper:
Windows PowerShell:
The install scripts download the requested GitHub Release asset, verify its
checksum, and install labby onto the user PATH. They do not perform
operator provisioning or environment setup. The scripts only install the binary
(from a release or fallback source build); all first-run provisioning is handled
inside labby via labby serve bootstrap and labby setup.
Override install behavior with LABBY_INSTALL_DIR, LABBY_INSTALL_VERSION, or
LABBY_INSTALL_REPO.
Prerequisites:
just for repo commands.cargo-nextest for the main test suite.pnpm 9.15.9 for the Labby web UI. The repo pins this in
.mise.toml and
apps/gateway-admin/package.json.openssl if you want to generate a bearer token manually.just install builds the all-features release binary and symlinks it to
~/.local/bin/labby.
On macOS, install the gateway as a persistent per-user service instead of
running labby serve in a terminal:
This installs a launchd LaunchAgent that keeps Labby listening on
127.0.0.1:8765, restarts it after login or exit, and writes logs under
~/.labby/. Use just macos-service-restart after changing service settings
or just macos-service-uninstall to remove it. The cross-platform
just service-install, just service-status, just service-restart, and
just service-uninstall bindings select launchd on macOS and systemd on
Linux. This is suitable for a Tailscale Serve/Funnel route whose OAuth
callback targets the local gateway.
For loopback development, labby serve can bootstrap a missing bearer token for
you. If LABBY_MCP_HTTP_TOKEN is absent and LABBY_AUTH_MODE is not oauth, it
generates a token, writes a minimal ~/.labby/.env, reloads it into the running
process, prints the setup URL, and continues. The token itself is stored in
~/.labby/.env rather than printed.
Bootstrap writes these required setup keys if no env exists yet:
LABBY_MCP_HTTP_TOKEN (generated random 64-character hex token)LABBY_MCP_TRANSPORT=httpLABBY_MCP_HTTP_HOST=127.0.0.1LABBY_MCP_HTTP_PORT=8765LABBY_AUTH_MODE=bearerIt also enforces secure file creation via Lab's env_merge path (0600 perms on
Unix) and then skips creating anything else until the web wizard runs.
For explicit setup:
Open http://127.0.0.1:8765/.
Build static Labby assets with just web-build first when running from a source
checkout.
The recommended self-hosted gateway substrate is an amd64 Ubuntu 26.04 Incus system container. Bare metal is the secondary supported shape for a dedicated gateway host or VM. Docker is retained for explicit development/image smoke, but it is not the recommended production boundary for Labby because stdio MCP servers and agent CLIs are installed and launched at runtime.
See docs/runtime/INCUS.md for the full Incus
runbook, bare-metal variant, /dev/net/tun Tailscale passthrough, manual
claude/codex/gemini login checklist, and rollback commands.
labby serve starts the hosted HTTP runtime: /v1 product APIs, /mcp
streamable HTTP MCP, auth routes, OAuth relay endpoints, and static Labby web
assets when an export is available. labby mcp is the stdio MCP entrypoint for
local MCP clients.
Stdio upstreams execute local commands when tested or reconciled, so gateway
tests and config mutations use the shared destructive-action confirmation gate.
The stdio spawn guard allows known runtimes such as npx, uvx, docker,
node, python, python3, deno, pipx, and dnx; customize it in
[gateway] inside config.toml.
When [code_mode].enabled = true, Labby hides raw proxied upstream tools from MCP
list_tools() and exposes the canonical synthetic codemode tool.
MCP call shapes:
Code Mode can call exposed upstream MCP tools only. It cannot call Labby actions from inside the sandbox.
Snippets are stored per-user under $LABBY_HOME and executed through the
gateway Code Mode runner, so they can reach exposed upstream tools but not Lab
actions. The snippets service is gateway-gated: it is unavailable in builds
without the gateway feature.
labby doctor --json is the CI-friendly form; the exit code reflects the worst
severity found.
Removed surfaces. Earlier releases documented
labby marketplace,labby stash,labby nodes, andlabby deploy, along with ACP chat, the MCP Registry browser, and device/fleet runtimes. Those products have been deleted from source, manifests, packaging, and CI — not merely feature-gated.scripts/check-retired-features.shguards against reintroduction, and the historical designs are archived under docs/references/retired-labby. Plugin marketplace assets now live in the separate dendrite repo.
Generic action dispatch:
Dedicated product routes also exist for catalog discovery (/v1/{service}/actions),
setup, doctor, snippets, filesystem, server logs, gateway OAuth
(/v1/gateway/oauth/*), OAuth relay, auth allowlists (/v1/auth/allowed-emails),
/v1/openapi, and the browser session routes under /auth/*. See
generated API routes and
OpenAPI.
| Surface | Entry Point | Notes |
|---|---|---|
| CLI | labby <command> | Current commands are generated in docs/generated/cli-help.md. Use --json for machine-readable output and `--color auto |
| MCP stdio | labby mcp | Local editor/desktop MCP clients. |
| MCP HTTP | labby serve plus /mcp | Streamable HTTP MCP with bearer or OAuth JWT auth. |
| HTTP API | labby serve plus /v1/* | Generic POST /v1/{service} action dispatch plus dedicated product routes. |
| Web UI | labby serve plus exported assets | Main routes are / (overview), /gateways, /gateway, /snippets, /usage, /settings (with core, services, services/[service], surfaces, features, doctor, extract, advanced subpages), /docs, /design-system, and /mcp/code-mode. |
MCP service tools use the shared action shape:
Every service tool also supports help and schema through the shared
dispatcher. Destructive MCP actions use elicitation when the client supports it;
headless clients pass "confirm": true inside params.
Configuration is split deliberately:
| Data | Location | Examples |
|---|---|---|
| Secrets and endpoint values | ~/.labby/.env | LABBY_MCP_HTTP_TOKEN, LABBY_GOOGLE_CLIENT_SECRET, upstream bearer token env values |
| Preferences | config.toml | transport, CORS, auth mode, workspace root, gateway spawn guard, and upstream behavior |
config.toml is searched in this order:
./config.toml~/.labby/config.toml~/.config/labby/config.tomlStartup loads the first config.toml, initializes tracing, then loads
~/.labby/.env and a CWD .env if present. Runtime precedence is:
config.tomlUseful environment variables:
| Variable | Purpose |
|---|---|
LABBY_MCP_HTTP_TOKEN | Static bearer token for protected admin/API/MCP routes. |
LABBY_AUTH_MODE | bearer or oauth. |
LABBY_PUBLIC_URL | Public base URL for OAuth metadata, issuer/audience, callbacks, and allowed-host derivation. |
LABBY_GOOGLE_CLIENT_ID / LABBY_GOOGLE_CLIENT_SECRET | Google OAuth credentials for OAuth mode. |
LABBY_AUTH_ADMIN_EMAIL | Bootstrap admin email; required in OAuth mode. |
LABBY_OAUTH_ENCRYPTION_KEY | Base64 32-byte key required for encrypted upstream OAuth credentials. Rotation requires reauthorizing affected upstreams. |
LABBY_WEB_ASSETS_DIR | Override static Labby export directory. |
LABBY_WEB_UI_AUTH_DISABLED | Development-only browser auth bypass. |
LABBY_LOG / LABBY_LOG_FORMAT / LABBY_LOG_COLOR | Tracing filter, text/json format, and non-TTY color policy. |
LABBY_LOG_DIR | Optional rolling JSON file log directory. |
LABBY_ACTOR_KEY_SECRET | Stable secret for redacted actor correlation in logs. |
LABBY_ADMIN_ENABLED | Runtime opt-in for the lab_admin tool. |
Bearer auth is an operator/admin shortcut for Lab routes. Public protected MCP
routes validate route-scoped Lab OAuth JWTs; do not treat LABBY_MCP_HTTP_TOKEN as
a public resource credential.
When driving the web UI with automation while OAuth is enabled, pass the bearer
token as a same-origin header. /auth/session recognizes that token and returns a
synthetic admin session:
See runtime configuration, environment variables, and OAuth.
Do not maintain action, feature, env, or coverage inventories by hand in this README. The generated artifacts are authoritative for the current branch:
| Artifact | Purpose |
|---|---|
| service-catalog.md | Registered services, exposure, features, categories, and surfaces. |
| action-catalog.md | Per-service actions and destructive metadata. |
| env-reference.md | Env vars generated from service metadata. |
| api-routes.md | Mounted HTTP routes. |
| openapi.json | OpenAPI 3.1 schema. |
| feature-matrix.md | Cargo feature invariants. |
| mcp-help.md | MCP help projection. |
| cli-help.md | Clap command help snapshot. |
Refresh and verify them with:
docs-check verifies generated-artifact freshness and invariants. It is not a
Markdown link checker, live health check, or onboarding policy audit.
The workspace has 11 members and uses Rust 2024, resolver 3, a single
[workspace.package] version, shared [workspace.dependencies], and shared
[workspace.lints] (unsafe_code = "forbid", mod_module_files = "deny",
disallowed_macros = "deny"). The MCP SDK is pinned exactly as
rmcp = "=3.1.0".
| Path | Role |
|---|---|
| crates/labby-primitives | Dependency-free leaf crate: ActionSpec/ParamSpec, PluginMeta/EnvVar/Category, UiSchema, static SSRF checks. |
| crates/labby-apis | Shared SDK contracts for core HTTP behavior, setup, and doctor. |
| crates/labby-auth | OAuth/JWT/session middleware, route support, and upstream OAuth runtime. |
| crates/labby-runtime | Surface-neutral contracts and helpers: ToolError, gateway config DTOs, dispatch helpers, redaction, path safety, and security helpers. |
| crates/labby-codemode | Client-neutral Code Mode runner kernel, broker, result shaping, snippets, and TypeScript descriptor generation. |
| crates/labby-gateway | Gateway manager, upstream MCP proxy pool, Code Mode host adapter, discovery/imports, virtual servers, protected routes, and OAuth lifecycle. |
| crates/labby-openapi | OpenAPI 3.1 schema assembly for the HTTP surface. |
| crates/labby-web | Embedded/filesystem web asset serving with symlink escape defense. |
| crates/labby | Product binary crate: CLI, MCP, HTTP API, config loading, gateway dispatch, logs, setup, snippets, filesystem access, and output rendering. |
| crates/labby-winjob | Windows Job Object process-tree support, isolated so the main workspace can keep unsafe_code = "forbid". |
| crates/xtask | Repo automation tasks; not published. |
| apps/gateway-admin | Labby web UI, statically exported and served by labby serve. |
| packages/labby-mcp | npm launcher wrapper behind npx -y @dinglebear/labby mcp. |
| plugins | Claude/Codex plugin assets and skills. |
| docs | Topic documentation and generated inventories. |
Shared behavior belongs in the shared execution layer. Upstream/domain logic
belongs in labby-apis; reusable gateway/runtime/code-mode behavior belongs in
the extracted labby-* crates; product dispatch belongs in
crates/labby/src/dispatch; CLI, MCP, HTTP, and web adapters stay thin. See
Architecture and Dispatch.
Prefer the just aliases:
Authoritative Rust verification is all-features:
CI uses the same posture and runs nextest with its CI profile. Use cargo test
only for narrow local slices or when a tool specifically requires it.
Frontend changes should also run the relevant pnpm scripts under
apps/gateway-admin, and just web-build when exported assets matter.
The recommended self-hosted gateway runtime is the Incus system container
provisioned by scripts/incus-bootstrap.sh --version vX.Y.Z and converged
in-box with labby setup --provision. Bare metal uses the same provisioner and
system unit when the host or VM is dedicated to Labby. The default service is
/etc/systemd/system/labby.service, running as User=labby, Group=labby, with
ExecStart=/usr/local/bin/labby serve. From a source checkout, just host-sync
remains the rebuild-and-restart developer shortcut. Docker remains available
for prod-like image smoke and adapter-container work, but it is no longer the
recommended agent gateway runtime.
The Compose stack is a trusted local operator environment, not a hardened
generic deployment. It bind-mounts Labby state, the repository, and built web
assets; secrets are loaded from the mounted /home/labby/.labby/.env. The image
installs pinned Claude, Codex, and Gemini CLIs for stdio upstreams that invoke
provider tools. It does not install ACP adapters or mount ACP-specific state.
Release Please maintains the version/changelog pull request and creates the
stable tag plus draft GitHub release when that pull request merges. Publishing
the release triggers the heavy GitHub-hosted x86_64 workflows. They build Linux
and Windows archives with checksums, build and scan the GHCR image, build and
smoke the Incus image, publish the npm launcher, and publish Labby's
server.json metadata to the official MCP Registry.
The plugins/labby plugin ships skills, an MCP config, and userConfig — not a
labby binary, and no Claude Code hooks. The former
plugins/labby/hooks/hooks.json (SessionStart / ConfigChange shims) has been
removed; operators run labby setup themselves. Do not reintroduce a hooks/
directory, bundle a binary under plugins/labby/bin/, or add
Docker/systemd bootstrap logic to plugin assets.
labby setup plugin-hook remains a CLI command for on-demand audit and settings
sync (--no-repair for read-only), exercised by just validate-plugin.
runraid) lives in unraid-rs/.Start at docs/README.md. High-value entrypoints:
Original Dinglebear-authored portions of this project are licensed under AGPL-3.0-only. Separate commercial licensing is available for organizations that need terms outside the AGPL. Third-party material remains under its original license. See LICENSING.md.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/labby)<a href="https://allmcps.com/mcp/labby"><img src="https://allmcps.com/api/badge/labby?style=directory" alt="Labby on AllMCPs" /></a>