Thanks for support..
Release: "Sentinel-IR-MCP v0.2.2 on GitLab" (https://gitlab.com/jakubrojicek11/sentinel-ir-mcp/-/tree/v0.2.2?ref_type=tags)
Package: "sentinel-ir-mcp@0.2.2 on npm" (https://www.npmjs.com/package/sentinel-ir-mcp/v/0.2.2)
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 spawnedC:\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. Screenshotsvscode-A-01-list-stopped.png/vscode-A-02-list-after-start.pngare 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 <path>; 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
claudeis 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-yreaches 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.ps1script, it is passed through as a literal argument. - The printed cmd.exe variants work for A and B (
√ Connected, exact path stored).
- A:
- Cursor: the README deeplink entry (raw
npx, user-level) connected with 3 tools without login; Cursor itself wraps it incmd.exe /d /s /c. The setup-written project entry (cmd /c npx,.cursor/mcp.json) was detected but stayeddisconnectedand was never spawned (enabledTotal: 0). Cause not verified (could be project-server approval, which is behind the login screen). -
doctordoes its own handshake against the local package (reports 0.2.3), so a passing doctor does not prove the configurednpx -y sentinel-ir-mcp@0.2command starts from inside the app. -
scripts/compat-smoke.jswrites into the real%APPDATA%\Claude\claude_desktop_config.jsonand%APPDATA%\devin\mcp_config.jsonand leftsentinel-irentries 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 --yeswithout--projectsilently 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*.logcontent (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") <- cmd.exe /d /s /c "npx ^"-y^" ^"sentinel-ir-mcp@0.2^" ^"C:\sentinel-test\my^ project^"" <- Cursor.exe <- Cursor.exe ~/.cursor/mcp.json written by the deeplink: {"mcpServers":{"sentinel-ir":{"command":"npx","args":["-y","sentinel-ir-mcp@0.2","${workspaceFolder}"],"env":{}}}} Devin / Windsurf log (excerpt)
mcpGateway.log: 2026-10-22 16:33:03.393 [info] [McpGatewayService] Initialized (no line containing "sentinel" in any file under %APPDATA%\devin\logs\20261022T163303) Claude Desktop logs
%APPDATA%\Claude\logs\ : directory exists, contains no files (no mcp*.log) after start and "Get started" -> Sign In screen. doctor --json
doctor --client cursor --project A --json (exit 0)
{ "ok": true, "checks": [ { "status": "ok", "id": "node", "message": "Node.js v22.23.4" }, { "status": "ok", "id": "package", "message": "sentinel-ir-mcp 0.2.3, sentinel-ir 0.2.0" }, { "status": "ok", "id": "cursor.entry", "message": "Cursor: \"sentinel-ir\" runs cmd /c npx -y sentinel-ir-mcp@0.2 ${workspaceFolder}" }, { "status": "ok", "id": "mcp.handshake", "message": "MCP handshake with sentinel-ir-mcp 0.2.3" }, { "status": "ok", "id": "mcp.tools", "message": "Tools: analyze_code, analyze_directory, analyze_file" }, { "status": "ok", "id": "mcp.call", "message": "analyze_directory works on C:\\sentinel-test\\my project (1 file(s) checked)" } ] } doctor --client windsurf --json (exit 0, A config)
{ "ok": true, "checks": [ { "status": "ok", "id": "node", "message": "Node.js v22.23.4" }, { "status": "ok", "id": "package", "message": "sentinel-ir-mcp 0.2.3, sentinel-ir 0.2.0" }, { "status": "ok", "id": "windsurf.entry", "message": "Windsurf: \"sentinel-ir\" runs cmd /c npx -y sentinel-ir-mcp@0.2 C:\\sentinel-test\\my project" }, { "status": "ok", "id": "mcp.handshake", "message": "MCP handshake with sentinel-ir-mcp 0.2.3" }, { "status": "ok", "id": "mcp.tools", "message": "Tools: analyze_code, analyze_directory, analyze_file" }, { "status": "ok", "id": "mcp.call", "message": "analyze_directory works on C:\\sentinel-test\\my project (1 file(s) checked)" } ] } doctor --client windsurf --json after legacy migration (exit 0)
{ "ok": true, "checks": [ { "status": "ok", "id": "node", "message": "Node.js v22.23.4" }, { "status": "ok", "id": "package", "message": "sentinel-ir-mcp 0.2.3, sentinel-ir 0.2.0" }, { "status": "ok", "id": "windsurf.entry", "message": "Windsurf: \"sentinel-ir\" runs cmd /c npx -y sentinel-ir-mcp@0.2 C:\\Users\\Administrator\\repos\\sentinel-ir-mcp" }, { "status": "ok", "id": "mcp.handshake", "message": "MCP handshake with sentinel-ir-mcp 0.2.3" }, { "status": "ok", "id": "mcp.tools", "message": "Tools: analyze_code, analyze_directory, analyze_file" }, { "status": "ok", "id": "mcp.call", "message": "analyze_directory works on C:\\Users\\Administrator\\repos\\sentinel-ir-mcp (1 file(s) checked)" } ] } doctor --client claude-desktop --json (exit 0)
{ "ok": true, "checks": [ { "status": "ok", "id": "node", "message": "Node.js v22.23.4" }, { "status": "ok", "id": "package", "message": "sentinel-ir-mcp 0.2.3, sentinel-ir 0.2.0" }, { "status": "ok", "id": "claude-desktop.entry", "message": "Claude Desktop: \"sentinel-ir\" runs cmd /c npx -y sentinel-ir-mcp@0.2 C:\\sentinel-test\\my project" }, { "status": "ok", "id": "mcp.handshake", "message": "MCP handshake with sentinel-ir-mcp 0.2.3" }, { "status": "ok", "id": "mcp.tools", "message": "Tools: analyze_code, analyze_directory, analyze_file" }, { "status": "ok", "id": "mcp.call", "message": "analyze_directory works on C:\\sentinel-test\\my project (1 file(s) checked)" } ] } Scripts
npm test (exit 0)
> sentinel-ir-mcp@0.2.3 test > 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\\AppD...





