Skip to content

chat: migrate supported workspace MCP servers - #333286

Draft
Vritant Bhardwaj (vritant24) wants to merge 1 commit into
mainfrom
agents/migrate-supported-mcp-servers
Draft

chat: migrate supported workspace MCP servers#333286
Vritant Bhardwaj (vritant24) wants to merge 1 commit into
mainfrom
agents/migrate-supported-mcp-servers

Conversation

@vritant24

Copy link
Copy Markdown
Member

Summary

  • Adds a dedicated customization migration for supported MCP servers defined in workspace-folder .vscode/mcp.json files.
  • Lets users select individual servers and move them into the workspace-root .mcp.json consumed directly by Agent Host harnesses.
  • Preserves unsupported, disabled, out-of-scope, and unselected servers in their original configuration.
  • Refuses migrations that would drop behavior, expose resolved variables, overwrite conflicts, or race concurrent file changes.
Technical context for AI-assisted review

Intent and previous behavior

Agent Host support reporting can distinguish MCP configurations it can consume from configurations whose source or shape is unsupported. Supported workspace-folder servers were forwarded through the client because Agent Host discovers root .mcp.json files but not .vscode/mcp.json. The customizations experience reported compatibility but offered no way to move those servers into the runtime-native location.

Implementation

The customization migration service now projects eligible workspace-folder servers as individual migration candidates. Candidate discovery uses the active session's working-directory scope, current MCP enablement, support assessment, and the original source entry. Only configurations whose source and projected destination forms are equivalent are offered, excluding unresolved variables and destination-incompatible behavior.

MCP is registered as a separate migration category alongside prompt-file and user-data migrations. The shared migration page provides per-server selection, source and target paths, confirmation, completion feedback, and live refresh when the MCP inventory or active session roots change.

The file transaction merges selected entries into strict { "mcpServers": { ... } } JSON at each workspace root and removes only those entries from .vscode/mcp.json. Existing equivalent entries are deduplicated; conflicting entries are left untouched. Reads and writes retain file metadata for optimistic concurrency checks, and the destination is verified after the source update so a concurrent destination change restores the source entry.

Behavior and constraints

  • Migration is limited to enabled, applicable, fully supported .vscode/mcp.json servers.
  • Servers using unresolved variables, SSE transport, explicit working directories, environment files, sandbox or development behavior, OAuth configuration, or marketplace metadata are not offered when root discovery cannot preserve that behavior.
  • Existing root .mcp.json files must use strict JSON and the supported mcpServers wrapper.
  • Multi-root sessions resolve one destination per workspace folder.
  • Unselected and unsupported entries remain in the source file.
  • Prompt-file and user-data migrations remain independent categories with their existing behavior.

Review context

The main review boundary is data safety across two independently editable configuration files. Candidate eligibility is recomputed after confirmation, source contents are revalidated before deletion, writes use optimistic concurrency metadata, and post-write verification avoids reporting success when the destination changed concurrently.

Offer per-server migration from .vscode/mcp.json into the workspace-root
.mcp.json for Agent Host harnesses. Preserve behavior by limiting candidates
to configurations the destination can represent and guard cross-file updates
against conflicts and concurrent changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings August 28, 2026 23:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 2 High severity · 3 Medium severity

新建议题s introduced by this change (5)
Severity Finding
Medium severity src/​vs/​workbench/​contrib/​chat/​browser/​aiCustomization/​customizationMigration.ts — The existing destination entry is compared in raw JSON form while the candidate is canonicalized.…
High severity src/​vs/​workbench/​contrib/​chat/​browser/​aiCustomization/​customizationMigrationServiceImpl.ts — A stale support snapshot can still reference a source file that has just been deleted or become…
Medium severity src/​vs/​workbench/​contrib/​chat/​browser/​aiCustomization/​aiCustomizationManagementEditor.ts — Unlike the existing file-migration path, this call omits the error callback, so permission errors,…
Medium severity src/​vs/​workbench/​contrib/​chat/​browser/​aiCustomization/​aiCustomizationManagementEditor.ts — In a multi-root workspace, different folders can contain MCP servers with the same name, but both…
High severity src/​vs/​workbench/​contrib/​chat/​browser/​aiCustomization/​customizationMigration.ts — The optimistic metadata does not reject concurrent deletion of a file that existed at read time.…
What changed in this PR

Adds migration of supported workspace MCP servers from .vscode/mcp.json to Agent Host–native root .mcp.json files.

Changes:

  • Discovers and validates per-server migration candidates.
  • Adds guarded migration, conflict handling, and rollback logic.
  • Integrates MCP migration into the customization UI with tests.
File Description
aiCustomizationManagementEditor.fixture.ts Supplies the migration service with a file service.
mcpServerMigration.test.ts Tests migration safety and conflict handling.
customizationMigrationServiceImpl.test.ts Tests MCP candidate discovery.
customizationMigration.test.ts Tests MCP migration messaging.
aiCustomizationManagementEditor.test.ts Tests selection, rendering, and refresh behavior.
agentHostMcpServerSupport.test.ts Tests exclusion of explicit working directories.
customizationMigrationService.ts Defines MCP migration candidate contracts.
customizationMigrationServiceImpl.ts Computes eligible MCP migration candidates.
customizationMigrationCategories.ts Adds the MCP migration category and copy.
customizationMigration.ts Implements MCP file migration transactions.
aiCustomizationManagementEditor.ts Integrates MCP migration into the editor UI.
agentHostMcpServerSupport.ts Exposes persistable MCP configurations.
AI_CUSTOMIZATIONS.md Documents the expanded migration contract.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +381 to +385
if (Object.hasOwn(targetServers, candidate.name) && !equals(targetServers[candidate.name], migrationConfiguration)) {
failedServerNames.push(candidate.name);
onMigrationError?.(new Error(`MCP server '${candidate.name}' already exists with a different configuration in ${group.targetUri.toString()}.`));
continue;
}
Comment on lines +195 to +196
private async readMcpServers(resource: URI): Promise<Record<string, unknown> | undefined> {
const content = (await this.fileService.readFile(resource)).value.toString();
const currentServers = currentMigration.candidates.filter(server => selectedIds.has(server.id));
const currentIds = new Set(currentServers.map(server => server.id));
const noLongerEligibleServerNames = servers.filter(server => !currentIds.has(server.id)).map(server => server.name);
const { migratedCount, failedServerNames } = await migrateMcpServers(currentServers, this.fileService);
const renderSelectionCheckbox = (row: HTMLElement, customization: CustomizationMigrationCandidate, onSelectionChange?: () => void): Checkbox => {
const checkboxContainer = DOM.append(row, $('.item-sync-checkbox.prompt-migration-checkbox'));
const checkboxTitle = localize('customizationMigrationSelectAriaLabel', "Select {0}", customization.name ?? basename(customization.uri));
const checkboxTitle = localize('customizationMigrationSelectAriaLabel', "Select {0}", getCandidateName(customization));
Comment on lines +503 to +508
function writeJsonDocument(resource: URI, content: string, document: IJsonDocument, fileService: IFileService): Promise<IFileStatWithMetadata> {
if (document.exists) {
return fileService.writeFile(resource, VSBuffer.fromString(content), {
etag: document.etag,
mtime: document.mtime,
});
注册 for free to join this conversation on GitHub. Already have an account? 登录 to comment

标签

None yet

项目

None yet

Development

Successfully merging this pull request may close these issues.

2 participants