This commit is contained in:
270
docs/ux-refactor/gap-cards/S08-mcp-hub.md
Normal file
270
docs/ux-refactor/gap-cards/S08-mcp-hub.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# Gap Card — S08 · MCP Hub
|
||||
|
||||
> UX-refactor planning artifact. Execution model is the LOCKED **in-place incremental refactor** of
|
||||
> `apps/web` + targeted backend extensions. Mockup is directional; PRD acceptance criteria win.
|
||||
> Every claim below cites a real file. PRD = `docs/Waggle_OS_UX_Refactor_Master_Handoff_Package/Waggle_OS_UX_Refactor_PRD.md`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Screen & purpose
|
||||
|
||||
**MCP Hub** — the power-user capability-extension surface for Model Context Protocol servers (PRD §12.8,
|
||||
PRD line 566-579). Belongs to the **Extend** IA layer (PRD §10.4; blueprint line 74, 81: route group
|
||||
`/mcps`). Explicit blueprint directive: **"Do not bury Connectors/MCPs inside Settings"** (blueprint line 79).
|
||||
|
||||
Purpose (PRD §12.8): *"Enable power-user extension through Model Context Protocol servers."* MCPs are
|
||||
auditable capability providers for power users and agents (blueprint line 140). The governing acceptance
|
||||
criterion: **"MCPs are powerful but always visible, scoped, auditable, and reversible."** (PRD line 579).
|
||||
|
||||
Primary user journey — **J11 / Journey 9 "Install MCP"** (PRD lines 736-743; blueprint line 206-208):
|
||||
power user opens MCP Hub → selects e.g. Postgres MCP → reviews risk and scope → approves installation →
|
||||
MCP becomes available to selected workspace/agent → **install audit is recorded**.
|
||||
|
||||
Mockup (directional only — `screen_08_mcp_hub.png`): top toolbar with tabs (Installed / Available /
|
||||
Marketplace / Custom / Remote Registry), search, "Add MCP Server" CTA; left an "Installed MCPs" table
|
||||
(name, status pill, connected-to, last-used, scope, actions) over an "Available MCPs" category-filtered
|
||||
grid; right rail with an "MCP Overview" donut (counts), "MCP Health", "Recent Activity" (audit/log feed),
|
||||
and a "Custom MCP" add affordance.
|
||||
|
||||
---
|
||||
|
||||
## 2. Required states (PRD / Blueprint)
|
||||
|
||||
**Tabs (PRD §12.8 line 572):** Installed · Available · Marketplace · Custom · Remote Registry.
|
||||
|
||||
**MCP object fields (PRD §12.8 line 573):** name, description, version, status, **connected to**,
|
||||
**last used**, **locality** (local/remote), **risk**, **permissions**, **logs**. Target schema
|
||||
`Extension/MCP` (blueprint line 554, PRD §15.2 `ExtensionType`): `id, type, name, source, version,
|
||||
endpoint, capabilities, riskLevel, approvalClass, status, health, installedAt, approvedBy`.
|
||||
|
||||
**Actions (PRD §12.8 line 574):** install · start/stop · test · scope · view logs · revoke · add custom MCP.
|
||||
Risky MCPs require approval + audit trail (PRD line 575; blueprint line 161 "elevated connectors/MCPs …
|
||||
require approval").
|
||||
|
||||
**Extension lifecycle states (PRD §14.7 lines 906-914):** Available · Installed · Update available ·
|
||||
Installing · Failed install · **Risk approval required** · Disabled/revoked. Plus per-server runtime
|
||||
status (blueprint line 334-335): installed; available; **running**; **stopped**; **error**; risk-approval-needed.
|
||||
|
||||
**Connector/MCP UI states (PRD §14.5 / blueprint line 467):** Loading, empty, populated, error.
|
||||
|
||||
**Scope (acceptance-critical):** an MCP must be scopeable to workspace and/or agent (PRD line 742;
|
||||
blueprint line 207 "scope to workspace/agent"; line 601 "Connector and MCP installs are visible,
|
||||
permissioned, health-checked and auditable"; line 600 "a workspace agent cannot run with hidden
|
||||
memory/tool/MCP access").
|
||||
|
||||
**Offline degradation (blueprint line 516):** offline mode degrades MCPs gracefully while keeping local
|
||||
workspace/memory available.
|
||||
|
||||
---
|
||||
|
||||
## 3. Current state in repo
|
||||
|
||||
**There is NO dedicated MCP Hub app today.** MCPs surface in three thin, mostly-static places:
|
||||
|
||||
1. **Static catalog (discovery only) — `apps/web/src/components/os/apps/connectors/McpCatalog.tsx`** +
|
||||
**`McpServerCard.tsx`** + **`mcp-registry.ts`** (a re-export shim of `@waggle/shared`). Rendered as the
|
||||
"MCP Servers" tab inside **`ConnectorsApp.tsx`** (`apps/web/src/components/os/apps/ConnectorsApp.tsx:197-205,348-349`).
|
||||
The catalog data is `MCP_CATALOG` / `MCP_CATEGORIES` / `CATEGORY_EMOJI` in
|
||||
**`packages/shared/src/mcp-catalog.ts`** (`McpServer` interface at `:17`; `MCP_CATALOG` at `:53`; 14
|
||||
categories at `:30`). Per the backend-map (`05f` §12, lines 391-401), this catalog is **static and not
|
||||
connected at runtime** — a discovery/install-command directory.
|
||||
- **The only "install" UX is copy-a-shell-command-then-restart** (`McpServerCard.tsx:30-37,98-138`
|
||||
copies `server.installCmd`; tooltip text `:111-116`: "Copy the command … Run it in your terminal …
|
||||
Restart Waggle"). There is **no in-app install, start/stop, test, scope, revoke, logs, risk, or
|
||||
status** — none of the PRD §12.8 actions/fields exist in the UI.
|
||||
|
||||
2. **Live runtime status (read-only) — `GET /api/capabilities/status`**
|
||||
(`packages/server/src/local/routes/capabilities.ts:35-53,103-110`) returns
|
||||
`mcpServers:[{name,state,healthy,tools}]` from the real runtime. **But the runtime is empty by default**
|
||||
(see #3 below), so this list is always `[]` on a stock install.
|
||||
|
||||
3. **The MCP runtime engine (rich, but unwired) — `packages/agent/src/mcp/mcp-runtime.ts`.**
|
||||
`McpRuntime` has the full lifecycle the PRD needs: `addServer(config)` (`:308`), `removeServer(name)`
|
||||
(`:327`), `startAll`/`stopAll`, per-instance `start()/stop()/callTool()` (`McpServerInstance` `:102,154,178`),
|
||||
`getServerStates()` (`:362`), `getHealthy()` (`:370`), `isServerHealthy(name)` (`:399`), and **per-workspace
|
||||
scoping** via `McpServerConfig.workspaceId` (`:13`) + `getToolsForWorkspace(workspaceId)` (`:385`).
|
||||
**CRITICAL GAP:** the runtime is instantiated empty — `const mcpRuntime = new McpRuntime()` with comment
|
||||
*"empty by default"* (`packages/server/src/local/index.ts:911`), and **nothing ever calls `addServer()`**
|
||||
(grep `mcpRuntime.addServer` / `.mcp.json` / `loadMcpConfig` → 0 matches in `packages/server/src`). So
|
||||
there is no persistence layer that loads installed MCP configs at boot, and no HTTP route to install/
|
||||
start/stop/test/remove a server.
|
||||
|
||||
**Install-audit substrate is present** (`AuditCapabilityType` includes `'mcp'` —
|
||||
`packages/core/src/install-audit.ts:22`; `InstallAuditStore.record/getRecent/getByCapability` exist) but
|
||||
**has no read HTTP route** (substrate-types inventory §d: writes only; `GET /api/audit/installs` exists in
|
||||
`skills.ts` but is a generic recent-installs feed). MCP installs are not currently audited because there is
|
||||
no MCP install path to audit.
|
||||
|
||||
**Adapter:** no `getMcps`/`installMcp`/`testMcp` methods in `apps/web/src/lib/adapter.ts` (grep → 0 matches).
|
||||
|
||||
**Disposition: `create-new`** (with substrate reuse). A net-new **MCPHub app** (`MCPHubApp.tsx`) promoted
|
||||
out of ConnectorsApp's MCP tab, **plus net-new `/api/mcps/*` backend routes wiring the existing `McpRuntime`
|
||||
+ a new persisted config store + install-audit**. The static catalog component (`McpCatalog`/`McpServerCard`)
|
||||
is reused as the "Available"/"Marketplace" tab content. This is the single largest backend gap on the Extend
|
||||
layer — the engine exists but is entirely unwired to UI or persistence.
|
||||
|
||||
---
|
||||
|
||||
## 4. Frontend work
|
||||
|
||||
**New IA placement:** add an `mcp-hub` (or reuse the dead `marketplace`-adjacent slot) `AppId` in
|
||||
`apps/web/src/lib/dock-tiers.ts`, register chrome in `Desktop.tsx` `appConfig` + a `renderAppContent`
|
||||
switch case (per frontend inventory §b lines 123-129), and add a dock entry under the **Extend** zone-parent
|
||||
(`dock-tiers.ts` zone model). MCP Hub is power-user/PRO-tier-gated (PRD personas: power user/developer needs
|
||||
MCPs — PRD line 151).
|
||||
|
||||
**Components to CREATE** (`apps/web/src/components/os/apps/`):
|
||||
- `MCPHubApp.tsx` — shell with the 5 PRD tabs (Installed / Available / Marketplace / Custom / Remote
|
||||
Registry). Mirror `ConnectorsApp.tsx`'s sidebar-tab + filter layout (`:183-216`) so it's visually
|
||||
consistent with the Connector Hub it splits from.
|
||||
- `mcp/InstalledMcpTable.tsx` — table of running/installed servers: name, status pill (running/stopped/
|
||||
error/installing — maps `McpServerState` `mcp-runtime.ts:16`), connected-to, last-used, locality,
|
||||
scope chip, row actions (start/stop, test, scope, view logs, revoke). Drives PRD §12.8 line 573-574.
|
||||
- `mcp/AddCustomMcpForm.tsx` — Custom tab: `{ name, command, args[], env{}, workspaceId? }` → `POST /api/mcps`
|
||||
(matches `McpServerConfig` `mcp-runtime.ts:8-14`). Reuse `injection-scanner` patterns server-side.
|
||||
- `mcp/McpDetailPanel.tsx` (right rail) — MCP Overview counts, MCP Health, permissions/scope editor,
|
||||
**logs viewer**, and the **risk/approval banner** ("Risk approval required" state). Reuse the approvals
|
||||
surface pattern from `ApprovalsApp.tsx` / inline-chat approval (same backend `/api/approval/*`).
|
||||
- `mcp/McpScopeDialog.tsx` — scope-to-workspace/agent picker (writes `workspaceId` onto the server config;
|
||||
later, `mcpIds[]` onto workspace/agent per §6).
|
||||
|
||||
**Components to REUSE (keep-promote):**
|
||||
- `McpCatalog.tsx` + `McpServerCard.tsx` + `mcp-registry.ts` → become the **Available** + **Marketplace** +
|
||||
**Remote Registry** tab bodies. Today `McpServerCard` only shows a copy-command strip
|
||||
(`McpServerCard.tsx:98-138`) — **rework** it to add a real **Install** button (calls the new
|
||||
`installMcp` adapter method) while keeping copy-command as the offline fallback.
|
||||
- `recommendConnectors` from `@waggle/shared` (already used `McpCatalog.tsx:15,69`) for "Recommended" tile.
|
||||
- `LockedFeature.tsx` for tier gating; `ContextMenu.tsx` for row actions; shadcn `table`, `badge`, `dialog`,
|
||||
`tabs`, `tooltip` primitives (`components/ui/*`, frontend inventory §e).
|
||||
|
||||
**Adapter methods to ADD** (`apps/web/src/lib/adapter.ts` — the single sidecar gateway, §c lines 162-265):
|
||||
`getMcps()`, `installMcp(payload)`, `addCustomMcp(config)`, `startMcp(id)`, `stopMcp(id)`, `testMcp(id)`,
|
||||
`scopeMcp(id, scope)`, `revokeMcp(id)`, `getMcpLogs(id)` — one per PRD §16.9 / §12.8 action.
|
||||
|
||||
**New hook:** `hooks/useMcps.ts` (mirrors the `useConnectors`-style pattern) returning
|
||||
`{ installed, available, custom, install, start, stop, test, scope, revoke, refresh }`. Wire SSE/poll over
|
||||
`/api/capabilities/status` or a new `/api/mcps` for live status (cache-invalidate on
|
||||
"connector sync" / install completion per blueprint line 514).
|
||||
|
||||
---
|
||||
|
||||
## 5. Backend work (PRD §16.9 endpoints — all MCP rows)
|
||||
|
||||
> All net-new routes live in a new `packages/server/src/local/routes/mcps.ts`, registered in
|
||||
> `local/index.ts`, wiring the already-built `McpRuntime` (`server.agentState.mcpRuntime`,
|
||||
> decorated `local/index.ts:1361`). **No new SQLite table is strictly required** — but a persisted
|
||||
> config source IS (see migration flag).
|
||||
|
||||
| PRD §16.9 endpoint | Status | Extend vs net-new + substrate it touches |
|
||||
|---|---|---|
|
||||
| `GET /api/mcps` | **PARTIAL → build net-new route over existing data** | No `/api/mcps` exists (grep-confirmed in backend-routes inventory, line 422 & §16.9 line 522). The data is **derivable today**: live runtime status from `McpRuntime.getServerStates()/getHealthy()/getAllTools()` (already surfaced in `capabilities.ts:35-53`), enriched with catalog metadata from `MCP_CATALOG` (`@waggle/shared`). **Net-new** thin route in `mcps.ts` that joins runtime state + persisted config + catalog into the `Extension/MCP` shape (§2). Touches: `McpRuntime` (agent), `MCP_CATALOG` (shared), new config store. |
|
||||
| `POST /api/mcps/install` | **PARTIAL → net-new, route through existing install path** | No `/api/mcps/install` (inventory §16.9 line 523). Closest install paths are marketplace (`POST /api/marketplace/install` — SecurityGate + audit, `marketplace.ts:224-319`) and plugin install (`POST /api/plugins/install`). **Net-new** MCP install that: (a) persists an `McpServerConfig`, (b) calls `mcpRuntime.addServer(config)` + `start()` (`mcp-runtime.ts:308,102`), (c) runs the **SecurityGate + writes an `install_audit` row** with `capability_type:'mcp'` (`install-audit.ts:22`) — satisfying the "install audit is recorded" acceptance step (PRD line 743). Risky servers → return `risk approval required` state instead of starting. Tier: PRO (match marketplace). |
|
||||
| `POST /api/mcps/:id/test` | **MISSING** | No MCP test/health route (inventory §16.9 line 524). Closest analog is `GET /api/connectors/:id/health`. **Net-new**: resolve the server, `start()` if needed, assert `isHealthy()` (`mcp-runtime.ts:94,399`) and/or do a `tools/list` round-trip, return health + discovered tools. Touches `McpRuntime`. |
|
||||
| `POST /api/mcps/:id/revoke` | **MISSING** | No MCP revoke/uninstall by id (inventory §16.9 line 525). Closest: `DELETE /api/plugins/:name`. **Net-new**: `mcpRuntime.removeServer(name)` (`mcp-runtime.ts:327`) + delete persisted config + write `install_audit` `action:'rejected'`/`'revoked'`. Touches `McpRuntime` + config store + install-audit. |
|
||||
| `GET /api/marketplace` | **PARTIAL** | Listing is `GET /api/marketplace/search` (`marketplace.ts`); the Marketplace tab reuses it. Alias of `/search` (inventory §16.9 line 526). Not MCP-specific work. |
|
||||
| `POST /api/marketplace/install` | **EXISTS** | `marketplace.ts` (Tier PRO, SecurityGate) — reused by the Marketplace tab. |
|
||||
|
||||
**Additional routes implied by PRD §12.8 actions not in §16.9 list (net-new):**
|
||||
- `POST /api/mcps` (add **custom** MCP) — blueprint API line 530 lists `GET/POST /mcps`. Persists config +
|
||||
`addServer` + audit. **Net-new.**
|
||||
- `POST /api/mcps/:id/start` and `POST /api/mcps/:id/stop` — PRD §12.8 "start/stop" action. Map to
|
||||
`McpServerInstance.start()/stop()` (`mcp-runtime.ts:102,154`). **Net-new.**
|
||||
- `PATCH /api/mcps/:id/permissions` (scope/permissions) — blueprint API line 530 (`PATCH /mcps/:id/permissions`).
|
||||
Writes `workspaceId`/scope onto the persisted config (runtime honors it via `getToolsForWorkspace`,
|
||||
`mcp-runtime.ts:385`). **Net-new.**
|
||||
- `GET /api/mcps/:id/logs` — PRD §12.8 "view logs". No log capture exists in `McpServerInstance` today
|
||||
(stderr is piped `:113` but not retained). **Net-new** + small runtime change to buffer stderr/state-change
|
||||
events for retrieval.
|
||||
- `GET /api/extend/audit` (or extend `/api/audit/installs`) — surface the install-audit trail for the MCP Hub
|
||||
right-rail "Recent Activity". `InstallAuditStore.getRecent()` exists but has no MCP-scoped HTTP read
|
||||
(substrate-types §d gap #1). **Net-new** (implied addition to §16.9, flagged in substrate inventory).
|
||||
|
||||
**Migration / persistence flag (IMPORTANT):**
|
||||
- **No `.mind` SQLite migration is required for the MCP entity itself** — installed MCP configs can persist as
|
||||
a JSON file (mirrors `workspace.json` / `.mcp.json` convention; note repo root already has an untracked
|
||||
`.mcp.json` per git status) read at boot to populate `mcpRuntime.addServer()`. **This persistence layer is
|
||||
entirely net-new** (today `mcpRuntime` is empty and never populated — `local/index.ts:911`). This is the
|
||||
load-bearing backend gap: without it, "Installed" MCPs do not survive restart.
|
||||
- **Install-audit DDL drift (latent, flag for the plan):** `AuditRiskLevel` TS includes `'critical'`
|
||||
(`install-audit.ts:16`) but both CHECK constraints allow only `low|medium|high`
|
||||
(`install-audit.ts:65`, `schema.ts:130`). Any MCP install recording `riskLevel:'critical'` would throw a
|
||||
CHECK violation — map CRITICAL → `'high'` + `approvalClass:'blocked'` as marketplace.ts already does
|
||||
(`marketplace.ts:224-319`), or fix the DDL.
|
||||
|
||||
---
|
||||
|
||||
## 6. Shared types needed (PRD §15 vs `lib/types.ts`)
|
||||
|
||||
- **`ExtensionType`** (PRD §15.2 line 953: `'skill'|'connector'|'mcp'|'model'|'template'|'external_tool'`)
|
||||
— **MISSING** in `apps/web/src/lib/types.ts` (substrate-types §e: none of the §15.2 unions exist in FE).
|
||||
Add it.
|
||||
- **`Extension` / `Mcp` interface** (blueprint line 554: `id, type, name, source, version, endpoint,
|
||||
capabilities, riskLevel, approvalClass, status, health, installedAt, approvedBy`) — **MISSING**. No
|
||||
`Extension`/`Mcp` type anywhere in FE. Add to `lib/types.ts` (and ideally `packages/shared/src/types.ts`
|
||||
so the sidecar route and FE share it). The existing `McpServer` (`@waggle/shared` `mcp-catalog.ts:17`:
|
||||
`id,name,description,author,category,url,installCmd,capabilities,official?,logo?`) is the **catalog/discovery**
|
||||
shape — distinct from the **installed-instance** `Mcp` shape; keep both, the Hub joins them by `id`.
|
||||
- **Runtime types already exist server-side** and should be the source of truth for the route contract:
|
||||
`McpServerConfig`, `McpServerState`, `McpToolInfo` (`packages/agent/src/mcp/mcp-runtime.ts:8-22`). Mirror
|
||||
`McpServerState` (`'starting'|'ready'|'error'|'stopped'`) into the FE status union (map to PRD §14.7 states).
|
||||
- **Reuse from install-audit:** `AuditCapabilityType`, `AuditRiskLevel`, `AuditApprovalClass`
|
||||
(`packages/core/src/install-audit.ts:15-22`) for the riskLevel/approvalClass/audit fields — do not invent
|
||||
parallel enums.
|
||||
- **`mcpIds[]` on Workspace/Agent** (PRD §15.3 `WorkspaceConfigV2.mcpIds`, §15.5 Agent `mcpIds`) —
|
||||
**MISSING** from both `WorkspaceConfig` (`workspace-manager.ts`, substrate-types §a) and `AgentDef`
|
||||
(`packages/shared/src/types.ts:36-47`, §e). Needed for the "scope to workspace/agent" action. Additive
|
||||
optional field (no DB migration — `workspace.json` is JSON).
|
||||
|
||||
---
|
||||
|
||||
## 7. Dependencies (screens / phases first)
|
||||
|
||||
- **Connector Hub (S07)** — MCP Hub is split OUT of `ConnectorsApp.tsx`'s MCP tab; do the Connector Hub
|
||||
promotion first (or jointly) so the shared sidebar-tab/filter/health/state patterns are settled and the
|
||||
MCP tab can be cleanly extracted. Same `Extend`-layer dock placement work.
|
||||
- **Extend layer / dock-zone IA** — requires the new `AppId` + dock-zone wiring (frontend inventory §b/§d:
|
||||
consolidate on `AppId`, add Extend zone entries). Blocks any new Extend app from being reachable.
|
||||
- **Install-audit read route (§d gap)** — shared with Skills (S?) and Connectors governance; build once,
|
||||
reuse across the Extend layer.
|
||||
- **Approvals surface** — risk-approval flow reuses existing `/api/approval/*` + `ApprovalsApp` patterns;
|
||||
no new approval substrate, but the wiring depends on that surface staying stable.
|
||||
- **Marketplace** — the Marketplace tab reuses `GET /api/marketplace/search` + `POST /api/marketplace/install`
|
||||
(already exist); ensure marketplace MCP packages are tagged so they route to the MCP install path.
|
||||
- **Phase hint:** later phase. Backend wiring (persisted config store + runtime population + `/api/mcps/*`)
|
||||
is the prerequisite for any non-static UI; the static catalog already ships, so this is a depth upgrade,
|
||||
not a day-1 blocker. Sequence after Home/Workspace/Memory core screens.
|
||||
|
||||
---
|
||||
|
||||
## 8. Effort: **XL**
|
||||
|
||||
Largest Extend-layer gap: the runtime engine exists but is **completely unwired** (empty `McpRuntime`, no
|
||||
persistence, no HTTP surface, copy-command-only UI). Requires a net-new persisted MCP-config store + boot-time
|
||||
runtime population + ~8 net-new sidecar routes (install/start/stop/test/scope/revoke/logs + custom add) +
|
||||
SecurityGate/audit integration + a full new app shell with 5 tabs, installed-table, detail/logs panel, scope
|
||||
dialog, risk-approval flow, and adapter/hook layer — while preserving the static catalog as the
|
||||
Available/Marketplace tabs. (Frontend-only would be M; the backend wiring + persistence + governance is what
|
||||
pushes it to XL.)
|
||||
|
||||
---
|
||||
|
||||
## 9. Open questions
|
||||
|
||||
1. **Persistence location/format for installed MCP configs** — JSON file (`.mcp.json` at dataDir, mirroring
|
||||
`workspace.json`; root already has an untracked `.mcp.json`) vs a new `install_audit`-adjacent table?
|
||||
Recommendation: JSON file (no migration), but confirm the dataDir path + multi-workspace scoping model.
|
||||
2. **Scope model** — is an MCP scoped by writing `workspaceId` onto its single config (1 server : 1 workspace,
|
||||
per current `McpServerConfig.workspaceId`), or by an `mcpIds[]` membership array on each workspace/agent
|
||||
(N:N)? PRD §15.3/§15.5 imply `mcpIds[]` (N:N); the runtime today only supports the single-`workspaceId`
|
||||
field (`mcp-runtime.ts:13,385`). N:N needs a runtime change.
|
||||
3. **Logs capture** — `McpServerInstance` pipes stderr but does not retain it (`mcp-runtime.ts:113`). Add a
|
||||
ring-buffer of stderr + stateChange events for `GET /api/mcps/:id/logs`, or defer logs to a later phase?
|
||||
4. **"Remote Registry" tab semantics** — is this the Composio gateway (already referenced in
|
||||
`McpCatalog.tsx:106,294-301`), the official `modelcontextprotocol/servers` registry, or a remote
|
||||
(HTTP/SSE-transport) MCP class distinct from local stdio? The runtime today is **stdio-only**
|
||||
(`mcp-runtime.ts:108-115`); remote-transport MCPs would need a new transport in `McpServerInstance`.
|
||||
5. **Install execution surface** — does in-app "Install" run `npx …` (spawn a child process to install the
|
||||
package) in the sidecar, or only register config + rely on a globally-installed binary? Security review
|
||||
needed (spawning installers vs the current copy-to-terminal model). Tauri IPC/CSP implications.
|
||||
6. **Tier gate** — confirm MCP Hub is PRO+ (matches marketplace install gate) vs power-user-density-tier
|
||||
(`UserTier`) only. Three tier vocabularies to reconcile (frontend inventory §f).
|
||||
Reference in New Issue
Block a user