Skip to content

fix(mcp): disabled MCPs reactivate after provider config change #28428

Closed as duplicate

Description

@danielxxomg

Description

When a user adds or modifies a provider in their opencode.json, ALL MCP servers restart and re-activate — including ones explicitly disabled via the /mcps toggle. This forces unwanted tools into the context window, increases token consumption, and confuses the agent.

The root issue is that the MCP disabled state is only in-memory (s.status[name]) and is never persisted to disk. Any config change that triggers an Instance reload wipes this state, causing all MCPs to come back enabled.

Steps to reproduce

  1. Configure multiple MCP servers in opencode.json
  2. Disable some via /mcps toggle (press Space)
  3. Edit opencode.json to change a provider (e.g., switch from opencode-go to openai)
  4. Restart OpenCode (or trigger config reload)
  5. Run /mcps — all previously disabled MCPs are now enabled again

Technical Root Cause

The disabled state is only stored in-memory in packages/opencode/src/mcp/index.ts:

  • Toggle path: MCP.disconnect() sets s.status[name] = { status: "disabled" } (in-memory only)
  • Init path: MCP.state() only reads from cfg.mcp (config file) — no persisted disabled state consulted
  • Reload: Config change → markInstanceForDisposal() → full Instance.disposeAll() → fresh MCP.state() → disabled state lost

Compare with model selection, which already persists to disk via Global.Path.state/model.json — the pattern already exists in the codebase.

Expected Behavior

MCP disabled state should survive:

Impact

  • Context window: Users with many MCPs keep most disabled to save tokens. Reactivation wastes ~20-65K tokens per session.
  • UX friction: Users must manually re-disable MCPs after every provider config change.
  • Security surface: MCPs like chrome-devtools (browser launch) and morphllm-fast-apply (remote npm code) remain active against user intent.

Proposed Fix Direction

Persist disabled MCP IDs to a state file (e.g., mcp-state.json in Global.Path.state), same pattern as model.json. Read it during MCP.state() init. No changes to Instance lifecycle or reload mechanism needed.

Related Issues / PRs

Operating System

Windows 11

Terminal

Windows Terminal

Activity

  1. github-actions commented on May 20, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions