Releases: M-Pineapple/warp-command-runner
Release list
v8.0.0 — remote MCP for phone and cloud hosts
Stdio is unchanged. Opt-in Streamable HTTP so Grok, ChatGPT, and Claude can call this Mac when you publish HTTPS yourself.
Added
warp-command-runner --http— Streamable HTTP on127.0.0.1only (default port 8741)- OAuth 2.1 with PKCE, Dynamic Client Registration, protected-resource metadata, refresh tokens
remoteblock inconfig.json:listenPort,publicBaseURL,allowKeystrokeTools(requireMacApprovalis parsed and reserved; it does not yet show a Mac prompt)--remote-doctor,--install-agent,--uninstall-agentdocs/REMOTE.mdandconfig/remote.example.json(fictionalhttps://mcp.example.com)
Changed
- Remote sessions refuse the five Warp-routing tools unless
allowKeystrokeToolsis true. Useexecute_pipeline. - Compatibility docs describe the tunnel path. This project still does not host a relay.
Notes
- The public URL is whatever you create (Cloudflare named tunnel, Tailscale Funnel, or a reverse proxy on your account). Quick tunnels change hostname every start.
- The Mac must stay awake and the
--httpprocess must stay running. - ChatGPT write tools need Developer mode. Whether iOS can invoke them is a host limit.
Upgrading: rebuild with ./build.sh, then rm -rf "/Applications/Warp Command Runner.app" && cp -R .build/release/warp-command-runner.app "/Applications/Warp Command Runner.app" and restart the MCP host. For remote MCP, run warp-command-runner --http (or --install-agent) and point your own tunnel at 127.0.0.1:8741. See docs/REMOTE.md.
See CHANGELOG.md for the full list.
v7.0.0 — Warp Command Runner rebrand
Formerly Claude Command Runner. Same MCP server; names and docs match how the protocol actually works.
The v6 binary already spoke standard MCP over stdio. Any local host (Warp Agent with Grok/GPT/Claude/Gemini, Claude Desktop, ChatGPT desktop, Cursor, VS Code, Continue, …) could call it. The product name still said "Claude", which hid that. v7.0 renames the project and records the compatibility boundary: local MCP hosts yes, browser cloud chats no.
Changed
- Package, executable, Swift module,
.appbundle, and MCPserverInfoname:warp-command-runner/ Warp Command Runner - Bundle ID
com.m-pineapple.warp-command-runner(v6 TCC grants on the old ID do not transfer — re-grant once) - Config/history directory
~/.warp-command-runner(copies~/.claude-command-runneron first launch; old folder is not deleted) - Capture files
/tmp/wcr_*(still reads leftover/tmp/claude_*from in-flight v6 commands) - Shell shim socket
/tmp/wcr-shell-shim-<uid>.sock; installer replaces the v6 rc marker WCR_CODESIGN_IDENTITY(the v6CCR_CODESIGN_IDENTITYalias still works)- Docs and
config/snippets for Warp, Claude Desktop, ChatGPT desktop, Cursor, VS Code, and generic stdio - New
docs/COMPATIBILITY.md
Docs
- Cursor splits MCP
commandon spaces, so/Applications/Warp Command Runner.app/...fails withspawn /Applications/Warp ENOENT. Runhelper/install-cursor-wrapper.shand point Cursor at~/.local/bin/warp-command-runner. Warp and Claude Desktop keep the official bundle path. Do not rename the.app.
Migration
- Build v7, copy the bundle to
/Applications/Warp Command Runner.app - Change every MCP config key and path from
claude-command-runnertowarp-command-runner - Re-grant Full Disk Access, Input Monitoring, Accessibility, and Automation for the new bundle
- Restart the host. Config and command history should already be in
~/.warp-command-runner
Notes
- This is not a remote/HTTPS MCP. Do not tunnel it to chatgpt.com / grok.com / claude.ai.
- Tool count and behaviour are unchanged from 6.2.0.
Upgrading: rebuild with ./build.sh, then rm -rf "/Applications/Warp Command Runner.app" && cp -R .build/release/warp-command-runner.app "/Applications/Warp Command Runner.app" and restart the MCP host.
See CHANGELOG.md for the full list.
v6.2.0 — full code audit: reliability, security ordering, real test suite
A full audit of the codebase (~9,500 lines) drove this release: two classes of live bug fixed, a security guard that only existed in dead code wired into the live path, ~900 lines of dead code removed, and the placeholder test replaced with a 30-test suite.
Fixed
- MCP protocol corruption —
DatabaseManagerlogged to stdout (the JSON-RPC channel), including on everyexecute_command. All logging now goes to stderr. - Pipe deadlocks — every spawn site waited for exit before reading pipes; children writing > ~64 KB deadlocked permanently. New shared
runProcess()drains pipes concurrently. - Unbounded hangs — execution timeouts added everywhere (pipeline/SSH 600s, file-watch 300s, AppleScript 30s) with SIGTERM → SIGKILL escalation; blocking waits moved off the Swift cooperative pool.
- Interactive-command guard now runs on the live execute path —
vim, baressh,topetc. are blocked with a helpful message instead of hanging the capture script. Pipe-spanning patterns (curl … | sh) can now match. - Security ordering — blocked commands were saved to history before the block check (recorded as executed). Checks now run first and cover the full command including the
cdprefix;working_directoryis escaped against quote-breakout. - Database hardening — serial queue +
SQLITE_OPEN_FULLMUTEX, NULL-handle guards,PRAGMA user_versionschema versioning, and retention cleanup that actually runs at startup (commands + analytics; the cleanup paths previously had no callers). - FileWatcher — suspended-source cancel crash, unbalanced suspend/resume, and actor-blocking command execution all fixed.
- Schema/handler mismatches —
open_terminal_tabhonoursworking_directory; numeric parameters accept JSON numbers as declared.
Removed
- The vestigial
--port/-poption (the TCP listener it configured was retired in v6.0). Remove it from your MCP configargsif present.
Tests
- 30-test suite: detector table tests, DB round-trips + 50-writer concurrency, large-output no-deadlock proof, timeout termination, live injection-prevention check, output-capture script executed for real.
Upgrading: rebuild with ./build.sh, then rm -rf "/Applications/Claude Command Runner.app" && cp -R .build/release/claude-command-runner.app "/Applications/Claude Command Runner.app" and restart Claude Desktop. TCC grants persist if you sign with the same identity.
See CHANGELOG.md for the full list.
v6.1.0 — template CRUD, real shell env capture, shim exit-code confirmation
Added
delete_template— completes the template CRUD (save / run / list / delete). Tool count 39 → 40.- Shell-shim exit-code confirmation — when the optional shim is active,
get_command_outputuses the shell's authoritative exit code and can confirm completion even if the/tmpcapture is missing. Safe no-op without the shim.
Changed
capture_environmentcaptures your real shell environment — spawns your login + interactive shell so~/.zprofile/~/.zshrcare sourced, with a timeout watchdog and graceful fallback.execute_pipelinesteps are recorded in command history (exit code + duration).suggest_commandacceptsworking_directoryso contextual git / Swift / Node suggestions actually fire; no more junk globs for natural-language queries.TerminalConfig.getPreferredTerminal()honoursconfig.jsonbefore auto-detecting.
See CHANGELOG.md for details.
v6.0.5 - correctness fixes
Correctness fixes from auditing each tool against its documented behavior.
- open_terminal_tab (Warp): reports tab creation as dispatched/unconfirmed; the returned id is a local tracking id, not a Warp session UUID
- get_command_output: the documented "last" alias resolves to the most recent output
- add_file_watch: the pattern filter is now applied
- command history: completed commands record exit code and duration instead of staying pending
- self_check: Warp running-state detection fixed (matches the app path)
- internal: resolved a latent DispatchQueue deadlock in DatabaseManager.updateCommand
See CHANGELOG.md for full details.
v6.0.4 — documented full macOS Sequoia TCC setup recipe
[6.0.4] - 2026-05-16 — full macOS Sequoia TCC setup recipe documented
Why this release exists
v6.0.3 shipped the .app bundle wrapper. Verifying it end-to-end on a live install revealed a fifth layer of macOS Sequoia's TCC enforcement that wasn't obvious from the code: kTCCServiceSystemPolicyAllFiles (Full Disk Access) is checked by the sandbox preflight before the AppleEvents/Input Monitoring chain even runs. Bundle ID grants in System Settings → Privacy & Security → Automation/Input Monitoring don't help if the bundle lacks Full Disk Access — sandboxd denies first, the user sees the misleading "send keystrokes" error, and they spend hours toggling the wrong panels.
Once FDA is granted to the bundle (in addition to Automation, Input Monitoring, and Accessibility), the chain works permanently. Empirically verified on macOS Sequoia 26.x with a 6-hour debugging session captured in detail.
Documentation
- README "🛡️ macOS Sequoia full setup recipe (the 7 ordered steps)" — a new top-level section under Installation replacing the old "Stable code signing" section. Documents the empirically-verified procedure for getting the 5 keystroke-routing tools working on macOS Sequoia:
- Have an Apple Development cert (or self-signed Code Signing cert) in Keychain
./build.shproduces the.appbundle at.build/release/claude-command-runner.app/- Copy the bundle into
/Applications/(TCC refuses to prompt for bundles in dev directories — this was the second-to-last layer) - Point Claude Desktop / Warp Agent config at the
/Applications/bundle path tccutil reset AppleEvents/ListenEvent/PostEvent/Accessibilityfor the bundle ID- Grant THREE permissions in System Settings → Privacy & Security: Full Disk Access (the surprise), Input Monitoring, Accessibility
- Restart Claude Desktop, accept the Automation prompt on first
execute_command
- Includes the diagnostic command for reading the TCC log (
log show --predicate 'process == "tccd"') and what to look for in the output (promptPolicy=0vs=2,Service Policy: Denied, attribution chain identifier). - README "Error 1002" troubleshooting rewritten to point users at the canonical recipe instead of repeating outdated partial fixes. Adds a quick-triage matrix mapping log signals to specific recipe steps.
- MCP
serverInfo.version6.0.3 → 6.0.4.
Notes
- No code changes — pure documentation pass that captures real install experience.
- Tool count unchanged at 39.
- The bundle architecture from v6.0.3 stays exactly as-is; this release is about helping the next user avoid the trap.
v6.0.3 — .app bundle wrapper (TCC prompts finally appear)
[6.0.3] - 2026-05-16 — .app bundle wrapper (TCC prompts actually appear now)
Why this release exists
v6.0.2 added stable code-signing to fix cdhash drift across rebuilds. That solved one layer of the TCC problem but uncovered the next: modern macOS (Sequoia and later) silently denies TCC permission prompts for CLI binaries that lack an embedded Info.plist with NSXxxUsageDescription strings. No dialog appears; no error in System Settings; just silent denial. The 5 keystroke-routing tools (execute_command, execute_with_auto_retrieve, execute_with_streaming, run_template, send_to_session) hit this. Hours of TCC-cleanup and re-grant cycles did not resolve it — the permission prompts the user needed to grant were never being shown because the binary had no Info.plist to drive them.
Empirical confirmation from the live TCC log: auth_value=1 (Unknown) on every request from claude-command-runner to kTCCServiceListenEvent, no Prompting entry ever appearing — the textbook silent-deny pattern for CLI binaries.
Fixed
scripts/make-app-bundle.sh(new) wraps the built CLI binary in a proper.appbundle at.build/release/claude-command-runner.app/. The bundle structure is minimal —Contents/MacOS/claude-command-runner+Contents/Info.plist, no Resources, no icon. TheInfo.plistdeclares:CFBundleIdentifier=com.m-pineapple.claude-command-runner(stable, reverse-DNS, so TCC can target the bundle by identity rather than by cdhash)LSUIElement=true(don't show in Dock when launched — we're a CLI, not a UI app)NSAppleEventsUsageDescription,NSInputMonitoringUsageDescription,NSAccessibilityUsageDescription— these are what macOS shows in the permission prompt; missing them = silent denial
build.shnow invokesscripts/make-app-bundle.shafter the binary is built (and code-signed ifCCR_CODESIGN_IDENTITYis set). The bundle is signed as a unit when the env var is present.config/claude-desktop-config.jsonandconfig/warp-agent-mcp.jsonupdated to point at the binary inside the bundle:.build/release/claude-command-runner.app/Contents/MacOS/claude-command-runner. README +docs/WARP_AGENT.mdfollow.- MCP
serverInfo.version6.0.2 → 6.0.3.
Changed (potentially breaking — see Migration)
- Recommended install path moved from
.build/release/claude-command-runnerto.build/release/claude-command-runner.app/Contents/MacOS/claude-command-runner. The bare-binary path still exists (we keep a copy for backwards compat) and still works for the 34 tools that don't use keystroke routing. The 5 keystroke-routing tools require the bundle path.
Migration (existing v6.0.x users)
Edit your config files and append .app/Contents/MacOS/claude-command-runner to the existing path:
- "command": ".../claude-command-runner/.build/release/claude-command-runner",
+ "command": ".../claude-command-runner/.build/release/claude-command-runner.app/Contents/MacOS/claude-command-runner",Restart Claude Desktop / Warp. On the next execute_command, macOS should finally prompt for AppleEvents / Input Monitoring permission — grant once and it sticks (combined with v6.0.2's stable signing, the grant survives future rebuilds).
If you'd previously added the bare claude-command-runner binary to System Settings → Privacy & Security → Input Monitoring / Automation, those entries become orphans (different identity from the bundle). Safe to remove for hygiene; not required for functionality.
Notes
- Tool count unchanged: 39.
- No source code changes beyond the version-string bump.
scripts/make-app-bundle.shis idempotent — re-runs overwrite the bundle cleanly.
v6.0.2 — optional stable code signing (eliminates TCC drift across rebuilds)
[6.0.2] - 2026-05-16 — stable code signing opt-in
Why this release exists
Live diagnosis on a user's machine revealed that the persistent "osascript is not allowed to send keystrokes (1002)" issue affecting the 5 AppleScript-routed tools is not a configuration problem — it's a structural one. Empirical evidence captured via log show --predicate 'process == "tccd"':
- The TCC service being denied is
kTCCServiceAppleEvents, NOTkTCCServiceAccessibility. The error message's "keystrokes" wording is misleading; the actual gate failing is the AppleEvents/Automation permission. - The binary is ad-hoc signed (Swift's default for
swift build). Every rebuild produces a newcdhash. macOS treats each rebuild as a separate program for TCC purposes, orphaning the previous grant. - The user's
System Settings → Privacy & Security → Automationpanel had three separateclaude-command-runnerentries — one per rebuild cycle — visually confirming the drift. - Claude Desktop spawns the MCP server via Apple's
responsibility_spawnattrs_setdisclaimhelper (/Applications/Claude.app/Contents/Helpers/disclaimer), which deliberately prevents Claude.app's TCC grants from propagating to the child. So granting Claude.app permissions doesn't help; the child binary's own identity is what TCC checks.
Every user who ever rebuilds this project hits this. The first install works (TCC prompts, user grants). The first git pull && ./build.sh silently breaks it. Until v6.0.2, the only "fix" was to re-grant after every rebuild — tedious and confusing.
Fixed
- build.sh now supports stable code signing via
CCR_CODESIGN_IDENTITYenv var. When set, the binary is signed with the user's chosen certificate (typically a self-signed cert from Keychain Access). Resulting cdhash is stable across rebuilds. Grant TCC once, it persists indefinitely. Opt-in to preserve backwards compatibility — unset means ad-hoc behavior unchanged from v6.0.x. - build.sh: dropped stale
--port 9876invocation hint from the post-build install instructions (the TCP listener was deleted in Tier A of v6.0.0). - build.sh: updated install hint to point at both Claude Desktop and Warp Agent config paths (was Warp-only and outdated).
- MCP
serverInfo.version6.0.1 → 6.0.2.
Documentation
- README "Stable code signing" section added under Installation (after the optional shell shim step). Explains the cdhash-drift problem in 3 sentences, the 5-step Keychain Access cert-generation flow, the
CCR_CODESIGN_IDENTITYenv var, verification command, and theexecute_pipelinefallback for users who'd rather not sign. - CHANGELOG v6.0.2 entry (this one) captures the empirical TCC log evidence so future readers don't have to re-do the investigation.
Migration
For existing users hitting the TCC stuckness:
- Generate a self-signed code-signing cert in Keychain Access (5 steps, see README)
export CCR_CODESIGN_IDENTITY="claude-command-runner"(or whatever you named the cert)./build.sh- Remove all stale
claude-command-runnerentries fromSystem Settings → Privacy & Security → Automation - Restart Claude Desktop
- Trigger an
execute_command→ TCC prompts fresh → grant → done. Permanent until you replace the cert.
Notes
- No behavior change for users who don't set
CCR_CODESIGN_IDENTITY— backwards-compatible. - Tool count unchanged: 39.
- No API changes.
v6.0.1 — parser fix, decoder robustness, troubleshooting docs
[6.0.1] - 2026-05-07 — patch follow-up to v6.0.0
Three real findings surfaced from the v6.0.0 live verification, plus one already-staged fix that was waiting for a tag.
Fixed
execute_and_parsegit_status parser garbled output for human-readable input. The parser was hardcoded forgit status --porcelain(2-char status code at line start) and would treat the first character of every prose line as a status code — producing nonsense likeStaged: 3 file(s) • O branch mainfor actualgit statusoutput. v6.0.1 now detects format (presence of "On branch", "HEAD detached", "Changes to be committed", etc.) and dispatches to a human-format parser or the existing porcelain parser. Output for both formats is now correct.Configurationdecoder failed loudly withkeyNotFounderrors when an existing on-disk~/.claude-command-runner/config.jsonpredated one or more top-level schema fields (e.g.security). Swift's auto-synthesizedCodableinit usesdecode(notdecodeIfPresent) and ignores property defaults. v6.0.1 adds a custominit(from:)toConfigurationthat usesdecodeIfPresent ?? <default>for every top-level field. Old configs continue to load without error logs; new fields silently fall back to defaults.- MCP
serverInfo.versionwas hardcoded to"5.0.0". v6.0.1 reports"6.0.1". (Already fixed onmainbetween v6.0.0 and v6.0.1; rolled into this tag.)
Documentation
- README troubleshooting for "Error 1002 / osascript not allowed to send keystrokes" rewritten with a "Why this is so painful" section explaining macOS responsible-process attribution. Step 5 (manual
osascript -e 'tell application "System Events" to keystroke "x"'from a real shell) is now flagged as mandatory, not optional — that's the step that actually causes macOS to re-prompt and unstick the chain. Empirically validated during v6.0.0 install: every System Settings toggle was correct, full Mac restart performed, but the chain only unstuck after step 5. Also adds a workaround note:execute_pipelineis a fully-functional substitute forexecute_commandwhile TCC is being figured out — no Apple Events involved.
Notes
- Tool count unchanged: still 39.
- No API breaking changes.
- AGPL hygiene unchanged (no new vendoring).
v6.0.0 — Warp re-pivot (dual-consumer MCP, deeplinks, OSC 777, shell shim)
[6.0.0] - 2026-05-07 — Warp re-pivot
This release is a re-pivot back to Warp Terminal, triggered by Warp going open source under AGPL-3.0 (github.com/warpdotdev/warp) in early May 2026. It re-establishes Warp as the primary integration target, replaces fragile AppleScript paths with documented surfaces, and adds a new install path: Warp's native agent panel as a first-class consumer alongside Claude Desktop.
Headline
claude-command-runner is now a dual-consumer MCP server: the same binary serves both Claude Desktop and Warp's built-in agent. Same code, same tools, just two consumers. See docs/WARP_AGENT.md for the new install path.
Added
- Warp Agent registration story (Tier D). Documented
~/.warp/.mcp.jsonsetup so Warp's native agent panel can call our tools. Sample atconfig/warp-agent-mcp.json. focus_warp_sessiontool — dispatcheswarp://session/<uuid>to focus a previously-opened pane. Requires a UUID Warp itself recognises (typically from the optional shell shim's OSC 777 stream).emit_warp_eventtool — builds aprintfinvocation that emits an OSC 777warp://cli-agentJSON event into Warp's notification UI. Schema reimplemented from upstreamevent/v1.rs. Surfaces session_start / prompt_submit / tool_complete / stop / permission_request / idle_prompt.shell_shim_statustool — reports the optional shell shim's listening state and recent events.- Optional shell shim (Tier E, opt-in beta,
helper/install-shim.sh). Adds zsh/bash hooks that emit preexec/command_finished events to a per-uid Unix domain socket the MCP listens on. Auto-disables outside Warp panes (gated on$WARP_SESSION_ID). Observability surface in v6.0;execute_commandauto-routing through shim events is deferred to v6.0.x. - Workspace profiles → Warp launch configs (Tier C).
save_workspace_profileacceptsinclude_warp_launch_config: true; when set, also writes a YAML to~/.warp/launch_configurations/<name>.yamlso the profile appears in Warp's launch UI. Schema reimplemented from upstreamLaunchConfig/TabTemplate/PaneTemplateType/CommandTemplate. Env vars are not emitted into the YAML (Warp's schema does not have a top-level env map); they remain in the private CCR JSON. - Session UUID tracking —
TerminalSessionnow carries a locally-minted UUID (returned byopen_terminal_tab). Used by our registry; not bound to Warp's internal session UUID. PRODUCT.mdandTECH.md— checked-in product/tech specs for v6.0.
Changed
open_terminal_tab(Warp path) useswarp://action/new_tab?path=...instead of clickingmenu item "New Tab"via System Events. The open path no longer requires Accessibility permission. Directory is baked into the URL — no follow-upcdkeystroke. AppleScript path remains for iTerm2 / Terminal / Alacritty (unchanged).README.md— rewritten for the dual-consumer story. Tool count corrected from 30 to 39 (was previously under-counted; v6.0 adds 3 new).- swift-sdk pinned to
0.10.xwith a reproducible patch script (scripts/patch-swift-sdk.sh). Previous loosefrom: "0.1.0"resolved 0.9.0 and failed under current Swift toolchains. The patch appliesnonisolated(unsafe)to twoBooldecls inNetworkTransport.swift. Build is reproducible from a fresh clone via./build.sh. config/— dropped--port 9876and--verbosefrom the exampleclaude_desktop_config.json(port 9876 was for the now-deleted TCP listener). Removedwarp-mcp-config.jsonandwarp-mcp-config-correct.json; replaced with a single canonicalwarp-agent-mcp.json.
Removed (dead code)
WarpDatabaseIntegration.swift(260 LOC) — never reached from any registered tool. Hardcoded Warp SQLite schema; would silently break on Warp updates.CommandReceiverService.swift(201 LOC) — TCP listener on127.0.0.1:9876with mock-only handlers; never invoked from production. The liveMCPServicestruct that was sharing the file has been extracted to its own file.CommandHistoryManager.loadFromWarpDatabaseand thewarpDBproperty — neither was reachable.- The unreachable
Task-based background monitor inCommandHandlers.swift— dispatch goes throughCommandHandlersStable. The dead Task was the prior crash trigger.
Fixed
- README claimed 30 tools; the dispatch table actually registered 36. Six previously-undocumented tools surfaced:
set_notification_preference,cleanup_sessions,list_file_watches,delete_workspace_profile,list_ssh_profiles,delete_ssh_profile. With v6.0's three new tools (focus_warp_session,emit_warp_event,shell_shim_status), the live count is 39.
Tool count
| Version | Tools | Note |
|---|---|---|
| v5.0.0 advertised | 30 | README claim |
| v5.0.0 actual | 36 | dispatch table |
| v6.0.0 | 39 | dispatch table |
Migration
- Existing Claude Desktop users: edit
claude_desktop_config.jsonto drop--port 9876fromargs. The MCP server still tolerates the flag (it's parsed and ignored), but it serves no purpose post-v6.0. - New Warp Agent users: see
docs/WARP_AGENT.md. - Optional shim users:
helper/install-shim.shadds a clearly-marked block to your~/.zshrcor~/.bashrc.helper/uninstall-shim.shremoves it. - Build: run
./build.sh(now invokesscripts/patch-swift-sdk.shautomatically). Or for manual builds:swift package resolve && ./scripts/patch-swift-sdk.sh && swift build -c release.
Non-goals (deliberately out of scope)
- Bridging Claude Desktop conversations into Warp (would require server-push; reinvents Claude Code).
- Replacing Claude Code as a TUI agent in a Warp pane.
- Reading Warp's internal SQLite (~80 Diesel migrations in 5 years; schema unstable).
- Becoming a Warp plugin (no third-party plugin API exists;
CLIAgentregistry is a closed enum). - Wave Terminal support (the prior local repurposing was incorrect; Wave is not a target).
AGPL hygiene
Warp is AGPL-3.0. Our MCP communicates with Warp over IPC (warp:// URLs and OSC escape sequences) and through the MCP protocol — copyleft does not propagate. No Warp source is vendored. All schemas (OSC 777 event JSON, launch config YAML) are reimplemented from observed shape, not copied.