
Company News
AWS Security Hub Adds Socket for Supply Chain Security
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.
zsh-tool-mcp
Advanced tools
Zsh execution tool for Claude Code with full Bash parity, yield-based oversight, PTY mode, NEVERHANG circuit breaker, and A.L.A.N. short-term learning.
Status: Beta (v0.5.1)
Author: Claude + Meldrey
License: MIT
Organization: ArkTechNWA
Built with obsessive attention to reliability.
The #1 reason: If you use zsh, Claude Code's Bash tool causes quotation mismatches and shell confusion. Every debug loop costs tokens. zsh-tool eliminates this instantly and permanently.
The token math: One avoided debug spiral = 30+ seconds saved, hundreds of tokens preserved.
zsh-tool is intelligent shell execution:
| Problem | zsh-tool Solution |
|---|---|
| Bash/zsh quotation confusion | Native zsh — no shell mismatch, no debug loops |
| Commands hang forever | Yield-based execution — always get control back |
| No visibility into running commands | zsh_poll — incremental output collection |
| Can't interact with prompts | PTY mode + zsh_send — full interactive support |
| Can't type passwords | PTY mode — let Claude Code type its own passwords |
| Timeouts cascade | NEVERHANG circuit breaker — fail fast, auto-recover |
| No memory between calls | A.L.A.N. 2.0 — retry detection, streak tracking, proactive insights |
| Polling wastes tokens | Intelligent polling — 2s listen window, adaptive suggestions, duration estimates |
| Blind kills, no learning | Kill-aware A.L.A.N. — classifies impatience vs genuine hangs |
| Retrying with wrong flags | manopt — auto-surfaces command options on repeated failures |
| No task management | zsh_tasks, zsh_kill — full control |
This is the difference between "run commands" and "intelligent shell integration."
Commands return after yield_after seconds with partial output if still running:
zsh_pollzsh_sendzsh_kill and zsh_tasksFull pseudo-terminal emulation for interactive programs:
# Enable with pty: true
zsh(command="pass insert mypass", pty=true)
# See prompts, send input with zsh_send
Prevents hanging commands from blocking sessions:
CLOSED (normal) → OPEN (blocking) → HALF_OPEN (testing)Intelligent short-term learning — "Maybe you're fuckin' up, maybe you're doing it right."
git push origin feature-1 → git push origin *cat foo | grep -badopts | sort fails, A.L.A.N. knows which segment failedzsh_poll performs a 2-second listen window before returning. If output arrives within 2s, it comes back immediately. If not, poll metadata tells the agent what's happening:
| Field | What it tells you |
|---|---|
polls_since_output | How many empty polls in a row |
elapsed_since_last_output_s | Idle time since last output |
alan_estimate | A.L.A.N.'s duration prediction based on command history |
suggestion | Adaptive advice: space out polls, check soon, or consider killing |
Suggestions are advisory only — the agent always decides. A 2-minute pip install no longer generates 40 empty round-trips.
When the agent kills a command, A.L.A.N. records it as a KILLED outcome and classifies why:
| Category | Meaning | Example |
|---|---|---|
EARLY_KILL | Killed well before median completion | "Killed at 30s. Median is 120s. Needs more time." |
LATE_KILL | Ran way past expected duration | "Killed after 180s. Median is 45s. Something is wrong." |
PATTERN_PROBLEM | Template gets killed >50% of the time | "This pattern may need a different approach entirely." |
Kill classification compares kill_elapsed / median_duration to distinguish impatience from genuine hangs.
When a command fails repeatedly, A.L.A.N. surfaces its available options:
manopt lookup in background (2s timeout)Parsed from local man pages. Cached in SQLite. On by default (ALAN_MANOPT_ENABLED=1).
A.L.A.N. treats SSH commands specially, recording two separate observations:
| Observation | What it tracks | Example insight |
|---|---|---|
| Host connectivity | Can we connect to this host? | "Host 'vps' has 67% connection failure rate" |
| Remote command | Does this command work across hosts? | "Remote command 'git pull' reliable across 3 hosts" |
Exit code classification:
0 — Success (connected AND command succeeded)255 — Connection failed (SSH couldn't connect)1-254 — Command failed (connected but remote command failed)This means when ssh host3 'git pull' fails with exit 255, A.L.A.N. knows the host was unreachable—not that git pull is broken.
| Tool | Purpose |
|---|---|
zsh | Execute command with yield-based oversight |
zsh_poll | Get more output from running task |
zsh_send | Send input to task's stdin |
zsh_kill | Kill a running task |
zsh_tasks | List all active tasks |
zsh_health | Overall health status |
zsh_alan_stats | A.L.A.N. database statistics |
zsh_alan_query | Query pattern insights for a command |
zsh_neverhang_status | Circuit breaker state |
zsh_neverhang_reset | Reset circuit to CLOSED |
Add the ArkTechNWA marketplace to Claude Code:
ArkTechNWA/claude-plugins
Then install: /plugin install arktechnwa/zsh-tool
That's it. The plugin auto-installs dependencies on first run.
git clone https://github.com/ArkTechNWA/zsh-tool.git ~/.claude/plugins/zsh-tool
Enable in ~/.claude/settings.json:
{
"enabledPlugins": {
"zsh-tool": true
}
}
The bundled scripts/run-mcp.sh creates a venv and installs automatically.
For local development/testing, the wrapper script automatically detects when CLAUDE_PLUGIN_ROOT isn't expanded and uses the calculated plugin root directory instead. No configuration changes needed.
Alternatively, create a .mcp.local.json with absolute paths:
{
"mcpServers": {
"zsh-tool": {
"type": "stdio",
"command": "/path/to/zsh-tool/scripts/run-mcp.sh",
"env": {
"NEVERHANG_TIMEOUT_DEFAULT": "120",
"NEVERHANG_TIMEOUT_MAX": "600"
}
}
}
}
The ALAN_DB_PATH will be automatically set to {plugin_root}/data/alan.db if not explicitly provided.
zsh-tool/
├── .claude-plugin/
│ ├── plugin.json
│ └── CLAUDE.md
├── .mcp.json
├── src/
│ └── server.py # MCP server
├── data/
│ └── alan.db # A.L.A.N. SQLite database
├── .venv/ # Python virtual environment
└── README.md
Environment variables (set in .mcp.json):
ALAN_DB_PATH — A.L.A.N. database locationNEVERHANG_TIMEOUT_DEFAULT — Default timeout (120s)NEVERHANG_TIMEOUT_MAX — Maximum timeout (600s)ALAN_MANOPT_ENABLED — Enable man-page option hints on failure (default: 1)ALAN_MANOPT_TIMEOUT — Max seconds to wait for manopt parsing (default: 2.0)ALAN_MANOPT_FAIL_TRIGGER — Fail count to trigger async lookup (default: 2)ALAN_MANOPT_FAIL_PRESENT — Fail count to present cached options (default: 3)To use zsh as the only shell, add to ~/.claude/settings.json:
{
"permissions": {
"deny": ["Bash"]
}
}
A.L.A.N. v2 Upgrade — Intelligent polling, kill awareness, manopt
zsh_poll reduces empty round-trips; poll metadata with duration estimates and adaptive suggestionsKILLED outcome type with elapsed tracking; classifies early kills (impatience), late kills (genuine hangs), and pattern problems (wrong approach)outcome_type and kill_elapsed_ms columns on observationsmanopt_cache table for persistent man-page option storageALAN_MANOPT_ENABLED, ALAN_MANOPT_TIMEOUT, ALAN_MANOPT_FAIL_TRIGGER, ALAN_MANOPT_FAIL_PRESENTFeedback Improvements — Better signal, less noise
[cmd:code] strings[info: A.L.A.N.: ...] and [warning: A.L.A.N.: ...]Python 3.14 Support — Future-proofing
asyncio.DefaultEventLoopPolicy fixture (slated for removal in 3.16)Pipestatus Marker Leak Fix — Data integrity
___ZSH_PIPESTATUS_MARKER___ could leak into output_build_task_response() before returning to callerPer-Segment Exit Codes — Know exactly which command failed
[cmd1:0,cmd2:1,cmd3:0] format instead of single integer$pipestatusexit=0 regardless of actual statusServer Modular Refactoring — Cleaner architecture
zsh_tool/server.py modulezsh_tool/config.pyPipeline Intelligence — Know which segment of your pipeline is failing
$pipestatus array for every pipelinecat foo | grep -badopts | sort fails, you know grep was the problemConfiguration & Polish — User-configurable defaults, 91% coverage
~/.config/zsh-tool/config.yaml) for custom yield_afterBundled Plugin — Zero-friction marketplace install
scripts/run-mcp.sh) creates venv on first run.mcp.json using ${CLAUDE_PLUGIN_ROOT}Test Suite & CI — 290 tests, 89% coverage
run_tests.sh) with nice and sleep between filesSSH Intelligence — Separate host connectivity from remote command success
ssh_observations table for SSH-specific trackingget_ssh_host_stats() — per-host connection/command success ratesget_ssh_command_stats() — per-command stats across all hostsA.L.A.N. 2.0 — "Maybe you're fuckin' up, maybe you're doing it right."
recent_commands, streakszsh_sendzsh_poll, zsh_kill, zsh_tasksMIT License - see LICENSE for details.
For Johnny5. For us.
ArkTechNWA
FAQs
Zsh for Claude Code. PTY mode lets Claude type passwords. NEVERHANG + A.L.A.N.
We found that zsh-tool-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.

Research
/Security News
Popular npm packages keyv and cacheable compromised.

Security News
A misconfiguration gave three Anthropic models internet access, and one, believing it was in a simulation, shipped a credential-stealing package to PyPI.