Skip to main content
Glama
crayonlu

MCP Home

by crayonlu

MCP Home

MCP Home is a single-user, self-hosted Remote MCP control plane and protocol gateway. Manage your upstream MCP servers and credentials in one place, then point any harness at stable, standard MCP URLs.

It exposes two data-plane entry points:

  • POST /mcp: aggregates all enabled servers, namespacing tool names and URIs automatically.

  • POST /mcp/{server_slug}: a per-server entry point that preserves original names, URIs, and extension semantics.

MCP Home does not write harness-specific adapters for Claude Code, Codex, Cursor, or anything else. Any harness that speaks standard Streamable HTTP MCP with Bearer auth works.

Web Console

The web console mirrors the full CLI surface: server and credential management, OAuth authorization, one-click Market installs, diagnostics, events, config export/import — with Chinese/English UI and mobile support.

Dashboard

Servers

Credentials

Market

Settings

Mobile:

Market mobile Dashboard mobile

Related MCP server: MCP Manager

Project Scope

MCP Home manages two kinds of MCPs:

  • Remote-native: upstreams that already speak Streamable HTTP, hosted on the public internet, a private network, or another server.

  • Home-hosted: stdio MCPs spawned on the MCP Home host and exposed remotely to harnesses.

MCPs that must run on the harness machine and depend on its browser or desktop state are out of scope. For example, a Chrome DevTools MCP on a harness laptop should stay configured locally on that harness. If it runs on the MCP Home host, it can be managed as a Home-hosted Server — but it operates on the host environment.

The first release explicitly excludes multi-tenancy, profiles, workspaces, and project management.

Protocol Capabilities

The per-server entry proxies losslessly; the aggregate virtualizes conflicting names while keeping everything routable:

  • Tools, Prompts, Resources, Resource Templates, Completion

  • Resource subscriptions and list-changed notifications

  • Sampling, Roots, Elicitation, and 2026 MRTR input_required

  • Final Tasks extension: tasks/get, tasks/update, tasks/cancel, task-ID virtualization, and Mcp-Name binding

  • MCP Apps: ui:// URIs are preserved on the aggregate; original App semantics on per-server entries

  • Logging, Progress, cancellation, and custom extension methods

  • Automatic 2026-07-28 / 2025-era negotiation, with remote SSE available as an explicit fallback

