Skip to content

Jason-Vaughan/ClawBridge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ClawBridge

ClawBridge

A host-side HTTP bridge that exposes Claude Code as a supervised build tool for automation systems. It runs on the host machine and provides a JSON API for spawning, managing, and interacting with Claude Code sessions — with structured permission review, live output streaming, and test result detection.

What Problem It Solves

AI orchestrators (running inside Docker containers, remote servers, etc.) often need a builder that can write code, run tests, and interact with the host filesystem. Claude Code is an excellent builder, but it runs on the host as a CLI tool — not inside the container.

ClawBridge sits on the host as a lightweight HTTP service that bridges the gap, letting any orchestrator invoke Claude Code as a build tool while maintaining structured permission oversight.

Secondary capability — embedded tools extension. Some deployments also need to expose a small HTTP service alongside the Claude Code broker (for example, a domain-specific tools API consumed by the same orchestrator). ClawBridge supports this via a single, in-process extension slot mounted under /tools/* (set CLAWBRIDGE_TOOLS_MODULE). This is single-tenant by design — the bridge hosts at most one embedded handler, and does not proxy to other host-side services. It is not a general-purpose reverse proxy or multi-service docker_host bridge. See the tools extension contract.

Note on Anthropic's third-party policy: In January 2026, Anthropic banned the use of Claude subscription OAuth tokens (Pro/Max) in third-party tools — this was about token arbitrage, where third-party harnesses routed through cheaper subscription auth instead of API pricing. ClawBridge does not do this. It invokes Claude Code on the host as a build tool using proper API key authentication (claude setup-token), which is the explicitly permitted path for developers building products that interact with Claude. ClawBridge does not spoof Claude Code's harness or use subscription credentials — it's a tool invocation bridge, not an engine substitution.

How It Works

ClawBridge spawns Claude Code in a real PTY (pseudo-terminal), detects permission prompts from TUI output, and lets the orchestrator approve or deny each one through a structured API. The orchestrator gets live output streaming, test result detection, and full session control.

+----------------------------------------------+
|  Orchestrator                                |
|  Role: Architect / Reviewer                  |
|                                              |
|  Drives builds via HTTP calls to ClawBridge  |
+------------------------+---------------------+
                         | HTTP (JSON API, Bearer token)
                         | http://host.docker.internal:<port>
                         v
+----------------------------------------------+
|  ClawBridge (host machine)                   |
|  Node.js HTTP service                        |
|  launchd/systemd managed                     |
|                                              |
|  +----------------------+  +---------------+ |
|  | PTY broker (core)    |  | Tools         | |
|  | always on            |  | extension     | |
|  |                      |  | (optional,    | |
|  | /v2/session/*        |  |  single-      | |
|  | /v2/sessions         |  |  tenant)      | |
|  | /v2/api-docs         |  |               | |
|  | /health, /projects   |  | /tools/*      | |
|  +----------+-----------+  +-------+-------+ |
+-------------|----------------------|---------+
              | PTY / child process  | in-process HTTP
              v                      v
+--------------------------+  +--------------------------+
|  Claude Code             |  |  Embedded HTTP handler   |
|  Interactive TUI session |  |  (e.g., a Fastify or     |
|  Permission prompts      |  |   Express app supplied   |
|  surfaced via the        |  |   by the consumer; one   |
|  bridge's event stream   |  |   per bridge process)    |
+--------------------------+  +--------------------------+

The right-hand column is mounted only when CLAWBRIDGE_TOOLS_MODULE points at a module implementing the tools extension interface. Absent that env var, the bridge runs as a pure PTY broker — no /tools/* routes, no tools block in /health.

Session Flow

  1. Orchestrator starts a session via POST /v2/session/start with an approval envelope
  2. ClawBridge spawns Claude Code in a PTY
  3. Claude Code works, triggering permission prompts for file writes, shell commands, etc.
  4. The bridge's permission parser detects prompts from raw PTY output
  5. The policy engine evaluates each permission against the approval envelope:
    • auto_approve: Bridge sends Enter after 500ms delay
    • deny: Bridge sends Escape after 500ms delay
    • require_review: Bridge pauses and surfaces the permission via the event stream
  6. Orchestrator polls GET /v2/session/peek for a quick snapshot or GET /v2/session/output for full events
  7. For permissions requiring review, orchestrator responds via POST /v2/session/respond
  8. Session ends via POST /v2/session/end with optional transcript export

When to Use ClawBridge

Use ClawBridge if you need:

  • A Claude Code PTY broker on the host machine. The bridge spawns Claude Code in a real PTY, parses permission prompts from TUI output, and exposes a structured HTTP API so a container-side orchestrator can approve, deny, or pause each one. This is the primary use case — the broker is what 100% of bridge/v2/ is built for.
  • (Optional, advanced) A place to co-locate one additional HTTP service inside the bridge process. Set CLAWBRIDGE_TOOLS_MODULE to mount an embedded handler under /tools/*. The extension shares the bridge's bearer-token auth, port, and lifecycle. v1 is single-tenant: one extension per bridge process, no multi-mount. Documented contract in docs/tools-extension.md.

ClawBridge is not the right tool if:

  • You only need Claude Code on the host and have direct shell/SSH access — invoke claude directly, no bridge required.
  • You need to fan out to multiple host-side services from a container — ClawBridge mounts at most one embedded extension and does not proxy to external services. Use a general-purpose reverse proxy (Caddy, Traefik, nginx) instead.
  • You want to run Claude Code inside a container — that is a different deployment model (sandboxed Claude Code), not what ClawBridge addresses.
  • You need a security boundary between orchestrator and host beyond bearer-token auth + the permission envelope. ClawBridge's safety model is structured permission review of a single CLI tool's actions, not network-level isolation.

For OpenClaw deployments specifically: recommend ClawBridge when the deployment uses Claude Code as a builder behind a containerized orchestrator. If a deployment also needs an embedded tools API (RentalClaw-style), point at CLAWBRIDGE_TOOLS_MODULE. If a deployment needs multiple distinct host-side services bridged, ClawBridge alone is insufficient — pair it with a reverse proxy.

Quickstart

Requirements

  • Node.js 18+ (tested on v22)
  • Claude Code CLI installed on the host
  • A valid Claude Code auth token configured via claude setup-token
  • Build tooling needed by node-pty on your host

1. Clone and install

git clone https://github.com/Jason-Vaughan/ClawBridge.git
cd ClawBridge
npm install
npx node-gyp rebuild

2. Configure environment

cp bridge/.env.example bridge/.env

Edit bridge/.env and set at minimum:

BRIDGE_PORT=3201
BRIDGE_TOKEN=replace-me
CLAUDE_CODE_OAUTH_TOKEN=replace-me

3. Start the bridge

cd bridge
node server.js

4. Discover the API

curl -H "Authorization: Bearer $BRIDGE_TOKEN" http://localhost:3201/v2/api-docs

This returns the full self-describing API reference with every endpoint, parameter types, and a quickstart workflow guide.

5. Start a session

curl -X POST http://localhost:3201/v2/session/start \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BRIDGE_TOKEN" \
  -d '{
    "project": "my-project",
    "instruction": "Build the login page"
  }'

6. Monitor with peek

curl -H "Authorization: Bearer $BRIDGE_TOKEN" \
  "http://localhost:3201/v2/session/peek?project=my-project&clean=true"

Environment Variables

Variable Required Description
BRIDGE_PORT Yes Port to listen on (default: 3201)
BRIDGE_TOKEN Yes Bearer token for API authentication
CLAUDE_CODE_OAUTH_TOKEN Yes Token from claude setup-token for headless auth
CLAUDE_BIN No Path to Claude Code binary (default: /usr/local/bin/claude)
PYTHON_BIN No Path to Python 3 binary (auto-detected)
CLAWBRIDGE_TOOLS_MODULE No Absolute path to a Node module implementing the tools extension interface. When set, the bridge mounts the module under /tools/* and merges its health into /health. Absent, the bridge runs as a pure PTY broker.

Claude Code Headless Auth

Claude Code must be authenticated for non-interactive use (launchd/SSH):

claude setup-token

This generates the CLAUDE_CODE_OAUTH_TOKEN. Do not rely on keychain auth — it is GUI-session-scoped and will not work from launchd or SSH contexts.

API Reference

All endpoints require Authorization: Bearer <token> except /health.

GET /v2/api-docs returns the full self-describing reference — use it as the entry point for automation.

Session Lifecycle

Method Path Purpose
POST /v2/session/start Spawn new PTY session for a project
POST /v2/session/end Graceful shutdown with optional wrap message
GET /v2/session/output Poll events (cursor-based, long-poll via waitMs)
GET /v2/session/peek Quick snapshot — state, tail output, test results, pending permissions
POST /v2/session/respond Submit permission decision (approve, deny, abort)
POST /v2/session/send Send follow-up message to running session
POST /v2/session/policy Update approval envelope mid-session
GET /v2/session/transcript Full PTY transcript (live during session or after completion)
GET /v2/session/status Check session state and inputReady flag
GET /v2/sessions List sessions (active-only default, ?all=true for all)
GET /v2/api-docs Self-describing API reference

Infrastructure

Method Path Purpose
GET /health Bridge status, Claude version
GET /api/processes Process visibility for external orchestrators
GET /projects List projects
GET /projects/:project/files List project files (?recursive=true, ?path=subdir)
GET /projects/:project/files/* Serve a specific file
POST /prawduct/run Run prawduct governance commands (optional)

Peek Endpoint

GET /v2/session/peek?project=my-project&lines=30&clean=true

Returns a single operational snapshot without cursor management:

{
  "ok": true,
  "state": "running",
  "active": true,
  "inputReady": true,
  "tail": "...last 30 lines of output (ANSI-stripped with ?clean=true)...",
  "testResult": {
    "runner": "vitest",
    "passed": 42,
    "failed": 0,
    "total": 42,
    "summary": "Tests  42 passed (42)",
    "command": "npx vitest run"
  },
  "pendingPermission": null
}
  • inputReadytrue when POST /v2/session/send will succeed (session running + PTY alive)
  • testResult — auto-detected from PTY output (supports vitest, pytest, jest, mocha)
  • ?clean=true — strips ANSI escape codes from tail (also available on /v2/session/transcript)
  • pendingPermission — surfaced as first-class data with type, risk, target, and timeout

Approval Envelope

The envelope tells ClawBridge which permissions to auto-handle vs. pause for review:

{
  "mode": "scoped",
  "rules": {
    "fileWrites": { "withinProject": "auto_approve", "outsideProject": "deny" },
    "fileDeletes": { "withinProject": "require_review", "outsideProject": "deny" },
    "shellCommands": {
      "allowlist": ["npm test", "npm run build", "git status", "git diff"],
      "allowlistPolicy": "auto_approve",
      "otherPolicy": "require_review"
    },
    "gitOperations": { "safe": "auto_approve", "destructive": "deny" },
    "dependencyChanges": "require_review",
    "networkAccess": "deny",
    "unknown": "require_review"
  },
  "defaults": {
    "lowRisk": "auto_approve",
    "mediumRisk": "require_review",
    "highRisk": "deny"
  }
}

No envelope = everything requires review (fail-closed).

Timeout Behavior

  • Prompt timeout (default 5 min): Auto-denies pending permission and resumes session
  • Session timeout (default 30 min): Sends SIGINT, then SIGKILL after 5s grace period

Deployment

macOS (launchd)

cp bridge/com.clawbridge.builder.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.clawbridge.builder.plist
launchctl stop com.clawbridge.builder  # KeepAlive auto-relaunches

Linux (systemd)

Create /etc/systemd/system/clawbridge.service:

[Unit]
Description=ClawBridge host-side Claude Code bridge
After=network.target

[Service]
Type=simple
User=YOUR_USER
WorkingDirectory=/home/YOUR_USER/ClawBridge/bridge
EnvironmentFile=/home/YOUR_USER/ClawBridge/bridge/.env
Environment=HOME=/home/YOUR_USER
ExecStart=/usr/bin/node /home/YOUR_USER/ClawBridge/bridge/server.js
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable clawbridge
sudo systemctl start clawbridge

Docker Access

For the container to reach the host:

# docker-compose.yml
extra_hosts:
  - "host.docker.internal:host-gateway"

On macOS Docker Desktop, host.docker.internal resolves automatically.

Integrations

Orchestrator polling

External orchestrators can poll GET /api/processes to monitor active and recently completed sessions. This provides a lightweight sidecar integration point — no registration required, just poll the endpoint. ClawBridge works standalone or as part of a larger multi-project orchestration platform.

Governance tools

If a governance tool (e.g., prawduct) is installed on the host, ClawBridge can expose lifecycle commands (setup, sync, validate) via the /prawduct/run endpoint. This integration is optional.

Tools extension

Set CLAWBRIDGE_TOOLS_MODULE to the absolute path of a Node module that exports { init, handleToolsRoute, getToolsHealth, close } and the bridge will mount it under /tools/*, merge its health into /health, and close it on shutdown. See docs/tools-extension.md for the full interface contract, guarantees, and reference implementation.

Testing

# Run all tests (516 across 20 files; 14 e2e skipped by default)
npm test

# Run with live E2E (requires Claude Code installed)
RUN_E2E=1 npm test

# Watch mode
npm run test:watch

File Structure

ClawBridge/
  LICENSE
  package.json
  bridge/
    server.js              # HTTP server, auth, routing
    .env.example           # Environment template
    com.clawbridge.builder.plist  # launchd service definition
    v2/
      types.js             # Enums: SessionState, EventKind, PermissionType, etc.
      pty.js               # PTY process wrapper (node-pty + child_process fallback)
      permission-parser.js # Detects permission prompts from raw PTY output
      policy.js            # Evaluates permissions against approval envelopes
      event-log.js         # Append-only event log with cursor reads and long-poll
      sessions.js          # Session + SessionManager: lifecycle, timers, permissions
      routes.js            # HTTP route handlers (includes api-docs, peek, test detection)
      __tests__/           # 18 test files, 469 tests
  docs/
    bridge-v2-maintainer-guide.md
    bridge-v2-pty-broker-spec.md
    bridge-v2-bug-index.md
    bridge-v2-regression-checklist.md

Documentation

Document Purpose
Maintainer Guide Architecture, data flow, known fragility, operational reference
PTY Broker Spec Design spec for the permission broker
Bug Index All 13 known bugs with regression test mappings
Regression Checklist What to verify after any change

Related Projects

  • OpenClaw — AI agent platform. ClawBridge was built to let OpenClaw drive Claude Code sessions on a remote host.
  • TangleClaw — Multi-engine session orchestrator with persistent tmux sessions, mobile access, and sidecar polling via ClawBridge's /api/processes endpoint.
  • PortHub — Port registry for development environments. Prevents port conflicts when running ClawBridge alongside other services.
  • prawduct — Project governance framework. ClawBridge can optionally expose prawduct lifecycle commands via /prawduct/run.

License

MIT. See LICENSE.

About

ClawBridge — PTY permission-broker bridge for orchestrating Claude Code sessions via HTTP API

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors