Skip to content

Server & task queue

hipmmcode serve runs a direct-connect HTTP + WebSocket server, so remote clients — web apps, phones, other machines — can drive full agent sessions. It speaks the same stream-json control protocol as the SDK host, plus a fire-and-forget async task queue.

bash
hipmmcode serve                                # 127.0.0.1:7777, auto-generated auth token
hipmmcode serve --port 9000 --auth-token S3CR3T
hipmmcode serve --host 0.0.0.0 --port 7777     # non-loopback binds print a security warning

On start it writes a discovery lockfile to ~/.hipmmcode/direct-connect.json (host, port, token) so local clients can find it. All requests authenticate with Authorization: Bearer <token>.

Interactive sessions (WebSocket)

POST   /sessions               → { "session_id": "…", "workspace_id": "…", "ws_url": "…" }
GET    /sessions/{id}          → session status + work_dir + workspace_id
DELETE /sessions/{id}          → remove the session and terminate every interactive terminal it owns
WS     /sessions/{id}/subscribe → bidirectional stream-json
POST   /threads/{id}/review    → enqueue a read-only structured review
GET    /threads/{id}           → Thread summary
GET    /threads/{id}/items     → cursor-paginated Turn/Item events
GET    /health                 → server status + task counts

Over the WebSocket you send user turns and control requests (set_model, interrupt, permission responses) and receive streamed events — text deltas, tool cards, results — exactly like the stdio SDK host. Disconnect and reconnect-resume the same session. One thread has one execution owner: a concurrent second subscription receives 409, and detached turns targeting the same tenant/workspace/thread run FIFO.

POST /threads/{id}/review accepts optional focus, provider, model, max_turns, and max_budget_usd. It exposes only read-oriented tools; mutating Bash commands reach the normal approval bridge and fail closed. The resulting reviewOutput item contains normalized findings with priority, confidence, absolute file path, and line range.

Each session gets a workspace_id that scopes its long-lived resources (notably exec_command PTY sessions). Idle-swept, deleted, and finished sessions have their PTYs terminated automatically; DELETE /sessions/{id} reports how many were killed.

Async task queue

Submit work, hang up, collect the result later — built for "send a task from your phone, read the answer whenever":

bash
# submit (connection can drop immediately)
curl -X POST http://127.0.0.1:7777/tasks \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"prompt": "audit the repo for TODOs and write a report to todos.md"}'
# → { "task_id": "task_…", "status": "queued" }

# check progress / result whenever
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:7777/tasks/task_…
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:7777/tasks        # list all

Submission fields

FieldDescription
prompt (required)The task
work_dirWorking directory for the run
provider / modelOverride the channel/model for this task
max_turnsCap tool-use iterations
max_budget_usdHard spend ceiling for the task
webhookURL that receives a POST with the full task record on completion
dangerously_skip_permissionsAllow mutating tools unattended (see below)

Task record

GET /tasks/{id} returns: status (queuedrunningcompleted / error / interrupted), result (final text), is_error, live progress (steps — completed tool calls — plus last_activity and its timestamp), created_at / finished_at, and the effective settings.

Semantics worth knowing

  • Detached — the task runs in the background regardless of your connection.
  • Persistent — tasks are saved to disk and reloaded on server restart (7-day retention). A task caught mid-run by a restart reloads as interrupted.
  • Fail-closed permissions — with nobody attached, any permission prompt is denied by default; the denial is visible in the task record. Pass dangerously_skip_permissions: true for autonomous tool use — only on servers you trust end-to-end.
  • Webhook — on completion the full record is POSTed to your webhook, so you don't need to poll.

Membership gateway

Share one upstream credential (e.g. Codex or xAI OAuth on the host) with teammates who each get their own quota, without handing out the raw API key:

bash
# Host: start serve with membership endpoints enabled
hipmmcode serve --gateway --auth-token S3CR3T
# or pure gateway (membership only):
hipmmcode serve --gateway-only

# Admin: create a member + one-time join code
hipmmcode member create --name alice --quota 1000000
# print activation code → give to Alice

# Member machine:
hipmmcode join <activation-code>
# then use hipmmcode as usual; requests are signed to the gateway

Useful admin subcommands: member list, member show, member set-quota, member disable, member delete. Members can inspect their own usage with member self-service commands after join. See hipmmcode member --help / hipmmcode join --help for the full surface.

The Claude subscription bridge (anthropic-claude) is not available as a gateway upstream — only channels that expose a reusable HTTP credential.

Security notes

  • Default bind is loopback. To expose it, prefer an SSH tunnel or a reverse proxy with TLS; a raw --host 0.0.0.0 bind means anyone with the token can run shell commands as your user.
  • The auth token gates every route. Rotate by restarting with a new --auth-token.
  • Workspace containment: set HIPMMCODE_WORKSPACE_ROOT=/path to reject any requested cwd outside that directory (canonicalized — symlink escapes are rejected too). Unset, the historical arbitrary-cwd behavior is preserved for local use.
  • Multi-tenant identity: HIPMMCODE_TENANT_ID labels every resource the server creates (defaults to local-server); interactive terminal sessions are only reachable by their owning tenant/workspace/session, and quota limits apply per level (HIPMMCODE_PTY_PER_AGENT / _PER_THREAD / _PER_WORKSPACE / _PER_TENANT / HIPMMCODE_MAX_PTY_SESSIONS).
  • Scoped persistence: app events are stored through ThreadStore; the local implementation keys platform files by tenant/workspace/thread and uses an advisory lock for cross-process monotonic sequences. Legacy unscoped JSONL remains readable.
  • Encrypted credentials: set a high-entropy HIPMMCODE_MASTER_KEY (32+ characters) to store MCP OAuth credentials in the encrypted scoped backend and migrate an existing owner-only JSON token on first read.