CLI reference
Full CLI
$ node setup-claude.js # interactive menu $ node setup-claude.js --help # usage + current targets $ node setup-claude.js --check # doctor only — zero writes $ node setup-claude.js --dry-run # show what would happen $ node setup-claude.js --fix-issues # apply only missing/wrong links $ node setup-claude.js --render-only # write link.*.json, skip symlinks $ node setup-claude.js --all # apply every target $ node setup-claude.js --uninstall # remove managed symlinks (asks) $ node setup-claude.js --uninstall --yes # skip the prompt $ node setup-claude.js --uninstall --dry-run # preview only
Unknown flags exit 1 with a --help hint — typos like --dryrun don’t
silently fall through to the menu.
How it works
Per run:
- Detects OS (
win/mac) - Probes the running IDEA over HTTP to find its MCP server: REST
127.0.0.1:63342–63352/api/mcp/list_tools, then SSE127.0.0.1:64342–64352/sse(IntelliJ 2025.3+). Falls back to64763(REST) if nothing answers - Renders per-OS
link.{os}.jsonfiles under the repo by:- Merging
base.json+ optionalbase.{os}.json - Substituting
<AUTO>→ IDEA port,<FS_PATH>→ filesystem MCP root - With SSE: replacing the
jetbrainsentry with annpx -y mcp-remote http://…/ssebridge (Claude Desktop is stdio-only) - On Mac: transforming
cmd /c npx …→npx …
- Merging
- Creates symlinks:
<project>/.claude→projects/<project>/claude/<project>/.mcp.json→projects/<project>/mcp/link.<os>.json- Claude Desktop config →
claude-desktop/link.<os>.json
Layout
claude-symlink/ ├── projects/ │ ├── demo-backend/ │ │ ├── claude/ # .claude folder content (symlinked as <project>/.claude) │ │ └── mcp/ │ │ ├── base.json # edit this (Windows format; Mac transform handles cmd /c) │ │ ├── link.win.json # generated — Windows symlink target │ │ └── link.mac.json # generated — Mac symlink target │ ├── demo-frontend/ │ │ ├── claude/ │ │ └── mcp/ │ │ ├── base.json # shared MCPs across OS │ │ ├── base.win.json # OPTIONAL — Windows-only entries (e.g. playwright msedge) │ │ ├── base.mac.json # OPTIONAL — Mac-only entries (e.g. playwright chrome) │ │ ├── link.win.json # generated │ │ └── link.mac.json # generated │ └── demo-env-only/ # env-only project (claude: false, mcp: false) │ └── .env # extras source (gitignored) ├── claude-desktop/ │ ├── base.json # all Claude Desktop MCPs incl. jetbrains, <AUTO>, <FS_PATH> │ ├── link.win.json # generated │ └── link.mac.json # generated ├── lib/ # config.js, targets.js, render.js, apply.js, menu.js, doctor.js, colors.js ├── user-config.js # USER-EDITED — PROJECTS, FILESYSTEM_MCP_PATH, IDEA_PORT_FALLBACK ├── setup-claude.js ├── README.md └── .gitignore
Naming rule: base.* are hand-edited sources. link.* are generated;
don’t edit them.
Configuration
Adding a new project
-
In
user-config.js, add an entry to thePROJECTSblock with absolute paths for Win and Mac:const PROJECTS = { 'demo-backend': { win: 'C:\\Projects\\demo-backend', mac: path.join(os.homedir(), 'Projects/demo-backend') }, 'demo-frontend': { win: 'C:\\Projects\\demo-frontend', mac: path.join(os.homedir(), 'Projects/demo-frontend') }, // 'new-project': { win: 'C:\\Path\\new', mac: path.join(os.homedir(), 'Projects/new') }, };Keep the root inside
FILESYSTEM_MCP_PATHon both OSes. Otherwise Claude Desktop’s filesystem MCP won’t be able to see the project, and the doctor will warn. -
Create the source folder in the repo:
projects/<new-project>/ ├── claude/ # (optional) .claude content — CLAUDE.md, plans/, agents/, etc. └── mcp/ └── base.json # MCP server list (Windows format: "cmd", "/c", "npx", …)
-
(Optional) If an MCP server has OS-specific args beyond the
cmd /ctransform (e.g. different browser executable paths), addmcp/base.win.jsonand/ormcp/base.mac.json. They merge intobase.jsonat render time. -
Run
node setup-claude.js --fix-issueson each machine.
Opt-in / opt-out flags
Each PROJECTS entry accepts optional fields. Defaults match the full flow
above.
| Field | Default | Effect |
|---|---|---|
claude |
true |
Symlink <project>/.claude to projects/<name>/claude/ |
mcp |
true |
Render and symlink <project>/.mcp.json |
extras |
[] |
Extra file symlinks. Each { src, dst } (both relative paths). |
extras: src is relative to projects/<name>/ in the repo; dst is
relative to the project root on disk. Files only. Good for env files,
secrets, any shared file.
Env-only project (no .claude/, no .mcp.json):
'demo-env-only': {
win: 'C:\\Projects\\demo-env-only',
mac: path.join(os.homedir(), 'Projects/demo-env-only'),
claude: false,
mcp: false,
extras: [{ src: '.env', dst: '.env' }],
},Place the source at projects/demo-env-only/.env. Run --fix-issues;
<project>/.env becomes a symlink to it.
Full flow plus an extra file:
'demo-backend': {
win: 'C:\\Projects\\demo-backend',
mac: path.join(os.homedir(), 'Projects/demo-backend'),
extras: [{ src: '.env.local', dst: '.env.local' }],
},
.env*files inprojects/*/are gitignored — put them in your sync folder (Dropbox/iCloud) to share across machines; Git doesn’t carry them.
FILESYSTEM_MCP_PATH
Defined in user-config.js. It’s the root directory handed to Claude
Desktop’s filesystem MCP server. Everything under it is readable/writable
by Claude Desktop via the filesystem tool; anything outside is invisible
to it.
Default:
| OS | Path |
|---|---|
| Windows | C:\Projects |
| Mac | ~/Projects |
In claude-desktop/base.json the filesystem MCP uses <FS_PATH> as the
placeholder, substituted at render time with the per-OS value.
Practical rule: keep every project root listed in PROJECTS inside
this path on both OSes. If a project lives outside, the doctor warns
(root outside FILESYSTEM_MCP_PATH) and Desktop-level filesystem access
breaks (project-level .mcp.json still works). Fix by moving the project
under the path, or widening FILESYSTEM_MCP_PATH to a common parent.
Placeholders
In any base.json under projects/*/mcp/ or claude-desktop/:
<AUTO>— detected IDEA MCP port at render time<FS_PATH>—FILESYSTEM_MCP_PATH[os](see above)
Other <TOKEN> patterns are flagged by the doctor as unknown — add a
substitution in lib/render.js or remove it from the base file.
Mac cmd /c transformation
Source files are written in Windows format ("command": "cmd", "args":
["/c", "npx", …]). On Mac, the renderer strips cmd and /c, producing
"command": "npx". You only maintain one format.
OS-specific base.win.json / base.mac.json also go through the
transform — write them in Windows format too (unless Mac genuinely needs
a different command).
Maintenance
Environment doctor (self-test)
Every run prints an Environment: block after the status table; --check
runs it alone. It checks:
- Each project root in
PROJECTSexists on this machine - All project roots are inside
FILESYSTEM_MCP_PATH - Claude Desktop is installed (config directory present)
- IDEA’s MCP server answered the HTTP probe (fallback port warning otherwise)
- Source files complete:
projects/<name>/claude/,mcp/base.json, eachextras.src - Base files parse as JSON and contain no unknown
<PLACEHOLDER>tokens - No orphan
projects/<foo>/folders (disk matchesPROJECTS)
Projects whose root is missing are automatically skipped during apply —
their row shows (root missing) in red. Rendered targets whose source
base.json was edited more recently get a yellow (stale) tag; re-run
--render-only (or any flow that renders) to clear it.
Safety
- Idempotent: correct symlinks are left alone.
- Any real (non-symlink) file at a target is renamed to
<name>.bak-YYYYMMDD-HHmmssbefore replacement. --dry-runshows planned actions without touching anything.--uninstallonly removes symlinks that point at our managedtargetPath. Real files, foreign symlinks (pointing elsewhere), and already-missing links are untouched. The repo source is never touched.
Paths
| Purpose | Windows | Mac |
|---|---|---|
| Repo root | wherever you clone the repo (e.g. C:\Users\<user>\Dropbox\claude-symlink) |
wherever you clone the repo (e.g. ~/Dropbox/claude-symlink) |
| Claude Desktop config | %APPDATA%\Claude\claude_desktop_config.json |
~/Library/Application Support/Claude/claude_desktop_config.json |
| IDEA MCP probe | 127.0.0.1:63342–63352/api/mcp/list_tools, then 127.0.0.1:64342–64352/sse |
same as Windows |
Git + sync folder
The repo can live inside a sync folder (Dropbox, iCloud Drive, …) for
cross-machine sync of content that’s too sensitive for Git — typically
.env* files. Git is the primary version history; the sync folder is
optional.
link.*.jsonand*.bak-*are gitignored because they’re OS-specific / regenerated.projects/*/.env*are gitignored too — rely on the sync folder (or manual placement) to carry them across machines.