MCP Tools
Claude Code integrates with external services through the Model Context Protocol (MCP). The MCP tool system provides a dynamic proxy for server tools, resource access, and authentication flows.
MCPTool (Dynamic Proxy)
MCPTool is a base tool definition that serves as a template for dynamically generated MCP tool instances. It is not used directly. Instead, the MCP client (src/services/mcp/client.ts) creates concrete tool instances by cloning MCPTool and overriding its properties with server-specific metadata.
How MCP Tools Are Created
When an MCP server connects, it advertises its available tools via the tools/list method. The MCP client:
- Receives each tool's name, description, and input schema from the server
- Creates a copy of
MCPToolwith overriddenname,description,prompt,call, anduserFacingName - Sets the tool's
inputJSONSchemadirectly from the server (MCP tools define schemas in JSON Schema format, not Zod) - Registers the tool in
appState.mcp.tools
Base Properties
const MCPTool = buildTool({
isMcp: true,
name: 'mcp', // Overridden per tool instance
maxResultSizeChars: 100_000,
async checkPermissions(): Promise<PermissionResult> {
return { behavior: 'passthrough', message: 'MCPTool requires permission.' }
},
// ... all rendering and behavior methods are overridden per instance
})Input Schema
MCP tools use a passthrough Zod schema (z.object({}).passthrough()) for the internal type system, since actual validation is defined by the server's JSON Schema. The inputJSONSchema property carries the server-provided schema for API serialization.
Permission Model
MCP tools use passthrough behavior by default, meaning permission checks fall through to the general permission system. Users can set allow/deny rules scoped to MCP server prefixes:
mcp__server: blanket deny/allow for all tools from a servermcp__server__tool: per-tool permission rules
When a blanket deny rule matches an MCP server prefix (e.g., mcp__server), all tools from that server are filtered out before the model sees them, not just at call time but at tool pool assembly time via filterToolsByDenyRules.
ListMcpResourcesTool
Lists resources available from connected MCP servers.
Parameters
Optional server name to filter resources by. If omitted, lists resources from all connected servers.
Behavior
- Iterates over all connected MCP clients (or the specified server)
- Calls
fetchResourcesForClientwhich is LRU-cached and pre-warmed at startup - Cache is invalidated on connection close and on
resources/list_changednotifications - Uses
ensureConnectedClientto reconnect if a server has disconnected
Output
Returns an array of resource descriptors:
{
uri: string // Resource URI
name: string // Resource display name
mimeType?: string // MIME type
description?: string // Resource description
server: string // Server that provides this resource
}Key Properties
- Read-only: Yes
- Concurrency-safe: Yes
- Deferred: Yes
- maxResultSizeChars: 100,000
ReadMcpResourceTool
Reads a specific resource from an MCP server by URI.
Parameters
The MCP server name.
The resource URI to read.
Behavior
- Finds the specified MCP client by name
- Verifies the server is connected and supports the resources capability
- Sends a
resources/readrequest to the server - For binary content (blobs), persists the data to a temporary file and returns the file path
- For text content, returns the text directly
Output
{
contents: Array<{
uri: string // Resource URI
mimeType?: string // MIME type of the content
text?: string // Text content (for text resources)
blobSavedTo?: string // File path (for binary resources)
}>
}Key Properties
- Read-only: Yes
- Concurrency-safe: Yes
- Deferred: Yes
- maxResultSizeChars: 100,000
McpAuthTool
A pseudo-tool created for MCP servers that require authentication. It replaces the server's real tools until authentication is complete.
How It Works
When an MCP server fails to connect due to an HTTP 401 (UnauthorizedError), the system creates a single McpAuthTool in place of the server's real tools. This tool:
- Is named
mcp__<server>__authenticate - Describes the authentication requirement in its prompt so the model knows the server exists
- When called, starts the OAuth flow via
performMCPOAuthFlow - Returns an authorization URL for the user to visit
- Once authentication completes in the background, the server reconnects and its real tools replace this pseudo-tool
OAuth Flow
[Model calls mcp__server__authenticate]
|
v
performMCPOAuthFlow(skipBrowserOpen)
|
v
Returns { status: 'auth_url', authUrl: '...' }
|
v
User visits URL and authenticates
|
v
OAuth callback fires
|
v
reconnectMcpServerImpl() runs
|
v
Real tools replace auth tool in appState.mcp.toolsFor claude.ai MCP connectors (type: "claudeai-proxy"), the programmatic auth flow is not available. The tool instead instructs the user to run /mcp and authenticate through the MCP server menu.
Key Properties
- Auto-allowed: Yes (no permission prompt needed to start the auth flow)
- Concurrency-safe: No
Key Source Files
src/tools/MCPTool/MCPTool.ts: Base MCP tool templatesrc/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts: Resource listingsrc/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts: Resource readingsrc/tools/McpAuthTool/McpAuthTool.ts: OAuth authentication pseudo-toolsrc/services/mcp/client.ts: MCP client connection and tool registration