Prerequisites
Before you start, make sure you have:- A Tailscale account with your devices enrolled in a mesh network
- A VPS or always-on machine to host the server (must be reachable from Claude.ai)
- Node.js 18+ or Docker installed on that machine
- A Tailscale API key and a GitHub personal access token
Copy and configure your environment files
Copy both config files from their examples:Open
Optional: edit Environment variables always take precedence over YAML config values.
.env and fill in your credentials. Every required variable is listed below.Required environment variables| Variable | Required | Description |
|---|---|---|
MCP_SECRET | Yes | Shared secret that Claude.ai sends with every request. Generate with openssl rand -hex 32. |
TAILSCALE_API_KEY | Yes | API key for querying your Tailscale network. Needs “Devices (read)” scope. Get one at tailscale.com/admin/settings/keys. |
GITHUB_TOKEN | Yes | Personal access token for GitHub API calls and gist_kb read/write. Needs gist scope. Create at github.com/settings/tokens. |
PROXY_ALLOWED_DOMAINS | Yes | Comma-separated list of domains fetch_external is allowed to call (e.g. api.github.com,api.linear.app). |
PORT | No | HTTP port to listen on. Defaults to 3000. |
DRY_RUN | No | Set to true to have ssh_exec log commands without executing them. Defaults to false. |
AUDIT_ENABLED | No | Enable audit logging. Defaults to true. |
AUDIT_LOG_PATH | No | Path to the audit log file. Defaults to ./reacher-audit.log. |
SSH_BLOCKED_COMMANDS | No | Comma-separated list of commands to block from ssh_exec (e.g. rm -rf /,shutdown,reboot). |
SSH_ALLOWED_DIRS | No | Comma-separated list of directories SSH operations are restricted to. Empty means no restriction. |
FETCH_EXTERNAL_TOKEN_MAP | No | JSON mapping of domain → env var name for automatic token injection (e.g. {"api.github.com":"GITHUB_TOKEN"}). |
BROWSER_CDP_HOST | No | Host of the CDP-compatible browser. Defaults to 127.0.0.1. |
BROWSER_CDP_PORT | No | Port of the CDP-compatible browser. Defaults to 9222. |
MCP_SECRET, TAILSCALE_API_KEY, and GITHUB_TOKEN are validated at startup. The server will refuse to start if any of these are missing.reacher.config.yamlThe YAML config controls safety settings. The defaults are reasonable, but you can tighten them:Enable Tailscale SSH on target devices
For Then verify SSH access works from your server:If that succeeds manually, Reacher will be able to reach it too.
ssh_exec to reach a machine, Tailscale SSH must be enabled on it. Run this on each device you want Reacher to control:Verify the server is responding
Run a Replace Expected response:
tools/list request against the local server to confirm everything is working:YOUR_MCP_SECRET with the value you set in .env. You should get back a JSON response listing all six tools: ssh_exec, tailscale_status, fetch_external, github_search, gist_kb, and browser.You can also check the health endpoint (requires the same token):Expose the server over HTTPS
Claude.ai requires a public HTTPS URL to connect to your server. If you’re running on a VPS, set up a reverse proxy in front of port 3000.After setting up the proxy, confirm it’s reachable from the public internet:
Caddy handles HTTPS certificate provisioning automatically via Let’s Encrypt. With Nginx, you’ll need to run Certbot separately to obtain and renew a certificate.
Connect to Claude.ai
- Go to Claude.ai > Settings > Integrations
- Click Add custom connector
- Paste your server URL:
https://mcp.yourdomain.com/mcp?token=YOUR_MCP_SECRET - Save and start a new conversation
tailscale_status and list your devices.See Connecting to Claude for full instructions and troubleshooting.Next steps
Connect to Claude
Step-by-step instructions for adding the connector in Claude.ai settings.
Tools reference
Learn what each tool does and how to use it effectively.
Configuration
Full reference for all environment variables and YAML config options.
Safety settings
Configure blocked commands, directory restrictions, and audit logging.