claudeClientToolMcpServer.ts ×4

Frontier kind: Code frontier

unlabeled · c_ce4ea448e264

319 tests · 3523 LOC · 21 files · introduces 0 tests · 72 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
4 ranges72 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
491 ranges3523 lines · 21 files · Browse complete extent
All tests (intent)
319 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 72 introduced LOC across 4 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/claude/clientTools/claudeClientToolMcpServer.ts 72 introduced LOC · 4 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- claudeClientToolMcpServer.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import type { McpSdkServerConfigWithInstance } from '@anthropic-ai/claude-agent-sdk';
7 > import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
8 > import type { ToolDefinition } from '../../../common/state/protocol/state.js';
9 > import type { IClaudeAgentSdkService } from '../claudeAgentSdkService.js';
10 > import { jsonSchemaToZodRawShape } from './claudeJsonSchemaToZod.js';
11 >
12 > /**
13 > * Anthropic SDK contract: the in-process MCP `tool()` handler receives a
14 > * `RequestHandlerExtra` whose `_meta` carries the originating
15 > * `tool_use_id` under this namespaced key. Verified empirically against
16 > * `@anthropic-ai/[email protected]`. If a future SDK version drops
17 > * or renames this field, the handler returns an error result instead of
18 > * silently deadlocking — see {@link extractToolUseId}.
19 > */
20 > const TOOL_USE_ID_META_KEY = 'claudecode/toolUseId';
21 >
22 > /**
23 > * Build the per-session in-process MCP server that surfaces the workbench
24 > * client's {@link ToolDefinition}s to the Claude SDK via
25 > * `Options.mcpServers['client']`.
26 > *
27 > * Each tool's handler reads the originating `tool_use_id` from the SDK's
28 > * `extra._meta["claudecode/toolUseId"]` and delegates to `awaitResult`,
29 > * which is expected to return a promise that settles when the workbench
30 > * echoes a completion (typically via a parked deferred owned by the
31 > * session). Keeping that plumbing behind a callback lets this factory
32 > * stay ignorant of how the host tracks in-flight tool calls.
33 > *
34 > * Pure factory — no SDK loading, no I/O.
35 > */
36 export async function buildClientToolMcpServer(
37 snapshot: readonly ToolDefinition[],
59 return sdk.createSdkMcpServer({ name: CLAUDE_CLIENT_MCP_SERVER_NAME, tools });
60 }
62 > /**
63 > * Recover the SDK-supplied `tool_use_id` from the MCP `tool()` handler's
64 > * `extra` argument. Returns `undefined` (and the handler degrades to an
65 > * error result) if the SDK ever drops the meta field — preferable to
66 > * deadlocking the call.
67 > */
68 > export function extractToolUseId(extra: unknown): string | undefined {
69 if (!extra || typeof extra !== 'object') {
70 return undefined;
77 return typeof value === 'string' ? value : undefined;
78 }
80 > /**
81 > * Name of the single in-process MCP server we register client tools on.
82 > * Exported so the stream mapper can strip the SDK's `mcp__<server>__` name
83 > * prefix before stamping `ChatToolCallStart.toolClientId`.
84 > */
85 > export const CLAUDE_CLIENT_MCP_SERVER_NAME = 'client';
86 >
87 > /**
88 > * Per the Anthropic SDK's MCP server naming convention, an in-process MCP
89 > * server registered as `Options.mcpServers[<serverName>]` surfaces its
90 > * tools to the model with names of the form `mcp__<serverName>__<toolName>`.
91 > * The stream mapper must strip the prefix before the workbench (which
92 > * registered tools by their unprefixed `ToolDefinition.name`) can
93 > * recognize them as client tools.
94 > *
95 > * Returns the input unchanged when it doesn't carry the prefix (SDK-owned
96 > * tools, subagent spawn tools, etc.) so non-client-tool calls flow
97 > * through without interference.
98 > */
99 > export function stripClientToolNamePrefix(toolName: string): string {
100 const prefix = `mcp__${CLAUDE_CLIENT_MCP_SERVER_NAME}__`;
101 return toolName.startsWith(prefix) ? toolName.slice(prefix.length) : toolName;
102 }
104 > /**
105 > * Whether the SDK-emitted tool name carries the in-process MCP server
106 > * prefix, i.e. the tool is one of the workbench's client-provided tools.
107 > * Used by the stream mapper to set `ChatToolCallStart.toolClientId` so
108 > * the workbench takes the client-tool invocation branch.
109 > */
110 > export function hasClientToolNamePrefix(toolName: string): boolean {
111 return toolName.startsWith(`mcp__${CLAUDE_CLIENT_MCP_SERVER_NAME}__`);
112 }