{
  "markdown": "<!-- Absolute raw URL, not relative: unraid/ca/labby.xml points Community Applications at this file's raw URL, and CA renders the markdown outside any repo context where a relative path would 404. Markdown image syntax, not <img>: the fleet repository contract's readme_lead() skips lines starting with '![' when locating the lead paragraph, but not raw HTML tags. Keep this comment on ONE line for the same reason -- only a comment's first line is skipped. -->\n![Labby](https://raw.githubusercontent.com/dinglebear-ai/labby/main/docs/assets/brand/labby-banner.png)\n\n# Labby\n\nRust MCP gateway with Code Mode, authentication, setup, logs, CLI, HTTP API, and operator web UI.\n\nCanonical remote: `git@github.com:dinglebear-ai/labby.git`.\n\nThe root README is the public entrypoint. The topic docs in\n[docs/](./docs/README.md) own the detailed contracts; when this file and a topic\ndoc disagree, fix the topic doc first and then refresh this summary.\n\n## Contents\n\n- [What Labby Does](#what-labby-does)\n- [Quick Start](#quick-start)\n- [Core Workflows](#core-workflows)\n- [Runtime Surfaces](#runtime-surfaces)\n- [Configuration](#configuration)\n- [Current Catalogs](#current-catalogs)\n- [Architecture](#architecture)\n- [Development](#development)\n- [Documentation](#documentation)\n\n## What Labby Does\n\nLabby is centered on the current gateway/operator surface:\n\n- **MCP gateway** - connect HTTP and stdio upstream MCP servers, inspect their\n  tools/resources/prompts, apply exposure filters, publish protected MCP routes,\n  and optionally collapse the upstream catalog into Code Mode `search` and\n  `execute`.\n- **Direct stdio proxy** - launch one stdio MCP server with\n  `labby proxy /path/to/dist.js` and expose its unmodified MCP surface over\n  loopback or an owned Tailscale Serve HTTPS port with tailnet, bearer, OAuth,\n  or explicit no-auth policy.\n- **Authentication and protected routes** - run bearer or OAuth authentication,\n  manage route-scoped access, authorize upstream OAuth connections, and publish\n  protected MCP endpoints.\n- **Code Mode snippets** - author, store, and run reusable JavaScript snippets\n  against the upstream catalog, with artifacts persisted under `$LABBY_HOME`.\n- **Setup and doctor** - bootstrap `~/.labby`, provision the host service, and\n  run a health audit across env, reachability, auth, and versions.\n- **Filesystem service** - scoped, path-safety-checked file operations exposed\n  through the same action dispatch as every other service.\n- **Server logs** - search and tail the local `labby serve` log stream.\n- **Incus and bare-metal setup** - provision and operate a dedicated Labby\n  gateway host without introducing a separate fleet or deployment product.\n- **Generated discovery** - publish code-owned service, action, environment,\n  proxy configuration, API route, OpenAPI, MCP help, CLI help, and\n  feature-matrix artifacts under\n  [docs/generated](./docs/generated/README.md).\n\nUse the generated service, action, and CLI catalogs below for the complete\ncurrent product surface instead of copying inventories into hand-written\ndocumentation. Standalone ACP chat, Marketplace/MCP Registry browser, Fleet,\nDeploy, and Stash products remain retired; bounded provider-backed discovery\nthrough the `artifacts` control-plane service does not restore those products.\n\n## Quick Start\n\n### Proxy One Stdio MCP Server\n\nAfter installing Labby, configure proxy defaults once and launch a JavaScript\nstdio server without proxy flags:\n\n```bash\nlabby setup proxy\nlabby doctor proxy\nlabby proxy /path/to/dist.js\n```\n\nThe built-in zero-flag policy is Tailscale Serve plus tailnet authorization on\na random high port. Child flags follow the first child token unchanged, and an\nexplicit separator is available for unusual commands:\n\n```bash\nlabby proxy /path/to/dist.js --workspace /srv/data --read-only\nlabby proxy -- npx -y @modelcontextprotocol/server-filesystem /srv/data\n```\n\nUse `labby proxy --local --auth none ...` for explicit loopback-only\ndevelopment. Bearer and OAuth setup, exact-port resource audiences, safe Serve\nownership, configuration precedence, output modes, and recovery are covered in\nthe [stdio MCP proxy guide](./docs/guides/STDIO_MCP_PROXY.md).\n\n### Install A Release\n\nLinux/macOS:\n\n```bash\nversion=vX.Y.Z\nbase=\"https://github.com/dinglebear-ai/labby/releases/download/$version\"\ncurl -fSLO \"$base/labby-install.sh\"\ncurl -fSLO \"$base/labby-install.sh.sha256\"\ngh attestation verify labby-install.sh \\\n  --repo dinglebear-ai/labby \\\n  --signer-workflow dinglebear-ai/labby/.github/workflows/release.yml \\\n  --source-ref \"refs/tags/$version\" \\\n  --deny-self-hosted-runners\nshasum -a 256 -c labby-install.sh.sha256\nLABBY_INSTALL_VERSION=\"$version\" sh ./labby-install.sh\nlabby setup\nlabby serve --host 127.0.0.1 --port 8765\n```\n\nMCP clients that prefer npm launchers can run Labby through the Node wrapper:\n\n```bash\nnpx -y @dinglebear/labby mcp\n```\n\nWindows PowerShell:\n\n```powershell\n$Version = \"vX.Y.Z\"\n$Base = \"https://github.com/dinglebear-ai/labby/releases/download/$Version\"\nInvoke-WebRequest \"$Base/labby-install.ps1\" -OutFile labby-install.ps1\nInvoke-WebRequest \"$Base/labby-install.ps1.sha256\" -OutFile labby-install.ps1.sha256\ngh attestation verify labby-install.ps1 `\n  --repo dinglebear-ai/labby `\n  --signer-workflow dinglebear-ai/labby/.github/workflows/release.yml `\n  --source-ref \"refs/tags/$Version\" `\n  --deny-self-hosted-runners\n$Expected = ((Get-Content labby-install.ps1.sha256) -split '\\s+')[0]\nif ((Get-FileHash labby-install.ps1 -Algorithm SHA256).Hash.ToLower() -ne $Expected) { throw \"installer digest mismatch\" }\n$env:LABBY_INSTALL_VERSION = $Version\n& ./labby-install.ps1\nlabby setup\nlabby serve --host 127.0.0.1 --port 8765\n```\n\nThe separately downloaded and attested install scripts resolve an immutable GitHub Release containing the current\nplatform asset, require `gh`, verify the archive's attestation against the\nLabby repository, `release.yml`, exact tag, and hosted-runner policy, verify its checksum, and install `labby` onto the\nuser PATH. They do **not** perform\noperator provisioning or environment setup. The scripts only install the binary\n(from a release or fallback source build); all first-run provisioning is handled\ninside `labby` via `labby serve` bootstrap and `labby setup`.\n\nOverride install behavior with `LABBY_INSTALL_DIR`, `LABBY_INSTALL_VERSION`, or\n`LABBY_INSTALL_REPO`. Source fallback is off by default. Opt in with\n`LABBY_ALLOW_SOURCE_FALLBACK=1`; a pinned `LABBY_INSTALL_VERSION` is passed to\nCargo as the exact tag instead of silently building the default branch.\n\nEach successful install retains the verified binary by SHA-256 plus an\nowner-only receipt beneath `<install-dir>/.labby-install/`. At least the prior\nverified artifact remains available when distribution is unavailable. Restore\nit without downloading or changing `$LABBY_HOME`:\n\n```bash\nLABBY_INSTALL_ROLLBACK=1 sh ./labby-install.sh\n```\n\n```powershell\n$env:LABBY_INSTALL_ROLLBACK = '1'\n& .\\labby-install.ps1\n```\n\nRollback switches only the installed executable and receipt. It does not\ndowngrade or delete configuration, credentials, databases, or other durable\nstate. Inspect the receipt at `<install-dir>/.labby-install/receipt` on Unix or\n`receipt.json` on Windows.\n\nRelease qualification can install an already-downloaded candidate without\nnetwork or source fallback by setting `LABBY_INSTALL_LOCAL_BINARY` and its exact\nlowercase `LABBY_INSTALL_LOCAL_SHA256`. The installer copies that input once to\nprivate staging, verifies the staged bytes, and activates those same bytes. It\nalso rehashes every existing cached artifact before reuse. Before changing the\nbinary or either receipt, the installer writes a recovery journal beneath\n`.labby-install/`; a later invocation restores the complete pre-install\nsnapshot when it finds an interrupted activation. If restoration fails, the\ninstaller stops and retains the journal for diagnosis.\n\n### Build From Source\n\nPrerequisites:\n\n- Rust 1.97.1 or newer. CI/release verifies with Rust 1.97.1.\n- `just` for repo commands.\n- `cargo-nextest` for the main test suite.\n- `pnpm 9.15.9` for the Labby web UI. The repo pins this in\n  [.mise.toml](./.mise.toml) and\n  [apps/gateway-admin/package.json](./apps/gateway-admin/package.json).\n- `openssl` if you want to generate a bearer token manually.\n\n```bash\ngit clone git@github.com:dinglebear-ai/labby.git\ncd labby\njust install\njust web-build\nlabby serve --host 127.0.0.1 --port 8765\n```\n\n`just install` builds the all-features release binary and symlinks it to\n`~/.local/bin/labby`.\n\nOn macOS, install the gateway as a persistent per-user service instead of\nrunning `labby serve` in a terminal:\n\n```bash\njust macos-service-install\njust macos-service-status\n```\n\nThis installs a `launchd` LaunchAgent that keeps Labby listening on\n`127.0.0.1:8765`, restarts it after login or exit, and uses the stable absolute\n`LABBY_HOME` (default `~/.labby`) as both working directory and durable\nconfiguration root. It never persists the directory from which installation\nwas invoked. Logs default to the same root. Use `just macos-service-restart`\nafter changing service settings\nor `just macos-service-uninstall` to remove it. The cross-platform\n`just service-install`, `just service-status`, `just service-restart`, and\n`just service-uninstall` bindings select launchd on macOS and systemd on\nLinux. This is suitable for a Tailscale Serve/Funnel route whose OAuth\ncallback targets the local gateway.\n\nWhen overriding the launchd paths, `LABBY_SERVICE_BIN`, `LABBY_STATE_DIR`, and\n`LABBY_HOME` must all be absolute; relative paths fail before the plist or\nservice is changed.\n\n### First Run\n\nFor loopback development, `labby serve` can bootstrap a missing bearer token for\nyou. If `LABBY_MCP_HTTP_TOKEN` is absent and `LABBY_AUTH_MODE` is not `oauth`, it\ngenerates a token, writes a minimal `~/.labby/.env`, reloads it into the running\nprocess, prints the setup URL, and continues. The token itself is stored in\n`~/.labby/.env` rather than printed.\n\nBootstrap writes these required `setup` keys if no env exists yet:\n\n- `LABBY_MCP_HTTP_TOKEN` (generated random 64-character hex token)\n- `LABBY_MCP_TRANSPORT=http`\n- `LABBY_MCP_HTTP_HOST=127.0.0.1`\n- `LABBY_MCP_HTTP_PORT=8765`\n- `LABBY_AUTH_MODE=bearer`\n\nIt also enforces secure file creation via Labby's `env_merge` path (`0600` perms on\nUnix) and then skips creating anything else until the web wizard runs.\n\nFor explicit setup:\n\n```bash\nmkdir -p ~/.labby\nprintf 'LABBY_AUTH_MODE=bearer\\nLABBY_MCP_HTTP_TOKEN=%s\\n' \"$(openssl rand -hex 32)\" > ~/.labby/.env\nchmod 600 ~/.labby/.env\nlabby setup\nlabby serve --host 127.0.0.1 --port 8765\n```\n\nOpen `http://127.0.0.1:8765/`.\nBuild static Labby assets with `just web-build` first when running from a source\ncheckout.\n\n### Self-Host The Gateway\n\nThe recommended self-hosted gateway substrate is an amd64 Ubuntu 26.04 Incus\nsystem container. Bare metal is the secondary supported shape for a dedicated\ngateway host or VM. Docker is retained for explicit development/image smoke,\nbut it is not the recommended production boundary for Labby because stdio MCP\nservers and agent CLIs are installed and launched at runtime.\n\n```bash\nscripts/incus-bootstrap.sh --version vX.Y.Z\nincus exec labby -- systemctl status labby --no-pager\nincus exec labby -- curl -fsS http://127.0.0.1:8765/ready\n```\n\nSee [docs/runtime/INCUS.md](./docs/runtime/INCUS.md) for the full Incus\nrunbook, bare-metal variant, `/dev/net/tun` Tailscale passthrough, manual\n`claude`/`codex`/`gemini` login checklist, and rollback commands.\n\n## Core Workflows\n\n### Start Labby\n\n```bash\nlabby serve --host 127.0.0.1 --port 8765\nlabby mcp\n```\n\n`labby serve` starts the hosted HTTP runtime: `/v1` product APIs, `/mcp`\nstreamable HTTP MCP, auth routes, OAuth relay endpoints, and static Labby web\nassets when an export is available. `labby mcp` is the stdio MCP entrypoint for\nlocal MCP clients. A client configured to launch `labby mcp` does not need an\nHTTP URL: when a `labby serve` daemon is reachable, the stdio process becomes a\ntransparent bridge to that daemon and uses its gateway configuration, upstream\nconnections, and OAuth state. If no daemon is found and no explicit target is\nset, it starts a standalone local gateway instead. See the\n[local bridge guide](./docs/surfaces/TRANSPORT.md#local-bridge-to-the-running-daemon)\nfor client configuration and `LABBY_SERVER_URL` fail-closed behavior.\n\n### Manage Upstream MCP Gateways\n\n```bash\nlabby gateway add \\\n  --name github \\\n  --url https://example.com/mcp \\\n  --bearer-token-env GITHUB_MCP_TOKEN \\\n  -y\n\nlabby gateway reload\nlabby gateway list\n```\n\nStdio upstreams execute local commands when tested or reconciled, so gateway\ntests and config mutations use the shared destructive-action confirmation gate.\nThe stdio spawn guard allows known runtimes such as `npx`, `uvx`, `docker`,\n`node`, `python`, `python3`, `deno`, `pipx`, and `dnx`; customize it in\n`[gateway]` inside `config.toml`.\n\n### Use Code Mode\n\nWhen `[code_mode].enabled = true`, Labby hides raw proxied upstream tools from MCP\n`list_tools()` and exposes the canonical synthetic `codemode` tool.\n\n```bash\nlabby gateway code status\nlabby gateway code enable\nlabby gateway code exec --code 'async () => tools.length'\n```\n\nMCP call shapes:\n\n```json\n{ \"code\": \"async () => (await codemode.search(\\\"github issues\\\")).results\" }\n```\n\n```json\n{ \"code\": \"async () => callTool(\\\"github::search_issues\\\", {\\\"query\\\":\\\"repo:dinglebear-ai/labby gateway\\\"})\" }\n```\n\n```json\n{ \"code\": \"async () => codemode.run(\\\"gateway-summary\\\", {\\\"includeHealth\\\": true})\" }\n```\n\nCode Mode can call exposed upstream MCP tools only. It cannot call Labby actions\nfrom inside the sandbox.\n\n### Work With Code Mode Snippets\n\n```bash\nlabby snippets list\nlabby snippets get gateway-summary\nlabby snippets create --name my-snippet --file ./my-snippet.js\nlabby snippets validate my-snippet\nlabby snippets exec my-snippet\nlabby snippets test my-snippet\n```\n\nSnippets are stored per-user under `$LABBY_HOME` and executed through the\ngateway Code Mode runner, so they can reach exposed upstream tools but not Labby\nactions. The `snippets` service is gateway-gated: it is unavailable in builds\nwithout the `gateway` feature.\n\n### Audit Health And Logs\n\n```bash\nlabby doctor            # audit every configured service\nlabby doctor system     # local env vars, Docker, disk, toolchain\nlabby doctor auth       # auth/OAuth env vars, files, permissions\nlabby doctor proxy      # zero-route stdio-proxy config/dependency preflight\nlabby doctor proxy --app-url URL --mcp-url URL --route /path\n                        # routed public reverse-proxy checks remain available\nlabby doctor oauth-relay\nlabby health            # lightweight liveness/readiness probe\nlabby logs              # tail the active deployment's service journal\n```\n\n`labby doctor --json` is the CI-friendly form; the exit code reflects the worst\nseverity found.\n\n> **Removed surfaces.** Earlier releases documented `labby marketplace`,\n> `labby stash`, `labby nodes`, and `labby deploy`, along with ACP chat, the MCP\n> Registry browser, and device/fleet runtimes. Those products have been deleted\n> from source, manifests, packaging, and CI — not merely feature-gated.\n> `scripts/check-retired-features.sh` guards against reintroduction, and the\n> historical designs are archived under\n> [docs/archive/retired-labby](./docs/archive/retired-labby/). Plugin\n> marketplace assets now live in the separate\n> [dendrite](https://github.com/dinglebear-ai/dendrite) repo.\n\n### Drive The API\n\nGeneric action dispatch:\n\n```bash\ncurl -s -X POST http://127.0.0.1:8765/v1/gateway \\\n  -H \"Authorization: Bearer $LABBY_MCP_HTTP_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"action\":\"gateway.list\",\"params\":{}}'\n```\n\nDedicated product routes also exist for catalog discovery (`/v1/{service}/actions`),\nsetup, doctor, snippets, filesystem, server logs, gateway OAuth\n(`/v1/gateway/oauth/*`), OAuth relay, auth allowlists (`/v1/auth/allowed-emails`),\n`/v1/openapi`, and the browser session routes under `/auth/*`. See\n[generated API routes](./docs/generated/api-routes.md) and\n[OpenAPI](./docs/generated/openapi.json).\n\n## Runtime Surfaces\n\n| Surface | Entry Point | Notes |\n| --- | --- | --- |\n| CLI | `labby <command>` | Current commands are generated in [docs/generated/cli-help.md](./docs/generated/cli-help.md). Use `--json` for machine-readable output and `--color auto|plain|color` for human output styling. |\n| MCP stdio | `labby mcp` | Local editor/desktop MCP clients. |\n| MCP HTTP | `labby serve` plus `/mcp` | Streamable HTTP MCP with bearer or OAuth JWT auth. |\n| HTTP API | `labby serve` plus `/v1/*` | Generic `POST /v1/{service}` action dispatch plus dedicated product routes. |\n| 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`. |\n\nMCP service tools use the shared action shape:\n\n```json\n{\n  \"action\": \"mcp.list\",\n  \"params\": { \"search\": \"postgres\", \"limit\": 10 }\n}\n```\n\nEvery service tool also supports `help` and `schema` through the shared\ndispatcher. Destructive MCP actions use elicitation when the client supports it;\nheadless clients pass `\"confirm\": true` inside `params`.\n\n## Configuration\n\nConfiguration is split deliberately:\n\n| Data | Location | Examples |\n| --- | --- | --- |\n| Secrets and endpoint values | `$LABBY_HOME/.env` | `LABBY_MCP_HTTP_TOKEN`, `LABBY_GOOGLE_CLIENT_SECRET`, upstream bearer token env values |\n| Preferences | `$LABBY_HOME/config.toml` | transport, CORS, auth mode, workspace root, gateway spawn guard, and upstream behavior |\n\n`LABBY_HOME` selects the one authoritative configuration and durable-state\nroot and must be absolute. It defaults to `~/.labby`; Labby does not implicitly\nread CWD or XDG fallback files. Existing process environment values win over\nvalues loaded from the selected `.env`. Runtime precedence is:\n\n1. CLI flags\n2. Environment variables\n3. `config.toml`\n4. Built-in defaults\n\nUseful environment variables:\n\n| Variable | Purpose |\n| --- | --- |\n| `LABBY_MCP_HTTP_TOKEN` | Static bearer token for protected admin/API/MCP routes. |\n| `LABBY_AUTH_MODE` | `bearer` or `oauth`. |\n| `LABBY_PUBLIC_URL` | Public base URL for OAuth metadata, issuer/audience, callbacks, and allowed-host derivation. |\n| `LABBY_AUTH_PROVIDER` | Inbound OAuth identity provider: `google` (stable) or `authelia` (open beta). |\n| `LABBY_GOOGLE_CLIENT_ID` / `LABBY_GOOGLE_CLIENT_SECRET` | Google credentials when Google is selected. |\n| `LABBY_AUTHELIA_ISSUER_URL` / `LABBY_AUTHELIA_CLIENT_ID` / `LABBY_AUTHELIA_CLIENT_SECRET` | Authelia OIDC configuration; see the pinned registration contract in the OAuth guide. |\n| `LABBY_AUTH_ADMIN_EMAIL` | Bootstrap admin email; required in OAuth mode. |\n| `LABBY_OAUTH_ENCRYPTION_KEY` | Base64 32-byte key required for encrypted upstream OAuth credentials. Rotation requires reauthorizing affected upstreams. |\n| `LABBY_WEB_ASSETS_DIR` | Override static Labby export directory. |\n| `LABBY_WEB_UI_AUTH_DISABLED` | Development-only browser auth bypass. |\n| `LABBY_LOG` / `LABBY_LOG_FORMAT` / `LABBY_LOG_COLOR` | Tracing filter, text/json format, and non-TTY color policy. |\n| `LABBY_LOG_DIR` | Optional rolling JSON file log directory. |\n| `LABBY_ACTOR_KEY_SECRET` | Stable secret for redacted actor correlation in logs. |\n| `LABBY_ADMIN_ENABLED` | Runtime opt-in for the `lab_admin` tool. |\n\nBearer auth is an operator/admin shortcut for Labby routes. Public protected MCP\nroutes validate route-scoped Labby OAuth JWTs; do not treat `LABBY_MCP_HTTP_TOKEN` as\na public resource credential.\n\nWhen driving the web UI with automation while OAuth is enabled, pass the bearer\ntoken as a same-origin header. `/auth/session` recognizes that token and returns a\nsynthetic admin session:\n\n```bash\nTOKEN=$(awk -F= '/^LABBY_MCP_HTTP_TOKEN=/{print $2}' ~/.labby/.env)\nagent-browser open http://127.0.0.1:8765/gateways \\\n  --headers \"{\\\"Authorization\\\":\\\"Bearer $TOKEN\\\"}\"\n```\n\nSee [runtime configuration](./docs/runtime/CONFIG.md),\n[environment variables](./docs/runtime/ENV.md), and\n[OAuth](./docs/runtime/OAUTH.md).\n\n## Current Catalogs\n\nDo not maintain action, feature, env, or coverage inventories by hand in this\nREADME. The generated artifacts are authoritative for the current branch:\n\n| Artifact | Purpose |\n| --- | --- |\n| [service-catalog.md](./docs/generated/service-catalog.md) | Registered services, exposure, features, categories, and surfaces. |\n| [action-catalog.md](./docs/generated/action-catalog.md) | Per-service actions and destructive metadata. |\n| [env-reference.md](./docs/generated/env-reference.md) | Env vars generated from service metadata. |\n| [api-routes.md](./docs/generated/api-routes.md) | Mounted HTTP routes. |\n| [openapi.json](./docs/generated/openapi.json) | OpenAPI 3.1 schema. |\n| [feature-matrix.md](./docs/generated/feature-matrix.md) | Cargo feature invariants. |\n| [mcp-help.md](./docs/generated/mcp-help.md) | MCP help projection. |\n| [cli-help.md](./docs/generated/cli-help.md) | Clap command help snapshot. |\n\nRefresh and verify them with:\n\n```bash\njust docs-generate\njust docs-check\n```\n\n`docs-check` verifies generated-artifact freshness and invariants. It is not a\nMarkdown link checker, live health check, or onboarding policy audit.\n\n## Architecture\n\nThe workspace has 11 members and uses Rust 2024, resolver 3, a single\n`[workspace.package]` version, shared `[workspace.dependencies]`, and shared\n`[workspace.lints]` (`unsafe_code = \"forbid\"`, `mod_module_files = \"deny\"`,\n`disallowed_macros = \"deny\"`). The MCP SDK is pinned exactly as\n`rmcp = \"=3.1.0\"`.\n\n| Path | Role |\n| --- | --- |\n| [crates/labby-primitives](./crates/labby-primitives) | Dependency-free leaf crate: `ActionSpec`/`ParamSpec`, `PluginMeta`/`EnvVar`/`Category`, `UiSchema`, static SSRF checks. |\n| [crates/labby-apis](./crates/labby-apis) | Shared SDK contracts for core HTTP behavior, setup, and doctor. |\n| [crates/labby-auth](./crates/labby-auth) | OAuth/JWT/session middleware, route support, and upstream OAuth runtime. |\n| [crates/labby-runtime](./crates/labby-runtime) | Surface-neutral contracts and helpers: `ToolError`, gateway config DTOs, dispatch helpers, redaction, path safety, and security helpers. |\n| [crates/labby-codemode](./crates/labby-codemode) | Client-neutral Code Mode runner kernel, broker, result shaping, snippets, and TypeScript descriptor generation. |\n| [crates/labby-gateway](./crates/labby-gateway) | Gateway manager, upstream MCP proxy pool, Code Mode host adapter, discovery/imports, virtual servers, protected routes, and OAuth lifecycle. |\n| [crates/labby-openapi](./crates/labby-openapi) | OpenAPI 3.1 schema assembly for the HTTP surface. |\n| [crates/labby-web](./crates/labby-web) | Embedded/filesystem web asset serving with symlink escape defense. |\n| [crates/labby](./crates/labby) | Product binary crate: CLI, MCP, HTTP API, config loading, gateway dispatch, logs, setup, snippets, filesystem access, and output rendering. |\n| [crates/labby-winjob](./crates/labby-winjob) | Windows Job Object process-tree support, isolated so the main workspace can keep `unsafe_code = \"forbid\"`. |\n| [crates/xtask](./crates/xtask) | Repo automation tasks; not published. |\n| [apps/gateway-admin](./apps/gateway-admin/README.md) | Labby web UI, statically exported and served by `labby serve`. |\n| [packages/labby-mcp](./packages/labby-mcp) | npm launcher wrapper behind `npx -y @dinglebear/labby mcp`. |\n| [plugins](./plugins) | Claude/Codex plugin assets and skills. |\n| [docs](./docs/README.md) | Topic documentation and generated inventories. |\n\nShared behavior belongs in the shared execution layer. Upstream/domain logic\nbelongs in `labby-apis`; reusable gateway/runtime/code-mode behavior belongs in\nthe extracted `labby-*` crates; product dispatch belongs in\n`crates/labby/src/dispatch`; CLI, MCP, HTTP, and web adapters stay thin. See\n[Architecture](./docs/ARCH.md) and [Dispatch](./docs/dev/DISPATCH.md).\n\n## Development\n\nPrefer the `just` aliases:\n\n```bash\njust check            # cargo check --workspace --all-features\njust test             # cargo nextest run --workspace --all-features\njust test-integration # cargo nextest run --workspace --all-features --run-ignored ignored-only\njust lint             # skill drift + cargo wrapper smoke + clippy -D warnings + fmt check\njust deny             # cargo deny check\njust build            # cargo build --workspace --all-features\njust build-release    # release build, bin/labby install, ~/.local/bin symlink\njust service-install  # build and install the native persistent gateway service\njust service-status   # inspect the native service manager state\nlabby setup host-service install --install-self -y # install current binary + start system service\nlabby setup host-service restart --install-self -y # reinstall current binary + restart service\nlabby setup host-service status --json # inspect the host Labby gateway service\njust host-sync        # repo dev shortcut: rebuild + install binary + restart host service\njust dev-container    # explicit Docker compatibility/prod-like smoke path\njust dev-container-debug # explicit Docker debug binary path\njust web-build        # cd apps/gateway-admin && pnpm build\njust web-watch        # rebuild web assets when frontend files change\njust run -- help      # cargo run --all-features -- <args>\njust chat-local       # local Labby admin UI workflow with browser auth disabled\njust dev-up           # start the explicit Docker compatibility stack\njust dev              # alias for just dev-container\njust dev-debug        # alias for just dev-container-debug\njust install          # build-release + symlink ~/.local/bin/labby\njust prod-run         # local prod-like image smoke on port 18765\njust mcp-token        # rotate LABBY_MCP_HTTP_TOKEN in .env\n```\n\nAuthoritative Rust verification is all-features:\n\n```bash\ncargo check --workspace --all-features\ncargo clippy --workspace --all-features -- -D warnings\ncargo nextest run --workspace --all-features\ncargo build --workspace --all-features\n```\n\nCI uses the same posture and runs nextest with its CI profile. Use `cargo test`\nonly for narrow local slices or when a tool specifically requires it.\n\nFrontend changes should also run the relevant `pnpm` scripts under\n`apps/gateway-admin`, and `just web-build` when exported assets matter.\n\n### Host Gateway Runtime\n\nThe recommended self-hosted gateway runtime is the Incus system container\nprovisioned by `scripts/incus-bootstrap.sh --version vX.Y.Z` and converged\nin-box with `labby setup --provision`. Bare metal uses the same provisioner and\nsystem unit when the host or VM is dedicated to Labby. The default service is\n`/etc/systemd/system/labby.service`, running as `User=labby`, `Group=labby`, with\n`ExecStart=/usr/local/bin/labby serve`. From a source checkout, `just host-sync`\nremains the rebuild-and-restart developer shortcut. Docker remains available\nfor prod-like image smoke and adapter-container work, but it is no longer the\nrecommended agent gateway runtime.\n\n### Dev Container\n\nThe development Compose stack mirrors the production process controls: a\nread-only root filesystem, dropped capabilities, `no-new-privileges`, loopback\nport binding, bounded logs, and named volumes for durable state and data. It\nalso bind-mounts the source repository read-only so locally built web assets are\nvisible without rebuilding the image. The clean-checkout defaults mount the\ntracked, non-secret `config/config.example.toml` and `config/.env.example`.\nSet `LABBY_CONFIG_FILE` and `LABBY_ENV_FILE` to select local runtime files;\nCompose mounts both read-only at their canonical paths beneath `$LABBY_HOME`. Labby-owned runtime\nstate remains writable in the surrounding `labby-home` named volume. Startup logs and the\nsetup settings state report `/home/labby/.labby/config.toml` as the effective\nsource. The image installs pinned Claude,\nCodex, and Gemini CLIs for stdio upstreams that invoke provider tools.\n\n### Releases\n\nRelease Please maintains the version/changelog pull request and creates the\nstable tag plus draft GitHub release when that pull request merges. The stable\ntag triggers the heavy GitHub-hosted candidate workflow. It builds Linux,\nmacOS, and Windows archives with checksums, builds and scans the GHCR image,\nbuilds and smokes the Incus image, publishes the npm launcher, and publishes Labby's\n`server.json` metadata to the official MCP Registry. Only after qualification\nand publication succeed does the workflow promote the draft GitHub release.\n\n### Plugin Setup\n\nThe `plugins/labby` plugin ships skills, an MCP config, and `userConfig` — not a\n`labby` binary, and no Claude Code hooks. The former\n`plugins/labby/hooks/hooks.json` (SessionStart / ConfigChange shims) has been\nremoved; operators run `labby setup` themselves. Do not reintroduce a `hooks/`\ndirectory, bundle a binary under `plugins/labby/bin/`, or add\nDocker/systemd bootstrap logic to plugin assets.\n\n`labby setup plugin-hook` remains a CLI command for on-demand audit and settings\nsync (`--no-repair` for read-only), exercised by `just validate-plugin`.\n\n## Related Servers\n\n- [soma](https://github.com/dinglebear-ai/soma) - RMCP runtime for provider-backed MCP servers.\n- [unifi-rmcp](https://github.com/dinglebear-ai/runifi) - UniFi controller REST API bridge.\n- [tailscale-rmcp](https://github.com/dinglebear-ai/rtailscale) - Tailscale API bridge for devices, users, and tailnet operations.\n- [unraid](https://github.com/dinglebear-ai/unraid) - Unraid monorepo; the Rust GraphQL bridge (`runraid`) lives in `unraid-rs/`.\n- [apprise-rmcp](https://github.com/dinglebear-ai/rapprise) - Apprise notification fan-out bridge for many delivery backends.\n- [gotify-rmcp](https://github.com/dinglebear-ai/rgotify) - Gotify push notification bridge for sends, messages, apps, and clients.\n- [arcane-rmcp](https://github.com/dinglebear-ai/rarcane) - Arcane Docker management bridge for containers and related resources.\n- [ytdl-rmcp](https://github.com/dinglebear-ai/rytdl) - Media download and metadata workflow server.\n- [synapse-rmcp](https://github.com/dinglebear-ai/synapse) - Local Synapse workflow server for scout and flux actions.\n- [cortex](https://github.com/dinglebear-ai/cortex) - Syslog and homelab log aggregation MCP server.\n- [axon](https://github.com/dinglebear-ai/axon) - RAG, crawl, scrape, extract, and semantic search project.\n- [lumen](https://github.com/dinglebear-ai/lumen) - Local semantic code search MCP server.\n\n## Documentation\n\nStart at [docs/README.md](./docs/README.md). High-value entrypoints:\n\n- [Architecture](./docs/ARCH.md)\n- [Configuration](./docs/runtime/CONFIG.md)\n- [Environment](./docs/runtime/ENV.md)\n- [OAuth](./docs/runtime/OAUTH.md)\n- [Transport](./docs/surfaces/TRANSPORT.md)\n- [Gateway](./docs/services/GATEWAY.md)\n- [Setup](./docs/services/SETUP.md)\n- [Server Logs](./docs/services/SERVER_LOGS.md)\n- [Testing](./docs/dev/TESTING.md)\n- [Operations](./docs/OPERATIONS.md)\n\n## License\n\nOriginal Dinglebear-authored portions of this project are licensed under [AGPL-3.0-only](LICENSE). Separate commercial licensing is available for organizations that need terms outside the AGPL. Third-party material remains under its original license. See [LICENSING.md](https://github.com/dinglebear-ai/labby/blob/main/LICENSING.md).\n",
  "bytes": 31492,
  "sha": "259506e5ac9b87679904dcc275a9be412313a887ed7acb93a4e323ff99301224",
  "repo_slug": "dinglebear-ai/labby",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_ai_dinglebear_labby_bc226a75/readme"
}