Why MCP Tools Disappear: Editor Modes and Permission Gates

June 23, 2026 · updated June 25, 2026 · AI Agent Internals: How Coding Agents Really Work (part 6)

▶ Watch on YouTube & subscribe to The Stack Underflow

You configure an MCP server, it shows up in the tool list, works fine — and then the next day, same editor, same server, same model, it does nothing. The instinct is to blame the server: restart it, re-read the docs, file a GitHub issue. Nine times out of ten that is wasted effort. The server is fine. What changed is the mode your editor is currently in, and that mode carries a gate that decides which capabilities are even permitted to fire.

Understanding why requires going one level below the surface — into how the MCP protocol actually exposes tools, and how editors use (or ignore) what the protocol tells them.

The one-sentence version: Your MCP tools did not break — the editor mode you are in has a permission gate that prevents them from firing, and that gate is an editor design decision layered on top of a protocol that is itself mode-agnostic.

What the MCP Protocol Actually Does (and Does Not Do)

The Model Context Protocol (MCP) is an open protocol, currently at spec version 2025-11-25 (modelcontextprotocol.io), governed by the Linux Foundation’s Agentic AI Foundation since December 2025. It is built on JSON-RPC 2.0 — a request/response message format where clients send requests and servers reply.

When an editor starts up and connects to an MCP server, the first exchange is a capability negotiation handshake in the initialize request. The client says which features it supports; the server replies with which features it exposes. If the server exposes tools, it declares a tools capability in its response:

{
  "capabilities": {
    "tools": {
      "listChanged": true
    }
  }
}

After the handshake, the client sends a tools/list request and gets back the full catalog of available tools — each with a name, description, and JSON Schema for its input parameters. This is tool discovery, and it happens at connection time, not at prompt time.

MCP initialization sequence

Editor (host)          MCP Client             MCP Server
     |                     |                      |
     |--- initialize() --->|                      |
     |                     |--- initialize ------->|
     |                     |<-- capabilities ------|
     |                     |--- tools/list -------->|
     |                     |<-- [tool1, tool2] -----|
     |<-- tools ready -----|                      |
     |                     |                      |
     | [mode switch: Ask]  |                      |
     |                     |                      |
     |  Host filters tool  |                      |
     |  list before        |                      |
     |  injecting into LLM |                      |
     |                     |                      |

Critically, the MCP protocol itself has no concept of “editor modes.” It does not know whether you are in Ask mode or Agent mode. The protocol delivers a tool list; what the editor does with that list is entirely an editor-level decision. The gate is above the protocol, not inside it.

Tool Annotations: The Protocol’s Risk Vocabulary

The 2025-11-25 spec added tool annotations — a set of boolean hints that servers attach to each tool to declare its risk profile. These annotations do not enforce behavior; they inform editors how to treat a tool before calling it.

AnnotationDefaultWhat it signals
readOnlyHintfalseTool only reads; does not modify any environment
destructiveHinttrueModifications may delete or overwrite, not just append
idempotentHintfalseCalling with the same args twice is safe
openWorldHinttrueTool reaches outside its local domain (network, APIs)

The spec is explicit: these are hints, not contracts. A malicious or poorly written server can lie. The MCP spec warns that “clients MUST treat tool annotations as untrusted unless they come from a trusted server” (modelcontextprotocol.io/specification/2025-11-25). So annotations inform UX decisions — confirmation dialogs, parallelism, risk warnings — but they cannot be the security boundary. The security boundary lives in the editor’s mode gate and your infrastructure’s access controls.

VS Code Copilot uses readOnlyHint to decide whether to show a confirmation dialog before a tool fires. Tools marked readOnlyHint: true from trusted servers skip the prompt. Everything else requires explicit approval. That approval model is VS Code’s interpretation of the annotation — other editors may do something different with the same data.

The Three Modes Most AI Editors Ship With

Most AI-powered editors expose three distinct permission levels inside the same product. The MCP protocol sees none of this — from its perspective, the client either calls tools/call or it does not.

ModeRead CodeEdit FilesRun TerminalCall MCP Tools
AskYesNoNoNo
EditYesYes (with approval)NoNo
AgentYesYesYesYes

Ask mode is read-only. The model can look at your codebase and answer questions, but every gate is closed. No edits, no terminal, no MCP tools.

Edit mode opens one more door. The model can propose file changes, which you approve individually. Terminal and MCP tools remain gated.

Agent mode is where the gates open fully. Read, write, run terminal commands, call MCP tools — all of it fires. This is exactly why your GitHub MCP server or database MCP tool “vanishes” when you drop back into Ask or Edit mode. The tool is still registered. The server is still running. The capability is not permitted in that context.

Permission gate per mode

Ask mode:   [READ] [    ] [      ] [    ]   almost everything gated
Edit mode:  [READ] [EDIT] [      ] [    ]   one more door open
Agent mode: [READ] [EDIT] [TERM  ] [MCP ]   all gates open
                                    ^
                                    MCP tools only
                                    live here

When you switch back to Agent mode, the tools reappear instantly — because the editor re-injects the already-discovered tool catalog into the model’s context. Nothing was broken; the tool list was just withheld.

Why Different Editors Gate Differently

The MCP protocol is universal. The same spec, the same tool definitions, the same JSON-RPC wire format runs everywhere. But editors make completely different choices about where to draw the permission line. That choice reveals each editor’s core design philosophy.

VS Code Copilot: opt-in with per-call approval. As of the June 2025 GA release, MCP tools are locked to Agent mode in VS Code. You have to consciously switch into that mode to get access. Within agent mode, every tool call — unless the tool is read-only from a trusted server — triggers an approval dialog. The user can approve for the current invocation, the current session, or all future invocations (devblogs.microsoft.com/visualstudio, June 2025). The default is maximum safety; you escalate deliberately. MCP servers are configured via an mcp.json file in the solution or workspace.

Cursor: power with staged approval. Cursor exposes MCP tools in Agent mode and gates them with a configurable run-mode spectrum rather than a binary ask/agent switch. The modes range from “require approval for every tool call” through an allowlist system where specific tools are pre-approved, all the way to “auto-review” (Cursor 3.6+) which routes each tool call through a three-stage filter — allowlist, sandbox, classifier subagent — before deciding whether to prompt (cursor.com/docs/agent/security). One practical constraint unique to Cursor: tool definitions are injected into the model’s context window, and Cursor has a ceiling of roughly 40 active tools across all connected MCP servers before definitions start crowding out your actual code context.

Claude Code: supervised power with plan approval. MCP tools are available broadly, but the agent surfaces a plan before it executes. As of the April 2026 redesign, a dedicated Plan side panel renders the current plan alongside the chat, with an Approve/Reject flow before anything runs (code.claude.com/docs/en/mcp). Enterprise deployments add a gateway layer that inspects developer identity and enforces per-team tool scoping — a frontend engineer’s session only sees frontend MCP tools; production database write access requires a time-bound break-glass procedure. The gate is not the mode; it is the plan-approval checkpoint.

Where each editor places its gate

VS Code:      SAFE <-- [mode switch + per-call dialog] --> POWER
Cursor:       SAFE <-- [configurable run-mode spectrum] --> POWER
Claude Code:  SAFE <-- [plan approval checkpoint]       --> POWER

Same underlying MCP layer. Three completely different answers to the question “at what point does a human confirm intent?”

Dynamic Tool Updates: When the Server Changes Mid-Session

There is a second reason tools can appear and disappear even within a single agent mode session: the server can change its own tool list while the session is live.

The MCP spec defines a notifications/tools/list_changed notification that a server sends when its tool catalog changes — new tools come online, existing tools are removed, or a tool’s schema updates. When the client receives this notification (and the server declared listChanged: true in its capabilities), the client re-issues tools/list and gets a fresh catalog.

Dynamic tool update flow

MCP Server                MCP Client             Editor
    |                         |                     |
    | [tool added at runtime] |                     |
    |                         |                     |
    |-notifications/tools/--->|                     |
    |   list_changed          |                     |
    |                         |--- tools/list ------>|... (to server)
    |<-- tools/list ----------|                     |
    |--- updated tool list -->|                     |
    |                         |--- refresh UI ------>|
    |                         |                     |

Not every editor handles this gracefully. If an editor fetches the tool list once at startup and never refreshes it, a server that adds tools mid-session will appear to have “disappeared” tools — the tool exists on the server, the protocol is delivering it, but the client never asked again. This is a client implementation gap, not a protocol gap.

How to Apply This Right Now

Concrete guidance ordered by impact:

  1. Check your mode before debugging the server. If tools stop responding, look at the mode indicator in your editor UI first. Switching from Ask or Edit back to Agent mode takes two seconds and resolves the issue nine times in ten.

  2. Configure MCP servers at the project level, not just globally. VS Code reads mcp.json from the workspace; Claude Code reads .claude/mcp.json; Cursor reads ~/.cursor/mcp.json or a project-level config. Project-level config means teammates get the same tool set without manual setup.

  3. Add tool annotations to every MCP server you build. Set readOnlyHint: true on any tool that only reads data. This lets editors like VS Code skip the confirmation prompt for safe tools, reducing friction without reducing safety. Set destructiveHint: true explicitly on delete/overwrite operations so editors surface those as high-risk actions.

  4. Watch your tool count in Cursor. If you have more than 40 tools across all connected servers, Cursor silently drops the later ones from the context. Audit which servers are connected and disable any you do not actively use. This is a context-window economics problem, not a permissions problem.

  5. Treat tools/list_changed as a first-class feature when building servers. If your server adds or removes tools dynamically (feature flags, permission changes, resource availability), implement the listChanged capability and emit the notification. Editors that support dynamic updates will pick up the change automatically; those that do not will at least have a defined contract to upgrade toward.

