Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 61 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,39 @@ See [Installation Guide](docs/installation.md) for details.

## Multi-Instance Mode

Orchestrate multiple OpenClaw gateways from a single MCP server — name them however you like (prod, staging, dev, lobster-supreme, the-claw-abides...):
Orchestrate multiple OpenClaw gateways from a single MCP server. One bridge, many claws — route requests to prod, staging, dev, or whatever you name them (lobster-supreme and the-claw-abides are perfectly valid names).

```
┌──────────────────────────────────────────────────────────────────────┐
│ Claude.ai / Claude Desktop │
│ (MCP Client) │
└──────────────────────┬───────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ OpenClaw MCP Bridge Server │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Instance │ │ Instance │ │ Instance │ │
│ │ Registry │ │ Resolver │ │ Validator │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ┌──────┴─────────────────┴──────────────────┴───────┐ │
│ │ Per-Instance OpenClaw Clients │ │
│ │ (separate auth, timeout, URL per instance) │ │
│ └────────┬──────────────┬──────────────┬────────────┘ │
└───────────┼──────────────┼──────────────┼────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 🦞 prod │ │ 🦞 staging │ │ 🦞 dev │
│ (default) │ │ │ │ │
│ :18789 │ │ :18789 │ │ :18789 │
│ OpenClaw GW │ │ OpenClaw GW │ │ OpenClaw GW │
└──────────────┘ └──────────────┘ └──────────────┘
```

### Setup

```bash
OPENCLAW_INSTANCES='[
Expand All @@ -164,9 +196,35 @@ OPENCLAW_INSTANCES='[
]'
```

All tools accept an optional `instance` parameter to target a specific gateway. When omitted, the default instance is used. Existing single-instance deployments work without any change.
### Usage

All tools accept an optional `instance` parameter to target a specific gateway:

```
# Chat with staging instance
openclaw_chat message="Deploy status?" instance="staging"

# Check health of prod
openclaw_status instance="prod"

# List all configured instances
openclaw_instances

# Async task targeting dev
openclaw_chat_async message="Run tests" instance="dev"
```

When `instance` is omitted, the default instance is used. Each instance has its own auth token, timeout, and URL — fully isolated.

### Key Features

- **Zero-migration upgrade** — existing single-instance deployments work without any config change
- **Per-instance isolation** — separate auth tokens, timeouts, and URLs
- **Dynamic routing** — Claude picks the right instance per request
- **Task tracking** — async tasks remember which instance they target
- **Security** — tokens are never exposed via `openclaw_instances`

See [Configuration — Multi-Instance Mode](docs/configuration.md#multi-instance-mode) for details.
See [Configuration — Multi-Instance Mode](docs/configuration.md#multi-instance-mode) for the full reference.

## Documentation

Expand Down
52 changes: 50 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ All configuration can be done via environment variables. Copy `.env.example` to

Orchestrate multiple OpenClaw gateways from a single MCP server. Set `OPENCLAW_INSTANCES` as a JSON array — when present, it takes precedence over `OPENCLAW_URL` / `OPENCLAW_GATEWAY_TOKEN`.

```
┌─────────────────┐
│ Claude Client │
└────────┬────────┘
┌─────────────▼─────────────┐
│ OpenClaw MCP Bridge │
│ │
│ instance="prod" ──────────────► OpenClaw GW (prod)
│ instance="staging" ────────────► OpenClaw GW (staging)
│ instance="dev" ───────────────► OpenClaw GW (dev)
│ (no instance) ──► default ──► OpenClaw GW (prod)
└────────────────────────────┘
```

| Variable | Description | Default |
| -------------------- | ------------------------------ | ----------------------------- |
| `OPENCLAW_INSTANCES` | JSON array of instance configs | (none — single-instance mode) |
Expand Down Expand Up @@ -45,11 +60,44 @@ Each instance object supports:
All gateway-facing tools (`openclaw_chat`, `openclaw_status`, `openclaw_chat_async`) accept an optional `instance` parameter. When omitted, the default instance is used.

```
# Target a specific instance
openclaw_chat message="Hello" instance="staging"
openclaw_instances # list all available instances

# Check health of a specific gateway
openclaw_status instance="prod"

# List all available instances (names, URLs, default — tokens are never exposed)
openclaw_instances

# Async tasks also support instance targeting
openclaw_chat_async message="Run migration" instance="dev"

# Filter task list by instance
openclaw_task_list instance="staging"
```

**How instance resolution works:**

1. If `instance` parameter is provided → use that instance
2. If `instance` is omitted → use the instance marked as `default`
3. If no instance is marked as default → the first instance in the array is used

Each instance gets its own isolated HTTP client with independent auth token, timeout, and base URL. Async tasks store the target instance ID so results are always routed correctly.

**Docker Compose with multi-instance:**

```yaml
services:
mcp-bridge:
image: ghcr.io/freema/openclaw-mcp:latest
environment:
- OPENCLAW_INSTANCES=[{"name":"prod","url":"http://prod-gw:18789","token":"tok1","default":true},{"name":"staging","url":"http://staging-gw:18789","token":"tok2"}]
- AUTH_ENABLED=true
- MCP_CLIENT_ID=openclaw
- MCP_CLIENT_SECRET=${MCP_CLIENT_SECRET}
```

**Backward compatibility:** When `OPENCLAW_INSTANCES` is not set, the server creates a single `"default"` instance from `OPENCLAW_URL` + `OPENCLAW_GATEWAY_TOKEN`. Existing deployments work without any configuration change.
**Backward compatibility:** When `OPENCLAW_INSTANCES` is not set, the server creates a single `"default"` instance from `OPENCLAW_URL` + `OPENCLAW_GATEWAY_TOKEN`. Existing deployments work without any configuration change — zero migration required.

### Server Settings (SSE transport)

Expand Down
Loading