# Claude Code MCP Deep Dive (4): From Tools List to an Entry in the Tool List

> Source: <https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-4-from-tools-list-to-an-entry-in-the-tool-list-3i53>
> Published: 2026-10-26 05:37:49+00:00

**TL;DR:** An MCP server can say, “I have a tool named `create_issue`,” but Claude Code does not simply put that bare name beside its built-in tools. It gives the tool a namespaced callable identity and adapts the server’s definition into the client’s tool surface. The namespace prevents collisions; the adapter makes a built-in action and an external action look like one coherent tool system to the model.

[The previous article](https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-3-from-a-child-process-to-a-remote-service-49nb) covered how bytes move between Claude Code and an MCP server. This article starts after the connection and initialization succeed: how does a tool declared by the server become something the model can actually call?

Imagine two connected servers, `jira` and `linear`. Both happen to offer a tool called `create_issue`.

If a client placed two bare `create_issue` entries in a shared tool list, the model would have no reliable way to select one. The collision can be even more confusing when a server declares a name that resembles a built-in tool. A call named `Write` should not ambiguously mean either “write a local file” or “invoke an unrelated external service.”

Claude Code resolves this by constructing a callable name that records the tool's origin. For a normally configured server, the shape is:

```
mcp__<server-name>__<tool-name>
```

So the two issue-creation tools become distinct entries such as:

```
mcp__jira__create_issue
mcp__linear__create_issue
```

The exact shape can gain more scope when a plugin bundles the server. Claude Code's current documentation, for example, gives plugin-provided tools the form:

```
mcp__plugin_<plugin-name>_<server-name>__<tool-name>
```

That additional context is not cosmetic. It lets names remain unique even when plugins, manually configured servers, and built-in capabilities share a session.

A useful consequence is that a tool name is also provenance information. The `mcp__` prefix signals an MCP-provided capability, and the following namespace identifies the server that owns it. In the next article, that naming pattern will matter again because permission rules can target a server's tools as a group rather than requiring one rule per tool.

Built-in tools are implemented and described by Claude Code itself. An MCP tool arrives differently: the server declares it through the protocol.

The MCP `tools/list` response includes a tool name, a human-readable description, and an `inputSchema` expressed as JSON Schema. It may also include a title, an output schema, and annotations. Claude Code can use that declaration to present a call surface to the model without inventing a second, client-owned parameter format for every server.

This is an important division of responsibility:

Suppose a server declares this simplified tool:

```
{
  "name": "create_issue",
  "description": "Create an issue in the selected project",
  "inputSchema": {
    "type": "object",
    "properties": {
      "title": { "type": "string" },
      "body": { "type": "string" }
    },
    "required": ["title"]
  }
}
```

The client does not need to translate `title` and `body` into a separate proprietary language before the model can use them. It preserves the server's contract while wrapping the invocation route: when the model calls the namespaced tool, Claude Code can map it back to the owning server and issue the corresponding `tools/call` request.

That is why adding an MCP server can add useful capabilities without requiring Claude Code to ship a new built-in implementation for each service. The server provides the domain-specific schema and behavior; the client provides the integration framework.

After adaptation, an MCP tool participates in the same broad decision loop as a built-in tool: it has a callable name, a description, an input contract, and a result.

The model should not need a separate decision procedure just because one action came from a remote issue tracker and another came from the local environment. It evaluates the available capabilities against the request, chooses an action, supplies arguments, and receives a result.

That does not mean origin disappears. It remains important for permissions, connection health, timeouts, and diagnostics. But it is intentionally not a burden on the model-facing interface. The client hides the transport and server-routing machinery behind a consistent tool abstraction.

For server authors, this has a practical implication: invest in a precise description and a clear JSON Schema. A vague description or underspecified schema does not become clearer when it crosses the MCP boundary. The client's wrapper can make the tool available; only the server can explain what a valid invocation means.

The normal behavior is namespacing, not replacement. A distinct `mcp__...` callable name means an external tool cannot silently shadow a built-in tool with the same short name.

Some embedding environments can make more specialized choices about their tool surface, including in-process SDK-hosted servers. Those are host-level design decisions, not a reason for a normally configured third-party server to depend on unprefixed overrides. Claude Code's public MCP configuration documentation explicitly distinguishes an SDK-only in-process server type from the regular configuration types.

The boundary is worth keeping clear: if a system intentionally replaces or aliases a capability, it still needs reliable internal provenance for routing and permissions. A display or callable name alone cannot be the whole security model.

MCP has more than tools. Servers may also offer **resources**: readable pieces of context or data.

It would be wasteful for every resource-capable server to register its own separate “list resources” and “read resource” tools with identical client-side behavior. A client can instead expose generic resource operations and route a selected resource back to the server that owns it. The user-facing result is a single resource capability model rather than a list that grows with duplicated plumbing every time another server connects.

The same principle appears throughout a good integration layer: server-specific content belongs to the server; cross-server mechanics belong to the client. A later article will examine resources and elicitation in more detail.

A connection does not freeze a server's capabilities forever. An MCP server that declares the `tools` capability can say that its list may change by advertising `listChanged`. When the list changes, the server can send a `notifications/tools/list_changed` notification.

Claude Code handles this as a refresh problem rather than requiring the user to disconnect and reconnect the server. Its current documentation says that an interactive session fetches the updated list; `claude -p` and Agent SDK sessions refresh the tool list on the notification. If refresh fails, Claude Code keeps the previously discovered tools, prompts, and resources until a later refresh succeeds.

This explains an otherwise surprising observation: an MCP server can gain or lose a tool during one session without a manual reconnection. The list was not permanently copied at handshake time; it is a cached view that the protocol allows the server to invalidate.

With several MCP servers installed, connections can complete at different times. One local process may start quickly while a remote service takes longer; another server may still be authenticating.

The important conceptual result is not the order of those events. Claude Code maintains a unified tool surface with stable naming and routes each namespaced call to the server that provided it. The model sees a coherent set of capabilities rather than needing to reason about a separate ad hoc interface for every connection.

This same design can scale further with tool search and deferred loading, but the basic transformation remains the same:

`tools/list`.` tools/call`.
A namespaced MCP tool appearing in the list does not mean every call is automatically approved. One of the questions from the opening article was: who gets to authorize the action?

The naming rule introduced here makes it possible to describe permissions at a useful granularity, including rules that cover an entire server. The next article continues from that boundary: **from matching a tool name to server-level authorization**.
