A Go MCP Server for System-Level Bash Execution

Persistent sessions, nested MCP support, and a compiled server that deploys as a single binary.

The Model Context Protocol gives Claude the ability to call external tools, and bash execution is one of the most immediately useful. The MCP Bash Server is a Go implementation that provides Claude with a persistent bash session on the host system, allowing it to run commands, build projects, manage files, and interact with the operating environment while maintaining state between calls.

Why a compiled server

Most MCP server implementations are written in Python or TypeScript. These work, but they carry runtime dependencies — a specific Node.js or Python version, package managers, virtual environments, and the associated maintenance overhead. A Go implementation compiles to a single static binary with no external dependencies. You copy it to the target machine, drop a two-line config file next to it, and it runs. There is no interpreter to install, no packages to resolve, and no version conflicts to manage.

This matters in practice. MCP servers are long-running processes that sit between Claude and the operating system. They need to start reliably, handle concurrent operations safely, and not quietly degrade over time. Go's compiled nature, goroutine model, and deterministic resource cleanup make it well suited to this role. Pre-built binaries are published for Linux and macOS on both x86_64 and ARM64, so most users never need to touch a compiler.

Persistent sessions

The server maintains a single bash process across tool calls. Working directory changes, environment variables, shell functions, and other session state persist between commands. Claude can cd into a project directory, set variables, run a build, and inspect the output across multiple exchanges without losing context. If the session needs a clean slate, a restart flag on any tool call will replace it.

Nested MCP execution

A less obvious problem arises when Claude uses the bash tool to run a command that itself invokes another MCP tool. Both the outer server and the inner tool expect to communicate over stdin/stdout, which deadlocks. Since version 1.1.0, the server handles this by injecting environment variables (MCP_NESTED=1, MCP_SOCKET_DIR) into the bash process. Downstream MCP tools that detect these variables switch to Unix socket communication, avoiding the conflict entirely. This is what allows Claude to execute multi-step workflows that orchestrate several MCP servers from within a single bash session.

Routing Claude to the correct bash environment

There is a deployment detail that is easy to overlook. When Claude is configured with an MCP bash tool, it has two bash environments available: the MCP server (which operates on your real filesystem) and its built-in sandbox (an isolated container with no access to your files that resets between calls). By default, Claude prefers the sandbox. This means a command like ls /home will silently execute inside a throwaway container and return results that have nothing to do with your machine. There is no error — the command succeeds, but against the wrong environment.

The repository includes a Claude skill (claude-skill/bash-preference.zip) that overrides this behaviour, instructing Claude to route all bash execution through the MCP server. Deploying it is straightforward:

1. In claude.ai, navigate to Settings → Profile → Claude Skills
2. Upload claude-skill/bash-preference.zip
3. The skill takes effect immediately for new conversations

If you have deployed an MCP bash server and Claude cannot see your files or file operations have no lasting effect, the missing skill is almost certainly the reason.

Configuration

The server looks for a config.json alongside the binary. A minimal configuration only needs two fields:

{  "commandTimeout": 600,  "enabled": true }

The timeout is in seconds and defaults to 600 (ten minutes). Network mode — which exposes the server over TCP/IP with IP-based access control — is available for advanced deployments but is intentionally excluded from the default configuration due to the security implications of an unauthenticated bash endpoint. A separate config.network.json example is provided for those who need it.

Getting started

The quickest path is to download a pre-built binary from the latest release, place it in a directory with the config file, and add the MCP entry to your Claude Desktop configuration:

{  "mcpServers": {    "bash": {      "command": "/usr/local/bin/mcp-bash/mcp-bash"    }  } }

Building from source requires Go 1.21 or later and a single go build command. The full installation steps, architecture documentation, and troubleshooting guides are in the repository.

Version 1.1.1

Today's patch release fixes several reliability issues around session lifecycle management that could cause orphaned bash processes under sustained use, particularly with commands producing large output. It also hardens the default configuration as described above and adds the Claude skill to the repository. Full details are in the changelog.