Skip to content

darnit install --client claude writes to ~/.claude/settings.json (Claude Desktop), not Claude Code's ~/.claude.json #270

@mlieberman85

Description

@mlieberman85

Summary

darnit install --client claude writes the MCP server config to ~/.claude/settings.json, which is Claude Desktop's config file. Claude Code reads from ~/.claude.json (different filename, different schema).

Net effect: a user runs darnit install, gets a success message saying the MCP server is configured, restarts Claude Code, and the darnit server doesn't appear. claude mcp list confirms it's not registered.

Discovered during the demo dry-run for feature 014 (#262) — multiple rounds of debug were needed because the install command's success message implies things are wired up.

Reproducer

# Fresh machine
darnit install --client claude
# → INFO: ✓ Installed darnit MCP server config in /Users/<you>/.claude/settings.json

# In any directory, ask Claude Code which MCP servers are available:
claude mcp list
# → no darnit entry; only the claude.ai-hosted servers (Slack, Notion, …)

# Where the config actually went:
cat ~/.claude/settings.json | jq '.mcpServers.darnit'
# → present, but Claude Code never reads this file

Root cause

packages/darnit/src/darnit/cli.py:492:

if args.client == "claude":
    settings_path = Path.home() / ".claude" / "settings.json"
else:
    settings_path = Path.home() / ".cursor" / "mcp.json"

The ~/.claude/settings.json path is what Claude Desktop uses on macOS for global settings (mcpServers block is the Desktop convention). Claude Code instead uses ~/.claude.json (different file, similar-but-not-identical schema).

The --client claude arg conflates two different clients with different config locations.

Proposed fix

Two layers:

1. Distinguish the clients

Split --client claude into --client claude-code (default) and --client claude-desktop. Or detect which is installed (heuristic: ~/.claude.json exists ⇒ Code; ~/Library/Application Support/Claude/ exists ⇒ Desktop) and write to the right one. Or write to BOTH if both clients are detected.

2. For Claude Code: use the right config path

if args.client == "claude-code":
    settings_path = Path.home() / ".claude.json"

Or, more robust: invoke claude mcp add --scope user darnit -- <command> <args…> as a subprocess. That delegates the file-format question to the Claude Code CLI itself, which already handles config-schema drift. Tradeoff: requires claude to be on PATH.

3. Project-local mode

darnit install --project currently writes skills to .claude/skills/ but MCP config still goes global (regardless of --project). For Claude Code, project-local MCP config lives in .mcp.json at the project root. The --project flag should also wire MCP config there for symmetry.

Acceptance

  • darnit install --client claude-code configures the MCP server in ~/.claude.json (or .mcp.json if --project).
  • After darnit install, claude mcp list shows the darnit server as ✓ Connected.
  • The previous --client claude is either renamed or aliased with a deprecation warning.
  • darnit install --client claude-desktop preserves the old behaviour for Desktop users (writes to ~/.claude/settings.json).

Workaround (for now)

Skip darnit install's MCP-config side and use Claude Code's own CLI:

claude mcp add --scope user darnit -- /Users/<you>/.local/bin/darnit serve --framework openssf-baseline

darnit install --mcp-only is essentially worthless against Claude Code without this fix; --project only gets the skills installed locally (which is still useful).

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions