Skip to content

Commit 5846a98

Browse files
committed
feat(routing): workspace-root-driven FeatureSet resolution
Replace per-client FeatureSet grants and the "active space" / "active feature set" concepts with a simpler model: a session's reported workspace root maps to a (Space, FeatureSet) pair via WorkspaceBinding; unmapped roots fall back to the system default Space and its Default FS. Backend - Drop client_feature_set_grants table and the entire grant API surface. - Drop space.active_feature_set_id, set_active_space, get_active_space. - New WorkspaceBinding entity + repository with longest-prefix lookup, cross-platform path normalization, and validation. - FeatureSetResolverService: resolve(session_id) -> (space, fs, source). - SessionRootsRegistry tracks per-session roots + last-resolved FS so the gateway can fire a per-peer tools/prompts/resources list_changed when a session's resolution flips post-init (roots arrive after initialize and now match a binding). - New get_workspace_effective_features command surfaces resolved FS members enriched with each backend's connection status. - Migrations 004 -> 007: workspace_bindings table, drop client pins, collapse FS types, drop space.active_feature_set_id. Desktop UI - New Workspaces tab: cards for live-reported roots + persisted bindings, native directory picker, debounced cross-platform path validation, status filter. - WorkspaceBindingSheet pops on first connect when roots are unmapped. - Inspector panel matches the FeatureSetPanel pattern: collapsible Mapping section (auto-save on edit, explicit submit on create) and collapsible Effective Features section grouping resolved members by server with availability progress bars and type-coded feature rows. - SpaceSwitcher loses the Set Active affordance; system tray submenu loses its active-checkmark and renames to "Switch Space". - New ConnectionCard component owns the dashboard URL/start surface. Tests - New workspace_binding_events integration tests cover per-peer list_changed on resolution flip. - appStore tests collapse activeSpaceId/viewSpaceId into one, e2e helpers swap getActiveSpace -> getDefaultSpace, comprehensive specs drop set-active flows. Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>
1 parent c8c3f1c commit 5846a98

118 files changed

Lines changed: 8640 additions & 8567 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1-
blank_issues_enabled: false
1+
blank_issues_enabled: true
22
contact_links:
33
- name: Questions & Help
44
url: https://github.com/mcpmux/mcp-mux/discussions/categories/q-a
55
about: Ask questions and get help in GitHub Discussions
66
- name: Feature Ideas
77
url: https://github.com/mcpmux/mcp-mux/discussions/categories/ideas
88
about: Share and discuss feature ideas
9+
- name: Contribute a Server Definition (PR)
10+
url: https://github.com/mcpmux/mcp-servers/blob/main/CONTRIBUTING.md
11+
about: Server definitions live in the mcp-servers repo and land via PR — read the guide
12+
- name: Request a Server
13+
url: https://github.com/mcpmux/mcp-servers/issues/new?template=request-server.yml
14+
about: Ask the community to add an MCP server to the registry
15+
- name: Report a Server Definition Bug
16+
url: https://github.com/mcpmux/mcp-servers/issues/new?template=bug-report.yml
17+
about: Found a broken or incorrect server in the registry? Report it here

AGENTS.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# AGENTS.md
2+
3+
Guidance for coding agents working inside the `mcp-mux` repo — the McpMux desktop app and local gateway. Complements [`README.md`](README.md) and [`CONTRIBUTING.md`](CONTRIBUTING.md); when anything here conflicts with an explicit user instruction in the current session, the user wins.
4+
5+
## Project Overview
6+
7+
McpMux is a Tauri 2 desktop app (Rust + React 19) with a local Axum HTTP gateway on `localhost:45818`. It lets users configure MCP servers once and connect every AI client (Cursor, Claude Desktop, VS Code, Windsurf) through a single endpoint, with credentials encrypted in the OS keychain instead of plain-text JSON files.
8+
9+
A more detailed map of the workspace lives in [`CLAUDE.md`](CLAUDE.md) at the repo root — read it for the crate layout, frontend architecture, and cross-project context. This file captures the minimum an agent needs to make safe, useful changes here.
10+
11+
## Workspace Layout
12+
13+
```
14+
mcp-mux/
15+
├── apps/desktop/ # Tauri shell — React frontend (src/) + Rust Tauri commands (src-tauri/)
16+
├── crates/
17+
│ ├── mcpmux-core/ # Domain entities, repository traits, service layer, EventBus
18+
│ ├── mcpmux-gateway/ # Axum gateway — routing, OAuth refresh, FeatureSet filtering
19+
│ ├── mcpmux-storage/ # SQLite + AES-256-GCM field encryption + OS keychain
20+
│ └── mcpmux-mcp/ # MCP protocol client wrapper (rmcp SDK)
21+
├── packages/ui/ # Shared UI components (`@mcpmux/ui`)
22+
├── schemas/ # JSON Schemas surfaced in the Monaco editor
23+
└── tests/ # Rust integration, TS unit (vitest), desktop E2E (WDIO), web E2E (playwright)
24+
```
25+
26+
## Build & Dev Commands
27+
28+
Run everything from `mcp-mux/`:
29+
30+
| Command | What it does |
31+
|---------|--------------|
32+
| `pnpm setup` | First-time dev environment setup (PowerShell on Windows). |
33+
| `pnpm dev` | Tauri desktop dev mode (Rust + React hot-reload). |
34+
| `pnpm dev:web` | Web UI only via Vite — no Rust, no Tauri shell. |
35+
| `pnpm build` | Production Tauri build for the current platform. |
36+
| `pnpm validate` | Full correctness gate — runs the items below in sequence. |
37+
| `pnpm lint` | ESLint (recursive) + `cargo clippy --workspace -- -D warnings`. |
38+
| `pnpm lint:fix` | Auto-fix lint issues. |
39+
| `pnpm format` | `prettier --write .` + `cargo fmt --all`. |
40+
| `pnpm format:check` | Formatting check (no writes). |
41+
| `pnpm typecheck` | Recursive TypeScript typecheck. |
42+
43+
**Before claiming a change is done**, run `pnpm validate` (or the relevant subset) — it mirrors what CI enforces.
44+
45+
## Testing
46+
47+
| Command | Scope |
48+
|---------|-------|
49+
| `pnpm test` | Rust + TypeScript, everything. |
50+
| `pnpm test:rust` | `cargo nextest run --workspace`. |
51+
| `pnpm test:rust:unit` | `cargo nextest run --workspace --lib`. |
52+
| `pnpm test:rust:int` | `cargo nextest run -p tests` — integration crate in `tests/rust`. |
53+
| `pnpm test:rust:doc` | `cargo test --workspace --doc`. |
54+
| `pnpm test:ts` | Vitest run (`tests/ts/vitest.config.ts`). |
55+
| `pnpm test:ts:watch` | Vitest watch. |
56+
| `pnpm test:e2e` | Desktop E2E via WebDriver IO — requires `MCPMUX_REGISTRY_URL`. |
57+
| `pnpm test:e2e:file -- tests/e2e/specs/foo.ts` | One WDIO spec file. |
58+
| `pnpm test:e2e:grep -- "test name"` | WDIO tests matching a name. |
59+
| `pnpm test:e2e:web` | Playwright on the web UI. |
60+
| `pnpm test:coverage` | `cargo llvm-cov` + Vitest coverage. |
61+
62+
Prefer narrow commands over `pnpm test` while iterating — the full suite is slow.
63+
64+
## Code Style
65+
66+
- **Rust:** 100-char max width, 4-space indent. Clippy runs with `avoid-breaking-exported-api = false`; all warnings are denied in CI.
67+
- **TypeScript / JSX:** Prettier — single quotes, 2-space indent, 100-char width, trailing commas (es5), Tailwind CSS plugin for class ordering.
68+
- **Path aliases:** `@/``apps/desktop/src/`; `@mcpmux/ui``packages/ui`.
69+
- **No emojis in code or commits** unless the user explicitly asks for them.
70+
- **Comments:** only when the *why* is non-obvious. Identifiers should explain the *what*.
71+
72+
## Commit & PR Guidelines
73+
74+
- Commits must be **signed off** (DCO): `git commit -s -m "..."`. CI rejects unsigned commits.
75+
- Prefer conventional-style subjects — releases use release-please for semantic versioning.
76+
- PRs follow [`.github/pull_request_template.md`](.github/pull_request_template.md): describe the change, how you tested, and check the `pnpm test` / `pnpm lint` / `pnpm typecheck` boxes.
77+
- Don't bypass hooks (`--no-verify`) or DCO signing unless explicitly told to.
78+
79+
## Platform Gotchas
80+
81+
### Child-process flags
82+
83+
Anything that spawns a child process (stdio MCP servers, installers, etc.) **must** go through `mcpmux_gateway::pool::transport::configure_child_process_platform()`. That helper applies:
84+
85+
- **Windows:** `CREATE_NO_WINDOW` (`0x08000000`) — release builds use `windows_subsystem = "windows"`, so without this the OS briefly flashes a console window when a child starts.
86+
- **Unix:** `process_group(0)` — stops SIGINT/SIGTSTP from the parent terminal from tearing down the child.
87+
88+
`tokio::process::Command` already exposes `creation_flags()` (Windows) and `process_group()` (Unix). **Do not** import `std::os::*::process::CommandExt` — those traits are unused with Tokio's `Command` and trigger clippy.
89+
90+
### Cross-platform CI
91+
92+
- The pre-commit hook runs `cargo clippy --workspace -- -D warnings` on your dev machine.
93+
- `#[cfg(unix)]` only compiles on Unix; `#[cfg(windows)]` only on Windows. CI is Linux, so Windows-gated code is **not** linted in CI, and Unix-gated code is not linted on a Windows dev box.
94+
- When you touch platform-conditional code, check the *other* platform compiles before pushing — CI won't catch a Windows-only clippy regression.
95+
96+
### Secret handling
97+
98+
- Never log tokens, API keys, headers with auth material, or raw OAuth responses. Use the existing sanitised-log helpers in `mcpmux-gateway`.
99+
- Credentials encrypt at rest via AES-256-GCM in SQLite plus DPAPI (Windows) / OS keychain (macOS, Linux). Don't add new code paths that persist secrets any other way.
100+
- Secrets should be wiped from memory after use via `zeroize`.
101+
- The gateway binds to `127.0.0.1`. Don't bind to `0.0.0.0` or expose it on the network.
102+
103+
## Frontend Notes
104+
105+
- Entry point: `apps/desktop/src/main.tsx``App.tsx`.
106+
- Global state: a single Zustand store at `src/stores/appStore.ts`.
107+
- Key hooks: `useServerManager` (server CRUD), `useSpaces` (workspace switching), `useDomainEvents` (Rust-side EventBus listener), `useDataSync`.
108+
- UI: React 19, Tailwind CSS, Lucide icons, Monaco Editor for JSON config surfaces.
109+
- Open external URLs through `openExternal` in `apps/desktop/src/lib/contribute.ts` — it routes through the Tauri opener plugin so links open in the user's default browser, not the webview.
110+
- For UI changes, launch `pnpm dev` and exercise the feature in the running app before reporting done — typecheck and tests verify correctness, not UX regressions.
111+
112+
## Rust Architecture Cues
113+
114+
- Cross-layer communication goes through the `EventBus` in `mcpmux-core`. Prefer emitting a domain event over reaching across module boundaries directly.
115+
- Storage is behind repository traits — don't call SQLx or SQLite APIs directly from gateway or app code; add or use a repo method.
116+
- Services are wired up via the `ApplicationServices` builders in `mcpmux-core`. New services should follow the same DI pattern.
117+
118+
## MCP Specification
119+
120+
The full MCP spec is vendored at `../modelcontextprotocol/docs/specification/`. Default to the latest stable version (`2025-11-25`) and **read the relevant section before** implementing or modifying protocol behaviour (transports, lifecycle, capability negotiation, OAuth flows, tools / resources / prompts). For features targeting a specific protocol version, use that version's folder.
121+
122+
## Server Definitions
123+
124+
Server catalog entries live in the separate [`mcp-servers`](https://github.com/mcpmux/mcp-servers) repo — **not here**. If a task involves adding, editing, or fixing a server definition, switch to that repo and follow its `AGENTS.md`.
125+
126+
## Things Not To Do
127+
128+
- Don't add backwards-compatibility shims, deprecated aliases, or `// removed` placeholder comments when removing code — delete it cleanly.
129+
- Don't introduce new fallbacks or input validation for states that are already framework-guaranteed. Trust internal invariants; validate only at the boundary (user input, external APIs).
130+
- Don't edit generated files: `CHANGELOG.md`, release-please manifests, `bundle/*.json` in sibling repos, `packages/ui/dist`.
131+
- Don't commit screenshots, videos, or large binaries to the repo — link out instead.

0 commit comments

Comments
 (0)