Claude Command Runner
About
MCP server for Warp Terminal. Drives Claude commands into your active Warp tab via warp:// deeplinks and OSC 777 events. Works from Claude Desktop or Warp's native agent panel. macOS, Swift.
Details
- Author
- m-pineapple
- Categories
- Developer Tools, Other
Jump to
🛡️ macOS Sequoia full setup recipe (the 7 ordered steps)
Ifexecute_command/execute_with_auto_retrieve/execute_with_streaming/run_template/send_to_sessionfail withosascript is not allowed to send keystrokes (1002)even though you've toggled every panel in System Settings,follow this in order — skipping any step leaves a silent denial somewhere in the chain.The other 34 tools work without any of this;execute_pipelineis a fully-functional substitute if you want to skip the whole TCC saga entirely.
This is the empirically-verified recipe from a real 6-hour debugging session. v6.0.3+ ships the bundle infrastructure that makes this possible; v6.0.4 is this documentation pass.
The denial pattern.macOS Sequoia's TCC and sandbox have layered,non-obviousrequirements for CLI binaries that driveosascript → System Events → keystroke. The error message is misleading — the actual block usually isn't keystroke permission; it's an earlier preflight check that silently aborts the chain. The five gates, in the order macOS evaluates them:
Step 3 — Install the bundle into/Applications/(CRITICAL)
macOS refuses to prompt for TCC permissions on bundles in.build/release/or other dev directories.The bundle must live in/Applications/. Copy it:
cp -R .build/release/claude-command-runner.app "/Applications/Claude Command Runner.app"
codesign --verify --deep --strict "/Applications/Claude Command Runner.app"
Lets Claude actually use your terminal.You ask, Claude types the command into yourWarptab, captures the output, and tells you what happened. It's a Model Context Protocol (MCP) server with 40 tools — command execution, project setups, file watching, SSH, clipboard, environment intelligence — and the same binary works from both Claude Desktop and Warp's built-in AI agent panel. macOS, Swift, open source.
Built forWarp Terminal(free, open source AGPL-3.0). The 5 most powerful tools route commands visibly into your active Warp tab — that's the magic of this MCP. If you don't use Warp yet,grab it here— it pairs with this MCP for what's probably the closest thing to "Claude with a real terminal" you can get right now.
🚀 What's New in v6.0.0 — Warp re-pivot
Triggered by Warp going open sourceunder AGPL-3.0 (github.com/warpdotdev/warp) in May 2026. v6.0 re-establishes Warp as the primary integration target and adds a new install path:Warp's native agent panel.
- Dual-consumer architecture: registerclaude-command-runnerin~/.warp/.mcp.jsonand Warp's built-in agent (which uses your configured LLM — Claude Sonnet, Opus, etc.) calls the same tools Claude Desktop calls. Same binary, same code, two consumers. Seedocs/WARP_AGENT.md.
- Deeplinks replace AppleScriptfor tab/window operations:open_terminal_tabnow useswarp://action/new_tab?path=.... No menu-clicking, no Accessibility permission for the open path.
- OSC 777 emitter(emit_warp_event): buildprintfinvocations that surface structured events into Warp's notification UI. Schema reimplemented from upstreamevent/v1.rs(no vendoring).
- Workspace profiles → Warp launch configs:save_workspace_profileacceptsinclude_warp_launch_config: trueto also write a YAML to~/.warp/launch_configurations/, making the profile appear in Warp's launch UI.
- Optional shell shim(Tier E, opt-in):helper/install-shim.shadds zsh/bash hooks that emit preexec/command_finished events to a per-uid Unix socket the MCP listens on. Auto-disables outside Warp panes. Observability surface in v6.0; auto-routingexecute_commandthrough it is deferred to v6.0.x.
- Cleanup: ~460 LOC of dead code removed (obsolete Warp DB integration, orphan TCP listener, unreachable background monitor). Tool count corrected: README claimed 30, reality was 36, v6.0 ships 39.
- Reproducible build: swift-sdk pinned to0.10.xwith a deterministicscripts/patch-swift-sdk.shso a fresh clone builds without manual patches.
Honest caveat:the "Claude" replying in Warp's agent panel isWarp'sagent (running whichever LLM you configure in Warp's AI settings), not your Claude Desktop instance. Both can call the MCP; they don't share conversations. v6.0 does not bridge them.
- Clipboard Bridge: Read from and write to the macOS clipboard without leaving the conversation
- macOS Notifications: Get native notifications when long-running commands finish
- Environment Intelligence: Probe your terminal context (git branch, active venv, Node version, Docker containers) in one call
- Output Parsers: Structured JSON parsing forgit status,docker ps, test results, and more
- Environment Snapshots: Capture and diff environment variables before/after installs or config changes
- Workspace Profiles: Save and restore project contexts (directory, env vars, common commands) per project
- Multi-Terminal Sessions: Open, name, and send commands to multiple terminal tabs
- Interactive Command Detection: Smart detection of interactive commands (vim, ssh, python REPL) with graceful handling
- File System Watchers: Watch directories for changes and trigger commands automatically
- SSH Remote Execution: Run commands on remote hosts via SSH key authentication
- v4.0: Command pipelines, output streaming, reusable templates
- v3.0: Smart auto-retrieve, SQLite history, configurable security
Claude Command Runner is adual-consumer MCP server— the same binary serves Claude DesktopandWarp's native agent panel. It enables an LLM (whichever you've configured in either client) to:
- Execute terminal commands directly from conversations
- Chain commands with conditional logic using pipelines
- Stream output in real-time for long builds
- Save and reuse command templates with variables
- Automatically capture output with intelligent timing
- Track command history and patterns
- Read/write the macOS clipboard
- Probe environment context (git, venv, Docker, Node)
- Parse command output into structured JSON
- Manage workspace profiles per project (with optional emission as Warp launch configs)
- Open terminal tabs (viawarp://deeplinks; AppleScript fallback for non-Warp terminals) and send commands to the active tab
- Watch files and trigger commands on changes
- Execute commands on remote hosts via SSH
- (v6.0)Surface tool-execution status to Warp's UI as OSC 777warp://cli-agentevents
- (v6.0, opt-in)Stream clean preexec / command-finished events from your shell to the MCP via a per-uid Unix domain socket
🧭 Which Claude product does this work with?
claude-command-runneris an MCP server, so any Anthropic surface that consumes MCP servers can call its 40 tools — but thevalue-add varies sharply by consumer, and you should pick deliberately.
- You use Warp + Claude Desktop and want commands visible in your terminal?→ Register here. Primary use case.
- You use Warp + Claude Code and want everything in one pane?→ Don't bother. Claude Code's built-inBashtool is enough.
- You use Warp + Claude Code and want commands in aseparateobservable Warp tab?→ Register and useexecute_commanddeliberately.
- You use Warp's native agent panel?→ Register in~/.warp/.mcp.json.
- You don't use Warp?→ This isn't the right MCP for you. Look at simpler subprocess-based MCPs.
The "40 tools" headline is honest but slightly misleading: 5 of those tools (the AppleScript-keystroke ones —execute_command,execute_with_auto_retrieve,execute_with_streaming,run_template,send_to_session) are the Warp-routing crown jewels, and 25 of them are pure server-side utilities that any subprocess-based MCP could provide. The remaining 10 sit in between (deeplinks, OSC 777, profiles, file watchers). If the Warp-routing 5 don't appeal, the rest of this MCP is fine but unremarkable.
Chain multiple commands with intelligent failure handling:
{ "steps": [ {"name": "Build", "command": "swift build", "on_fail": "stop"}, {"name": "Test", "command": "swift test", "on_fail": "continue"}, {"name": "Package", "command": "swift build -c release", "on_fail": "stop"} ] }
- stop– Halt pipeline on failure
- continue– Log error and proceed to next step
- warn– Show warning and continue
Real-time output for long-running commands:
{ "command": "swift build -c release", "update_interval": 3, "max_duration": 180 }
- Long compilation processes
- Test suites
- Any command that previously "hung" waiting for output
Save reusable patterns with variable substitution:
// Save a template { "name": "swift-release", "template": "cd {{project}} && swift build -c release", "category": "Swift Development", "description": "Build Swift project in release mode" } // Run with variables { "name": "swift-release", "variables": {"project": "~/GitHub/MyApp"} }
Templates are stored in~/.claude-command-runner/templates.jsonand persist across sessions.
Theexecute_with_auto_retrievecommand intelligently detects command types and adjusts wait times:
- Quick commands(echo, pwd): 2-6 seconds
- Moderate commands(git, npm): up to 20 seconds
- Build commands(swift build, make): up to 77 seconds
- Test commands: up to 40 seconds
Output capture (/tmp/<id>.jsonpolling) and the 24 tools that don't touch the terminal at all (clipboard, SSH, file watch, env snapshots, etc.) work identically across all terminals.
- macOS 13.0 or later
- Swift 6.0+ (Xcode 16+)
- Claude Desktop
- A supported terminal (Warpstrongly recommended)
git clone https://github.com/M-Pineapple/claude-command-runner.git cd claude-command-runner # For the 5 keystroke-routing tools (execute_command, etc.) to work, the build # must be SIGNED with your code-signing identity. build.sh auto-detects a single # Apple Development / Developer ID identity; to be explicit (or if you have # several), export it first — find yours with: # security find-identity -v -p codesigning export CCR_CODESIGN_IDENTITY="<your-cert-sha1>" # optional if auto-detect finds one; persist in ~/.zshrc ./build.sh
Only need the 34 non-keystroke tools (incl.execute_pipeline)? An unsigned build is fine — skip theexport.
-
Pick your consumer(s)— you can install for one or both.v6.0.3 ships a.appbundle wrapper— point at the binary INSIDE the bundle (the wrapper carries the Info.plist that macOS Sequoia+ needs to prompt for TCC permissions; without it, the 5 keystroke-routing tools silently fail):
A — Claude Desktop(~/Library/Application Support/Claude/claude_desktop_config.json):
{ "mcpServers": { "claude-command-runner": { "command": "/path/to/claude-command-runner/.build/release/claude-command-runner.app/Contents/MacOS/claude-command-runner", "args": [] } } }
B — Warp's native agent(~/.warp/.mcp.json):
{ "mcpServers": { "claude-command-runner": { "command": "/path/to/claude-command-runner/.build/release/claude-command-runner.app/Contents/MacOS/claude-command-runner", "args": [] } } }
Seedocs/WARP_AGENT.mdfor the full guide.
Upgrading from v6.0.0–6.0.2?Edit your existing config file and append.app/Contents/MacOS/claude-command-runnerto the path. The legacy bare-binary path still works for the 34 non-keystroke tools, butexecute_command/execute_with_auto_retrieve/execute_with_streaming/run_template/send_to_sessionwill silently fail without the bundle path.
Grant Accessibility permission(only required forsend_to_sessionkeystroke injection in v6.0; tab/window opening uses deeplinks and does not require it):
- OpenSystem Settings → Privacy & Security → Accessibility
- Click+and navigate toclaude-command-runner/.build/release/
- PressCmd+Shift+.to reveal the hidden.buildfolder
- Select theclaude-command-runnerbinary and toggle iton
Important:macOS tracks permissions by binary identity. After every rebuild (./build.sh), you must remove the old entry and re-add the new binary in Accessibility settings.
-
Restart your client(s)(Claude Desktop and/or Warp).
(Optional)Install the shell shim for cleaner block-boundary capture:
Seehelper/shell-shim.zsh/helper/shell-shim.bashfor the implementation. Uninstall withhelper/uninstall-shim.sh.
If you already have a signed install working (TCC permissions granted), upgrading is:
cd claude-command-runner git pull # Rebuild with the SAME signing identity you used originally. Without it, build.sh # falls back to an ad-hoc-signed bundle, macOS sees a new identity, and your # keystroke (TCC) grants stop applying → error 1002 on execute_command. # (build.sh auto-detects a single identity; export to be explicit.) export CCR_CODESIGN_IDENTITY="<your-cert-sha1>" # persist in ~/.zshrc so you don't forget ./build.sh # Confirm it signed with your cert (NOT adhoc) BEFORE replacing your good bundle: codesign -dvv .build/release/claude-command-runner.app 2>&1 | grep -E "Authority=Apple|Signature=adhoc" # Replace the deployed bundle (rm first — cp -R onto an existing .app nests it): rm -rf "/Applications/Claude Command Runner.app" cp -R .build/release/claude-command-runner.app "/Applications/Claude Command Runner.app"
Then restart Claude Desktop. Because the bundle keeps the same identifier and is signed with the same certificate, your existing TCC grants (Automation, Input Monitoring, Accessibility, Full Disk Access) carry over —no re-granting needed. If the keystroke tools start failing with error 1002 after an upgrade, you almost certainly rebuilt unsigned; re-sign with your cert and redeploy.
🛡️ macOS Sequoia full setup recipe (the 7 ordered steps)
Ifexecute_command/execute_with_auto_retrieve/execute_with_streaming/run_template/send_to_sessionfail withosascript is not allowed to send keystrokes (1002)even though you've toggled every panel in System Settings,follow this in order — skipping any step leaves a silent denial somewhere in the chain.The other 34 tools work without any of this;execute_pipelineis a fully-functional substitute if you want to skip the whole TCC saga entirely.
This is the empirically-verified recipe from a real 6-hour debugging session. v6.0.3+ ships the bundle infrastructure that makes this possible; v6.0.4 is this documentation pass.
The denial pattern.macOS Sequoia's TCC and sandbox have layered,non-obviousrequirements for CLI binaries that driveosascript → System Events → keystroke. The error message is misleading — the actual block usually isn't keystroke permission; it's an earlier preflight check that silently aborts the chain. The five gates, in the order macOS evaluates them:
Step 1 — Have an Apple Development cert (or self-signed Code Signing cert)
If you have a paid Apple Developer account, you already have one (check viasecurity find-identity -v -p codesigning). If not, create a self-signed one:
- Keychain Access→ menuCertificate Assistant → Create a Certificate…
- Name:claude-command-runner, Identity Type:Self Signed Root, Certificate Type:Code Signing
- ClickCreate→Continuethrough warnings →Done
Export the cert identifier forbuild.shto find:
# Get the SHA-1 hash (more reliable than the cert name) security find-identity -v -p codesigning # Then in your shell rc (~/.zshrc, ~/.config/fish/config.fish, etc.): export CCR_CODESIGN_IDENTITY="<the-sha1-hash-from-above>"
Step 2 — Build (creates the signed.appbundle)
build.shinvokesscripts/make-app-bundle.sh, which wraps the CLI in.build/release/claude-command-runner.app/with a properInfo.plist(CFBundleIdentifiercom.m-pineapple.claude-command-runner, the three requiredNSXxxUsageDescriptionstrings, LSUIElement=true). IfCCR_CODESIGN_IDENTITYis set, the bundle is signed with that cert as a unit — stable cdhash across rebuilds.
codesign --display --verbose=4 .build/release/claude-command-runner.app | grep -E 'Identifier|TeamIdentifier|CDHash' codesign --verify --deep --strict .build/release/claude-command-runner.app # should succeed silently
Step 3 — Install the bundle into/Applications/(CRITICAL)
macOS refuses to prompt for TCC permissions on bundles in.build/release/or other dev directories.The bundle must live in/Applications/. Copy it:
cp -R .build/release/claude-command-runner.app "/Applications/Claude Command Runner.app"
codesign --verify --deep --strict "/Applications/Claude Command Runner.app"
Step 4 — Point your MCP config at the/Applications/path
Claude Desktop(~/Library/Application Support/Claude/claude_desktop_config.json):
{ "mcpServers": { "claude-command-runner": { "command": "/Applications/Claude Command Runner.app/Contents/MacOS/claude-command-runner", "args": [] } } }
Mirror in~/.warp/.mcp.jsonif you use the Warp Agent path.
Step 5 — Reset stale TCC entries for the bundle ID
If you've been struggling with TCC denials previously, your TCC.db likely has staleDeniedentries from earlier rebuilds with different cdhashes. Wipe them for the bundle:
for svc in AppleEvents ListenEvent PostEvent Accessibility; do tccutil reset "$svc" com.m-pineapple.claude-command-runner done
Each line should print "Successfully reset". If you see "no entries", that's also fine — means TCC had nothing recorded yet.
Step 6 — Grant thethreeTCC permissions (Full Disk Access is the surprise one)
InSystem Settings → Privacy & Security, add/Applications/Claude Command Runner.appto each of:
- Full Disk Access—unexpected but mandatory.macOS sandbox does a preflight check forkTCCServiceSystemPolicyAllFilesbefore allowing osascript to spawn for keystroke chains. Without FDA on the bundle, the sandbox denies before TCC's AppleEvents check ever fires, and you get the misleading "send keystrokes" error.
- Input Monitoring— forkTCCServiceListenEvent/kTCCServicePostEvent(synthetic keystroke generation).
- Accessibility— for thekeystrokeAppleEvent action itself.
Each grant requires Touch ID / admin password to confirm.Bundle name appears as "Claude Command Runner"in the panels.
Step 7 — Restart Claude Desktop, trigger once, grant the Automation prompt
⌘QClaude Desktop, reopen. On your firstexecute_command, macOS may show one more prompt —Automation → "Claude Command Runner wants to control System Events"— click Allow. After that, it's permanent. Future rebuilds don't reset anything (the cert keeps cdhash stable; the bundle keeps the identity stable).
Diagnostic: what does TCC see right now?
If something doesn't work after the recipe, the only reliable way to figure out which gate is failing is the TCC log:
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





