Skip to content

fix(setup): use absolute MCP paths on Windows#111

Merged
Alan-TheGentleman merged 1 commit intomainfrom
fix/windows-mcp-absolute-path
Mar 21, 2026
Merged

fix(setup): use absolute MCP paths on Windows#111
Alan-TheGentleman merged 1 commit intomainfrom
fix/windows-mcp-absolute-path

Conversation

@Alan-TheGentleman
Copy link
Collaborator

Linked Issue

Closes #100

Summary

  • write a durable Claude Code MCP config on Windows using the absolute engram binary path
  • use the same absolute-path resolution for Gemini CLI and Codex on Windows
  • update setup output and add focused tests so users do not have to patch config manually

Problem

On Windows, MCP subprocesses do not reliably inherit the PATH that contains engram.exe. The Claude Code plugin cache also overwrites manual fixes to .mcp.json, so the user-side workaround is fragile and recurring.

Fix

This change resolves the command path from os.Executable() on Windows and writes a user-owned Claude MCP config under ~/.claude/mcp/engram.json, which survives plugin updates. Gemini CLI and Codex now also use absolute command paths on Windows.

Test Plan

  • go test ./cmd/engram ./internal/setup ./internal/mcp ./internal/server ./internal/store ./internal/sync ./internal/tui ./internal/version
  • Added focused tests for Windows absolute-path behavior, Claude MCP config writing, and Gemini/Codex parity

Copilot AI review requested due to automatic review settings March 21, 2026 22:25
@Alan-TheGentleman Alan-TheGentleman added the type:bug Bug fix label Mar 21, 2026
@Alan-TheGentleman Alan-TheGentleman merged commit b80b214 into main Mar 21, 2026
9 of 10 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes Windows MCP startup reliability by ensuring agent configurations use an absolute engram binary path (avoiding fragile PATH inheritance), and adds targeted tests to prevent regressions.

Changes:

  • Add Windows-aware resolveEngramCommand() and use it for Gemini CLI + Codex MCP registrations.
  • Write a durable Claude Code user-level MCP config at ~/.claude/mcp/engram.json during setup.
  • Expand setup tests to cover Claude MCP config writing and Windows absolute-path behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
internal/setup/setup.go Adds absolute-path resolution, durable Claude MCP config writing, and updates Gemini/Codex injection to use resolved command.
internal/setup/setup_test.go Adds/updates tests for Claude user MCP config writing and Windows absolute-path expectations across agents.
cmd/engram/main.go Updates Claude Code post-setup output messaging to mention the durable MCP config location.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +770 to +771
fmt.Println(" 3. MCP config written to ~/.claude/mcp/engram.json using absolute binary path")
fmt.Println(" (survives plugin auto-updates; re-run 'engram setup claude-code' if you move the binary)")
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

The post-install message for Claude Code always claims the MCP config was written to ~/.claude/mcp/engram.json, but setup treats that write as non-fatal and can fail (it only warns to stderr). This can mislead users into thinking the durable config exists when it doesn’t. Consider passing the setup.Result into printPostInstall (or a boolean) and only printing this step when the user MCP config write actually succeeded (or wording it as “attempted/will be written if possible”).

Suggested change
fmt.Println(" 3. MCP config written to ~/.claude/mcp/engram.json using absolute binary path")
fmt.Println(" (survives plugin auto-updates; re-run 'engram setup claude-code' if you move the binary)")
fmt.Println(" 3. Engram will attempt to write MCP config to ~/.claude/mcp/engram.json using the absolute binary path")
fmt.Println(" (this config survives plugin auto-updates; re-run 'engram setup claude-code' if you move the binary, and verify the file exists)")

Copilot uses AI. Check for mistakes.
Comment on lines +478 to +483
// claudeCodeMCPDir returns the directory for user-level Claude Code MCP configs.
// Files placed here are NOT managed by the plugin system and survive plugin updates.
func claudeCodeMCPDir() string {
home, _ := userHomeDir()
return filepath.Join(home, ".claude", "mcp")
}
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

claudeCodeMCPDir() ignores the error from os.UserHomeDir(). If home resolution fails, this will fall back to a relative path (".claude/mcp"), and writeClaudeCodeUserMCP() could end up creating/writing files in the current working directory. It would be safer to surface the error (e.g., return (string, error) and propagate) or at least guard against an empty home before using filepath.Join.

Copilot uses AI. Check for mistakes.
Comment on lines +85 to +97
// codexEngramBlock is the canonical Codex TOML MCP block.
// Command is always the bare "engram" name in this constant because
// upsertCodexEngramBlock generates the actual content via codexEngramBlockStr()
// which uses resolveEngramCommand() at runtime. This constant is kept for tests
// that verify idempotency against the already-written string.
const codexEngramBlock = "[mcp_servers.engram]\ncommand = \"engram\"\nargs = [\"mcp\", \"--tools=agent\"]"

// codexEngramBlockStr returns the Codex TOML block for the engram MCP server,
// using the resolved command (absolute path on Windows, bare name on Unix).
func codexEngramBlockStr() string {
cmd := resolveEngramCommand()
return "[mcp_servers.engram]\ncommand = " + fmt.Sprintf("%q", cmd) + "\nargs = [\"mcp\", \"--tools=agent\"]"
}
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

codexEngramBlockStr() makes the Codex MCP block OS-dependent (absolute path on Windows), but the file still keeps codexEngramBlock as a single canonical constant used by tests for exact string equality. This can make those tests fail on Windows (where upsertCodexEngramBlock() now returns a different block). Consider updating any exact-string expectations to use codexEngramBlockStr() (or resolveEngramCommand()) instead of codexEngramBlock so tests are portable across GOOS.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP server fails on Windows when engram is not in subprocess PATH

2 participants