fix(zed): translate MCP servers, map the global default and write_file, use the Windows config dir - #2450
Merged
Merged
Conversation
…e, use the Windows config dir Zed silently ignores config keys it does not know, so several canonical fields used to produce settings Zed reads as something else - most seriously a server with disabled: true was emitted enabled. - MCP: translate canonical servers into the context_servers shapes Zed parses (disabled -> enabled: false, httpUrl -> url, array command -> string command + args), drop canonical-only keys, pass unknown fields through, skip sse/ws/url-less/command-less servers with a warning, write a transport-less server as the extension variant and import it into the zed-scoped block. - permissions: the canonical * category's catch-all now sets agent.tool_permissions.default instead of an inert tools['*'] entry (round-tripped, stale entry cleaned up), and canonical write maps to Zed's write_file tool. - global scope: resolve the user config dir to %APPDATA%/Zed on Windows for rules, MCP and permissions, with both spellings declared to the shared-write derivation and gateway ownership table. Refs #2415 (fixes gaps 1, 3, 4 and 7; gaps 2, 5, 6 stay open there). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…en MCP entry handling Review follow-ups on the previous commit: - toRulesyncPermissions read a stale tools['*'] entry (which Zed ignores) after the top-level default (which Zed enforces), so the ignored value overwrote the enforced one in the canonical model - a deny could come back as allow. The stale entry is now read only when no enforced default exists. - A transport-less server's canonical fields beyond disabled are dropped with a warning naming them, matching the Kilo toggle convention. - A null or array context_servers entry is skipped on import instead of crashing the run with a destructuring TypeError. - A non-boolean enabled value stays in place on import instead of having a disablement intent silently erased. Refs #2415 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Owner
Author
|
@dyoshikawa Thank you! |
This was referenced Jul 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes gaps 1, 3, 4 and 7 of #2415 (Refs #2415 — gaps 2, 5 and 6 are feature additions and stay open there). Zed silently ignores config keys it does not know, so several canonical fields used to produce settings Zed reads as something else — most seriously, a server the user disabled in rulesync was emitted enabled.
Changes
Gap 1 — MCP translation (
zed-mcp.ts).context_serversentries are now translated into the shapes Zed's untagged enum actually parses, instead of forwarding canonical fields verbatim:disabled: true→enabled: false(and imports back asdisabled: true); a server that says nothing aboutdisabledwrites noenabledkey.httpUrlis normalized to theurlZed reads; an arraycommandis flattened to Zed's single command string with the rest prepended toargs.type/transport,alwaysAllow,trust,cwd,networkTimeout, the Kiro lists…) are dropped — the drop list is derived fromMcpServerSchemaitself, so unknown fields (a remote server'soauth, an extension server'ssettings) pass through untouched.mcp-transport.tshelpers:sse/wstransports (Zed has neither), a remote server with no url, a local one with no command.zed.mcpServersblock rather than the shared map (mirroring the Kilo/OpenCode handling from fix(kilo): accept a bare MCP toggle entry, and type steps as the number it is #2448).Gap 3 — global tool-permission default (
zed-permissions.ts). The canonical*category's catch-all rule now setsagent.tool_permissions.default(rung 6 of Zed's precedence ladder, and the documented mechanism for MCP tools) instead of an inerttools["*"]entry. Round-tripped on import; a staletools["*"]entry written by an earlier version is cleaned up when the canonical config carries a*category; pattern-scoped*-category rules are dropped with a warning; a user-setdefaultsurvives when canonical says nothing.Gap 4 —
writemapping. Canonicalwritemaps to Zed'swrite_filetool (same class of bug as the fixedweb_search→search_web, #1850). Also corrected the stalewebsearch → web_searchclaim in the docs.Gap 7 — Windows global path.
getZedGlobalDir()resolves the user config dir to%APPDATA%\Zedon Windows (per Zed's docs) for rules, MCP and permissions. Both spellings are declared to the shared-write derivation viagetExtraSharedWritePathsand to the gateway ownership table, so the cross-check tests stay platform-complete; the zed-related e2e specs now use the platform-aware path.Verification
pnpm cicheckgreen (unit tests include new cases for every behavior above).e2e-mcp/e2e-permissions/e2e-rulesspecs pass locally.default,%APPDATA%\Zedpaths).🤖 Generated with Claude Code