src/vs/platform/mcp/common/allowedMcpServers.ts

145 LOC · 141 covered · 4 uncovered · 29 ranges · 41 concepts · 17 introducers · 20 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

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 related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the fileallowedMcpServersService.ts ×1 · 3 introduced LOCallowedMcpServersService…allowedMcpServersService.test|title=AllowedMcpServersService isAllowed matches an installable stdio server by its command|occurrence=1 · 0 introduced LOCallowedMcpServersService…allowedMcpServersService.ts ×1 · 2 introduced LOCallowedMcpServersService…allowedMcpServersService.ts ×4 · 9 introduced LOCallowedMcpServersService…allowedMcpServersService.test|title=AllowedMcpServersService denylist blocks by remote URL wildcard even without an allowlist|occurrence=1 · 0 introduced LOCallowedMcpServersService…allowedMcpServersService.test|title=AllowedMcpServersService allowlist permits only matching servers|occurrence=1 · 0 introduced LOCallowedMcpServersService…allowedMcpServersService.ts ×1 · 1 introduced LOCallowedMcpServersService…allowedMcpServersService.test|title=AllowedMcpServersService denylist blocks a matching server even when it is also allowed|occurrence=1 · 0 introduced LOCallowedMcpServersService…allowedMcpServersService.ts ×1 · 1 introduced LOCallowedMcpServersService…allowedMcpServersService.ts ×1 · 2 introduced LOCallowedMcpServersService…allowedMcpServersService.ts ×1 · 5 introduced LOCallowedMcpServersService…allowedMcpServersService.ts ×7 · 40 introduced LOCallowedMcpServersService…allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed deny blocks even when no allowlist is configured|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched matches by local command as an ordered argument list|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.ts ×1 · 3 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched matches by remote URL with wildcards, case-insensitively|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched exact URL pattern matches only that URL|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.ts ×1 · 2 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.ts ×1 · 1 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.ts ×5 · 26 introduced LOCallowedMcpServers.ts ×5allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed allowlist permits only matching servers|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.ts ×2 · 9 introduced LOCallowedMcpServers.ts ×2allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed deny takes precedence over allow|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.ts ×1 · 2 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed empty allowlist blocks everything as NotAllowed|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed no lists configured allows everything|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched matches by server name|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.ts ×1 · 2 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.ts ×1 · 1 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.ts ×1 · 2 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.ts ×1 · 2 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.test|title=AllowedMcpServers getMcpServerMatchers coerces non-arrays to undefined|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers getMcpServerMatchers empty array is preserved|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.ts ×1 · 2 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.ts ×2 · 2 introduced LOCallowedMcpServers.ts ×2allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched undefined and empty match nothing|occurrence=1 · 0 introduced LOCallowedMcpServers.test|t…allowedMcpServers.ts ×1 · 2 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.ts ×1 · 2 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.ts ×1 · 2 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.ts ×1 · 1 introduced LOCallowedMcpServers.ts ×1allowedMcpServers.ts ×7 · 80 introduced LOCallowedMcpServers.ts ×7allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed allowlist permits only matching servers|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed allowlist permits only matching servers|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed deny blocks even when no allowlist is configured|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed deny blocks even when no allowlist is configured|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed deny takes precedence over allow|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed deny takes precedence over allow|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed empty allowlist blocks everything as NotAllowed|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed empty allowlist blocks everything as NotAllowed|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed no lists configured allows everything|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers checkMcpServerAllowed no lists configured allows everything|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers getMcpServerMatchers coerces non-arrays to undefined|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers getMcpServerMatchers coerces non-arrays to undefined|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers getMcpServerMatchers drops malformed and multi-field matcher entries|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers getMcpServerMatchers drops malformed and multi-field matcher entries|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers getMcpServerMatchers empty array is preserved|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers getMcpServerMatchers empty array is preserved|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched exact URL pattern matches only that URL|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched exact URL pattern matches only that URL|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched matches by local command as an ordered argument list|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched matches by local command as an ordered argument list|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched matches by remote URL with wildcards, case-insensitively|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched matches by remote URL with wildcards, case-insensitively|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched matches by server name|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched matches by server name|occurrence=1allowedMcpServers.test|t…allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched undefined and empty match nothing|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServers.test|title=AllowedMcpServers isMcpServerMatched undefined and empty match nothing|occurrence=1allowedMcpServers.test|t…allowedMcpServersService.test|title=AllowedMcpServersService allowlist permits only matching servers|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServersService.test|title=AllowedMcpServersService allowlist permits only matching servers|occurrence=1allowedMcpServersService…allowedMcpServersService.test|title=AllowedMcpServersService allows any server when nothing is configured|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServersService.test|title=AllowedMcpServersService allows any server when nothing is configured|occurrence=1allowedMcpServersService…allowedMcpServersService.test|title=AllowedMcpServersService blocks all servers when access is None|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServersService.test|title=AllowedMcpServersService blocks all servers when access is None|occurrence=1allowedMcpServersService…allowedMcpServersService.test|title=AllowedMcpServersService denylist blocks a matching server even when it is also allowed|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServersService.test|title=AllowedMcpServersService denylist blocks a matching server even when it is also allowed|occurrence=1allowedMcpServersService…allowedMcpServersService.test|title=AllowedMcpServersService denylist blocks by remote URL wildcard even without an allowlist|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServersService.test|title=AllowedMcpServersService denylist blocks by remote URL wildcard even without an allowlist|occurrence=1allowedMcpServersService…allowedMcpServersService.test|title=AllowedMcpServersService isAllowed matches an installable remote server by its URL|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServersService.test|title=AllowedMcpServersService isAllowed matches an installable remote server by its URL|occurrence=1allowedMcpServersService…allowedMcpServersService.test|title=AllowedMcpServersService isAllowed matches an installable stdio server by its command|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/mcp/test/common/allowedMcpServersService.test|title=AllowedMcpServersService isAllowed matches an installable stdio server by its command|occurrence=1allowedMcpServersService…Focused file · src/vs/platform/mcp/common/allowedMcpServers.ts · 145 LOCcommon/allowedMcpServers…

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- allowedMcpServers.ts ×7
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 { equals } from '../../../base/common/arrays.js';
7 > import { escapeRegExpCharacters } from '../../../base/common/strings.js';
8 > import { isObject, isString } from '../../../base/common/types.js';
9 >
10 > /**
11 > * A single entry in the `chat.mcp.allowedServers` allowlist. Identifies an MCP server by exactly
12 > * one strategy: its configured name, a remote server URL pattern (supporting `*` wildcards), or a
13 > * local stdio command invocation (matched as an ordered argument list). Delivered as JSON via user
14 > * settings or enterprise managed settings and validated at match time, so only the field matching
15 > * the intended strategy is meaningful.
16 > */
17 > export interface IMcpServerMatcher {
18 > readonly serverName?: string;
19 > readonly serverUrl?: string;
20 > readonly serverCommand?: readonly string[];
21 > }
22 >
23 > /**
24 > * Normalized identity of an MCP server used for allowlist matching. Both the install-time and the
25 > * runtime enforcement paths reduce their server representation to this shape: `url` is set for
26 > * remote (HTTP/SSE) servers and `command` (the full `[command, ...args]` invocation) for local
27 > * stdio servers.
28 > */
29 > export interface IMcpServerIdentity {
30 > readonly name: string;
31 > readonly url?: string;
32 > readonly command?: readonly string[];
33 > }
34 >
35 > /**
36 > * The result of evaluating an MCP server against the allow/deny lists.
37 > */
38 > export const enum McpServerAllowResult {
39 > /** Permitted: not denied, and either no allowlist is configured or it matches one. */
40 > Allowed,
41 > /** Blocked because it matches a deny entry (deny always wins). */
42 > Denied,
43 > /** Blocked because an allowlist is configured and it matches no entry. */
44 > NotAllowed,
45 > }
46 >
47 > /**
48 > * Coerces a resolved `chat.mcp.allowedServers` / `chat.mcp.deniedServers` configuration value into a
49 > * list of matchers. Returns `undefined` (meaning "not configured") when the value is not an array —
50 > * which is also how an unset setting surfaces (the registered `null` default). Malformed matcher
51 > * entries (non-objects, or entries that do not carry exactly one valid matching field) are dropped
52 > * so a bad payload degrades to "no match" rather than throwing during matching.
53 > */
54 > export function getMcpServerMatchers(value: unknown): readonly IMcpServerMatcher[] | undefined {
55 > if (!Array.isArray(value)) { allowedMcpServers.ts ×1
56 > return undefined; allowedMcpServers.ts ×1
57 > }
58 > return value.filter(isValidMatcher); allowedMcpServers.ts ×1
59 > }
61 > function isValidMatcher(entry: unknown): entry is IMcpServerMatcher { allowedMcpServers.ts ×2
62 > if (!isObject(entry)) {
63 > return false; allowedMcpServers.ts ×1
64 > }
65 > const { serverName, serverUrl, serverCommand } = entry as IMcpServerMatcher; allowedMcpServers.ts ×2
66 > const hasName = isString(serverName) && serverName.length > 0;
67 > const hasUrl = isString(serverUrl) && serverUrl.length > 0;
68 > const hasCommand = Array.isArray(serverCommand) && serverCommand.length > 0 && serverCommand.every(isString);
69 > // Exactly one matching strategy per the canonical schema's `oneOf`.
70 > return (hasName ? 1 : 0) + (hasUrl ? 1 : 0) + (hasCommand ? 1 : 0) === 1;
71 > }
73 > /**
74 > * Whether the server identity matches at least one of the given matchers. A `undefined` or empty
75 > * matcher list matches nothing.
76 > */
77 > export function isMcpServerMatched(matchers: readonly IMcpServerMatcher[] | undefined, identity: IMcpServerIdentity): boolean {
78 > return !!matchers && matchers.some(matcher => matchesMatcher(matcher, identity)); allowedMcpServers.ts ×1
79 > }
81 > /**
82 > * Evaluates an MCP server against the allow and deny lists. Deny always takes precedence; an unset
83 > * (`undefined`) allowlist imposes no restriction, while a configured allowlist requires a match.
84 > */
85 > export function checkMcpServerAllowed(allowlist: readonly IMcpServerMatcher[] | undefined, denylist: readonly IMcpServerMatcher[] | undefined, identity: IMcpServerIdentity): McpServerAllowResult {
86 > if (isMcpServerMatched(denylist, identity)) { allowedMcpServers.ts ×2
87 > return McpServerAllowResult.Denied; allowedMcpServers.ts ×1
88 > }
89 > if (allowlist !== undefined && !isMcpServerMatched(allowlist, identity)) { allowedMcpServers.ts ×2
90 > return McpServerAllowResult.NotAllowed; allowedMcpServers.ts ×1
91 > }
92 > return McpServerAllowResult.Allowed; allowedMcpServers.ts ×1
93 > }
95 > function matchesMatcher(matcher: IMcpServerMatcher, identity: IMcpServerIdentity): boolean { allowedMcpServers.ts ×1
96 > if (isString(matcher.serverName)) {
97 > return matcher.serverName === identity.name; allowedMcpServers.ts ×1
98 > }
99 > if (isString(matcher.serverUrl)) { allowedMcpServers.ts ×1
100 > return identity.url !== undefined && matchesUrlPattern(matcher.serverUrl, identity.url); allowedMcpServers.ts ×5
101 > }
102 > if (Array.isArray(matcher.serverCommand)) { allowedMcpServers.ts ×1
103 > return identity.command !== undefined && equals(matcher.serverCommand, identity.command);
104 > }
105 return false;
106 }
108 > /**
109 > * Matches a URL against a pattern that may contain `*` wildcards. Matching is case-insensitive,
110 > * anchored to the whole string, and every non-wildcard character is matched literally.
111 > *
112 > * Wildcard reach is region-aware so an authority wildcard cannot swallow the path: a `*` inside
113 > * the authority region (scheme + `//` + host/port, i.e. everything before the first `/` of the
114 > * path) matches any run of non-`/` characters, while a `*` in the path/query region matches any
115 > * run of characters. This prevents patterns like `https://*.example.com/*` from matching a URL
116 > * whose real host is untrusted, e.g. `https://evil.test/.example.com/tool`.
117 > */
118 > function matchesUrlPattern(pattern: string, url: string): boolean { allowedMcpServers.ts ×5
119 > const regexSource = buildUrlPatternRegexSource(pattern);
120 > try {
121 > return new RegExp(regexSource, 'i').test(url);
122 > } catch {
123 return false;
124 }
127 > function buildUrlPatternRegexSource(pattern: string): string { allowedMcpServers.ts ×5
128 > // The authority region spans from the start of the pattern up to (but not including) the first
129 > // `/` of the path. Wildcards there must not cross a `/` so they cannot consume path segments.
130 > const schemeSeparator = pattern.indexOf('://');
131 > const authorityStart = schemeSeparator >= 0 ? schemeSeparator + 3 : 0;
132 > const pathStart = pattern.indexOf('/', authorityStart);
133 > const authorityEnd = pathStart >= 0 ? pathStart : pattern.length;
134 >
135 > let source = '^';
136 > for (let i = 0; i < pattern.length; i++) {
137 > const char = pattern[i];
138 > if (char === '*') {
139 > source += i < authorityEnd ? '[^/]*' : '.*'; allowedMcpServers.ts ×1
140 > } else { allowedMcpServers.ts ×5
141 > source += escapeRegExpCharacters(char);
142 > }
143 > }
144 > return source + '$';
145 > }