Skip to content

Commit e8620d9

Browse files
committed
Merge remote-tracking branch 'origin' into feat-streamable-http
2 parents 9af909c + 96795b0 commit e8620d9

12 files changed

Lines changed: 1180 additions & 83 deletions

File tree

CLAUDE.md

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Codebase Search
6+
7+
This repository is indexed for semantic code search via the `claude-context` MCP server. Prefer `mcp__claude-context__search_code` (with path `D:\mcpmux`) over Grep/Glob when looking for implementations, understanding how features work, or finding related code across the codebase. Use Grep/Glob for exact string matches or filename patterns. If search returns an indexing error, re-index with `mcp__claude-context__index_codebase` first.
8+
9+
## What is McpMux
10+
11+
McpMux is a desktop app + local gateway that lets users configure MCP servers once and connect every AI client (Cursor, Claude Desktop, VS Code, Windsurf) through a single `localhost:45818` endpoint. Credentials are encrypted in the OS keychain instead of plain-text JSON files.
12+
13+
## Repository Structure
14+
15+
This is a multi-project workspace with 6 independent projects (not a unified monorepo):
16+
17+
| Project | Tech | Purpose |
18+
|---------|------|---------|
19+
| `mcp-mux/` | Tauri 2 (Rust + React 19), pnpm workspace | Desktop app + local MCP gateway |
20+
| `mcpmux.bundler/` | Cloudflare Worker | GitHub webhook receiver that processes server definitions into D1/R2 |
21+
| `mcpmux.serverhub.api/` | Cloudflare Worker (Hono) | REST API for server registry discovery (KV -> D1 -> R2 fallback chain) |
22+
| `mcpmux.discover.ui/` | Next.js 16, shadcn/ui, Tailwind 4 | Web UI for browsing the server registry |
23+
| `mcp-servers/` | JSON + AJV validation | Community MCP server definitions repository |
24+
| `mcpmux.space/` | Docs | Documentation and design space |
25+
26+
## mcp-mux (Desktop App) - Main Project
27+
28+
### Build & Dev Commands
29+
30+
All commands run from `mcp-mux/`:
31+
32+
```bash
33+
pnpm setup # First-time dev environment setup (PowerShell)
34+
pnpm dev # Tauri desktop app dev mode (Rust + React hot-reload)
35+
pnpm dev:web # Web UI only (Vite, no Rust)
36+
pnpm build # Production Tauri build (all platforms)
37+
```
38+
39+
### Testing
40+
41+
```bash
42+
pnpm test # All tests (Rust + TypeScript)
43+
pnpm test:rust # cargo nextest run --workspace
44+
pnpm test:rust:unit # cargo nextest run --workspace --lib
45+
pnpm test:rust:int # cargo nextest run -p tests
46+
pnpm test:rust:doc # cargo test --workspace --doc
47+
pnpm test:ts # vitest run -c tests/ts/vitest.config.ts
48+
pnpm test:ts:watch # vitest watch mode
49+
pnpm test:e2e # WebDriver IO desktop E2E (needs MCPMUX_REGISTRY_URL)
50+
pnpm test:e2e:file # Single E2E spec: pnpm test:e2e:file -- tests/e2e/specs/foo.ts
51+
pnpm test:e2e:grep # E2E by name: pnpm test:e2e:grep -- "test name"
52+
pnpm test:e2e:web # Playwright web UI E2E
53+
pnpm test:coverage # cargo llvm-cov + vitest coverage
54+
```
55+
56+
### Linting & Validation
57+
58+
```bash
59+
pnpm validate # Full check: cargo fmt + clippy + check + eslint + typecheck
60+
pnpm lint # ESLint (recursive) + cargo clippy --workspace -- -D warnings
61+
pnpm lint:fix # Auto-fix lint issues
62+
pnpm format # prettier --write . && cargo fmt --all
63+
pnpm format:check # Check formatting without modifying
64+
pnpm typecheck # TypeScript type checking (recursive)
65+
```
66+
67+
### Rust Crate Architecture
68+
69+
The Cargo workspace has 4 library crates + 1 app crate + 1 test crate:
70+
71+
- **mcpmux-core** (`crates/mcpmux-core/`) - Domain layer: entities (Space, InstalledServer, FeatureSet, Client), repository traits, domain services, application services with event emission, and the central EventBus
72+
- **mcpmux-gateway** (`crates/mcpmux-gateway/`) - Axum HTTP gateway: routes MCP calls to correct servers, manages OAuth 2.1+PKCE token refresh, filters tools/resources/prompts based on FeatureSets, per-client access key auth, server connection pooling
73+
- **mcpmux-storage** (`crates/mcpmux-storage/`) - SQLite persistence with AES-256-GCM field-level encryption via ring, typed credential rows (per-token encryption), DPAPI key storage on Windows (`keychain_dpapi.rs`), OS keychain on macOS/Linux via keyring crate, zeroize for secure memory clearing
74+
- **mcpmux-mcp** (`crates/mcpmux-mcp/`) - MCP protocol client management using rmcp SDK
75+
- **apps/desktop/src-tauri** - Tauri 2 app shell, Tauri commands, system tray, deep-link handler (`mcpmux://`)
76+
- **tests/rust** - Integration test crate
77+
78+
Key patterns: event-driven architecture (EventBus), repository pattern (trait-based storage abstraction), service layer pattern with DI via ApplicationServices builders.
79+
80+
### Frontend Architecture
81+
82+
- **Entry**: `apps/desktop/src/main.tsx` -> `App.tsx`
83+
- **State**: Zustand store (`stores/appStore.ts`)
84+
- **Hooks**: `useServerManager` (server CRUD), `useSpaces` (workspace switching), `useDomainEvents` (Rust event listeners), `useDataSync` (data synchronization)
85+
- **UI**: React 19 + Tailwind CSS + Lucide icons + Monaco Editor (config editing)
86+
- **Path aliases**: `@/` -> `src/`, `@mcpmux/ui` -> shared UI package
87+
88+
### Data Flow
89+
90+
```
91+
AI Clients -> McpMux Gateway (localhost:45818/mcp) -> MCP Servers (stdio/HTTP)
92+
|
93+
Authenticates (access keys)
94+
Routes (per-space server config)
95+
Filters (FeatureSet permissions)
96+
OAuth token refresh (automatic)
97+
Credentials (DPAPI files on Windows / OS Keychain on macOS+Linux + encrypted SQLite)
98+
```
99+
100+
### Prerequisites
101+
102+
Rust 1.75+, Node.js 20+, pnpm 9+. Linux: `gnome-keyring libsecret-1-dev librsvg2-dev pkg-config`.
103+
104+
### Code Style
105+
106+
- Rust: 100 char max width, 4-space indent, `clippy` with `avoid-breaking-exported-api = false`
107+
- TypeScript/JSX: Prettier with single quotes, 2-space indent, 100 char width, trailing commas (es5), Tailwind CSS plugin
108+
- Commits require `Signed-off-by` line (use `git commit -s`)
109+
110+
## mcp-servers (Server Definitions Repository)
111+
112+
All commands run from `mcp-servers/` (sibling repo):
113+
114+
```bash
115+
pnpm install # Install dependencies (vitest, ajv, glob)
116+
pnpm validate:all # Validate all server definitions against JSON schema
117+
pnpm validate <file> # Validate specific server definition file(s)
118+
pnpm build # Build registry bundle (bundle/bundle.json)
119+
pnpm test # Run all tests (schema validation, consistency, categories, bundle)
120+
```
121+
122+
The JSON schema at `schemas/server-definition.schema.json` defines the structure for server definitions in `servers/`. Input definitions support: `id`, `label`, `type`, `required`, `secret`, `description`, `default`, `placeholder`, and `obtain` (with `url`, `instructions`, `button_label`).
123+
124+
## Cloudflare Workers
125+
126+
Each worker is an independent project with its own `package.json`:
127+
128+
**mcpmux.serverhub.api/** - Hono-based registry API:
129+
```bash
130+
cd mcpmux.serverhub.api && pnpm dev # wrangler dev
131+
cd mcpmux.serverhub.api && pnpm test # vitest (cloudflare pool)
132+
```
133+
134+
**mcpmux.bundler/** - Webhook-triggered bundle processor:
135+
```bash
136+
cd mcpmux.bundler && pnpm dev # wrangler dev
137+
cd mcpmux.bundler && pnpm test # vitest run
138+
```
139+
140+
## mcpmux.discover.ui (Discovery Web UI)
141+
142+
```bash
143+
cd mcpmux.discover.ui && pnpm dev # next dev
144+
cd mcpmux.discover.ui && pnpm test # vitest
145+
cd mcpmux.discover.ui && pnpm test:e2e # playwright
146+
```
147+
148+
## Important Patterns
149+
150+
### Child Process Platform Flags
151+
152+
When spawning child processes (e.g., stdio MCP servers), **always** use `configure_child_process_platform()` from `mcpmux_gateway::pool::transport`. This applies:
153+
- **Windows**: `CREATE_NO_WINDOW` (`0x08000000`) — prevents visible console windows in release builds (where `windows_subsystem = "windows"` means the app is a GUI subsystem process)
154+
- **Unix**: `process_group(0)` — isolates child from parent terminal signals (SIGINT, SIGTSTP)
155+
156+
Note: `tokio::process::Command` already exposes `creation_flags()` (Windows) and `process_group()` (Unix) natively — do **not** import `std::os::unix::process::CommandExt` or `std::os::windows::process::CommandExt` as the traits are unused with Tokio's Command.
157+
158+
### Cross-Platform CI Awareness
159+
160+
The pre-commit hook runs `cargo clippy --workspace -- -D warnings` locally, but `#[cfg(unix)]` / `#[cfg(windows)]` blocks are only compiled on the matching platform. **CI runs on Linux**, so:
161+
- `#[cfg(unix)]` code is only linted in CI, not on a Windows dev machine
162+
- `#[cfg(windows)]` code is only linted locally on Windows, not in CI
163+
- Always validate that platform-conditional code compiles correctly on both platforms before pushing
164+
165+
## CI
166+
167+
GitHub Actions runs on push/PR to main: Rust format + clippy + check, ESLint + typecheck, cargo nextest, vitest, desktop E2E (Windows/macOS/Linux), web E2E (Playwright). Releases use release-please for semantic versioning with multi-platform Tauri builds.

Cargo.lock

Lines changed: 17 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ glob = "0.3"
5454
url = "2.5"
5555
urlencoding = "2.1"
5656
dotenvy = "0.15"
57+
os_pipe = "1"
5758

5859
# MCP Protocol
5960
# NOTE: Never use local path dependency - E:\one-mcp\rust-sdk is for source lookup only

0 commit comments

Comments
 (0)