MCP · filesystem + shell

Turn your computer into an MCP-controlled surface.

Run OpenHammer once and point any MCP client at a single HTTP endpoint. Claude Desktop, Claude Code, Cursor, or something you built yourself. Whatever connects gets read, write, search and shell on your machine. Local by default, tunneled to the world when you decide it should be.

$ git clone https://github.com/harry-hathorn/openhammer && cd openhammer && npm i && npm run build && node dist/cli.js
MIT license Node 20+ No LLM inside, bring your own client
openhammer · 127.0.0.1:3000
The toolhead

Eight tools. That's the whole thing.

The best agents aren't buried under SDK abstractions. They're an LLM iterating over a filesystem with bash. OpenHammer serves exactly that surface and nothing else.

guideRead-first orientation: the working-root contract and the tools.no params
readRead a file, text or image.2000 lines / 50KB head
bashRun a shell command. Merged stdout and stderr, full output spilled to a temp file.tail-truncated
editExact-text replacement. Preserves BOM and CRLF, forgiving on whitespace and quotes.surgical
writeCreate or overwrite a file. Parent dirs get created for you.mkdir -p built in
grepripgrep content search, .gitignore-aware, NDJSON output.needs rg
findfd file search by glob, .gitignore-aware.needs fd
lsList a directory. Alphabetical, dotfiles included./ on dirs

Every response is bounded twice: per-tool truncation plus a universal 512KB backstop that emits a structured response_too_large block.

Quick start

From clone to connected client in three moves.

01

Raise the hammer

# build and boot the control center
npm install
npm run build
node dist/cli.js

# first boot mints a bearer token into
# ~/.openhammer/credential.json (0600)

The TUI dashboard is the entrance. Status, channels, clients, monitor and doctor all live on one screen.

02

Point a client

{
  "mcpServers": {
    "openhammer": {
      "type": "http",
      "url": "http://127.0.0.1:3000/mcp",
      "headers": {
        "Authorization": "Bearer <token>"
      }
    }
  }
}

Works with Claude Code, Claude Desktop, Cursor, the MCP Inspector, anything that speaks Streamable HTTP.

03

Go public (if you dare)

# add a tunnel channel
openhammer channel add
  # ngrok / cloudflare / static

# OAuth for Claude web and Code
openhammer auth set-login
openhammer auth add-client

export MCP_PUBLIC_URL=https://…

Live channels boot the tunnel with the server. OAuth discovery picks up the public URL on its own.

Gates & channels

Every path in is authenticated.

Whosoever holds this token, if they be worthy, shall possess the shell.

Three auth paths

Accepted in fall-through order at the /mcp gate.

bearer token · minted on first boot, constant-time compared
client credentials · id and secret for machine clients (HS256 JWT)
auth-code + PKCE · the login flow Claude web and Claude Code use

Three channel types

A channel is how a remote client reaches you.

ngrok · live tunnel, URL read from its inspector API
cloudflare · live quick-tunnel via cloudflared
static / nginx · you run the endpoint, OpenHammer probes /health

It runs real shell as you. Respect the hammer.

OpenHammer exposes a powerful surface on purpose. A connected client can do anything your OS user can, so treat the bearer token like a password to your machine.

Bound the workspace : scope the file tools with MCP_ROOT_DIR
Never tunnel without auth : a public URL plus a weak token means internet shell access
Contain for isolation : mount only the target dir, the container is the sandbox
Know the limit : bash is not jailed, it reaches whatever your user can
The mead hall

Build with us.

Questions, harness designs, channel providers, weird tunneling setups. Bring them.