docs(dashboard): add Connecting to the Hub reference page

Covers local setup, remote (COULOMBCORE) one-liner registration,
ops-bridge tunnel config, bridge states, MCP transport modes, and
adding new remote hosts. Registered in Reference nav + reference.md index.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-16 00:22:43 +01:00
parent f3fca3088f
commit fbdc6dda80
3 changed files with 191 additions and 0 deletions

View File

@@ -43,6 +43,7 @@ export default {
collapsible: true,
open: false,
pages: [
{ name: "Connecting to the Hub", path: "/docs/connecting" },
{ name: "Contributions", path: "/docs/contributions" },
{ name: "Decision Health", path: "/docs/decisions-kpi" },
{ name: "Decisions", path: "/docs/decisions" },

View File

@@ -0,0 +1,189 @@
---
title: Connecting to the State Hub — Reference
---
# Connecting to the State Hub — Reference
How Claude Code agents on local and remote machines connect to the State Hub API
and its MCP server.
---
## Architecture overview
The State Hub runs on the **work laptop** only. Remote machines (COULOMBCORE,
Railiance nodes) never run their own copy — they connect to the single source
of truth via an encrypted SSH reverse tunnel managed by **ops-bridge**.
```
Work laptop Remote machine (e.g. COULOMBCORE)
───────────────────── ─────────────────────────────────
PostgreSQL :5432 Claude Code session
↑ │
FastAPI :8000 ←── ops-bridge ────→ :18000 (API health / tools)
MCP SSE :8001 ←── ops-bridge ────→ :18001 (MCP for Claude Code)
```
Two services are exposed through the tunnel:
| Service | Local port | Remote port | Purpose |
|---------|-----------|-------------|---------|
| State Hub API | `8000` | `18000` | Health checks, direct curl queries |
| MCP SSE server | `8001` | `18001` | Claude Code MCP integration |
---
## Local setup (work laptop)
### Start the services
```bash
cd ~/the-custodian/state-hub
make api # FastAPI on :8000
make mcp-http # MCP SSE server on :8001 (separate terminal)
```
`make mcp-http` sets `MCP_TRANSPORT=sse MCP_PORT=8001` and starts the same
MCP server that Claude Code uses locally in stdio mode. The SSE mode exposes
the identical tool surface over HTTP.
### Start the tunnels
```bash
bridge up # brings up both tunnels defined in ~/.config/bridge/tunnels.yaml
bridge status
```
Both tunnels must show `connected` (or `degraded` — see below) before remote
agents can connect.
### Local Claude Code registration (stdio, default)
Claude Code on the work laptop uses the stdio MCP server. Registration is in
`~/.claude.json` via `.mcp.json` at the repo root. No changes needed for local
use.
---
## Remote setup (COULOMBCORE or any remote host)
### Prerequisites
- ops-bridge tunnels running on the work laptop (`bridge status`)
- SSH key `~/.ssh/id_ops` authorised on the remote host for user `tegwick`
### One-time MCP registration on the remote
```bash
claude mcp add-json -s user state-hub \
'{"type":"sse","url":"http://127.0.0.1:18001/sse"}'
```
Restart Claude Code after running this. That's the only setup required — no
Python, no repo clone, no local services.
### Verify connectivity
```bash
# API reachable through tunnel?
curl -s http://127.0.0.1:18000/state/health
# → {"status":"ok","db":"connected"}
# MCP SSE endpoint reachable?
curl -s --max-time 2 http://127.0.0.1:18001/sse | head -2
# → event: endpoint
# → data: /messages/?session_id=...
```
---
## ops-bridge tunnel config
Tunnels are defined in `~/.config/bridge/tunnels.yaml` on the work laptop:
```yaml
tunnels:
state-hub-coulombcore: # API tunnel
host: 92.205.130.254
remote_port: 18000
local_port: 8000
ssh_user: tegwick
ssh_key: ~/.ssh/id_ops
actor: agent.claude-coulombcore
health_check:
url: http://127.0.0.1:18000/state/health
interval_seconds: 30
timeout_seconds: 5
reconnect:
max_attempts: 0 # retry forever
backoff_initial: 5
backoff_max: 60
state-hub-mcp-coulombcore: # MCP SSE tunnel
host: 92.205.130.254
remote_port: 18001
local_port: 8001
ssh_user: tegwick
ssh_key: ~/.ssh/id_ops
actor: agent.claude-coulombcore
health_check:
url: http://127.0.0.1:18001/sse
interval_seconds: 30
timeout_seconds: 5
reconnect:
max_attempts: 0
backoff_initial: 5
backoff_max: 60
```
ops-bridge source: `~/ops-bridge` · SSH key: `~/.ssh/id_ops`
---
## Bridge states
| State | Meaning |
|-------|---------|
| `connected` | SSH process alive, health check passing |
| `degraded` | SSH process alive, health check failing (SSE endpoint streams — not always a real error) |
| `reconnecting` | SSH dropped, backoff loop active |
| `stopped` | Not started or manually stopped |
The MCP SSE tunnel often shows `degraded` because the `/sse` health check
receives a streaming response rather than a clean 200 — the tunnel is still
functional. Confirm with `curl http://127.0.0.1:18001/sse` from the remote.
---
## MCP transport modes
The MCP server (`state-hub/mcp_server/server.py`) supports two transports
selected by environment variable:
| Variable | Default | Effect |
|----------|---------|--------|
| `MCP_TRANSPORT` | `stdio` | stdio transport (local Claude Code) |
| `MCP_TRANSPORT=sse` | — | SSE/HTTP transport for remote clients |
| `MCP_PORT` | `8001` | Port for SSE mode |
| `API_BASE` | `http://127.0.0.1:8000` | State Hub API URL the MCP server calls |
On a remote machine the MCP server process runs locally inside Claude Code — it
does not run on the remote host. The transport layer (SSE over the tunnel)
handles the connection.
---
## Adding a new remote host
1. Generate or reuse an SSH key pair (recommend `~/.ssh/id_ops`)
2. Add the public key to the remote host's `~/.ssh/authorized_keys`
3. Check port availability on the remote: `ssh user@host "ss -tlnp | grep 18001"`
4. Add two tunnel entries to `~/.config/bridge/tunnels.yaml` (API + MCP)
5. `bridge up <tunnel-name>` for each
6. On the remote: `claude mcp add-json -s user state-hub '{"type":"sse","url":"http://127.0.0.1:18001/sse"}'`
---
*The State Hub runs on the work laptop only. Remote machines are read-only
consumers connected via tunnel — they never own a copy of the database.*

View File

@@ -20,6 +20,7 @@ convention used in the Custodian State Hub.
| Page | What it covers |
|------|---------------|
| [Connecting to the Hub](/docs/connecting) | Local and remote connection setup, ops-bridge tunnels, MCP transports |
| [Contributions](/docs/contributions) | Contribution types, lifecycle, third-party todo workflow |
| [Decision Health](/docs/decisions-kpi) | KPI formula, avg resolve time, open-age colour thresholds |
| [Decisions](/docs/decisions) | Decision types, statuses, escalation rules, filter bar |