Skip to content

fix(mcp): align Claude Code user/project MCP command strings#204

Merged
zzet merged 1 commit into
mainfrom
fix/mcp-scope-conflict
Jun 30, 2026
Merged

fix(mcp): align Claude Code user/project MCP command strings#204
zzet merged 1 commit into
mainfrom
fix/mcp-scope-conflict

Conversation

@zzet

@zzet zzet commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Closes #201.

What the issue was

The "MCP config diagnostics ⚠ / Conflicting scopes" message is emitted by Claude Code, not Gortex — no crash, no failed tool call. Claude Code stores OAuth tokens per endpoint (command + args), and the reporter had gortex registered in two scopes with two different command strings:

Scope Endpoint
user C:\Users\daoti\AppData\Local\Programs\gortex\gortex.exe mcp
project gortex mcp

Root cause

The two registration paths wrote the command differently. The project .mcp.json template (ProjectMCPJSON) hardcodes the portable bare "gortex", while the global install path (upsertGlobalMCPConfig) hand-rolled an absolute os.Executable() path. On a machine with both scopes populated, the strings disagree and Claude Code flags it.

Fix

Make the strings agree (the source of the conflict):

  • Add agents.ResolveGortexCommand() — prefers bare "gortex" when it resolves on PATH to the same running binary, falling back to the absolute path only when gortex is genuinely not on PATH (e.g. a Windows install dir not on PATH). The global entry now matches the portable project template.
  • upsertGlobalMCPConfig now uses UpsertMCPServerWithMigration instead of UpsertMCPServer, and IsGortexAuthoredMCPEntry recognizes the legacy absolute-path form — so an older …\gortex.exe stanza is rewritten in place on the next gortex install rather than left behind (otherwise the warning would persist after upgrade).

Catch the cases that can't be unified:

  • Project-mode init warns and skips writing .mcp.json when gortex is already registered at user scope (override with --force, e.g. to commit a .mcp.json for teammates without a global install). When a .mcp.json already exists alongside a user-scope entry, it warns and points at claude mcp remove.

Net effect for the reporter

After upgrading and re-running gortex install, the migration rewrites their C:\…\gortex.exe user-scope stanza to bare gortex (their working bare-command project entry implies gortex is on PATH), matching .mcp.json — and the warning clears on its own.

Tests

All pass under -race:

  • TestResolveGortexCommandFrom — 5 cases incl. not-on-PATH Windows path and same-vs-different-binary.
  • TestIsGortexAuthoredMCPEntryAbsolutePath — incl. the literal issue-Conflicting scopes #201 Windows path; user wrapper scripts still preserved.
  • TestProjectModeSkipsMCPWhenUserScopeRegistered / TestProjectModeWritesMCPWhenNoUserScope — skip+warn without --force, write with --force, unchanged common path.

go build ./..., go vet, and golangci-lint are clean on the touched packages.

The user-scope ~/.claude.json gortex stanza was written with an
absolute os.Executable() path while the project .mcp.json template
uses the bare "gortex" command. Claude Code stores OAuth tokens per
endpoint (command + args), so the two differing strings trip its
"conflicting scopes" diagnostic.

- Add agents.ResolveGortexCommand: prefer bare "gortex" when it
  resolves on PATH to the same running binary, falling back to the
  absolute path only when gortex is not on PATH. The global install
  now matches the portable project template.
- Heal stale stanzas: upsertGlobalMCPConfig uses
  UpsertMCPServerWithMigration, and IsGortexAuthoredMCPEntry now
  recognizes the legacy absolute-path form so an older entry is
  rewritten in place instead of left behind.
- Project-mode init warns and skips writing .mcp.json when gortex is
  already registered at user scope (override with --force), and warns
  about the duplication when a .mcp.json already exists.
@zzet zzet merged commit cd2d5ad into main Jun 30, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Conflicting scopes

1 participant