Skip to content

Conversation

@ThomasK33
Copy link
Member

Summary

Adds per-workspace MCP server and tool configuration. Users can now customize which MCP servers are enabled and which tools are exposed for each workspace, without modifying the project-level .mux/mcp.jsonc.

Changes

Backend

  • Types & Schemas: Added WorkspaceMCPOverrides schema with disabledServers and toolAllowlist fields
  • Config helpers: getWorkspaceMCPOverrides() and setWorkspaceMCPOverrides() methods in Config class
  • ORPC endpoints: workspace.mcp.get and workspace.mcp.set for frontend access
  • MCPServerManager: Updated to filter servers and tools based on workspace overrides
  • AIService: Fetches and passes overrides when getting MCP tools

Frontend

  • WorkspaceMCPModal: New modal component for per-workspace MCP configuration
  • WorkspaceHeader: Added Server button (⚙️) to open the modal
  • UI features:
    • Toggle servers enabled/disabled for the workspace
    • Fetch tools from each server
    • Checkbox allowlist to select which tools to expose
    • "Allow all" shortcut button

Tests

  • 5 tests for workspace override filtering in MCPServerManager
  • 6 tests for workspace MCP override Config helpers

How it works

  1. Server definitions remain per-project in .mux/mcp.jsonc
  2. Per-workspace overrides are stored in ~/.mux/config.json under each workspace entry
  3. Effective servers = (project servers) - (workspace disabledServers)
  4. Effective tools = filtered by toolAllowlist[server] if set

📋 Implementation Plan

Plan: Selective MCP tools + per-workspace configuration

Goals

  1. Selective MCP tools — For each workspace, expose only an allowlisted subset of MCP tools to the model.
  2. Per-workspace MCP configuration — Allow enabling/disabling MCP servers (and tool allowlists) per workspace, without impacting other workspaces.
  3. Backwards compatible — Existing per-project .mux/mcp.jsonc continues to work unchanged.

Proposed approach (recommended)

1) Keep server definitions per-project; add per-workspace overrides

  • Per-project (existing): PROJECT_ROOT/.mux/mcp.jsonc
    • Source of truth for server commands.
  • Per-workspace (new, stored in mux global config ~/.mux/config.json under each workspace entry):
    • Which servers are enabled for that workspace.
    • Which tools are allowlisted (per server) for that workspace.

This avoids needing to read/write config inside SSH workspaces (remote filesystem) and keeps the current "configure once per project" ergonomics, while still enabling workspace-specific behavior.

2) Workspace MCP override schema

Add an optional mcp field on WorkspaceConfigSchema:

// Stored under each workspace entry in ~/.mux/config.json
export interface WorkspaceMCPOverrides {
  /** If set, these servers are disabled for this workspace (after project config). */
  disabledServers?: string[];

  /**
   * Optional per-server allowlist of tools.
   * Key: server name (from .mux/mcp.jsonc)
   * Value: raw MCP tool names (NOT namespaced)
   *
   * If omitted for a server => expose all tools from that server.
   */
  toolAllowlist?: Record<string, string[]>;
}

Semantics:

  • Effective servers for a workspace = (project-config enabled servers) minus disabledServers.
  • Effective tools for a server:
    • If toolAllowlist[server] present => only expose those tool names.
    • Else => expose all tools from that server.

3) Runtime behavior changes

  • MCPServerManager.getToolsForWorkspace(...) filters the returned tool map using the workspace allowlists before it is merged into getToolsForModel.
  • MCPServerManager.listServers(...) gains a workspace-aware variant so the system prompt lists only the servers enabled for that workspace.
  • No restart required when only tool allowlists change (servers stay running; we just filter what we expose).

Generated with mux • Model: anthropic:claude-opus-4-5 • Thinking: high

@chatgpt-codex-connector
Copy link

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

Add the ability to configure which MCP servers and tools are available
at both project and workspace levels.

- Enable/disable MCP servers per project
- Configure tool allowlists per server (restrict which tools are exposed)

- Override project settings per workspace
- Enable servers that are disabled at project level (opt-in)
- Disable servers that are enabled at project level (opt-out)
- Configure workspace-specific tool allowlists

- New WorkspaceMCPModal for per-workspace MCP configuration
- Shared ToolSelector component with All/None bulk selection buttons
- Shared useMCPTestCache hook - tools fetched in Settings are cached
  and immediately available in workspace modal
- Tool count display (e.g., '5/43') shows filtering at a glance

WorkspaceMCPOverrides:
- disabledServers: string[] - servers to disable (overrides project enabled)
- enabledServers: string[] - servers to enable (overrides project disabled)
- toolAllowlist: Record<string, string[]> - per-server tool filtering

Signed-off-by: Thomas Kosiewski <tk@coder.com>

---
_Generated with `mux`_

Change-Id: Idc97d085b6f1d1c5c0e98196d6d31625dea117d8
Added comprehensive storybook stories for MCP configuration:

- ProjectSettingsEmpty: No MCP servers configured
- ProjectSettingsWithServers: Multiple servers configured
- ProjectSettingsMixedState: Mix of enabled/disabled servers
- ProjectSettingsWithToolAllowlist: Servers with tool filtering

- WorkspaceMCPNoOverrides: Default state, inherits project settings
- WorkspaceMCPProjectDisabledServer: Server disabled at project level
- WorkspaceMCPEnabledOverride: Project-disabled server enabled at workspace
- WorkspaceMCPDisabledOverride: Project-enabled server disabled at workspace
- WorkspaceMCPWithToolAllowlist: Workspace-level tool filtering

- ToolSelectorInteraction: Tests All/None bulk selection buttons
- ToggleServerEnabled: Tests toggling server enabled state

Also added:
- MCP mock endpoints to .storybook/mocks/orpc.ts
- Test IDs to WorkspaceHeader for story automation

Signed-off-by: Thomas Kosiewski <tk@coder.com>

---
_Generated with mux_

Change-Id: Ic01bbfe0568b2eafba6e7d2e5568a34c30316354
@ThomasK33 ThomasK33 enabled auto-merge December 15, 2025 20:13
@ThomasK33 ThomasK33 added this pull request to the merge queue Dec 15, 2025
Merged via the queue into main with commit b220762 Dec 15, 2025
20 checks passed
@ThomasK33 ThomasK33 deleted the selective-mcp-tools branch December 15, 2025 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant