豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit 1761632

Browse files
digitaraldHarald KirschnerCopilot
authored
Add githubMcpServer.channel setting for MCP Insiders mode (#4946)
* Add githubMcpServer.channel setting for MCP Insiders mode * Address review: add union type and unit tests for channel setting --------- Co-authored-by: Harald Kirschner <digitarald@gmail.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: digitarald <8599+digitarald@users.noreply.github.com>
1 parent 1a089d9 commit 1761632

File tree

5 files changed

+79
-0
lines changed

5 files changed

+79
-0
lines changed

package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3330,6 +3330,22 @@
33303330
"experimental"
33313331
]
33323332
},
3333+
"github.copilot.chat.githubMcpServer.channel": {
3334+
"type": "string",
3335+
"default": "stable",
3336+
"enum": [
3337+
"stable",
3338+
"insiders"
3339+
],
3340+
"enumDescriptions": [
3341+
"%github.copilot.config.githubMcpServer.channel.stable%",
3342+
"%github.copilot.config.githubMcpServer.channel.insiders%"
3343+
],
3344+
"markdownDescription": "%github.copilot.config.githubMcpServer.channel%",
3345+
"tags": [
3346+
"experimental"
3347+
]
3348+
},
33333349
"github.copilot.chat.switchAgent.enabled": {
33343350
"type": "boolean",
33353351
"default": false,

package.nls.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,9 @@
469469
"github.copilot.config.githubMcpServer.toolsets": "Specify toolsets to use from the GitHub MCP Server. [Learn more](https://aka.ms/vscode-gh-mcp-toolsets).",
470470
"github.copilot.config.githubMcpServer.readonly": "Enable read-only mode for the GitHub MCP Server. When enabled, only read tools are available. [Learn more](https://aka.ms/vscode-gh-mcp-readonly).",
471471
"github.copilot.config.githubMcpServer.lockdown": "Enable lockdown mode for the GitHub MCP Server. When enabled, hides public issue details created by users without push access. [Learn more](https://aka.ms/vscode-gh-mcp-lockdown).",
472+
"github.copilot.config.githubMcpServer.channel": "Select the channel for the GitHub MCP Server. When set to Insiders, enables access to experimental features that may change or be removed based on community feedback. [Learn more](https://aka.ms/vscode-gh-mcp-channel).",
473+
"github.copilot.config.githubMcpServer.channel.stable": "Use the stable version of the GitHub MCP Server.",
474+
"github.copilot.config.githubMcpServer.channel.insiders": "Connect to the Insiders version of the GitHub MCP Server with experimental features.",
472475
"copilot.tools.runSubagent.name": "Run Subagent",
473476
"copilot.tools.runSubagent.description": "Runs a task within an isolated subagent context. Enables efficient organization of tasks and context window management.",
474477
"copilot.tools.searchSubagent.name": "Search Subagent",

src/extension/githubMcp/common/githubMcpDefinitionProvider.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider<
4141
logService.debug('GitHubMcpDefinitionProvider: Configuration change affects GitHub MCP lockdown mode.');
4242
return true;
4343
}
44+
// If they change the channel
45+
if (e.affectsConfiguration(ConfigKey.GitHubMcpChannel.fullyQualifiedId)) {
46+
logService.debug('GitHubMcpDefinitionProvider: Configuration change affects GitHub MCP channel.');
47+
return true;
48+
}
4449
// If they change to GHE or GitHub.com
4550
if (e.affectsConfiguration(ConfigKey.Shared.AuthProvider.fullyQualifiedId)) {
4651
logService.debug('GitHubMcpDefinitionProvider: Configuration change affects GitHub auth provider.');
@@ -82,6 +87,10 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider<
8287
return this.configurationService.getConfig<boolean>(ConfigKey.GitHubMcpLockdown);
8388
}
8489

90+
private get channel(): ConfigKey.GitHubMcpChannelValue {
91+
return this.configurationService.getConfig<ConfigKey.GitHubMcpChannelValue>(ConfigKey.GitHubMcpChannel);
92+
}
93+
8594
private get gheConfig(): string | undefined {
8695
return this.configurationService.getNonExtensionConfig<string>(EnterpriseURLConfig);
8796
}
@@ -101,6 +110,7 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider<
101110
const toolsets = this.toolsets.sort().join(',');
102111
const readonly = this.readonly;
103112
const lockdown = this.lockdown;
113+
const channel = this.channel;
104114
const isSignedIn = !!this.authenticationService.permissiveGitHubSession;
105115

106116
const basics = providerId === AuthProviderId.GitHubEnterprise
@@ -124,6 +134,10 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider<
124134
headers['X-MCP-Lockdown'] = 'true';
125135
version += '|lockdown';
126136
}
137+
if (channel === 'insiders') {
138+
headers['X-MCP-Insiders'] = 'true';
139+
version += '|insiders';
140+
}
127141
} else {
128142
version = 'signedout';
129143
}

src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ describe('GitHubMcpDefinitionProvider', () => {
8282
toolsets?: string[];
8383
readonly?: boolean;
8484
lockdown?: boolean;
85+
channel?: ConfigKey.GitHubMcpChannelValue;
8586
hasPermissiveToken?: boolean;
8687
}): Promise<GitHubMcpDefinitionProvider> {
8788
const serviceCollection = new TestingServiceCollection();
@@ -103,6 +104,9 @@ describe('GitHubMcpDefinitionProvider', () => {
103104
if (configOverrides?.lockdown !== undefined) {
104105
await configService.setConfig(ConfigKey.GitHubMcpLockdown, configOverrides.lockdown);
105106
}
107+
if (configOverrides?.channel !== undefined) {
108+
await configService.setConfig(ConfigKey.GitHubMcpChannel, configOverrides.channel);
109+
}
106110

107111
serviceCollection.define(IConfigurationService, configService);
108112
serviceCollection.define(ICopilotTokenStore, new SyncDescriptor(CopilotTokenStore));
@@ -251,6 +255,38 @@ describe('GitHubMcpDefinitionProvider', () => {
251255
expect(definitions[0].version).toBe('default|readonly|lockdown');
252256
});
253257

258+
test('includes X-MCP-Insiders header when channel is insiders', async () => {
259+
const insidersProvider = await createProvider({ channel: 'insiders' });
260+
261+
const definitions = insidersProvider.provideMcpServerDefinitions();
262+
263+
expect(definitions[0].headers['X-MCP-Insiders']).toBe('true');
264+
});
265+
266+
test('does not include X-MCP-Insiders header when channel is stable', async () => {
267+
const stableProvider = await createProvider({ channel: 'stable' });
268+
269+
const definitions = stableProvider.provideMcpServerDefinitions();
270+
271+
expect(definitions[0].headers['X-MCP-Insiders']).toBeUndefined();
272+
});
273+
274+
test('version includes insiders flag when channel is insiders', async () => {
275+
const insidersProvider = await createProvider({ channel: 'insiders' });
276+
277+
const definitions = insidersProvider.provideMcpServerDefinitions();
278+
279+
expect(definitions[0].version).toBe('default|insiders');
280+
});
281+
282+
test('version includes all flags when readonly, lockdown, and insiders are set', async () => {
283+
const allFlagsProvider = await createProvider({ readonly: true, lockdown: true, channel: 'insiders' });
284+
285+
const definitions = allFlagsProvider.provideMcpServerDefinitions();
286+
287+
expect(definitions[0].version).toBe('default|readonly|lockdown|insiders');
288+
});
289+
254290
test('version is just toolsets when readonly and lockdown are false', async () => {
255291
const toolsets = ['issues', 'pull_requests'];
256292
const normalProvider = await createProvider({ toolsets, readonly: false, lockdown: false });
@@ -327,6 +363,14 @@ describe('GitHubMcpDefinitionProvider', () => {
327363

328364
await eventPromise;
329365
});
366+
367+
test('fires when channel configuration changes', async () => {
368+
const eventPromise = Event.toPromise(provider.onDidChangeMcpServerDefinitions);
369+
370+
await configService.setConfig(ConfigKey.GitHubMcpChannel, 'insiders');
371+
372+
await eventPromise;
373+
});
330374
});
331375

332376
describe('edge cases', () => {

src/platform/configuration/common/configurationService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,8 @@ export namespace ConfigKey {
977977
export const GitHubMcpToolsets = defineSetting<string[]>('chat.githubMcpServer.toolsets', ConfigType.Simple, ['default']);
978978
export const GitHubMcpReadonly = defineSetting<boolean>('chat.githubMcpServer.readonly', ConfigType.Simple, false);
979979
export const GitHubMcpLockdown = defineSetting<boolean>('chat.githubMcpServer.lockdown', ConfigType.Simple, false);
980+
export type GitHubMcpChannelValue = 'stable' | 'insiders';
981+
export const GitHubMcpChannel = defineSetting<GitHubMcpChannelValue>('chat.githubMcpServer.channel', ConfigType.Simple, 'stable');
980982

981983
export const GetSearchResultsViewSkill = defineSetting<boolean>('chat.getSearchViewResultsSkill.enabled', ConfigType.ExperimentBased, false);
982984

0 commit comments

Comments
 (0)