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 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 , 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.