mcpConfiguration.ts ×6

Frontier kind: Code frontier

unlabeled · c_62f782bb576e

75 tests · 24958 LOC · 129 files · introduces 0 tests · 511 LOC · 2 files

Introduces — evidence that enters the hierarchy at this concept

Code
7 ranges511 lines · 2 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
2547 ranges24958 lines · 129 files · Browse complete extent
All tests (intent)
75 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.

2 files ranked by introduced lines: 511 introduced LOC across 7 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/workbench/contrib/mcp/common/mcpConfiguration.ts 362 introduced LOC · 6 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- mcpConfiguration.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 { MarkdownString } from '../../../../base/common/htmlContent.js';
7 > import { IJSONSchema, IJSONSchemaMap } from '../../../../base/common/jsonSchema.js';
8 > import { Disposable } from '../../../../base/common/lifecycle.js';
9 > import { localize } from '../../../../nls.js';
10 > import { IExtensionManifest, IMcpCollectionContribution } from '../../../../platform/extensions/common/extensions.js';
11 > import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
12 > import { Registry } from '../../../../platform/registry/common/platform.js';
13 > import { mcpSchemaId } from '../../../services/configuration/common/configuration.js';
14 > import { inputsSchema } from '../../../services/configurationResolver/common/configurationResolverSchema.js';
15 > import { Extensions, IExtensionFeaturesRegistry, IExtensionFeatureTableRenderer, IRenderedData, IRowData, ITableData } from '../../../services/extensionManagement/common/extensionFeatures.js';
16 > import { IExtensionPointDescriptor } from '../../../services/extensions/common/extensionsRegistry.js';
17 >
18 > const mcpActivationEventPrefix = 'onMcpCollection:';
19 >
20 > /**
21 > * note: `contributedCollectionId` is _not_ the collection ID. The collection
22 > * ID is formed by passing the contributed ID through `extensionPrefixedIdentifier`
23 > */
24 > export const mcpActivationEvent = (contributedCollectionId: string) =>
25 mcpActivationEventPrefix + contributedCollectionId;
27 > export const enum DiscoverySource {
28 > ClaudeDesktop = 'claude-desktop',
29 > Windsurf = 'windsurf',
30 > CursorGlobal = 'cursor-global',
31 > CursorWorkspace = 'cursor-workspace',
32 > }
33 >
34 > export const allDiscoverySources = Object.keys({
35 > [DiscoverySource.ClaudeDesktop]: true,
36 > [DiscoverySource.Windsurf]: true,
37 > [DiscoverySource.CursorGlobal]: true,
38 > [DiscoverySource.CursorWorkspace]: true,
39 > } satisfies Record<DiscoverySource, true>) as DiscoverySource[];
40 >
41 > export const discoverySourceLabel: Record<DiscoverySource, string> = {
42 > [DiscoverySource.ClaudeDesktop]: localize('mcp.discovery.source.claude-desktop', "Claude Desktop"),
43 > [DiscoverySource.Windsurf]: localize('mcp.discovery.source.windsurf', "Windsurf"),
44 > [DiscoverySource.CursorGlobal]: localize('mcp.discovery.source.cursor-global', "Cursor (Global)"),
45 > [DiscoverySource.CursorWorkspace]: localize('mcp.discovery.source.cursor-workspace', "Cursor (Workspace)"),
46 > };
47 > export const discoverySourceSettingsLabel: Record<DiscoverySource, string> = {
48 > [DiscoverySource.ClaudeDesktop]: localize('mcp.discovery.source.claude-desktop.config', "Claude Desktop configuration (`claude_desktop_config.json`)"),
49 > [DiscoverySource.Windsurf]: localize('mcp.discovery.source.windsurf.config', "Windsurf configurations (`~/.codeium/windsurf/mcp_config.json`)"),
50 > [DiscoverySource.CursorGlobal]: localize('mcp.discovery.source.cursor-global.config', "Cursor global configuration (`~/.cursor/mcp.json`)"),
51 > [DiscoverySource.CursorWorkspace]: localize('mcp.discovery.source.cursor-workspace.config', "Cursor workspace configuration (`.cursor/mcp.json`)"),
52 > };
53 >
54 > export const mcpConfigurationSection = 'mcp';
55 > export const mcpDiscoverySection = 'chat.mcp.discovery.enabled';
56 > export const mcpServerSamplingSection = 'chat.mcp.serverSampling';
57 > export const mcpServerCollisionBehaviorSection = 'chat.mcp.collisionBehavior';
58 > /**
59 > * Configuration key for the enterprise-managed MCP IdP bag. The setting is
60 > * registered with `included: false` so it is hidden from the Settings UI and
61 > * settings.json IntelliSense; it is intended to be delivered through enterprise
62 > * policy (Windows Group Policy / macOS managed preferences / Linux
63 > * `/etc/vscode/policy.json`), with hand-editing of `settings.json` as a
64 > * developer escape hatch.
65 > */
66 > export const mcpEnterpriseManagedAuthIdpSection = 'mcp.enterpriseManagedAuth.idp';
67 >
68 > /**
69 > * Shape of the {@link mcpEnterpriseManagedAuthIdpSection} setting. All fields
70 > * are optional so partial configurations (e.g. just the issuer) remain valid.
71 > */
72 > export interface IMcpEnterpriseManagedAuthIdpConfig {
73 > readonly issuer?: string;
74 > readonly clientId?: string;
75 > readonly clientSecret?: string;
76 > }
77 >
78 > export const enum McpCollisionBehavior {
79 > Disable = 'disable',
80 > Suffix = 'suffix',
81 > }
82 >
83 > export interface IMcpServerSamplingConfiguration {
84 > allowedDuringChat?: boolean;
85 > allowedOutsideChat?: boolean;
86 > allowedModels?: string[];
87 > }
88 >
89 > export const mcpSchemaExampleServers = {
90 > 'mcp-server-time': {
91 > command: 'python',
92 > args: ['-m', 'mcp_server_time', '--local-timezone=America/Los_Angeles'],
93 > env: {},
94 > }
95 > };
96 >
97 > const httpSchemaExamples = {
98 > 'my-mcp-server': {
99 > url: 'http://localhost:3001/mcp',
100 > headers: {},
101 > }
102 > };
103 >
104 > const mcpDevModeProps = (stdio: boolean): IJSONSchemaMap => ({
105 > dev: {
106 > type: 'object',
107 > markdownDescription: localize('app.mcp.dev', 'Enabled development mode for the server. When present, the server will be started eagerly and output will be included in its output. Properties inside the `dev` object can configure additional behavior.'),
108 > examples: [{ watch: 'src/**/*.ts', debug: { type: 'node' } }],
109 > properties: {
110 > watch: {
111 > description: localize('app.mcp.dev.watch', 'A glob pattern or list of glob patterns relative to the workspace folder to watch. The MCP server will be restarted when these files change.'),
112 > examples: ['src/**/*.ts'],
113 > oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }],
114 > },
115 > ...(stdio && {
116 > debug: {
117 > markdownDescription: localize('app.mcp.dev.debug', 'If set, debugs the MCP server using the given runtime as it\'s started.'),
118 > oneOf: [
119 > {
120 > type: 'object',
121 > required: ['type'],
122 > properties: {
123 > type: {
124 > type: 'string',
125 > enum: ['node'],
126 > description: localize('app.mcp.dev.debug.type.node', "Debug the MCP server using Node.js.")
127 > }
128 > },
129 > additionalProperties: false
130 > },
131 > {
132 > type: 'object',
133 > required: ['type'],
134 > properties: {
135 > type: {
136 > type: 'string',
137 > enum: ['debugpy'],
138 > description: localize('app.mcp.dev.debug.type.python', "Debug the MCP server using Python and debugpy.")
139 > },
140 > debugpyPath: {
141 > type: 'string',
142 > description: localize('app.mcp.dev.debug.debugpyPath', "Path to the debugpy executable.")
143 > },
144 > },
145 > additionalProperties: false
146 > }
147 > ]
148 > }
149 > })
150 > }
151 > }
152 > });
153 >
154 > export const mcpStdioServerSchema: IJSONSchema = {
155 > type: 'object',
156 > additionalProperties: false,
157 > examples: [mcpSchemaExampleServers['mcp-server-time']],
158 > properties: {
159 > type: {
160 > type: 'string',
161 > enum: ['stdio'],
162 > description: localize('app.mcp.json.type', "The type of the server.")
163 > },
164 > sandboxEnabled: {
165 > type: 'boolean',
166 > default: false,
167 > description: localize('app.mcp.json.sandboxEnabled', "Whether to run the server in a sandboxed environment.")
168 > },
169 > command: {
170 > type: 'string',
171 > description: localize('app.mcp.json.command', "The command to run the server.")
172 > },
173 > cwd: {
174 > type: 'string',
175 > description: localize('app.mcp.json.cwd', "The working directory for the server command. Defaults to the workspace folder when run in a workspace."),
176 > examples: ['${workspaceFolder}'],
177 > },
178 > args: {
179 > type: 'array',
180 > description: localize('app.mcp.args.command', "Arguments passed to the server."),
181 > items: {
182 > type: 'string'
183 > },
184 > },
185 > envFile: {
186 > type: 'string',
187 > description: localize('app.mcp.envFile.command', "Path to a file containing environment variables for the server."),
188 > examples: ['${workspaceFolder}/.env'],
189 > },
190 > env: {
191 > description: localize('app.mcp.env.command', "Environment variables passed to the server."),
192 > additionalProperties: {
193 > anyOf: [
194 > { type: 'null' },
195 > { type: 'string' },
196 > { type: 'number' },
197 > ]
198 > }
199 > },
200 > ...mcpDevModeProps(true),
201 > }
202 > };
203 >
204 > export const mcpServerSchema: IJSONSchema = {
205 > id: mcpSchemaId,
206 > type: 'object',
207 > title: localize('app.mcp.json.title', "Model Context Protocol Servers"),
208 > allowTrailingCommas: true,
209 > allowComments: true,
210 > additionalProperties: false,
211 > properties: {
212 > sandbox: {
213 > description: localize('app.mcp.json.sandbox', "Sandbox config that determines file system and network access. Sandboxing is enabled when sandboxEnabled property is set at the server level on Mac OS and Linux only."),
214 > type: 'object',
215 > additionalProperties: false,
216 > properties: {
217 > network: {
218 > description: localize('app.mcp.json.sandbox.network', "Network access settings for the sandboxed server."),
219 > type: 'object',
220 > additionalProperties: false,
221 > properties: {
222 > allowedDomains: {
223 > description: localize('app.mcp.json.sandbox.network.allowedDomains', "List of domains that the server is allowed to access. Wildcards are supported, e.g. `*.example.com`."),
224 > type: 'array',
225 > items: { type: 'string' },
226 > default: []
227 > },
228 > deniedDomains: {
229 > description: localize('app.mcp.json.sandbox.network.deniedDomains', "List of domains that the server is not allowed to access. e.g. `invalid.example.com`."),
230 > type: 'array',
231 > items: { type: 'string' },
232 > default: []
233 > }
234 > }
235 > },
236 > filesystem: {
237 > description: localize('app.mcp.json.sandbox.filesystem', "Filesystem access settings for the sandboxed server. Glob patterns are supported for Mac OS only."),
238 > type: 'object',
239 > additionalProperties: false,
240 > properties: {
241 > denyRead: {
242 > description: localize('app.mcp.json.sandbox.filesystem.denyRead', "List of file paths that the server is not allowed to read. By default, all files are allowed to be read. e.g. `~/src/secrets`."),
243 > type: 'array',
244 > items: { type: 'string' },
245 > default: []
246 > },
247 > allowWrite: {
248 > description: localize('app.mcp.json.sandbox.filesystem.allowWrite', "List of file paths that the server is allowed to write to. e.g. `~/src/`."),
249 > type: 'array',
250 > items: { type: 'string' },
251 > default: []
252 > },
253 > denyWrite: {
254 > description: localize('app.mcp.json.sandbox.filesystem.denyWrite', "List of file paths that the server is not allowed to write to. e.g. `~/src/auth/`."),
255 > type: 'array',
256 > items: { type: 'string' },
257 > default: []
258 > }
259 > }
260 > }
261 > }
262 > },
263 > servers: {
264 > examples: [
265 > mcpSchemaExampleServers,
266 > httpSchemaExamples,
267 > ],
268 > additionalProperties: {
269 > oneOf: [
270 > mcpStdioServerSchema, {
271 > type: 'object',
272 > additionalProperties: false,
273 > required: ['url'],
274 > examples: [httpSchemaExamples['my-mcp-server']],
275 > properties: {
276 > type: {
277 > type: 'string',
278 > enum: ['http', 'sse'],
279 > description: localize('app.mcp.json.type', "The type of the server.")
280 > },
281 > url: {
282 > type: 'string',
283 > format: 'uri',
284 > pattern: '^https?:\\/\\/.+',
285 > patternErrorMessage: localize('app.mcp.json.url.pattern', "The URL must start with 'http://' or 'https://'."),
286 > description: localize('app.mcp.json.url', "The URL of the Streamable HTTP or SSE endpoint.")
287 > },
288 > headers: {
289 > type: 'object',
290 > description: localize('app.mcp.json.headers', "Additional headers sent to the server."),
291 > additionalProperties: { type: 'string' },
292 > },
293 > oauth: {
294 > type: 'object',
295 > description: localize('app.mcp.json.oauth', "OAuth configuration for authenticating with the server."),
296 > additionalProperties: false,
297 > minProperties: 1,
298 > properties: {
299 > clientId: {
300 > type: 'string',
301 > minLength: 1,
302 > markdownDescription: localize('app.mcp.json.oauth.clientId', "The OAuth client ID to use when authenticating with the server. When `enterpriseManaged` is `true`, this is the **resource** authorization server's client ID (the client trusted by the protected resource), not the IdP's. To set the matching client secret, use the *Set Client Secret* code lens above this field — secrets are stored in the OS secret store, not in this file.")
303 > },
304 > enterpriseManaged: {
305 > type: 'boolean',
306 > default: false,
307 > markdownDescription: localize('app.mcp.json.oauth.enterpriseManaged', "(Preview) When set to `true`, this MCP server authenticates through the SSO issuer configured by `#mcp.enterpriseManagedAuth.idp#` using OAuth Identity Assertion Authorization Grant (ID-JAG). After a one-time sign-in, subsequent enterprise-managed servers connect silently. The IdP issuer and client credentials are read from the `#mcp.enterpriseManagedAuth.idp#` setting; the `clientId` on this server entry is passed to the resource authorization server.")
308 > }
309 > }
310 > },
311 > ...mcpDevModeProps(false),
312 > }
313 > },
314 > ]
315 > }
316 > },
317 > inputs: inputsSchema.definitions!.inputs
318 > }
319 > };
320 >
321 > export const mcpContributionPoint: IExtensionPointDescriptor<IMcpCollectionContribution[]> = {
322 > extensionPoint: 'mcpServerDefinitionProviders',
323 > activationEventsGenerator: function* (contribs) {
324 for (const contrib of contribs) {
325 if (contrib.id) {
328 }
329 },
330 > jsonSchema: { mcpConfiguration.ts
331 > description: localize('vscode.extension.contributes.mcp', 'Contributes Model Context Protocol servers. Users of this should also use `vscode.lm.registerMcpServerDefinitionProvider`.'),
332 > type: 'array',
333 > defaultSnippets: [{ body: [{ id: '', label: '' }] }],
334 > items: {
335 > additionalProperties: false,
336 > type: 'object',
337 > defaultSnippets: [{ body: { id: '', label: '' } }],
338 > properties: {
339 > id: {
340 > description: localize('vscode.extension.contributes.mcp.id', "Unique ID for the collection."),
341 > type: 'string'
342 > },
343 > label: {
344 > description: localize('vscode.extension.contributes.mcp.label', "Display name for the collection."),
345 > type: 'string'
346 > },
347 > when: {
348 > description: localize('vscode.extension.contributes.mcp.when', "Condition which must be true to enable this collection."),
349 > type: 'string'
350 > }
351 > }
352 > }
353 > }
354 > };
355 >
356 class McpServerDefinitionsProviderRenderer extends Disposable implements IExtensionFeatureTableRenderer {
357
358 readonly type = 'table';
360 > shouldRender(manifest: IExtensionManifest): boolean {
361 return !!manifest.contributes?.mcpServerDefinitionProviders && Array.isArray(manifest.contributes.mcpServerDefinitionProviders) && manifest.contributes.mcpServerDefinitionProviders.length > 0;
362 }
364 > render(manifest: IExtensionManifest): IRenderedData<ITableData> {
365 const mcpServerDefinitionProviders = manifest.contributes?.mcpServerDefinitionProviders ?? [];
366 const headers = [localize('id', "ID"), localize('name', "Name")];
381 };
382 }
384 >
385 > Registry.as<IExtensionFeaturesRegistry>(Extensions.ExtensionFeaturesRegistry).registerExtensionFeature({
386 > id: mcpConfigurationSection,
387 > label: localize('mcpServerDefinitionProviders', "MCP Servers"),
388 > access: {
389 > canToggle: false
390 > },
391 > renderer: new SyncDescriptor(McpServerDefinitionsProviderRenderer),
392 > });
393
src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts 149 introduced LOC · 1 range

Open complete file

1 > /*--------------------------------------------------------------------------------------------- configurationResolverSchema.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 * as nls from '../../../../nls.js';
7 > import { IJSONSchema } from '../../../../base/common/jsonSchema.js';
8 >
9 > const idDescription = nls.localize('JsonSchema.input.id', "The input's id is used to associate an input with a variable of the form ${input:id}.");
10 > const typeDescription = nls.localize('JsonSchema.input.type', "The type of user input prompt to use.");
11 > const descriptionDescription = nls.localize('JsonSchema.input.description', "The description is shown when the user is prompted for input.");
12 > const defaultDescription = nls.localize('JsonSchema.input.default', "The default value for the input.");
13 >
14 >
15 > export const inputsSchema: IJSONSchema = {
16 > definitions: {
17 > inputs: {
18 > type: 'array',
19 > description: nls.localize('JsonSchema.inputs', 'User inputs. Used for defining user input prompts, such as free string input or a choice from several options.'),
20 > items: {
21 > oneOf: [
22 > {
23 > type: 'object',
24 > required: ['id', 'type', 'description'],
25 > additionalProperties: false,
26 > properties: {
27 > id: {
28 > type: 'string',
29 > description: idDescription
30 > },
31 > type: {
32 > type: 'string',
33 > description: typeDescription,
34 > enum: ['promptString'],
35 > enumDescriptions: [
36 > nls.localize('JsonSchema.input.type.promptString', "The 'promptString' type opens an input box to ask the user for input."),
37 > ]
38 > },
39 > description: {
40 > type: 'string',
41 > description: descriptionDescription
42 > },
43 > default: {
44 > type: 'string',
45 > description: defaultDescription
46 > },
47 > password: {
48 > type: 'boolean',
49 > description: nls.localize('JsonSchema.input.password', "Controls if a password input is shown. Password input hides the typed text."),
50 > },
51 > }
52 > },
53 > {
54 > type: 'object',
55 > required: ['id', 'type', 'description', 'options'],
56 > additionalProperties: false,
57 > properties: {
58 > id: {
59 > type: 'string',
60 > description: idDescription
61 > },
62 > type: {
63 > type: 'string',
64 > description: typeDescription,
65 > enum: ['pickString'],
66 > enumDescriptions: [
67 > nls.localize('JsonSchema.input.type.pickString', "The 'pickString' type shows a selection list."),
68 > ]
69 > },
70 > description: {
71 > type: 'string',
72 > description: descriptionDescription
73 > },
74 > default: {
75 > type: 'string',
76 > description: defaultDescription
77 > },
78 > options: {
79 > type: 'array',
80 > description: nls.localize('JsonSchema.input.options', "An array of strings that defines the options for a quick pick."),
81 > items: {
82 > oneOf: [
83 > {
84 > type: 'string'
85 > },
86 > {
87 > type: 'object',
88 > required: ['value'],
89 > additionalProperties: false,
90 > properties: {
91 > label: {
92 > type: 'string',
93 > description: nls.localize('JsonSchema.input.pickString.optionLabel', "Label for the option.")
94 > },
95 > value: {
96 > type: 'string',
97 > description: nls.localize('JsonSchema.input.pickString.optionValue', "Value for the option.")
98 > }
99 > }
100 > }
101 > ]
102 > }
103 > }
104 > }
105 > },
106 > {
107 > type: 'object',
108 > required: ['id', 'type', 'command'],
109 > additionalProperties: false,
110 > properties: {
111 > id: {
112 > type: 'string',
113 > description: idDescription
114 > },
115 > type: {
116 > type: 'string',
117 > description: typeDescription,
118 > enum: ['command'],
119 > enumDescriptions: [
120 > nls.localize('JsonSchema.input.type.command', "The 'command' type executes a command."),
121 > ]
122 > },
123 > command: {
124 > type: 'string',
125 > description: nls.localize('JsonSchema.input.command.command', "The command to execute for this input variable.")
126 > },
127 > args: {
128 > oneOf: [
129 > {
130 > type: 'object',
131 > description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.")
132 > },
133 > {
134 > type: 'array',
135 > description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.")
136 > },
137 > {
138 > type: 'string',
139 > description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.")
140 > }
141 > ]
142 > }
143 > }
144 > }
145 > ]
146 > }
147 > }
148 > }
149 > };