AI agents can write code, but they're stuck on one machine. They can't check logs on prod, grep for errors across services, or edit a config on staging.

Claw is an MCP server that extends your agent's tools to any remote machine. 8 tools. Any host you can SSH into. Zero config on the remote.

You: "Check why the API is returning 500s on prod, look at the logs, and fix the nginx config"

Agent: connects to prod-api via SSH
       greps /var/log/nginx/error.log for errors
       reads the nginx config
       edits the misconfigured upstream block
       runs nginx -t && systemctl reload nginx

Done. Across machines. Autonomously.

No ports to open. No daemons. No root required. Claw uses your SSH keys, deploys a tiny binary on first connect, and cleans up after itself.

Quickstart

1. Install

npx -y @opsyhq/claw serve
# or install globally
npm install -g @opsyhq/claw

2. Connect to your agent

claude mcp add claw -- npx -y @opsyhq/claw serve

Or run the installer:

npx -y @opsyhq/claw install claude-code

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "claw": {
      "command": "npx",
      "args": ["-y", "@opsyhq/claw", "serve"]
    }
  }
}

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "claw": {
      "command": "npx",
      "args": ["-y", "@opsyhq/claw", "serve"]
    }
  }
}
npx -y @opsyhq/claw serve
# Speaks MCP over stdio

3. Add your machines

The agent can add machines itself via the claw_machines tool, or you can set them up ahead of time:

# Import from your SSH config
claw init --from-ssh

# Or add manually
claw add prod-api --ssh [email protected]
claw add staging --ssh [email protected]

4. Go

Talk to your agent. It now has claws on every machine you configured.

"Show me running containers on prod-api"
"Grep for 'connection refused' in the logs on staging"
"Find all .env files across prod-api and staging"
"Edit the upstream block in nginx.conf on prod-api"

How it works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  AI Agent (Claude, Cursor, etc.)    β”‚
β”‚       ↓ MCP tool calls              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Claw (runs locally)               β”‚
β”‚                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Tool Router  β”‚ β”‚ Conn Pool     β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚
β”‚          β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”           β”‚
β”‚          β”‚ SSH  β”‚ Local  β”‚           β”‚
β”‚          β””β”€β”€β”¬β”€β”€β”€β”˜β”€β”€β”€β”¬β”€β”€β”€β”˜           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β–Ό       β–Ό
          β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”
          β”‚ prod β”‚ β”‚ your β”‚
          β”‚ api  β”‚ β”‚ mac  β”‚
          β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜

On first connect, Claw auto-deploys a small static binary (pincer) to ~/.claw/pincer on the remote host. Pincer speaks JSON-RPC over stdin/stdout and handles all tool execution β€” structured file editing, safe command handling, grep with regex support.

Connections are persistent and pooled. No reconnecting per command.

Tools

Claw exposes 8 MCP tools. These match the tools agents already know from local development (Claude Code's Read/Write/Edit/Bash/Grep/Glob/LS) β€” just extended to remote machines.

Tool Description
claw_machines List, add, remove, and update machines
claw_bash Run a shell command
claw_read Read a file with optional line range
claw_write Create or overwrite a file
claw_edit Find-and-replace in a file
claw_grep Search file contents with regex
claw_glob Find files by pattern
claw_ls List directory contents

Every tool takes a host parameter β€” the machine name to target.

claw_bash(host: "prod-api", command: "docker ps")
claw_grep(host: "prod-api", pattern: "error|timeout", path: "/var/log", include: "*.log")
claw_edit(host: "staging", path: "/app/config.yaml", old_string: "port: 80", new_string: "port: 8080")

Configuration

Global config β€” ~/.config/claw/machines.yaml

machines:
  prod-api:
    transport: ssh
    host: prod-api.example.com
    user: deploy

  staging:
    transport: ssh
    host: staging.example.com
    user: deploy

  local:
    transport: local

SSH transport uses your existing ~/.ssh/config automatically β€” keys, ports, jump hosts all just work.

Project config β€” claw.yaml

Drop a claw.yaml in your project root:

machines:
  dev:
    transport: local

  staging:
    transport: ssh
    host: staging.myapp.com
    user: deploy

Commit this to your repo. Your whole team gets the same machine setup, each using their own SSH keys.

Security

  • Your existing access β€” Claw uses your SSH keys. It can only reach what you already can.
  • No open ports β€” All connections are outbound SSH from your machine.
  • No persistence β€” The remote binary only runs during your session.
  • Audit log β€” Every tool call is logged to ~/.config/claw/logs/.
  • Want guardrails? β€” For approval workflows and policy enforcement on remote operations, check out Opsy.

CLI Reference

claw serve                # Start MCP server (stdio)
claw init --from-ssh      # Import machines from ~/.ssh/config
claw add <name> --ssh user@host   # Add a remote machine
claw add <name> --local           # Add local machine
claw install claude-code  # Write MCP config for Claude Code
claw install cursor       # Write MCP config for Cursor

Roadmap

  • SSH transport
  • Local transport
  • Runtime binary download from GitHub Releases
  • npm trusted publishing (OIDC)
  • Docker transport
  • Kubernetes transport
  • AWS SSM transport

Contributing

PRs welcome. See the development guide to get started.

npm install         # Install dependencies
npm run build       # Build TypeScript
npm run typecheck   # Type-check without emitting
npm run build-pincer # Cross-compile pincer (requires Go)
npm run dev         # Watch mode

Project structure:

claw/
β”œβ”€β”€ bin/claw.ts              # CLI entrypoint
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ cli/                 # CLI commands (serve, init, add, install)
β”‚   β”œβ”€β”€ config/              # YAML config loading + SSH config parser
β”‚   β”œβ”€β”€ server/              # MCP server, tool schemas, router
β”‚   β”œβ”€β”€ tools/               # Local tool implementations
β”‚   β”œβ”€β”€ transports/          # Transport layer (local, SSH, pool, deployer)
β”‚   └── logging/             # Audit log
β”œβ”€β”€ pincer/                  # Go binary deployed to remote hosts
β”‚   β”œβ”€β”€ main.go              # JSON-RPC stdin/stdout server
β”‚   β”œβ”€β”€ rpc/                 # Request dispatcher
β”‚   └── tools/               # Tool implementations in Go
└── scripts/build-pincer.sh  # Cross-compile for linux/amd64+arm64