Dev.to · 27 min read

sentinel-ir-mcp 0.2.3 setup: Windows desktop-app compatibility report (no login)

sentinel-ir-mcp 0.2.3 setup: Windows desktop-app compatibility report (no login)

Coming next week: AI Agents on Windows, Linux and Beyond 🛠️ Getting AI agents connected shouldn't require a maze of manual configuration. I'm testing desktop compatibility for Sentinel-IR-MCP, starting with Windows, while keeping Linux and other environments in the picture. More details next week. Still testing, still verifying. No compatibility claims without evidence. Date: 2026-10-22 (UTC). Branch work/compat-windows-gui, commit d6119a5 ("COMPATIBILITY: Windows measurement of npx inside a folder with %"), package.json version 0.2.3. Checkout: C:\Users\Administrator\repos\sentinel-ir-mcp (anonymous HTTPS clone, npm install). No login, no account, no credentials entered in any app. Nothing pushed, no MR touched, nothing published. Machine OS: Windows Server 2022, build 10.0.20348.5622 (Windows PowerShell 5.1.20348.5622) CPU arch: AMD64 Node: v22.23.4 (MSI node-v22.23.4-x64.msi), npm: 10.9.9 Note: the VM initially had Node 20.19.0 (C:\hostedtoolcache\node\20.19.0\x64) earlier on PATH. My first VS Code start of A spawned C:\hostedtoolcache\node\20.19.0\x64\npx.CMD; I removed that PATH entry, restarted VS Code and repeated the test. All results below are from the Node 22 / npm 10.9.9 runs. Screenshots vscode-A-01-list-stopped.png / vscode-A-02-list-after-start.png are from that earlier Node 20.19.0 run (kept for completeness). Summary table app app version how configured project path used result (connected? tools? serverInfo) evidence not verified VS Code 1.143.0 (2d0b7506a36c1d6db9a466440131a8e01eab2289, x64) setup --client vscode --project A → printed PowerShell cmd (code --% --add-mcp ...) run in PS 5.1 A C:\sentinel-test\my project Running, "Discovered 3 tools" vscode-A-node22-01-list-before.png, vscode-A-node22-02-list-after-start.png; log Code\logs\20261022T162230\...sentinel-ir.log: Connection state: Running / Discovered 3 tools serverInfo version not shown in VS Code UI/log (0.2.2 inferred from compat-smoke only); tool calls from chat not tested (needs Copilot sign-in) VS Code same setup --client vscode --project B → printed PowerShell cmd in PS 5.1 B C:\sentinel-test\it's $HOME & 100% ^caret! (x) Running, "Discovered 3 tools"; stored arg equals B exactly vscode-B-ps51-01-list-before.png, vscode-B-ps51-02-list-after-start.png; log 20261022T162631; mcp.json arg C:\\sentinel-test\\it's $HOME & 100% ^caret! (x) serverInfo version in app; tool calls VS Code same server removed, then printed cmd.exe cmd (code --add-mcp ...) for B B Running, "Discovered 3 tools"; stored arg equals B exactly vscode-B-cmd-01-list-before.png, vscode-B-cmd-02-list-after-start.png; log 20261022T162840 serverInfo version in app; tool calls Claude Code 2.1.308 printed PowerShell cmd, run in PS 5.1 from A and from B A, B FAILED: A error: unknown option '-y' (exit 1); B error: unknown option '--%' (exit 1). claude resolves to C:\Users\Administrator\AppData\Roaming\npm\claude.ps1 claude-code-AB-ps51-error.png (also claude-code-A-ps51-error.png, contains an extra Set-Location error from my wrapper; the unknown option '-y' line is the relevant one) behaviour when claude resolves to claude.cmd/claude.exe from PowerShell; PowerShell 7 Claude Code 2.1.308 printed cmd.exe cmd run from A and from B A, B claude mcp list: √ Connected for both; claude mcp get: Command cmd, Args /c npx -y sentinel-ir-mcp@0.2 ; B stored path equals real path (no %...% expansion; verified in ~/.claude.json, -ceq True). No login was required for add/list/get raw output below (claude mcp list/get) serverInfo version (not printed by Claude Code); tool calls in a Claude session (needs login) Cursor 3.26.16 (8fcb8ace5c73fa31f2e2707fd6783160e4ed3e40, x64) setup --client cursor --project A --yes → A\.cursor\mcp.json (cmd /c npx -y sentinel-ir-mcp@0.2 ${workspaceFolder}), opened folder A A App stops at Log In / Sign Up screen. Project server detected but never started: State transition: project-0-my project-sentinel-ir none → disconnected (twice), census "projectServers":1,...,"enabledTotal":0; no process spawned cursor-A-01-start.png; logs/cursor-20261022T163122/window1/workbench.mcp.oauth.log, workbench.mcp.files.log whether the project server connects after login / after enabling it in MCP settings (settings UI not reachable without login) Cursor same README deeplink cursor://anysphere.cursor-deeplink/mcp/install?... → "Install MCP server?" dialog (Command npx, args -y, sentinel-ir-mcp@0.2, ${workspaceFolder}) → clicked Install written to ~\.cursor\mcp.json; Cursor resolved ${workspaceFolder} to A Connected, tools=3 (without login): mcp-server-user-sentinel-ir.log: Successfully connected to stdio server, connection:connect_success; Server "user-sentinel-ir" fingerprint changed: tools=3, status=connected. Process: cmd.exe /d /s /c "npx ^"-y^" ^"sentinel-ir-mcp@0.2^" ^"C:\sentinel-test\my^ project^"" (parent Cursor.exe) cursor-A-02-deeplink.png, cursor-A-03-deeplink-after-install.png (UI returns to login screen); logs/cursor-20261022T163122/mcp-server-user-sentinel-ir.log, .../Mcp FileSystem Writer.log serverInfo version (not in Cursor log); tool names (only count 3 logged); tool calls Windsurf / Devin Desktop Devin 1.126.0, windsurfVersion 3.10.67 (DevinUserSetup-x64-3.10.67.exe) setup --client windsurf --project A --yes → %APPDATA%\devin\mcp_config.json with "command": "cmd", "args": ["/c","npx","-y","sentinel-ir-mcp@0.2","C:\\sentinel-test\\my project"] (verified) A App stops at onboarding "Customize" → after Next: "Welcome to Devin – Sign up / Log in". No sentinel-ir process spawned; Devin logs contain no sentinel/MCP server start line (mcpGateway.log only [McpGatewayService] Initialized) windsurf-A-01-start.png, windsurf-A-02-after-next.png; logs/devin-20261022T163303/ whether Devin/Windsurf starts the server after login; tools; serverInfo Windsurf legacy migration n/a (CLI only) legacy %USERPROFILE%\.codeium\windsurf\mcp_config.json with dummy-other; new file deleted; setup --client windsurf --yes (no --project) cwd = C:\Users\Administrator\repos\sentinel-ir-mcp (setup used the current folder) New file has dummy-other + sentinel-ir; legacy file SHA256 B8D27368...1A1C88 before = after (unchanged); doctor ok raw output below app reading the migrated file (stops at login) Claude Desktop 3.1623.4 (Claude-Setup-x64.exe, AnthropicClaude\app-3.1623.4) setup --client claude-desktop --project A --yes → %APPDATA%\Claude\claude_desktop_config.json (cmd /c npx entry, verified) A App shows "Claude for Windows – Get started" → Sign In (Google / email). %APPDATA%\Claude\logs\ is empty (no mcp*.log); no sentinel-ir process spawned by claude.exe claude-desktop-A-01-start.png, claude-desktop-A-02-after-get-started.png whether Claude Desktop starts the server after login; mcp log lines; tools; serverInfo serverInfo version observed: 0.2.2 for the published sentinel-ir-mcp@0.2 started via npx and via cmd /c npx (compat-smoke, MCP SDK client). No desktop app on this machine displayed the serverInfo version. doctor --json reports MCP handshake with sentinel-ir-mcp 0.2.3, i.e. doctor handshakes with the local checkout server, not with the configured npx -y sentinel-ir-mcp@0.2 command. Findings Claude Code + Windows PowerShell 5.1: both printed PowerShell commands fail when claude is the npm global install (resolves to %APPDATA%\npm\claude.ps1). A: claude mcp add --transport stdio sentinel-ir -- cmd /c npx -y sentinel-ir-mcp@0.2 "C:\sentinel-test\my project" → error: unknown option '-y' (exit 1). PowerShell consumes the -- when invoking a .ps1, so -y reaches Claude's parser. B: claude mcp add-json --% sentinel-ir "{...}" → error: unknown option '--%' (exit 1). The stop-parsing token is not applied when the target is a .ps1 script, it is passed through as a literal argument. The printed cmd.exe variants work for A and B (√ Connected, exact path stored). Cursor: the README deeplink entry (raw npx, user-level) connected with 3 tools without login; Cursor itself wraps it in cmd.exe /d /s /c. The setup-written project entry (cmd /c npx, .cursor/mcp.json) was detected but stayed disconnected and was never spawned (enabledTotal: 0). Cause not verified (could be project-server approval, which is behind the login screen). doctor does its own handshake against the local package (reports 0.2.3), so a passing doctor does not prove the configured npx -y sentinel-ir-mcp@0.2 command starts from inside the app. scripts/compat-smoke.js writes into the real %APPDATA%\Claude\claude_desktop_config.json and %APPDATA%\devin\mcp_config.json and left sentinel-ir entries pointing to a deleted temp folder (C:\Users\ADMINI~1\AppData\Local\Temp\sentinel-compat-1D3tdj\my project). I saved them (smoke-leftover-*.json) and deleted them before the app tests. setup --client windsurf --yes without --project silently used the current directory (repo checkout) as project. Cursor, Devin/Windsurf and Claude Desktop all require login before showing MCP state in the UI. Not verified serverInfo version as seen by any desktop app (only 0.2.2 via compat-smoke SDK client). Any actual tool call from inside an app's chat/agent (all need login). Cursor project-level (setup-written) entry ever connecting; Cursor MCP settings UI. Devin/Windsurf and Claude Desktop starting the server at all (stopped at login; no process, no log). Claude Desktop mcp*.log content (no log files were created before login). PowerShell 7; Claude Code via native installer (claude.exe); arm64; other Windows versions. VS Code deeplink (vscode:mcp/install?...) was not tested. Raw outputs Setup outputs setup --client vscode --project A VS Code adds MCP servers with its own command. Nothing was written. Run in PowerShell: code --% --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\sentinel-test\\my project\"]}" or in Command Prompt (cmd.exe): code --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\sentinel-test\\my project\"]}" Access: C:\sentinel-test\my project (only this folder, read-only) Then check the connection: npx -y sentinel-ir-mcp@0.2 doctor --project C:\sentinel-test\my project setup --client vscode --project B VS Code adds MCP servers with its own command. Nothing was written. Run in PowerShell: code --% --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\sentinel-test\\it's $HOME \u0026 100\u0025 \u005ecaret\u0021 (x)\"]}" or in Command Prompt (cmd.exe): code --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\sentinel-test\\it's $HOME \u0026 100\u0025 \u005ecaret\u0021 (x)\"]}" Access: C:\sentinel-test\it's $HOME & 100% ^caret! (x) (only this folder, read-only) Then check the connection: npx -y sentinel-ir-mcp@0.2 doctor --project C:\sentinel-test\it's $HOME & 100% ^caret! (x) Note: this folder path contains %. npm 10.8 (measured: 10.8.2, 10.8.3) fails with "npm error URI malformed" when npx is started inside such a folder; npm 10.9.9 and 11.19.1 work. If the client reports that error, update npm or use a folder without % in its path. VS Code mcp.json after A (PS 5.1) { "servers": { "sentinel-ir": { "type": "stdio", "command": "npx", "args": [ "-y", "sentinel-ir-mcp@0.2", "C:\\sentinel-test\\my project" ] } }, "inputs": [] } VS Code mcp.json after B (PS 5.1) { "servers": { "sentinel-ir": { "type": "stdio", "command": "npx", "args": [ "-y", "sentinel-ir-mcp@0.2", "C:\\sentinel-test\\it's $HOME & 100% ^caret! (x)" ] } }, "inputs": [] } VS Code mcp.json after B (cmd.exe) { "servers": { "sentinel-ir": { "type": "stdio", "command": "npx", "args": [ "-y", "sentinel-ir-mcp@0.2", "C:\\sentinel-test\\it's $HOME & 100% ^caret! (x)" ] } }, "inputs": [] } setup --client claude-code --project A Claude Code adds MCP servers with its own command. Nothing was written. Run in PowerShell: claude mcp add --transport stdio sentinel-ir -- cmd /c npx -y sentinel-ir-mcp@0.2 "C:\sentinel-test\my project" or in Command Prompt (cmd.exe): claude mcp add --transport stdio sentinel-ir -- cmd /c npx -y sentinel-ir-mcp@0.2 "C:\sentinel-test\my project" Access: C:\sentinel-test\my project (only this folder, read-only) Then check the connection: npx -y sentinel-ir-mcp@0.2 doctor --project C:\sentinel-test\my project setup --client claude-code --project B Claude Code adds MCP servers with its own command. Nothing was written. Run in PowerShell: claude mcp add-json --% sentinel-ir "{\"type\":\"stdio\",\"command\":\"cmd\",\"args\":[\"/c\",\"npx\",\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\sentinel-test\\it's $HOME \u0026 100\u0025 \u005ecaret\u0021 (x)\"]}" or in Command Prompt (cmd.exe): claude mcp add-json sentinel-ir "{\"type\":\"stdio\",\"command\":\"cmd\",\"args\":[\"/c\",\"npx\",\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\sentinel-test\\it's $HOME \u0026 100\u0025 \u005ecaret\u0021 (x)\"]}" Access: C:\sentinel-test\it's $HOME & 100% ^caret! (x) (only this folder, read-only) Then check the connection: npx -y sentinel-ir-mcp@0.2 doctor --project C:\sentinel-test\it's $HOME & 100% ^caret! (x) Note: this folder path contains %. npm 10.8 (measured: 10.8.2, 10.8.3) fails with "npm error URI malformed" when npx is started inside such a folder; npm 10.9.9 and 11.19.1 work. If the client reports that error, update npm or use a folder without % in its path. setup --client cursor --project A --yes Client: Cursor Config: C:\sentinel-test\my project\.cursor\mcp.json (new file) Access: C:\sentinel-test\my project (only this folder, read-only) Change: create the file with "sentinel-ir" {"command":"cmd","args":["/c","npx","-y","sentinel-ir-mcp@0.2","${workspaceFolder}"]} Written. Next: restart Cursor, then check the connection: npx -y sentinel-ir-mcp@0.2 doctor --client cursor --project C:\sentinel-test\my project Optional instructions for your agent: npx -y sentinel-ir-mcp@0.2 guide setup --client windsurf --project A --yes Client: Windsurf Config: C:\Users\Administrator\AppData\Roaming\devin\mcp_config.json (new file) Access: C:\sentinel-test\my project (only this folder, read-only) Change: create the file with "sentinel-ir" {"command":"cmd","args":["/c","npx","-y","sentinel-ir-mcp@0.2","C:\\sentinel-test\\my project"]} Written. Next: restart Windsurf, then check the connection: npx -y sentinel-ir-mcp@0.2 doctor --client windsurf Optional instructions for your agent: npx -y sentinel-ir-mcp@0.2 guide setup --client claude-desktop --project A --yes Client: Claude Desktop Config: C:\Users\Administrator\AppData\Roaming\Claude\claude_desktop_config.json (new file) Access: C:\sentinel-test\my project (only this folder, read-only) Change: create the file with "sentinel-ir" {"command":"cmd","args":["/c","npx","-y","sentinel-ir-mcp@0.2","C:\\sentinel-test\\my project"]} Written. Next: restart Claude Desktop, then check the connection: npx -y sentinel-ir-mcp@0.2 doctor --client claude-desktop Optional instructions for your agent: npx -y sentinel-ir-mcp@0.2 guide Windsurf legacy migration: setup --client windsurf --yes Client: Windsurf Config: C:\Users\Administrator\AppData\Roaming\devin\mcp_config.json (new file) Access: C:\Users\Administrator\repos\sentinel-ir-mcp (only this folder, read-only) Change: create the file with "sentinel-ir" Copied from: C:\Users\Administrator\.codeium\windsurf\mcp_config.json (old location; that file stays unchanged) {"command":"cmd","args":["/c","npx","-y","sentinel-ir-mcp@0.2","C:\\Users\\Administrator\\repos\\sentinel-ir-mcp"]} Kept unchanged: dummy-other Written. Next: restart Windsurf, then check the connection: npx -y sentinel-ir-mcp@0.2 doctor --client windsurf Optional instructions for your agent: npx -y sentinel-ir-mcp@0.2 guide Windsurf legacy migration: files legacy C:\Users\Administrator\.codeium\windsurf\mcp_config.json (before and after, SHA256 B8D27368D1841B67644990E4EA3510778773CC95CAA38B0DBC6DA6B3171A1C88 both times): {"mcpServers":{"dummy-other":{"command":"node","args":["-e","0"]}}} new %APPDATA%\devin\mcp_config.json after setup: { "mcpServers": { "dummy-other": { "command": "node", "args": ["-e", "0"] }, "sentinel-ir": { "command": "cmd", "args": ["/c","npx","-y","sentinel-ir-mcp@0.2","C:\\Users\\Administrator\\repos\\sentinel-ir-mcp"] } } } Claude Code (2.1.308), PowerShell 5.1 (printed PowerShell commands) PowerShell 5.1.20348.5622 claude resolves to: C:\Users\Administrator\AppData\Roaming\npm\claude.ps1 --- cwd A: C:\sentinel-test\my project PS> claude mcp add --transport stdio sentinel-ir -- cmd /c npx -y sentinel-ir-mcp@0.2 "C:\sentinel-test\my project" error: unknown option '-y' exit=1 --- cwd B: C:\sentinel-test\it's $HOME & 100% ^caret! (x) PS> claude mcp add-json --% sentinel-ir "{\"type\":\"stdio\",\"command\":\"cmd\",\"args\":[\"/c\",\"npx\",\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\sentinel-test\\it's $HOME \u0026 100\u0025 \u005ecaret\u0021 (x)\"]}" error: unknown option '--%' exit=1 Claude Code after the printed cmd.exe commands: claude mcp list / claude mcp get sentinel-ir ===== cwd: C:\sentinel-test\my project --- claude mcp list Checking MCP server health… sentinel-ir: cmd /c npx -y sentinel-ir-mcp@0.2 C:\sentinel-test\my project - √ Connected exit=0 --- claude mcp get sentinel-ir sentinel-ir: Scope: Local config (private to you in this project) Status: √ Connected Type: stdio Command: cmd Args: /c npx -y sentinel-ir-mcp@0.2 C:\sentinel-test\my project Environment: To remove this server, run: claude mcp remove sentinel-ir -s local exit=0 ===== cwd: C:\sentinel-test\it's $HOME & 100% ^caret! (x) --- claude mcp list Checking MCP server health… sentinel-ir: cmd /c npx -y sentinel-ir-mcp@0.2 C:\sentinel-test\it's $HOME & 100% ^caret! (x) - √ Connected exit=0 --- claude mcp get sentinel-ir sentinel-ir: Scope: Local config (private to you in this project) Status: √ Connected Type: stdio Command: cmd Args: /c npx -y sentinel-ir-mcp@0.2 C:\sentinel-test\it's $HOME & 100% ^caret! (x) To remove this server, run: claude mcp remove sentinel-ir -s local exit=0 ~/.claude.json check: project key: C:/sentinel-test/it's $HOME & 100% ^caret! (x) args: /c | npx | -y | sentinel-ir-mcp@0.2 | C:\sentinel-test\it's $HOME & 100% ^caret! (x) last arg equals B (case-sensitive): True VS Code MCP output logs A (PS 5.1), Code\logs\20261022T162230\window1\mcpServer.mcp.config.usrlocal.sentinel-ir.log 2026-10-22 16:25:09.347 [info] Starting server sentinel-ir 2026-10-22 16:25:09.347 [info] Connection state: Starting 2026-10-22 16:25:09.347 [info] Starting server from LocalProcess extension host 2026-10-22 16:25:09.374 [info] Connection state: Starting 2026-10-22 16:25:09.375 [info] Connection state: Running 2026-10-22 16:25:10.400 [info] Discovered 3 tools B (PS 5.1), 20261022T162631 2026-10-22 16:27:11.210 [info] Starting server sentinel-ir 2026-10-22 16:27:11.230 [info] Connection state: Running 2026-10-22 16:27:12.342 [info] Discovered 3 tools B (cmd.exe), 20261022T162840 2026-10-22 16:29:20.611 [info] Starting server sentinel-ir 2026-10-22 16:29:20.632 [info] Connection state: Running 2026-10-22 16:29:21.547 [info] Discovered 3 tools Cursor logs (excerpts) workbench.mcp.files.log: [MCPService] Plugin MCP census: {"trigger":"plugins_changed","providerOutcome":"ok","descriptorsReceived":0,"pluginServersAssigned":0,"defaultServers":0,"userServers":0,"projectServers":1,"extensionServers":0,"providerServers":1,"effectiveTotal":2,"enabledTotal":0,"remoteAuthorityPrefix":"local"} workbench.mcp.oauth.log: 16:31:28.926 [MCPService] State transition: project-0-my project-sentinel-ir none -> disconnected 16:31:31.676 [MCPService] State transition: project-0-my project-sentinel-ir none -> disconnected After deeplink Install (user-level entry), mcp-server-user-sentinel-ir.log: 16:34:39.301 connecting stdio for "sentinel-ir" (user-sentinel-ir) 16:34:39.315 MCP stdio spawn policy decision: sandboxed=false, sandboxReason=controls_disabled, ... 16:34:40.255 Successfully connected to stdio server 16:34:40.255 [V2 FSM] connection:connect_success: conn=connecting,auth=unknown -> conn=connected,auth=unknown Mcp FileSystem Writer.log: 16:34:40.385 Server "user-sentinel-ir" fingerprint changed: tools=3, status=connected Process tree: node.exe(npx-cli.js -y sentinel-ir-mcp@0.2 "C:\sentinel-test\my project") node --test test/*.test.js TAP version 13 # Subtest: --version and --help ok 1 - --version and --help --- duration_ms: 528.4001 type: 'test' ... # Subtest: invalid arguments exit with code 2 ok 2 - invalid arguments exit with code 2 --- duration_ms: 1137.9108 type: 'test' ... # Subtest: package metadata is publishable ok 3 - package metadata is publishable --- duration_ms: 0.7091 type: 'test' ... # Subtest: guide prints the agent workflow and writes nothing ok 4 - guide prints the agent workflow and writes nothing --- duration_ms: 219.1589 type: 'test' ... # Subtest: subcommands: --help, unknown options exit 2; help lists the commands ok 5 - subcommands: --help, unknown options exit 2; help lists the commands --- duration_ms: 2192.8319 type: 'test' ... # Subtest: a folder named 'setup' is still reachable as ./setup; bare 'setup' is now the command ok 6 - a folder named 'setup' is still reachable as ./setup; bare 'setup' is now the command --- duration_ms: 618.7325 type: 'test' ... # Subtest: doctor after setup: real handshake, exactly three tools, analyze_directory call, exit 0 ok 7 - doctor after setup: real handshake, exactly three tools, analyze_directory call, exit 0 --- duration_ms: 393.9711 type: 'test' ... # Subtest: doctor resolves ${workspaceFolder} in a Cursor project config ok 8 - doctor resolves ${workspaceFolder} in a Cursor project config --- duration_ms: 323.5309 type: 'test' ... # Subtest: doctor exits 1 with a fix for a missing config, a missing entry, invalid JSON, a wrong entry or a missing folder ok 9 - doctor exits 1 with a fix for a missing config, a missing entry, invalid JSON, a wrong entry or a missing folder --- duration_ms: 1443.7103 type: 'test' ... # Subtest: doctor never runs the command stored in the client config ok 10 - doctor never runs the command stored in the client config --- duration_ms: 295.9379 type: 'test' ... # Subtest: doctor without a client checks configs it finds and the project folder; text output ok 11 - doctor without a client checks configs it finds and the project folder; text output --- duration_ms: 551.1745 type: 'test' ... # Subtest: entryFolders skips flags and their values ok 12 - entryFolders skips flags and their values --- duration_ms: 0.8652 type: 'test' ... # Subtest: doctor fails with exit 1 on Node.js older than 20 ok 13 - doctor fails with exit 1 on Node.js older than 20 --- duration_ms: 306.2257 type: 'test' ... # Subtest: doctor on Windows (simulated): cmd /c npx is ok, plain npx gets a warning ok 14 - doctor on Windows (simulated): cmd /c npx is ok, plain npx gets a warning --- duration_ms: 700.7408 type: 'test' ... # Subtest: doctor reads an old ~/.codeium Windsurf config and warns that it moved ok 15 - doctor reads an old ~/.codeium Windsurf config and warns that it moved --- duration_ms: 349.2272 type: 'test' ... # Subtest: without folder arguments the server uses the client's MCP roots ok 16 - without folder arguments the server uses the client's MCP roots --- duration_ms: 95.206 type: 'test' ... # Subtest: folder arguments take precedence over client roots ok 17 - folder arguments take precedence over client roots --- duration_ms: 16.0228 type: 'test' ... # Subtest: non-file roots are ignored ok 18 - non-file roots are ignored --- duration_ms: 2.4636 type: 'test' ... # Subtest: with no folders and no client roots only analyze_code works ok 19 - with no folders and no client roots only analyze_code works --- duration_ms: 389.4016 type: 'test' ... # Subtest: clean install writes only the sentinel-ir entry with @0.2 and the project path ok 20 - clean install writes only the sentinel-ir entry with @0.2 and the project path --- duration_ms: 7.9313 type: 'test' ... # Subtest: existing servers and other fields are kept; a backup is made first; second run changes nothing ok 21 - existing servers and other fields are kept; a backup is made first; second run changes nothing --- duration_ms: 7.2713 type: 'test' ... # Subtest: a different existing sentinel-ir entry is replaced, shown before/after, never duplicated ok 22 - a different existing sentinel-ir entry is replaced, shown before/after, never duplicated --- duration_ms: 4.4657 type: 'test' ... # Subtest: invalid JSON or a wrong shape is never overwritten ok 23 - invalid JSON or a wrong shape is never overwritten --- duration_ms: 4.4217 type: 'test' ... # Subtest: --dry-run and a missing --yes write nothing; an interactive 'y' writes, anything else cancels ok 24 - --dry-run and a missing --yes write nothing; an interactive 'y' writes, anything else cancels --- duration_ms: 7.3121 type: 'test' ... # Subtest: interactive client choice by number ok 25 - interactive client choice by number --- duration_ms: 1.755 type: 'test' ... # Subtest: refuses the home folder, a disk root and missing folders ok 26 - refuses the home folder, a disk root and missing folders --- duration_ms: 3.8325 type: 'test' ... # Subtest: Cursor: project config uses ${workspaceFolder}; --global uses ~/.cursor with the absolute path ok 27 - Cursor: project config uses ${workspaceFolder}; --global uses ~/.cursor with the absolute path --- duration_ms: 3.7166 type: 'test' ... # Subtest: Claude Desktop: macOS and Windows locations (simulated HOME/APPDATA); Linux needs --config ok 28 - Claude Desktop: macOS and Windows locations (simulated HOME/APPDATA); Linux needs --config --- duration_ms: 5.2605 type: 'test' ... # Subtest: a symlinked config file is updated in place; the link stays a link ok 29 - a symlinked config file is updated in place; the link stays a link --- duration_ms: 3.8342 type: 'test' ... # Subtest: VS Code and Claude Code: setup prints their official command and writes nothing ok 30 - VS Code and Claude Code: setup prints their official command and writes nothing --- duration_ms: 2.0226 type: 'test' ... # Subtest: one-click links decode to the same pinned entry ok 31 - one-click links decode to the same pinned entry --- duration_ms: 0.3563 type: 'test' ... # Subtest: Windsurf: Devin config location, XDG_CONFIG_HOME and Windows %APPDATA% (simulated) ok 32 - Windsurf: Devin config location, XDG_CONFIG_HOME and Windows %APPDATA% (simulated) --- duration_ms: 3.9786 type: 'test' ... # Subtest: Windsurf: servers in the old ~/.codeium file are copied to the new file; the old file is not touched ok 33 - Windsurf: servers in the old ~/.codeium file are copied to the new file; the old file is not touched --- duration_ms: 3.8914 type: 'test' ... # Subtest: Windows (simulated): file entries use cmd /c npx; printed Claude Code command is for PowerShell ok 34 - Windows (simulated): file entries use cmd /c npx; printed Claude Code command is for PowerShell --- duration_ms: 5.0278 type: 'test' ... # Subtest: lists the three read-only tools ok 35 - lists the three read-only tools --- duration_ms: 377.6617 type: 'test' ... # Subtest: server reports name, version and instructions ok 36 - server reports name, version and instructions --- duration_ms: 0.7976 type: 'test' ... # Subtest: analyze_code returns the compact IR as text and structured content ok 37 - analyze_code returns the compact IR as text and structured content --- duration_ms: 31.7461 type: 'test' ... # Subtest: analyze_code keeps comment text out of the IR ok 38 - analyze_code keeps comment text out of the IR --- duration_ms: 2.6057 type: 'test' ... # Subtest: analyze_code reports source that does not parse ok 39 - analyze_code reports source that does not parse --- duration_ms: 2.5981 type: 'test' ... # Subtest: analyze_file reads a file by relative and by absolute path ok 40 - analyze_file reads a file by relative and by absolute path --- duration_ms: 17.6316 type: 'test' ... # Subtest: analyze_file refuses paths outside the allowed folder ok 41 - analyze_file refuses paths outside the allowed folder --- duration_ms: 6.592 type: 'test' ... # Subtest: analyze_file refuses a symlink that points outside ok 42 - analyze_file refuses a symlink that points outside --- duration_ms: 2.8177 type: 'test' ... # Subtest: analyze_file refuses non-JavaScript files, folders and missing files ok 43 - analyze_file refuses non-JavaScript files, folders and missing files --- duration_ms: 6.8568 type: 'test' ... # Subtest: analyze_directory summarizes files sorted by risk and skips what it must ok 44 - analyze_directory summarizes files sorted by risk and skips what it must --- duration_ms: 25.5832 type: 'test' ... # Subtest: analyze_directory honours recursive, max_files and sub-folders ok 45 - analyze_directory honours recursive, max_files and sub-folders --- duration_ms: 20.8562 type: 'test' ... # Subtest: analyze_directory refuses folders outside and rejects invalid limits ok 46 - analyze_directory refuses folders outside and rejects invalid limits --- duration_ms: 3.5449 type: 'test' ... # Subtest: --max-file-bytes refuses larger files and skips them in folders ok 47 - --max-file-bytes refuses larger files and skips them in folders --- duration_ms: 532.962 type: 'test' ... # Subtest: parse failures are counted once, sorted, and add up to analyzed ok 48 - parse failures are counted once, sorted, and add up to analyzed --- duration_ms: 73.9205 type: 'test' ... # Subtest: the summary is identical across repeated runs ok 49 - the summary is identical across repeated runs --- duration_ms: 96.216 type: 'test' ... # Subtest: a file that cannot be read is listed in skipped.unreadable, not counted ok 50 - a file that cannot be read is listed in skipped.unreadable, not counted --- duration_ms: 16.0529 type: 'test' ... # Subtest: max_files truncation keeps counts consistent ok 51 - max_files truncation keeps counts consistent --- duration_ms: 30.1648 type: 'test' ... # Subtest: a real unreadable file (chmod 000) is skipped ok 52 - a real unreadable file (chmod 000) is skipped # SKIP chmod 000 does not block reads on Windows --- duration_ms: 0.1253 type: 'test' ... # Subtest: analyze_file picks the TypeScript grammar from the extension ok 53 - analyze_file picks the TypeScript grammar from the extension --- duration_ms: 383.0449 type: 'test' ... # Subtest: broken TypeScript is reported as incomplete ok 54 - broken TypeScript is reported as incomplete --- duration_ms: 3.7632 type: 'test' ... # Subtest: analyze_code accepts a language or infers it from target ok 55 - analyze_code accepts a language or infers it from target --- duration_ms: 30.5589 type: 'test' ... # Subtest: analyze_directory includes TypeScript files with their language ok 56 - analyze_directory includes TypeScript files with their language --- duration_ms: 15.1161 type: 'test' ... 1..56 # tests 56 # suites 0 # pass 55 # fail 0 # cancelled 0 # skipped 1 # todo 0 # duration_ms 5139.4793 node scripts/win-quote-probe.js (exit 0) powershell5: version 5.1.20348.5622 OK powershell5 vscode [my project]: code --% --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\my project\"]}" OK powershell5 claude [my project]: claude mcp add --transport stdio sentinel-ir -- cmd /c npx -y sentinel-ir-mcp@0.2 "C:\Users\ADMINI~1\AppData\Local\Temp\quote-probe-XzRn1Y\my project" OK powershell5 vscode [it's $HOME & co]: code --% --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\it's $HOME \u0026 co\"]}" OK powershell5 claude [it's $HOME & co]: claude mcp add --transport stdio sentinel-ir -- cmd /c npx -y sentinel-ir-mcp@0.2 'C:\Users\ADMINI~1\AppData\Local\Temp\quote-probe-XzRn1Y\it''s $HOME & co' OK powershell5 vscode [100% ^caret! (x)]: code --% --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\100\u0025 \u005ecaret\u0021 (x)\"]}" OK powershell5 claude [100% ^caret! (x)]: claude mcp add-json --% sentinel-ir "{\"type\":\"stdio\",\"command\":\"cmd\",\"args\":[\"/c\",\"npx\",\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\100\u0025 \u005ecaret\u0021 (x)\"]}" OK powershell5 vscode [a %OS% b]: code --% --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\a \u0025OS\u0025 b\"]}" OK powershell5 claude [a %OS% b]: claude mcp add-json --% sentinel-ir "{\"type\":\"stdio\",\"command\":\"cmd\",\"args\":[\"/c\",\"npx\",\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\a \u0025OS\u0025 b\"]}" OK powershell5 vscode [x`y; @z]: code --% --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\x`y; @z\"]}" OK powershell5 claude [x`y; @z]: claude mcp add --transport stdio sentinel-ir -- cmd /c npx -y sentinel-ir-mcp@0.2 'C:\Users\ADMINI~1\AppData\Local\Temp\quote-probe-XzRn1Y\x`y; @z' OK cmd vscode [my project]: code --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\my project\"]}" OK cmd claude [my project]: claude mcp add --transport stdio sentinel-ir -- cmd /c npx -y sentinel-ir-mcp@0.2 "C:\Users\ADMINI~1\AppData\Local\Temp\quote-probe-XzRn1Y\my project" OK cmd vscode [it's $HOME & co]: code --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\it's $HOME \u0026 co\"]}" OK cmd claude [it's $HOME & co]: claude mcp add --transport stdio sentinel-ir -- cmd /c npx -y sentinel-ir-mcp@0.2 "C:\Users\ADMINI~1\AppData\Local\Temp\quote-probe-XzRn1Y\it's $HOME & co" OK cmd vscode [100% ^caret! (x)]: code --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\100\u0025 \u005ecaret\u0021 (x)\"]}" OK cmd claude [100% ^caret! (x)]: claude mcp add-json sentinel-ir "{\"type\":\"stdio\",\"command\":\"cmd\",\"args\":[\"/c\",\"npx\",\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\100\u0025 \u005ecaret\u0021 (x)\"]}" OK cmd vscode [a %OS% b]: code --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\a \u0025OS\u0025 b\"]}" OK cmd claude [a %OS% b]: claude mcp add-json sentinel-ir "{\"type\":\"stdio\",\"command\":\"cmd\",\"args\":[\"/c\",\"npx\",\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\a \u0025OS\u0025 b\"]}" OK cmd vscode [x`y; @z]: code --add-mcp "{\"name\":\"sentinel-ir\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"sentinel-ir-mcp@0.2\",\"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\quote-probe-XzRn1Y\\x`y; @z\"]}" OK cmd claude [x`y; @z]: claude mcp add --transport stdio sentinel-ir -- cmd /c npx -y sentinel-ir-mcp@0.2 "C:\Users\ADMINI~1\AppData\Local\Temp\quote-probe-XzRn1Y\x`y; @z" node scripts/compat-smoke.js (exit 0) PASS tarball version: 0.2.3 PASS setup claude-desktop: {"file":"C:\\Users\\Administrator\\AppData\\Roaming\\Claude\\claude_desktop_config.json","entry":{"command":"cmd","args":["/c","npx","-y","sentinel-ir-mcp@0.2","C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\sentinel-compat-1D3tdj\\my project"]}} PASS setup claude-desktop again is a no-op: 0 PASS doctor claude-desktop: ok:node ok:package ok:claude-desktop.entry ok:mcp.handshake ok:mcp.tools ok:mcp.call PASS setup cursor: {"file":"C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\sentinel-compat-1D3tdj\\my project\\.cursor\\mcp.json","entry":{"command":"cmd","args":["/c","npx","-y","sentinel-ir-mcp@0.2","${workspaceFolder}"]}} PASS setup cursor again is a no-op: 0 PASS doctor cursor: ok:node ok:package ok:cursor.entry ok:mcp.handshake ok:mcp.tools ok:mcp.call PASS setup windsurf: {"file":"C:\\Users\\Administrator\\AppData\\Roaming\\devin\\mcp_config.json","entry":{"command":"cmd","args":["/c","npx","-y","sentinel-ir-mcp@0.2","C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\sentinel-compat-1D3tdj\\my project"]}} PASS setup windsurf again is a no-op: 0 PASS doctor windsurf: ok:node ok:package ok:windsurf.entry ok:mcp.handshake ok:mcp.tools ok:mcp.call INFO raw spawn('npx', no shell): {"started":false,"error":"ENOENT"} INFO MCP SDK client, command "npx": {"ok":true,"version":"0.2.2","tools":["analyze_code","analyze_directory","analyze_file"],"files":["run.js:critical","broken.ts:low"],"incomplete":["broken.ts"]} INFO MCP SDK client, command "cmd /c npx": {"ok":true,"version":"0.2.2","tools":["analyze_code","analyze_directory","analyze_file"],"files":["run.js:critical","broken.ts:low"],"incomplete":["broken.ts"]} PASS published sentinel-ir-mcp@0.2 starts through npx from an MCP SDK client: see INFO lines INFO npm 10.9.9, npx started inside a folder whose path contains %: {"ok":true,"version":"0.2.2","tools":["analyze_code","analyze_directory","analyze_file"],"files":["run.js:critical"],"incomplete":[]} INFO npx started elsewhere, folder argument contains %: {"ok":true,"version":"0.2.2","tools":["analyze_code","analyze_directory","analyze_file"],"files":["run.js:critical"],"incomplete":[]} compat-smoke leftover: %APPDATA%\Claude\claude_desktop_config.json { "mcpServers": { "sentinel-ir": { "command": "cmd", "args": [ "/c", "npx", "-y", "sentinel-ir-mcp@0.2", "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\sentinel-compat-1D3tdj\\my project" ] } } } compat-smoke leftover: %APPDATA%\devin\mcp_config.json { "mcpServers": { "sentinel-ir": { "command": "cmd", "args": [ "/c", "npx", "-y", "sentinel-ir-mcp@0.2", "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\sentinel-compat-1D3tdj\\my project" ] } } }

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More AI & Machine Learning News