diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml new file mode 100644 index 00000000..edd2e349 --- /dev/null +++ b/.github/workflows/docs-deploy.yml @@ -0,0 +1,22 @@ +name: Deploy Docs + +on: + push: + branches: [main] + paths: + - 'docs/guide/**' + +# Restrict permissions to minimum needed +permissions: {} + +jobs: + trigger-deploy: + runs-on: ubuntu-latest + # Only run for pushes by repo collaborators, not automated merges from unknown sources + if: github.repository == 'mcpmux/mcp-mux' + steps: + - name: Trigger mcpmux.com rebuild + run: | + curl -s -X POST "$CF_PAGES_DEPLOY_HOOK" + env: + CF_PAGES_DEPLOY_HOOK: ${{ secrets.CF_PAGES_DEPLOY_HOOK }} diff --git a/docs/guide/clients.mdx b/docs/guide/clients.mdx new file mode 100644 index 00000000..916f27b9 --- /dev/null +++ b/docs/guide/clients.mdx @@ -0,0 +1,101 @@ +--- +title: Clients — AI Application Management +description: Connect Cursor, Claude Desktop, VS Code, Windsurf, and other AI clients to McpMux. Configure connection modes and per-Space permissions for each client. +--- + +Clients are the AI applications that connect to McpMux's gateway to access MCP tools, resources, and prompts. McpMux lets you manage each client independently with its own permissions and Space behavior. + +## Supported Clients + +McpMux works with any MCP-compatible client, including: + +| Client | Type | Connection | +|--------|------|-----------| +| Cursor | IDE | Streamable HTTP | +| Claude Desktop | Desktop App | Streamable HTTP | +| Claude Code | CLI | Streamable HTTP | +| VS Code (Copilot) | IDE | Streamable HTTP | +| ChatGPT Desktop | Desktop App | Streamable HTTP | +| Windsurf | IDE | Streamable HTTP | +| JetBrains IDEs | IDE | Streamable HTTP | +| Zed | Editor | Streamable HTTP | +| Gemini CLI | CLI | Streamable HTTP | + +All clients connect to the same endpoint: `http://localhost:45818/mcp` + +![Authorization Request dialog — VS Code connecting to McpMux with connection mode selection](/screenshots/clients.png) + +## Connection Modes + +Each client has a **connection mode** that determines how it interacts with Spaces: + +### Follow Active + +The client automatically uses whichever Space is currently active. When you switch the active Space, the client immediately sees the new Space's servers and tools. + +**Best for:** Your primary development tools that should always match your current context. + +### Locked + +The client always uses a specific Space, regardless of which Space is active. This is useful for: + +- A monitoring tool that should always see production servers +- A client dedicated to a specific project +- Background automation that shouldn't change behavior + +### Ask on Change + +When the active Space changes, McpMux prompts you to confirm whether this client should switch too. This provides a safety net for important clients. + +**Best for:** Clients with elevated permissions where an accidental Space switch could be problematic. + +## Per-Space Permissions + +Each client receives **FeatureSet grants** per Space. This means a single client can have different permissions in different Spaces: + +| Client | Work Space | Personal Space | +|--------|-----------|---------------| +| Cursor | All tools | Read Only | +| Claude Desktop | Developer FeatureSet | All tools | +| Monitoring Bot | Read Only | — (no access) | + +This is configured in the **Clients** page by selecting a client and managing its grants for each Space. + +![Client detail panel — Cursor with per-Space FeatureSet grants and permission management](/screenshots/client-detail.png) + +## Access Keys + +Each client authenticates with McpMux using an **access key**. Access keys are: + +- Generated automatically when a client registers +- Stored encrypted in the OS keychain +- Unique per client +- Revocable at any time + +## Client Lifecycle + +### Registration + +Clients can be registered in two ways: + +1. **Automatic** — when a new client connects to the gateway via OAuth, McpMux prompts you to approve it +2. **Manual** — add a client through the McpMux UI and copy the access key into your client's configuration + +![Effective Features view showing 45 tools, 8 prompts, and 3 resources available to Cursor](/screenshots/client-permissions.png) + +### Monitoring + +The **Clients** page shows: +- Each registered client's name and type +- Connection mode (Follow Active / Locked / Ask on Change) +- Last seen timestamp + +### Disconnecting + +You can disconnect or remove a client at any time from the Clients page. This revokes its access key and it will no longer be able to make MCP requests through the gateway. + +## Next Steps + +- [Configure FeatureSets](/docs/feature-sets/) to build permission bundles for your clients +- [Learn about Spaces](/docs/spaces/) to understand how connection modes interact with workspaces +- [Set up the Gateway](/docs/gateway/) to understand how client requests are routed diff --git a/docs/guide/feature-sets.mdx b/docs/guide/feature-sets.mdx new file mode 100644 index 00000000..f1ac9c86 --- /dev/null +++ b/docs/guide/feature-sets.mdx @@ -0,0 +1,111 @@ +--- +title: FeatureSets — Permission Control +description: FeatureSets control which MCP tools, resources, and prompts each AI client can access in McpMux. Create role-based permissions, domain bundles, or read-only views. +--- + +FeatureSets are permission bundles that control what MCP capabilities (tools, resources, and prompts) each AI client can access. They let you grant fine-grained permissions per client, per Space. + +## Why FeatureSets + +Without permission control, every AI client connected through the gateway can access every tool from every server. This creates risks: + +- A junior developer's client could access destructive database tools +- An experimental AI agent could call deployment tools +- A read-only analysis tool could accidentally modify production data + +FeatureSets solve this by letting you define exactly what each client can do. + +![FeatureSets page showing All Features, Default, Custom (Cloudflare Workers, Full Stack Dev, React Development, Read Only)](/screenshots/featuresets.png) + +## FeatureSet Types + +McpMux creates and manages four types of FeatureSets: + +### All + +Grants access to **every tool, resource, and prompt** from every connected server in the Space. Use this for fully trusted clients. + +### Default + +Automatically granted to **all clients** in the Space. Define a baseline set of capabilities that every client gets. You can still add more FeatureSets on top for specific clients. + +### ServerAll + +Automatically created when a server first connects. Grants access to **all features from that specific server**. For example, when you enable the GitHub server, McpMux creates a "GitHub — All" FeatureSet containing all of GitHub's tools and resources. + +### Custom + +User-defined FeatureSets with manually selected features. This is where you build your own permission bundles. + +## Include and Exclude + +Each FeatureSet member can be set to **include** or **exclude** mode: + +- **Include** — add this tool/resource/prompt to the set +- **Exclude** — remove this tool/resource/prompt from the set + +Exclude rules always win over include rules. This means you can create a permissive base and then remove specific dangerous tools: + +**Example:** "All GitHub except delete operations" +1. Include the **GitHub — All** ServerAll FeatureSet +2. Exclude `delete_repository`, `delete_branch`, `delete_file` + +## Composition + +FeatureSets can **contain other FeatureSets**. This lets you build hierarchical permission structures: + +- **"Read Only"** = Include tools that only read data from multiple servers +- **"Android Development"** = Include "GitHub — All" + "Firebase — All" + specific Gradle tools +- **"Senior Developer"** = Include "All" but exclude deployment and infrastructure tools +- **"Intern"** = Include "Read Only" + specific write tools for their assigned project + +## Common Use Cases + +### Role-Based Access + +| FeatureSet | Contains | +|-----------|----------| +| Read Only | Search, list, and read tools only | +| Developer | Read Only + code editing + PR management | +| DevOps | Developer + deployment + infrastructure | +| Admin | All capabilities | + +### Domain Bundles + +| FeatureSet | Contains | +|-----------|----------| +| Frontend | Browser tools + CSS/JS linting + design system resources | +| Backend | Database queries + API testing + log analysis | +| Full Stack | Frontend + Backend | + +### Safety Limits + +| FeatureSet | Contains | +|-----------|----------| +| No Delete | All minus any delete/remove/drop operations | +| No Deploy | All minus CI/CD and deployment tools | +| Sandbox | Only filesystem (read) + search + documentation | + +## Managing FeatureSets + +![React Development FeatureSet — configuring included features from each server](/screenshots/featureset-detail.png) + +### Creating a Custom FeatureSet + +1. Go to the **FeatureSets** page +2. Click **Create FeatureSet** +3. Give it a name and optional description +4. Add members — select features or other FeatureSets +5. Set each member to include or exclude mode + +### Assigning to Clients + +FeatureSets are assigned to clients per Space. Go to the **Clients** page, select a client, and manage its FeatureSet grants for each Space. + +A client's effective permissions are the combination of all its granted FeatureSets, with exclude rules taking priority. + +## Next Steps + +- [Set up Clients](/docs/clients/) and assign FeatureSets per Space +- [Learn about Spaces](/docs/spaces/) for environment isolation +- [Understand the Gateway](/docs/gateway/) to see how permissions are enforced at request time diff --git a/docs/guide/gateway.mdx b/docs/guide/gateway.mdx new file mode 100644 index 00000000..5a24743b --- /dev/null +++ b/docs/guide/gateway.mdx @@ -0,0 +1,97 @@ +--- +title: Gateway — Local MCP Proxy +description: The McpMux Gateway runs on localhost:45818 and routes MCP requests from AI clients to the correct servers with automatic authentication and permission filtering. +--- + +The **Gateway** is the core of McpMux — a local HTTP server that acts as a single entry point for all your AI clients. Instead of configuring each client to connect to each MCP server individually, every client connects to the gateway at `http://localhost:45818/mcp`. + +## How It Works + +``` +Cursor ──────────┐ +Claude Desktop ──┤ +VS Code ─────────┤──→ McpMux Gateway ──┬──→ GitHub Server +Windsurf ────────┤ (localhost:45818) ├──→ Slack Server +ChatGPT ─────────┘ ├──→ PostgreSQL Server + └──→ Filesystem Server +``` + +The gateway receives MCP JSON-RPC requests from clients and: + +1. **Authenticates** the client using its access key +2. **Resolves** which Space the client should use (based on connection mode) +3. **Collects** the client's FeatureSet grants for that Space +4. **Filters** the available tools, resources, and prompts based on permissions +5. **Routes** each request to the correct backend MCP server +6. **Returns** the response to the client + +## Request Routing + +When a client calls a tool (e.g., `github_create_issue`), the gateway: + +1. Looks up which server provides that tool +2. Checks that the client has permission to use it (via FeatureSets) +3. Forwards the request to the server's active connection +4. Returns the server's response to the client + +Clients only see tools they have permission to use. If a FeatureSet excludes a tool, the client doesn't even know it exists — it won't appear in `tools/list` responses. + +## FeatureSet Filtering + +The gateway enforces permissions at the protocol level: + +- **`tools/list`** — only returns tools the client is permitted to use +- **`tools/call`** — rejects calls to tools the client doesn't have access to +- **`resources/list`** — only returns permitted resources +- **`prompts/list`** — only returns permitted prompts + +This means you can have multiple clients connected to the same gateway with different levels of access, all managed through FeatureSets. + +## OAuth Token Management + +For servers that use OAuth 2.1 + PKCE authentication, the gateway handles the full token lifecycle: + +- **Initial authorization** — opens a browser for you to log in and grant permissions +- **Token storage** — tokens are encrypted and stored in the OS keychain +- **Automatic refresh** — when a token expires, the gateway refreshes it transparently +- **Re-authorization** — if a refresh fails, McpMux prompts you to re-authenticate + +You never need to manually manage OAuth tokens — the gateway takes care of it. + +## Connection Pooling + +The gateway maintains a pool of connections to backend MCP servers: + +- Each server gets a connection based on its configuration and credentials +- Connections are reused across clients (when they share the same Space and credentials) +- The pool key is computed from `server_id + sha256(final_config_with_credentials)` +- When credentials change (e.g., token refresh), a new connection is created with the updated credentials +- Idle connections are cleaned up after a configurable timeout + +This means if two clients in the same Space both use the GitHub server, they share a single connection to GitHub — reducing resource usage. + +![Dashboard showing gateway running on localhost:45818 with server stats and client configuration](/screenshots/dashboard.png) + +## Starting and Stopping + +Control the gateway from the **Dashboard** in McpMux: + +- **Start Gateway** — begins listening on `localhost:45818` and connects to enabled servers +- **Stop Gateway** — disconnects all servers and stops accepting requests + +The gateway also starts automatically when McpMux launches (configurable in Settings). + +## Gateway Status + +The dashboard shows real-time gateway status: + +- **Running** / **Stopped** — whether the gateway is accepting connections +- **Connected Servers** — count of actively connected backend servers +- **Registered Clients** — count of AI clients that have connected + +## Next Steps + +- [Set up Clients](/docs/clients/) to connect your AI applications +- [Configure FeatureSets](/docs/feature-sets/) to control what each client can access +- [Manage Servers](/docs/servers/) to add and configure backend MCP servers +- [Learn about Security](/docs/security/) to understand how the gateway protects your credentials diff --git a/docs/guide/getting-started.mdx b/docs/guide/getting-started.mdx new file mode 100644 index 00000000..b3cd4064 --- /dev/null +++ b/docs/guide/getting-started.mdx @@ -0,0 +1,137 @@ +--- +title: Getting Started with McpMux +description: Download McpMux, install your first MCP server, and connect Cursor, Claude, or VS Code in under 5 minutes. Step-by-step setup guide. +--- + +Get McpMux running and connect your first AI client in just a few steps. + +## Prerequisites + +- **Operating System**: Windows 10+, macOS 12+, or Linux (Ubuntu 20.04+, Fedora 38+) +- **AI Client**: At least one MCP-compatible client installed (Cursor, Claude Desktop, VS Code, etc.) + +## Step 1: Download and Install + +Download McpMux for your platform from the [download page](/download/). + +- **Windows**: Run the `.msi` installer +- **macOS**: Open the `.dmg` and drag McpMux to Applications +- **Linux**: Install via `.deb`, `.rpm`, or `.AppImage` + +McpMux runs in the system tray — look for the McpMux icon after installation. + +## Step 2: Create a Space + +When you first open McpMux, a default Space is created for you. Spaces are isolated environments with their own server configurations and credentials. + +You can create additional Spaces later for different contexts: +- **Work** — company tools with work credentials +- **Personal** — side projects with personal API keys +- **Client-A** — isolated environment for a specific client + +To create a Space, go to the **Spaces** page and click **Create Space**. + +![Space switcher in the sidebar lets you quickly switch between workspaces](/screenshots/space-switcher.png) + +## Step 3: Browse and Install a Server + +Navigate to **Discover Servers** in McpMux or browse the [server registry](/) on this website. You'll find 100+ MCP servers for popular tools. + +![Discover Servers page — browse, search, and install MCP servers from the registry](/screenshots/discover.png) + +Click **Install** on any server to add it to your active Space. Popular choices to start with: + +- **Filesystem** — read and write local files +- **GitHub** — interact with repositories, issues, and PRs +- **Brave Search** — web search capabilities +- **Playwright** — browser automation + +## Step 4: Configure Credentials + +If the server requires authentication (API keys, tokens, etc.), a configuration dialog appears automatically after installation. Fill in the required fields: + +- **API keys** are stored encrypted using AES-256-GCM — they never touch disk in plaintext +- Click the **obtain** link (if provided) to go directly to the service's token creation page +- Sensitive fields are masked in the UI and stored in the OS keychain + +See [Server Management](/docs/servers/) for details on all configuration options. + +## Step 5: Start the Gateway + +Go to the **Dashboard** and click **Start Gateway**. The gateway starts on `localhost:45818` and begins connecting to your enabled servers. + +![Dashboard with gateway running and connected servers](/screenshots/dashboard.png) + +You'll see server status indicators change: +- 🟡 **Connecting** — establishing MCP handshake +- 🟢 **Connected** — ready to serve requests +- 🔴 **Error** — check server logs for details + +## Step 6: Connect Your AI Client + +Configure your AI client to connect to McpMux's gateway endpoint. The exact setup depends on your client: + +### Cursor + +Add to your Cursor MCP settings (`.cursor/mcp.json`): + +```json +{ + "mcpServers": { + "mcpmux": { + "url": "http://localhost:45818/mcp" + } + } +} +``` + +### Claude Desktop + +Add to your Claude Desktop config (`claude_desktop_config.json`): + +```json +{ + "mcpServers": { + "mcpmux": { + "url": "http://localhost:45818/mcp" + } + } +} +``` + +### VS Code (Copilot) + +Add to your VS Code settings (`.vscode/mcp.json`): + +```json +{ + "servers": { + "mcpmux": { + "url": "http://localhost:45818/mcp" + } + } +} +``` + +### Windsurf + +Add to your Windsurf MCP configuration: + +```json +{ + "mcpServers": { + "mcpmux": { + "serverUrl": "http://localhost:45818/mcp" + } + } +} +``` + +Once connected, your AI client can access all the tools, resources, and prompts from every enabled MCP server — through the single McpMux gateway endpoint. + +## Next Steps + +- [Learn about Spaces](/docs/spaces/) to organize your environments +- [Configure FeatureSets](/docs/feature-sets/) to control tool permissions +- [Browse the server registry](/) to find more MCP servers +- [Understand security](/docs/security/) and how McpMux protects your credentials diff --git a/docs/guide/index.mdx b/docs/guide/index.mdx new file mode 100644 index 00000000..40bff3d1 --- /dev/null +++ b/docs/guide/index.mdx @@ -0,0 +1,78 @@ +--- +title: What is McpMux +description: Configure MCP servers once, connect every AI client through a single endpoint. McpMux is a free desktop app and local gateway for MCP server management with encrypted credential storage. +--- + +![McpMux desktop app — dashboard with gateway running, server stats, and client configuration](/screenshots/features-hero.png) + +## The Problem + +Every AI-powered development tool — Cursor, Claude Desktop, VS Code, Windsurf, ChatGPT, JetBrains — requires its own MCP server configuration. This means: + +- **Duplicate configurations** across every tool, each with slightly different JSON formats +- **Plaintext credentials** scattered in config files on disk +- **No access control** — every client sees every tool from every server +- **Manual context switching** when moving between work, personal, and client projects +- **No visibility** into which servers are connected or what tools are available + +## The Solution + +**McpMux** is a free, open-source desktop app that solves all of these problems. Configure your MCP servers once in McpMux, then connect every AI client through a single `localhost:45818` endpoint. + +``` +AI Clients (Cursor, Claude, VS Code, …) + ↓ +McpMux Gateway (localhost:45818/mcp) + ↓ +MCP Servers (GitHub, Slack, PostgreSQL, …) +``` + +![McpMux dashboard showing gateway status, connected servers, FeatureSets, clients, and connection config](/screenshots/dashboard.png) + +McpMux sits between your AI clients and your MCP servers. It handles: + +- **Routing** — directs each MCP request to the correct server +- **Authentication** — manages OAuth tokens, API keys, and credentials +- **Permissions** — controls which tools each client can access via FeatureSets +- **Encryption** — stores all credentials with AES-256-GCM in the OS keychain +- **Isolation** — separates environments with Spaces (work, personal, client projects) + +## Key Concepts + +### [Spaces](/docs/spaces/) + +Isolated workspaces with separate server configurations and credentials. Keep your work GitHub token completely separate from your personal one. + +### [FeatureSets](/docs/feature-sets/) + +Permission bundles that control which MCP tools, resources, and prompts each AI client can access. Create read-only views, role-based access, or domain-specific bundles. + +### [Clients](/docs/clients/) + +AI applications connected to McpMux. Configure connection modes (follow active Space, lock to a Space, or ask on change) and assign permissions per Space. + +### [Servers](/docs/servers/) + +MCP servers installed and managed through McpMux. Supports both local stdio servers and remote HTTP endpoints with automatic credential injection. + +### [Gateway](/docs/gateway/) + +The local HTTP server running on `localhost:45818` that routes MCP requests, manages OAuth tokens, filters tools by permissions, and pools server connections. + +## Supported Clients + +McpMux works with every MCP-compatible AI client: + +- **Cursor** — AI code editor +- **Claude Desktop** — Anthropic's desktop app +- **Claude Code** — CLI coding assistant +- **VS Code** — with GitHub Copilot or Cline extensions +- **ChatGPT Desktop** — OpenAI's desktop app +- **Windsurf** — AI-powered IDE +- **JetBrains IDEs** — IntelliJ, WebStorm, PyCharm, and more +- **Zed** — next-generation code editor +- **Gemini CLI** — Google's command-line AI + +## Get Started + +Ready to try McpMux? Follow the [Getting Started guide](/docs/getting-started/) to install the app, add your first MCP server, and connect your AI client in under 5 minutes. diff --git a/docs/guide/meta.json b/docs/guide/meta.json new file mode 100644 index 00000000..98e6c70c --- /dev/null +++ b/docs/guide/meta.json @@ -0,0 +1,17 @@ +{ + "root": true, + "pages": [ + "---Getting Started---", + "index", + "getting-started", + "---Core Concepts---", + "spaces", + "feature-sets", + "clients", + "servers", + "---Advanced---", + "gateway", + "server-definitions", + "security" + ] +} diff --git a/docs/guide/security.mdx b/docs/guide/security.mdx new file mode 100644 index 00000000..7c285ed2 --- /dev/null +++ b/docs/guide/security.mdx @@ -0,0 +1,100 @@ +--- +title: Security & Credential Encryption +description: McpMux encrypts all credentials with AES-256-GCM and stores encryption keys in the OS keychain. No plaintext credentials ever touch disk. Learn about McpMux's security model. +--- + +Security is a core design principle of McpMux. Every credential — API keys, OAuth tokens, passwords — is encrypted before it ever touches disk. McpMux never stores plaintext credentials. + +## The Problem with MCP Credentials Today + +Without McpMux, MCP server credentials are stored in plaintext JSON configuration files: + +```json +{ + "mcpServers": { + "github": { + "env": { + "GITHUB_TOKEN": "ghp_abc123_YOUR_REAL_TOKEN_HERE" + } + } + } +} +``` + +These files sit in your home directory, readable by any process on your machine. If your machine is compromised, every MCP credential is immediately exposed. + +## How McpMux Protects Credentials + +### AES-256-GCM Encryption + +Every credential stored by McpMux is encrypted using **AES-256-GCM** (Galois/Counter Mode) — the same standard used by banks and governments. Each credential gets its own encryption, so compromising one doesn't expose others. + +### OS Keychain Integration + +Encryption keys are stored in the operating system's secure keychain: + +| Platform | Keychain | +|----------|----------| +| Windows | **DPAPI** (Data Protection API) — tied to your Windows user account | +| macOS | **Keychain** — protected by your login password and Secure Enclave | +| Linux | **Secret Service** (GNOME Keyring / KWallet) — encrypted with your login session | + +The encryption keys never exist as plaintext files. They're protected by the OS and require your user session to access. + +### Per-Token Encryption + +McpMux doesn't use a single master key for all credentials. Each stored token is encrypted with its own derived key, meaning: + +- Compromising one credential doesn't expose others +- Rotating a credential doesn't require re-encrypting everything +- Deletion of a credential securely removes its encryption key + +### Memory Zeroization + +Sensitive values in memory are securely wiped using the `zeroize` crate when they're no longer needed. This prevents credentials from lingering in memory after use, reducing the window for memory-based attacks. + +## Per-Space Credential Isolation + +Credentials are scoped to individual Spaces. Your work GitHub token in the "Work" Space is completely separate from your personal GitHub token in the "Personal" Space. They use different encryption keys and are stored independently. + +This means: +- Switching Spaces switches credentials — no cross-contamination +- Deleting a Space securely removes all its credentials +- Different team members can use different credentials for the same service + +## Before vs After + +| | Without McpMux | With McpMux | +|---|---|---| +| **Storage** | Plaintext JSON files | AES-256-GCM encrypted database | +| **Key management** | None — keys are in the file | OS keychain (DPAPI / Keychain / Secret Service) | +| **Isolation** | All credentials in one file | Per-Space, per-token isolation | +| **Access control** | Any process can read | Requires user session + keychain access | +| **Token refresh** | Manual | Automatic with encrypted storage | +| **Memory** | Tokens may linger | Zeroized after use | +| **Audit** | No visibility | Server logs and connection tracking | + +## OAuth Security + +For servers using OAuth 2.1, McpMux implements the full security specification: + +- **PKCE** (Proof Key for Code Exchange) — prevents authorization code interception +- **Short-lived tokens** — access tokens expire after approximately 1 hour +- **Automatic refresh** — tokens are refreshed transparently before expiry +- **Encrypted storage** — both access and refresh tokens are encrypted at rest +- **Consent UI** — OAuth authorization requests show a consent dialog in the desktop app, ensuring the user explicitly approves each connection + +## Deep Link Security + +When McpMux receives an OAuth authorization request via deep link (`mcpmux://authorize?request_id=xxx`): + +- Only the `request_id` is passed in the URL — no client information or credentials +- The consent token is shared only via local IPC, never over HTTP +- The desktop app validates the request server-side before showing the consent dialog + +## Next Steps + +- [Get started with McpMux](/docs/getting-started/) to see encryption in action +- [Learn about Spaces](/docs/spaces/) for credential isolation +- [Configure Servers](/docs/servers/) with encrypted credential storage +- [Download McpMux](/download/) to protect your MCP credentials today diff --git a/docs/guide/server-definitions.mdx b/docs/guide/server-definitions.mdx new file mode 100644 index 00000000..aa792aa4 --- /dev/null +++ b/docs/guide/server-definitions.mdx @@ -0,0 +1,434 @@ +--- +title: Server Definitions — Registry Schema +description: Learn how to create MCP server definitions for the McpMux registry. Complete JSON schema reference with field descriptions, transport types, input metadata, authentication, and examples. +--- + +A **server definition** is a JSON file that describes an MCP server — how to run it, what credentials it needs, and what capabilities it provides. Server definitions power the [McpMux server registry](/) and enable one-click installation. + +![McpMux web registry — browse and install MCP servers with one click](/screenshots/discover-web.png) + +## Required Fields + +Every server definition needs exactly three fields: + +### id + +A unique identifier in reverse-domain notation: `{tld}.{publisher}-{name}` + +``` +com.github-mcp # Official GitHub server +community.brave-search # Community-maintained Brave Search server +com.cloudflare-docs # Official Cloudflare documentation server +``` + +**Rules:** +- Lowercase letters, numbers, and hyphens only +- Pattern: `^[a-z0-9]+\.[a-z0-9][a-z0-9-]*$` +- Filename must match: `servers/{id}.json` +- One publisher can have multiple servers + +**Namespaces:** +- `com.*` — official publisher or well-known organization +- `community.*` — community contributors + +### name + +Human-readable display name shown in the registry and McpMux UI. + +```json +"name": "GitHub" +``` + +### transport + +Defines how to run or connect to the server. Must be one of two types: + +## Transport Types + +### stdio — Local Command Execution + +Runs a process on the user's machine. McpMux communicates over stdin/stdout. + +```json +{ + "type": "stdio", + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-github"], + "env": { + "GITHUB_PERSONAL_ACCESS_TOKEN": "${input:GITHUB_TOKEN}" + }, + "metadata": { + "inputs": [ + { + "id": "GITHUB_TOKEN", + "label": "GitHub Personal Access Token", + "type": "password", + "required": true, + "secret": true, + "placeholder": "ghp_xxxxxxxxxxxxxxxxxxxx", + "obtain": { + "url": "https://github.com/settings/tokens/new", + "instructions": "1. Click 'Generate new token (classic)'\n2. Select scopes: repo, read:org\n3. Copy the token", + "button_label": "Create Token" + } + } + ] + } +} +``` + +**Fields:** +| Field | Required | Description | +|-------|----------|-------------| +| `type` | Yes | Always `"stdio"` | +| `command` | Yes | Command to execute (`npx`, `uvx`, `docker`, `python`, `node`) | +| `args` | No | Array of command-line arguments | +| `env` | No | Environment variables (supports `${input:ID}` placeholders) | +| `cwd` | No | Working directory | +| `metadata.inputs` | No | User input definitions (see [Input Metadata](#input-metadata)) | + +### http — Remote Endpoint + +Points to a hosted HTTP server implementing the Streamable HTTP MCP transport. + +```json +{ + "type": "http", + "url": "https://mcp.atlassian.com/v1/mcp", + "headers": { + "Authorization": "Bearer ${input:API_TOKEN}" + }, + "metadata": { + "inputs": [ + { + "id": "API_TOKEN", + "label": "API Token", + "type": "password", + "required": true, + "secret": true + } + ] + } +} +``` + +**Fields:** +| Field | Required | Description | +|-------|----------|-------------| +| `type` | Yes | Always `"http"` | +| `url` | Yes | HTTP(S) endpoint URL | +| `headers` | No | Custom HTTP headers (supports `${input:ID}` placeholders) | +| `metadata.inputs` | No | User input definitions | + +## Input Metadata + +Inputs define the credentials and configuration values that users need to provide. They are referenced in `env`, `args`, and `headers` using the `${input:ID}` placeholder syntax. + +### Input Fields + +```json +{ + "id": "GITHUB_TOKEN", + "label": "GitHub Personal Access Token", + "type": "password", + "required": true, + "secret": true, + "description": "Token with repo and read:org scopes", + "default": "", + "placeholder": "ghp_xxxx", + "obtain": { + "url": "https://github.com/settings/tokens/new", + "instructions": "1. Click 'Generate new token'\n2. Select scopes\n3. Copy token", + "button_label": "Create Token" + } +} +``` + +| Field | Required | Description | +|-------|----------|-------------| +| `id` | Yes | Uppercase identifier matching `^[A-Z0-9_]+$` | +| `label` | Yes | Human-readable label shown in the UI | +| `type` | No | Input type (default: `"text"`) | +| `required` | No | Whether the value must be provided (default: `false`) | +| `secret` | No | Encrypt this value in the OS keychain (default: `false`) | +| `description` | No | Help text shown below the input | +| `default` | No | Default value if user provides nothing | +| `placeholder` | No | Greyed-out hint text in the input field | +| `obtain` | No | Instructions for getting the value | + +### Input Types + +| Type | Description | +|------|-------------| +| `text` | Single-line text input (default) | +| `password` | Masked text input for secrets | +| `number` | Numeric input | +| `boolean` | Toggle/checkbox | +| `url` | URL input with validation | +| `select` | Dropdown with predefined options | +| `file_path` | File picker | +| `directory_path` | Directory picker | + +### The `obtain` Field + +The `obtain` object tells users how to get the required credential: + +```json +"obtain": { + "url": "https://github.com/settings/tokens/new", + "instructions": "1. Click 'Generate new token (classic)'\n2. Select the 'repo' scope\n3. Click 'Generate token'\n4. Copy the token value", + "button_label": "Create Token" +} +``` + +McpMux renders this as a clickable button that opens the URL, with the instructions displayed as help text. + +### Select Options + +For `select` type inputs, define the available options: + +```json +{ + "id": "REGION", + "label": "AWS Region", + "type": "select", + "required": true, + "options": [ + { "value": "us-east-1", "label": "US East (N. Virginia)" }, + { "value": "us-west-2", "label": "US West (Oregon)" }, + { "value": "eu-west-1", "label": "EU (Ireland)" } + ] +} +``` + +## Recommended Fields + +Beyond the three required fields, these fields improve discoverability and user experience: + +### description + +Short description of what the server does (one sentence): + +```json +"description": "Interact with GitHub repositories, issues, pull requests, and more" +``` + +### alias + +Short CLI-friendly name in lowercase kebab-case: + +```json +"alias": "gh" +``` + +### icon + +Emoji or image URL for display: + +```json +"icon": "🐙" +``` + +### categories + +Array of category IDs from the predefined list: + +```json +"categories": ["developer-tools", "version-control"] +``` + +**Available categories:** + +| ID | Name | +|----|------| +| `developer-tools` | Developer Tools | +| `version-control` | Version Control | +| `cloud` | Cloud Services | +| `productivity` | Productivity | +| `database` | Database | +| `search` | Search & Web | +| `communication` | Communication | +| `file-system` | File System | +| `documentation` | Documentation | +| `ai-ml` | AI & Machine Learning | +| `monitoring` | Monitoring & Observability | +| `security` | Security | + +### tags + +Searchable keywords: + +```json +"tags": ["git", "code", "issues", "pull-requests", "actions"] +``` + +### auth + +Authentication type and instructions: + +```json +"auth": { + "type": "api_key", + "instructions": "Create a token at https://github.com/settings/tokens with repo scope" +} +``` + +**Auth types:** `none`, `api_key`, `optional_api_key`, `oauth`, `basic` + +### capabilities + +Declare what MCP features the server supports: + +```json +"capabilities": { + "tools": true, + "resources": true, + "prompts": false, + "read_only_mode": false +} +``` + +Set `read_only_mode: true` for servers that never modify data (documentation, search, analytics). + +### links + +URLs for more information: + +```json +"links": { + "repository": "https://github.com/modelcontextprotocol/servers", + "homepage": "https://modelcontextprotocol.io", + "documentation": "https://modelcontextprotocol.io/docs" +} +``` + +### platforms + +Supported operating systems: + +```json +"platforms": ["all"] +``` + +Or restrict to specific platforms: `["windows", "macos", "linux"]` + +### contributor + +Who created this definition: + +```json +"contributor": { + "name": "Model Context Protocol", + "github": "modelcontextprotocol", + "url": "https://modelcontextprotocol.io" +} +``` + +## Complete Example + +Here's a full server definition for a local stdio server with API key authentication: + +```json +{ + "$schema": "../schemas/server-definition.schema.json", + "id": "com.github-mcp", + "name": "GitHub", + "alias": "gh", + "description": "Interact with GitHub repositories, issues, pull requests, and more", + "icon": "🐙", + "schema_version": "2.1", + "categories": ["developer-tools", "version-control"], + "tags": ["git", "code", "issues", "pr", "actions"], + "transport": { + "type": "stdio", + "command": "docker", + "args": [ + "run", "-i", "--rm", + "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", + "ghcr.io/github/github-mcp-server" + ], + "env": { + "GITHUB_PERSONAL_ACCESS_TOKEN": "${input:GITHUB_TOKEN}" + }, + "metadata": { + "inputs": [ + { + "id": "GITHUB_TOKEN", + "label": "GitHub Personal Access Token", + "type": "password", + "required": true, + "secret": true, + "placeholder": "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "obtain": { + "url": "https://github.com/settings/tokens/new", + "instructions": "1. Click 'Generate new token (classic)'\n2. Select scopes: repo, read:org\n3. Copy the token", + "button_label": "Create Token" + } + } + ] + } + }, + "auth": { + "type": "api_key", + "instructions": "Create a personal access token at https://github.com/settings/tokens" + }, + "contributor": { + "name": "Model Context Protocol", + "github": "modelcontextprotocol", + "url": "https://modelcontextprotocol.io" + }, + "links": { + "repository": "https://github.com/modelcontextprotocol/servers", + "documentation": "https://modelcontextprotocol.io/docs" + }, + "platforms": ["all"], + "capabilities": { + "tools": true, + "resources": true, + "prompts": false, + "read_only_mode": false + } +} +``` + +## Validation and Contribution + +### Validating Locally + +The registry uses AJV with JSON Schema 2020-12 for validation: + +```bash +# Validate a specific definition +pnpm validate servers/your-server.json + +# Validate all definitions +pnpm validate:all + +# Check for ID/alias conflicts +pnpm check-conflicts +``` + +### Contributing to the Registry + +1. Fork the [mcp-servers repository](https://github.com/mcpmux/mcp-servers) +2. Create your definition file: `servers/{your-id}.json` +3. Validate locally with `pnpm validate` and `pnpm test` +4. Submit a pull request with DCO sign-off (`git commit -s`) + +Definitions are reviewed for accuracy, working install commands, proper credential instructions, and trademark compliance. + +### Platform-Managed Fields + +Some fields are computed by the platform and stripped if submitted by contributors: + +- `badges` — computed from verification status +- `stats` — download counts +- `sponsored` — commercial sponsorship +- `featured` — homepage selection +- Any field prefixed with `_platform` + +## Next Steps + +- [Browse existing server definitions](/) to see examples in the registry +- [Learn about server management](/docs/servers/) to understand how definitions are used +- [Understand security](/docs/security/) to see how credentials from inputs are protected diff --git a/docs/guide/servers.mdx b/docs/guide/servers.mdx new file mode 100644 index 00000000..1f48cb31 --- /dev/null +++ b/docs/guide/servers.mdx @@ -0,0 +1,139 @@ +--- +title: Server Management +description: Install, configure, and manage MCP servers in McpMux. Supports stdio and HTTP transports with encrypted credential storage, environment variable overrides, and OAuth authentication. +--- + +MCP servers provide the tools, resources, and prompts that AI clients use through McpMux. Each server connects to an external service (GitHub, Slack, a database, etc.) or provides local capabilities (filesystem access, browser automation). + +## Installing Servers + +### From the Registry + +The fastest way to add a server is through the [McpMux server registry](/): + +1. Browse or search for the server you need +2. Click **Install** — if you have McpMux open, it installs directly via deep link +3. If the server requires credentials, the configuration dialog opens automatically +4. Fill in the required fields and click **Save** + +You can also browse the registry inside the McpMux desktop app under **Discover Servers**. + +### Manual Installation + +For servers not in the registry, you can add them manually in McpMux by providing the server definition JSON directly. + +![My Servers page — installed servers with connection status, auth type, and transport badges](/screenshots/servers.png) + +## Transport Types + +MCP servers communicate using one of two transport types: + +### stdio (Local) + +The server runs as a local process on your machine. McpMux launches the command and communicates over stdin/stdout. + +**Common commands:** +- `npx -y @modelcontextprotocol/server-filesystem` — Node.js servers +- `uvx mcp-server-sqlite` — Python servers +- `docker run -i --rm ghcr.io/github/github-mcp-server` — Docker containers + +**Best for:** Servers that need local filesystem access, are written in different languages, or require specific runtime environments. + +### HTTP (Remote) + +The server is hosted remotely and accessible via an HTTP endpoint. McpMux connects using the Streamable HTTP MCP transport. + +**Example endpoints:** +- `https://mcp.atlassian.com/v1/mcp` — Atlassian (Jira & Confluence) +- `https://docs.mcp.cloudflare.com/mcp` — Cloudflare Docs + +**Best for:** Cloud-hosted servers, SaaS integrations, and servers that require no local installation. + +## Server Configuration + +Each installed server can be configured per-Space with: + +### Input Values + +Credentials and settings required by the server. These are defined by the server definition and include: + +- **API keys and tokens** — stored encrypted, never in plaintext +- **URLs** — service endpoints +- **Feature flags** — enable/disable specific behaviors +- **Paths** — file or directory locations + +### Environment Variable Overrides + +Override or add environment variables passed to stdio servers: + +``` +GITHUB_API_URL=https://github.example.com/api/v3 +LOG_LEVEL=debug +``` + +### Additional Arguments (stdio only) + +Extra command-line arguments appended to the server's command: + +``` +--workspace /path/to/project +--verbose +``` + +### HTTP Headers (HTTP only) + +Custom headers sent with every request to HTTP servers: + +``` +Authorization: Bearer sk-xxxx +X-Custom-Header: value +``` + +## Enable and Disable + +Each installed server has an **enabled/disabled** toggle: + +- **Enabled** — the gateway connects to this server and exposes its tools +- **Disabled** — the server is installed but not running; no connection is maintained + +Disabling a server immediately disconnects it and removes its tools from connected clients. + +![Expanded server view showing available tools and prompts for each connected server](/screenshots/server-expanded.png) + +## Connection Status + +The **My Servers** page shows real-time connection status for each server: + +| Status | Meaning | +|--------|---------| +| Connecting | MCP handshake in progress | +| Connected | Server is online and serving requests | +| Disconnected | Server is installed but not connected | +| Error | Connection failed — check server logs | + +## Server Logs + +Each server has its own log stream accessible from the **My Servers** page. Logs show: + +- Connection and disconnection events +- MCP protocol messages +- Error details and stack traces +- Tool invocations and responses + +Use logs to troubleshoot connection issues or understand what requests are being made. + +## OAuth-Authenticated Servers + +Some HTTP servers use **OAuth 2.1 + PKCE** for authentication. McpMux handles the entire OAuth flow: + +1. When you enable an OAuth server, McpMux initiates the authorization flow +2. A browser window opens for you to log in and grant permissions +3. Tokens are stored encrypted and refreshed automatically +4. If a token expires, McpMux refreshes it transparently — no manual intervention + +## Next Steps + +- [Browse the server registry](/) to find servers for your tools +- [Learn about server definitions](/docs/server-definitions/) to contribute to the registry +- [Configure FeatureSets](/docs/feature-sets/) to control which server tools each client can access +- [Understand security](/docs/security/) and how credentials are encrypted diff --git a/docs/guide/spaces.mdx b/docs/guide/spaces.mdx new file mode 100644 index 00000000..930ec26f --- /dev/null +++ b/docs/guide/spaces.mdx @@ -0,0 +1,95 @@ +--- +title: Spaces — Isolated Workspaces +description: Spaces let you organize MCP servers into isolated environments with separate credentials. Keep work, personal, and client projects completely separated in McpMux. +--- + +Spaces are isolated workspaces in McpMux. Each Space has its own server configurations, credentials, and enabled servers — keeping different contexts completely separate. + +## Why Spaces + +Without Spaces, all your MCP credentials and server configurations live in a single shared context. This means: + +- Your work GitHub token is accessible alongside personal projects +- Client credentials from different customers can leak across contexts +- Switching between project contexts requires manual reconfiguration +- There's no way to limit which servers are available for which work + +Spaces solve this by providing **complete isolation** between environments. + +![Workspaces page showing My Space (active), Open Source, Personal, and Work spaces](/screenshots/spaces.png) + +## How Spaces Work + +Each Space is an independent environment containing: + +- **Installed servers** — which MCP servers are available in this Space +- **Server configurations** — per-Space credentials, environment variables, and settings +- **FeatureSets** — permission bundles scoped to this Space +- **Client grants** — which FeatureSets each AI client gets in this Space + +### Active Space + +Only one Space can be **active** at a time. The active Space determines: + +- Which servers the gateway connects to +- Which tools AI clients can see and use (for clients in "Follow Active" mode) +- Which credentials are injected into server connections + +Switching the active Space immediately changes what servers and tools are available — no restart required. + +![Space switcher dropdown in the sidebar for quick context switching](/screenshots/space-switcher.png) + +### Default-Enabled Servers + +When you install a server, you can mark it as **default-enabled**. Default-enabled servers are automatically available in all Spaces without needing to install them individually. This is useful for universal tools like Filesystem or Brave Search that you want everywhere. + +## Common Space Configurations + +### Work vs Personal + +The most common setup separates work and personal contexts: + +| | Work Space | Personal Space | +|---|---|---| +| GitHub | Work org token | Personal token | +| Slack | Company workspace | — | +| AWS | Production credentials | Personal account | +| Notion | Team workspace | Personal workspace | + +### Multi-Client Freelancing + +Freelancers and consultants can create a Space per client: + +- **Client-Alpha** — their GitHub, Jira, and Slack +- **Client-Beta** — their GitHub and Linear +- **Personal** — your own tools and projects + +Each client's credentials are completely isolated. There's no risk of accidentally using Client-Alpha's API key while working on Client-Beta. + +### Dev / Staging / Prod + +For operations work, separate Spaces prevent accidentally running production commands: + +- **Development** — local services, test databases +- **Staging** — staging API keys, staging databases +- **Production** — production credentials (used sparingly and intentionally) + +## Managing Spaces + +### Creating a Space + +Navigate to **Spaces** in McpMux and click **Create Space**. Give it a name and optional icon. + +### Switching Active Space + +Click on any Space to set it as active. The dashboard and server list update immediately to reflect the new context. AI clients using "Follow Active" mode switch automatically. + +### Deleting a Space + +Deleting a Space removes all its server configurations and stored credentials. This action is irreversible. The servers themselves (their definitions) remain in the registry — only the per-Space installation and credentials are deleted. + +## Next Steps + +- [Configure FeatureSets](/docs/feature-sets/) to control permissions within a Space +- [Set up Clients](/docs/clients/) with connection modes that interact with Spaces +- [Manage Servers](/docs/servers/) to install and configure per-Space server instances