Skip to content
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
"@anthropic-ai/sandbox-runtime": "0.0.42",
"@github/copilot": "^1.0.24",
"@github/copilot-sdk": "^0.2.2",
"@github/mcp-registry": "^0.1.5",
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@microsoft/dev-tunnels-connections": "^1.3.41",
Expand Down
23 changes: 23 additions & 0 deletions src/vs/base/common/defaultAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,35 @@ export interface IEntitlementsData extends ILegacyQuotaSnapshotData {
};
}

/**
* An enterprise MCP registry entry from the `copilot/mcp_registry` response
* that signals GitHub-native enterprise allowlist enforcement.
*/
export interface IMcpAllowlistEntry {
/** The enterprise registry base URL (e.g., "https://registry.github.com/mcp") */
readonly registryUrl: string;
/** The registry access level */
readonly registryAccess: 'allow_all' | 'registry_only';
/** The owner (org or enterprise) login */
readonly ownerLogin: string;
/** The owner (org or enterprise) numeric ID */
readonly ownerId: number;
/** The owner type (e.g., "Organization") */
readonly ownerType: string;
/** Parent enterprise login, if the owner is an org under an enterprise */
readonly parentLogin: string | null;
/** Priority for evaluation ordering */
readonly priority: number;
}

export interface IPolicyData {
readonly mcp?: boolean;
readonly chat_preview_features_enabled?: boolean;
readonly chat_agent_enabled?: boolean;
readonly mcpRegistryUrl?: string;
readonly mcpAccess?: 'allow_all' | 'registry_only';
/** Enterprise MCP allowlist entries discovered from `copilot/mcp_registry`. */
readonly mcpAllowlistEntries?: readonly IMcpAllowlistEntry[];
}

export interface ICopilotTokenInfo {
Expand Down
51 changes: 51 additions & 0 deletions src/vs/platform/mcp/common/mcpAllowListService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { CancellationToken } from '../../../base/common/cancellation.js';
import { IMarkdownString } from '../../../base/common/htmlContent.js';
import { createDecorator } from '../../instantiation/common/instantiation.js';

/**
* State of the enterprise MCP allow list service.
*/
export const enum McpAllowListState {
/** Enterprise allow list enforcement is not applicable (no enterprise entries). */
NotApplicable,
/** The allow list is currently being fetched. */
Loading,
/** The allow list has been loaded and is ready for enforcement. */
Ready,
/** The allow list could not be loaded (network failure, etc.). */
Unavailable,
}

/**
* Service that manages enterprise MCP server allow lists.
*
* When a user is in an enterprise with MCP allow list policies, this service
* fetches the allow list from the enterprise registry and gates server launches.
*/
export const IMcpAllowListService = createDecorator<IMcpAllowListService>('IMcpAllowListService');
export interface IMcpAllowListService {
readonly _serviceBrand: undefined;

/** State of the allow list service. */
readonly state: McpAllowListState;

/**
* Waits until the allow list is loaded or the service determines that
* enterprise allow list enforcement is not applicable. Returns immediately
* if already resolved.
*/
waitForReady(token?: CancellationToken): Promise<void>;

/**
* Checks whether a server (identified by its fingerprint) is allowed to run.
*
* @param fingerprint The computed SHA-256 fingerprint of the server's identity.
* @returns `true` if the server is allowed, or an `IMarkdownString` explaining why it was blocked.
*/
isAllowed(fingerprint: string): true | IMarkdownString;
}
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/git/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function getOrderedRemotes(repositoryState: GitRepositoryState): readonly GitRem
return Array.from(remotes.values());
}

function parseRemoteUrl(fetchUrl: string): { host: string; rawHost: string; path: string } | undefined {
export function parseRemoteUrl(fetchUrl: string): { host: string; rawHost: string; path: string } | undefined {
fetchUrl = fetchUrl.trim();
try {
// Normalize git shorthand syntax (git@github.com:user/repo.git) into an explicit ssh:// url
Expand Down
3 changes: 3 additions & 0 deletions src/vs/workbench/contrib/mcp/browser/mcp.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { SyncDescriptor } from '../../../../platform/instantiation/common/descri
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
import * as jsonContributionRegistry from '../../../../platform/jsonschemas/common/jsonContributionRegistry.js';
import { mcpAccessConfig, McpAccessValue } from '../../../../platform/mcp/common/mcpManagement.js';
import { IMcpAllowListService } from '../../../../platform/mcp/common/mcpAllowListService.js';
import { IQuickAccessRegistry, Extensions as QuickAccessExtensions } from '../../../../platform/quickinput/common/quickAccess.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { EditorPaneDescriptor, IEditorPaneRegistry } from '../../../browser/editor.js';
Expand Down Expand Up @@ -49,7 +50,9 @@ import { McpServerEditor } from './mcpServerEditor.js';
import { McpServerEditorInput } from './mcpServerEditorInput.js';
import { McpServersViewsContribution } from './mcpServersView.js';
import { MCPContextsInitialisation, McpWorkbenchService } from './mcpWorkbenchService.js';
import { McpAllowListService } from '../common/mcpAllowListService.js';

registerSingleton(IMcpAllowListService, McpAllowListService, InstantiationType.Delayed);
registerSingleton(IMcpRegistry, McpRegistry, InstantiationType.Delayed);
registerSingleton(IMcpSandboxService, McpSandboxService, InstantiationType.Delayed);
registerSingleton(IMcpService, McpService, InstantiationType.Delayed);
Expand Down
Loading
Loading