MCP server env vars from .mcp.json not passed to spawned process

Status Fixed / completed
Maintainer reply None cached
Activity 5 comments · opened Feb 2, 2026 · closed Feb 2, 2026

Description

Environment variables defined in .mcp.json under a server's env key are not being passed to the spawned MCP server process. This means MCP servers that depend on env-based configuration (like @modelcontextprotocol/server-memory with MEMORY_FILE_PATH) silently fall back to defaults.

Steps to Reproduce

  1. Create .mcp.json in a project root:
{
  "mcpServers": {
    "memory": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-memory"],
      "env": {
        "MEMORY_FILE_PATH": "/Users/me/.claude-memory/memory.json"
      }
    }
  }
}
  1. Start a Claude Code session in that project directory
  2. Use a memory MCP tool (e.g., mcp__memory__search_nodes)
  3. Inspect the spawned mcp-server-memory process environment:
ps eww -p <PID> | grep MEMORY_FILE_PATH

Expected Behavior

The process should have MEMORY_FILE_PATH=/Users/me/.claude-memory/memory.json in its environment, and the MCP memory server should read/write to that file.

Actual Behavior

  • MEMORY_FILE_PATH is not set on the spawned process (confirmed via ps eww)
  • The server uses an ephemeral in-memory store instead of the configured file
  • Data written via Claude Code's MCP tools is lost on server restart
  • The same .mcp.json env config works correctly when used by Claude Desktop via claude_desktop_config.json

Diagnostic Evidence

# Claude Desktop's server (PID from Claude.app) — env var present:
MEMORY_FILE_PATH=/Users/me/.claude-memory/memory.json

# Claude Code's server (PID from npx) — env var missing:
MEMORY_FILE_PATH not set

Both servers use identical config ("env": {"MEMORY_FILE_PATH": "..."}) — only the Claude Code spawner fails to pass it through.

Impact

  • MCP servers that rely on env vars for configuration silently malfunction
  • No error or warning is shown — the server starts fine but with wrong config
  • For server-memory specifically: knowledge graph data is not persisted and not shared with Claude Desktop, defeating the purpose of a shared memory store

Environment

  • macOS (Darwin 25.2.0, arm64)
  • Claude Code (latest as of 2026-02-02)
  • @modelcontextprotocol/server-memory via npx
  • .mcp.json in project root

View original on GitHub ↗

5 Comments

edumusikse · 8 months ago

Additional Finding: User-scope config also affected

Tried moving the MCP server config from project scope (.mcp.json) to user scope via claude mcp add -e MEMORY_FILE_PATH=... -s user:

$ claude mcp get memory
memory:
  Scope: User config (available in all your projects)
  Status: ✓ Connected
  Type: stdio
  Command: npx
  Args: -y @modelcontextprotocol/server-memory
  Environment:
    MEMORY_FILE_PATH=/Users/stephan/.claude-memory/memory.json

The config shows correctly with the env var listed. However, the already-running server process in this session still doesn't have the env var:

$ ps eww -p <PID> | grep MEMORY_FILE_PATH
# (empty — not set)

This needs a fresh Claude Code session to test properly. Will update after restarting Claude Code to confirm whether user-scope config correctly passes env vars on fresh session start.

The claude mcp get output confirms Claude Code knows about the env var — the question is whether it passes it to the spawned process.

github-actions[bot] · 8 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/1254
  2. https://github.com/anthropics/claude-code/issues/14870
  3. https://github.com/anthropics/claude-code/issues/11927

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

edumusikse · 8 months ago

Workaround Found

The @modelcontextprotocol/server-memory has a default fallback path when MEMORY_FILE_PATH is not set:

// From dist/index.js
export const defaultMemoryPath = path.join(
  path.dirname(fileURLToPath(import.meta.url)), 
  'memory.jsonl'
);

This resolves to: ~/.npm/_npx/<hash>/node_modules/@modelcontextprotocol/server-memory/dist/memory.jsonl

Workaround: Symlink the default fallback file to the actual shared memory file:

# Find the default file
DEFAULT_PATH=$(find ~/.npm/_npx -path "*/server-memory/dist/memory.jsonl" 2>/dev/null | head -1)

# Replace with symlink to shared memory file  
rm "$DEFAULT_PATH"
ln -s ~/.claude-memory/memory.json "$DEFAULT_PATH"

This makes Claude Code's memory server read/write the same file as Claude Desktop, even though the env var isn't being passed.

Limitation: The symlink breaks whenever npx refreshes its cache for @modelcontextprotocol/server-memory, since the entire _npx/<hash>/ directory gets recreated. Needs periodic re-symlinking.

The underlying bug remains: Claude Code should be passing env vars from .mcp.json to spawned MCP server processes, matching Claude Desktop's behavior.

edumusikse · 8 months ago

Closing as duplicate of #11927. Added diagnostic evidence from this reproduction as a comment there.

github-actions[bot] · 8 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.