Downstream 2026 requests stay stateless; 2025-era clients use a persistent session bound to the authenticated principal, preserving initialize capability declarations and bidirectional request semantics. Parts of the Final Tasks extension not yet registered by SDK 2.0 are filled in by an isolated compatibility layer that still speaks the official tasks/* wire contract.

Aggregated tool names are {server_slug}.{upstream_name}. Unknown extension methods use mcp-home/{server_slug}/{upstream_method} on the aggregate and pass through untouched on per-server entries. MCP Apps that use original tool names are routed by App resource context or globally unique names; use a per-server entry when names collide.

When a modern harness calls a legacy upstream, MCP Home suspends push-style Elicitation, Sampling, and Roots in Tool, Prompt, and Resource Read calls, converts them to modern input_required multi-turn interactions, then resumes the same upstream request. Legacy extensions that issue private server-to-client requests inside a custom method have no standard representation in the closed MRTR type set; use a legacy harness or upgrade the upstream protocol for those.

See architecture and protocol compatibility for details.

Quick Start

Requires Node.js 24 or newer.

npm install
cp .env.example .env

Generate two independent random values for MCP_HOME_MASTER_KEY and the first-boot MCP_HOME_BOOTSTRAP_CONTROL_KEY. Both must be at least 32 characters and must differ.

npm run build
set -a
source .env
set +a
npm start

Open MCP_HOME_PUBLIC_URL and sign in to the web console with the bootstrap Control API Key. Once you create a new Control Key, you can revoke the bootstrap key.

For development, run the server and web separately:

npm run dev
npm run dev:web

Vite proxies /api requests to http://127.0.0.1:3344.

Docker

export MCP_HOME_MASTER_KEY="$(openssl rand -base64 48)"
export MCP_HOME_BOOTSTRAP_CONTROL_KEY="$(openssl rand -base64 48)"
export MCP_HOME_PUBLIC_URL="https://mcp.example.com"
export MCP_HOME_ALLOWED_HOSTS="mcp.example.com"
docker compose up -d --build

Put an HTTPS reverse proxy in front of MCP Home in production. OAuth callbacks, URL-based Client IDs, and remote harness connections should all use a stable HTTPS MCP_HOME_PUBLIC_URL. The value must be a canonical origin — no path, query, fragment, username, or password. Data lives in /data/mcp-home.sqlite (SQLite, WAL mode).

npm packages for Home-hosted stdio servers are installed by the Market into the data volume (MCP_HOME_MARKET_DIR, default <dataDir>/market) — no Dockerfile changes needed. Don't run arbitrary npm packages in the container: use the Market's curated catalog instead.

CI/CD

GitHub Actions (.github/workflows/ci.yml) runs on every push to main or tag:

  1. test: server check + test, web typecheck + test

  2. docker: build dists -> docker build -> push ghcr.io/crayonlu/mcp-home:latest (tags also get :v*)

  3. deploy: SSH to server docker compose pull && up -d

Deployment requires three GitHub Secrets: DEPLOY_HOST, DEPLOY_USER, DEPLOY_KEY (SSH private key). The GHCR package must be set to Public (after first push, in Package Settings).

Market

The Market ships a curated catalog of common MCP servers and installs them with one command, creating the Credential and Server for you:

npm run cli -- market list
npm run cli -- market install resend --set RESEND_API_KEY=re_xxx
npm run cli -- market uninstall resend
  • Entries are either remote (official Streamable HTTP endpoints, OAuth or API key) or home-stdio (npm packages installed into the Market directory).

  • Installing a home-stdio entry runs npm install --prefix <marketDir> and creates an env Credential plus the matching Server.

  • The web console's Market page offers the same flow graphically; OAuth entries need the authorization flow after install.

Connecting a Harness

First create an MCP Access API Key from the console or CLI. The generic aggregate configuration is:

{
  "url": "https://mcp.example.com/mcp",
  "headers": {
    "Authorization": "Bearer mch_mcp_..."
  }
}

For a single GitHub server only:

{
  "url": "https://mcp.example.com/mcp/github",
  "headers": {
    "Authorization": "Bearer mch_mcp_..."
  }
}

Access Keys only call the MCP data plane; they cannot read server or credential configuration. Control Keys only call the control plane and cannot be used as an MCP identity.

The data plane also implements OAuth 2.1: a harness can discover the authorization server via RFC 9728 metadata and use Authorization Code + PKCE to obtain an access token bound to a specific MCP endpoint.

Downstream Dynamic Client Registration returns a stateless Client ID signed with the master key — no in-process registry, valid across restarts with the same key. HTTPS URL-based Client Metadata is also supported, with limits on response size, redirects, and non-public targets.

Upstream Authentication

Remote-native servers support:

  • Bearer token

  • API key header

  • Multiple custom headers

  • OAuth 2.1 / OIDC

OAuth/OIDC uses the official MCP TypeScript SDK auth orchestrator, covering RFC 9728 discovery, Authorization Server/OIDC metadata, PKCE, RFC 9207 issuer validation, CIMD, DCR, refresh, and RFC 8707 resource indicators. An OAuth Credential is bound 1:1 to a Remote Server, preventing token reuse across resources or issuers.

If an upstream authorization server advertises URL-based Client Metadata support but cannot fetch it from a proxied origin (for example Cloudflare-hosted MCP), set MCP_HOME_OAUTH_URL_CLIENT_ID=false to force Dynamic Client Registration.

Home-hosted servers use an Environment Credential or the transport's own env.

Put secrets in Credentials, not in Remote URL query strings or stdio arguments — the latter are structural configuration and cannot be reliably redacted.

CLI

After building, run mcp-home; from source, use npm run cli --.

npm run cli -- auth login \
  --url https://mcp.example.com \
  --control-key "$MCP_HOME_CONTROL_KEY"

npm run cli -- server list
npm run cli -- server add ./server.json
npm run cli -- credential authorize cloudflare
npm run cli -- access-key create laptop
npm run cli -- endpoint aggregate
npm run cli -- doctor

credential authorize <name> resolves by credential name (or id), opens the browser, and waits until authorization succeeds, fails, or times out:

npm run cli -- credential authorize notion --server notion   # explicit server (auto-resolved if omitted)
npm run cli -- credential authorize notion --force            # clear the old client and re-authorize
npm run cli -- credential authorize notion --no-open          # don't open the browser
npm run cli -- credential authorize notion --no-wait          # print the URL and exit
npm run cli -- credential authorize notion --timeout 300      # wait time in seconds (default 600)

The CLI exposes a command for every Control API capability plus a general escape hatch:

npm run cli -- api GET /api/v1/openapi.json

Config export is redacted and reviewable by default, and cannot be used to restore. Credential payloads, static HTTP header values, and stdio transport env values are hidden. When secrets are explicitly included, the CLI writes the file with 0600 permissions; import rebuilds credentials, remaps related IDs, and rolls back atomically in a single SQLite transaction if any step fails.

npm run cli -- config export backup.json --include-secrets
npm run cli -- config import backup.json

Backups contain plaintext secrets and deserve the same protection as the master key. --include-secrets requires an explicit output file to avoid leaking secrets into terminal logs, and the CLI forces 0600 after writing. Omit it for routine review.

Configuration

Environment variable

Description

Default

MCP_HOME_HOST

Listen address

127.0.0.1

MCP_HOME_PORT

Listen port

3344

MCP_HOME_PUBLIC_URL

Externally reachable canonical origin

http://127.0.0.1:3344

MCP_HOME_DATA_DIR

SQLite and runtime data directory

./data

MCP_HOME_MASTER_KEY

Root key for secret encryption/signing/digests

required

MCP_HOME_BOOTSTRAP_CONTROL_KEY

Control Key written on first database boot

required on first boot

MCP_HOME_ALLOWED_HOSTS

Allowed Hosts, comma-separated

Public URL hostname

MCP_HOME_LOG_LEVEL

debug, info, warn, error

info

MCP_HOME_WEB_DIR

Web console static files directory

disabled

MCP_HOME_MARKET_DIR

Market npm install directory

<dataDir>/market

MCP_HOME_OAUTH_URL_CLIENT_ID

Enable URL-based Client Metadata

true

Security Model

  • Upstream secrets are AES-256-GCM encrypted before being written to SQLite.

  • The database stores an encrypted master-key check; booting with the wrong master key fails immediately instead of silently locking existing API keys.

  • API Keys are stored only as HMAC digests; the full secret is returned once at creation.

  • Control and MCP Access Keys use distinct prefixes and validation domains.

  • The web console exchanges the Control Key for a short-lived, HttpOnly, SameSite=Strict session cookie.

  • Downstream OAuth tokens have exact endpoint audiences; an aggregate token cannot call per-server endpoints and vice versa.

  • OAuth callbacks validate state, PKCE, issuer, and discovery state.

  • URL-based client metadata rejects private-network and insecure targets and pins validated public-resolved addresses for HTTPS fetches, reducing SSRF and DNS-rebinding risk.

  • Downstream DCR Client IDs are signed with the master key, verifiable across restarts, and never stored in the database.

  • Diagnostic events keep the last ~10,000 entries; Home-hosted stderr is redacted against transport env and Environment Credential values before entering the event stream.

Back up the database and MCP_HOME_MASTER_KEY, or keep a tightly protected --include-secrets config export. Losing the master key makes encrypted credentials in the original database unrecoverable.

Engineering Commands

npm run check
npm run format:check
npm run build
npm run test
npm run test:real

npm run test:real prefers to launch the built MCP Home process and connects Home-hosted stdio and Remote-native HTTP fixtures. It uses the official MCP Client to verify aggregate/per-server entries, modern/legacy harnesses, Progress, cancellation, list-changed, MRTR, Tasks, and auth boundaries; it falls back to source entry points when no build artifact exists, which is handy for local debugging.

/healthz reports process liveness only; /readyz returns 503 while runtime state is unavailable.

License

MIT

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    -
    quality
    D
    maintenance
    MCP Gateway that aggregates multiple upstream MCP servers into a single endpoint with persistent connections, tool registry, and authentication.
    21
    2
    MIT
  • A
    license
    -
    quality
    A
    maintenance
    Self-hosted MCP proxy and aggregation platform. Register multiple upstream MCP servers and expose them through a single unified endpoint with namespace routing, multi-transport support (HTTP/SSE, stdio, OpenAPI→MCP), per-tool overrides, and a web admin UI.
    16
    MIT
  • A
    license
    -
    quality
    B
    maintenance
    Centralized MCP control plane that proxies multiple upstream MCP servers with tool namespacing, filtering, policy enforcement, audit logging, and health checks.
    7
    MIT
  • A
    license
    -
    quality
    B
    maintenance
    A universal MCP gateway that aggregates multiple MCP servers into a single endpoint, providing features like hot-reload, auto-healing, and a hook system for request/response mutation.
    1
    MIT

View all related MCP servers

Related MCP Connectors

  • Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.

  • MCP server for Appcircle mobile CI/CD platform.

  • Control plane for autonomous software labor. Agents claim objectives over MCP with audit trail.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/crayonlu/MCP-home'

If you have feedback or need assistance with the MCP directory API, please join our Discord server