Common Misconceptions

“My MCP server crashed.” The most common assumption when tools stop appearing, and almost always wrong. Check the mode first. The server process is almost certainly running; you are in a context where the editor does not expose it. A crashed server produces explicit error output in your terminal; a mode gate produces silence.

“Tool annotations guarantee safety.” Annotations are hints from the server. A server can mark a destructive tool as readOnlyHint: true and the protocol cannot prevent that. The MCP spec is explicit: treat annotations as untrusted from servers you do not control. Annotations shape UX and friction; deterministic access controls in your infrastructure (network rules, IAM policies, gateway enforcement) are the actual safety boundary.

“Agent mode is always more dangerous.” Agent mode has more capability, but editors like Claude Code add a plan approval checkpoint and Claude Code Auto Mode adds an injection probe and action gate on top of that. Supervised agent mode can be safer in practice than ungated edit mode, because it shows you exactly what it plans to do before anything runs.

“The MCP protocol controls which modes expose tools.” The protocol has no mode concept at all. MCP delivers a tool catalog to whoever asks for it. The editor decides whether to ask, and whether to inject the resulting tools into the model’s context. Mode gating is entirely an editor-layer decision.

Frequently Asked Questions

Why do some editors hide MCP tools in certain modes instead of showing them grayed out?

It is a UX and safety choice. Showing a tool as grayed-out implies “this should work, something is wrong.” Hiding it entirely accurately reflects the mode’s capability surface — the tool genuinely does not exist in that context from the model’s perspective. If the editor injected a grayed-out tool into the system prompt, the model would still know it exists and might try to reason about it.

Can I configure VS Code to expose MCP tools outside Agent mode?

As of the June 2025 GA release, VS Code gates MCP to Agent mode by design. That is the intended behavior, not a configuration gap. The VS Code team has indicated that Ask and Edit experiences are “evolving toward an architecture that, like the agent, utilizes tools” — suggesting possible future convergence, but it is not there yet. If you need MCP tools without full agent permissions, Cursor’s allowlist mode or Claude Code’s plan-approval flow may fit your workflow better.

If MCP is universal, can I use the same MCP server across VS Code, Cursor, and Claude Code?

Yes. A well-written MCP server is fully editor-agnostic. Each editor connects to it using the same JSON-RPC protocol over the same transport (stdio or SSE). The difference is only in when each editor permits your session to call it. Point all three editors at the same server config and they all discover the same tools — they just gate them differently.

Does switching modes mid-conversation reset the context?

Generally no. The conversation history (the token stream in the context window) persists when you switch modes. What changes is the set of tools injected into the model’s available-tools list going forward. You do not lose your conversation; you open or close capability gates. Note that some editors do truncate or summarize context when a session gets long, which is separate from the mode switch.

What is the 40-tool limit in Cursor and why does it cause tools to silently disappear?

Tool definitions are injected into the model’s context window as part of the system prompt. Each tool definition — name, description, parameter schema — costs tokens. Cursor’s agent has a finite context budget, and past roughly 40 active tools the definitions start crowding out actual code context. Cursor silently drops tools beyond that count rather than erroring. The fix is to reduce the number of active MCP servers or disable tools you are not using. This is a context-window economics issue, not an MCP protocol issue.

How does the tools/list_changed notification work in practice?

When a server’s tool catalog changes at runtime — because a feature flag toggled, a permission changed, or a resource came online — the server sends notifications/tools/list_changed to the client (if it declared listChanged: true in its capabilities). The client re-issues tools/list and gets the fresh catalog. If the editor supports dynamic updates, the UI refreshes automatically. If it fetched the list only once at startup, the new tool never appears until you reconnect. This is the most common cause of tools appearing in Claude Desktop but not in another editor — one client handles dynamic updates and the other does not.

Where This Fits in the Series

This tutorial is the finale of the “AI Agent Internals” series on The Stack Underflow. It closes the loop on the core execution model by tying together the lower-level tutorials in the playlist:

The next series digs into the hidden costs of AI coding — tokens, context windows, and the limits that shape every decision the agent makes:

Browse all tutorials to follow the full series.

Found this useful? The deep version lives on YouTube — new breakdowns of how AI dev tools actually work, weekly.

Subscribe on YouTube →