@skilder-ai/runtime 0.9.24 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,14 +38,24 @@ This will start a long-living node process with the ability to host MCP Servers
38
38
 
39
39
  ## Running in Docker / Health check
40
40
 
41
- ### Health endpoint
41
+ ### Health endpoints
42
42
 
43
- When `REMOTE_PORT` is set, the runtime exposes `GET /health`:
43
+ When `REMOTE_PORT` is set, the runtime exposes two endpoints answering deliberately different questions.
44
+
45
+ **`GET /health` — liveness.** Is the process up and serving? Always **`200 { status: 'ok' }`**, with no I/O. It is available as soon as the port binds, before the runtime has connected to NATS, and it stays up across reconnect cycles. **This is the one to point a `HEALTHCHECK` at.**
46
+
47
+ **`GET /ready` — readiness.** Is this runtime connected, authenticated, and able to reach NATS?
44
48
 
45
49
  - **`200 { status: 'ok' }`** — NATS connected, an active round-trip probe (`flush`, 2s timeout) succeeded, and the runtime is authenticated
46
50
  - **`503 { status: 'error', message: '...' }`** — NATS disconnected, NATS unreachable (flush timed out), not authenticated, or an unexpected error occurred
47
51
 
48
- > **Note:** The health endpoint is only available when `REMOTE_PORT` is set. CLI/standalone mode (no `REMOTE_PORT`) does not start an HTTP server this is intentional.
52
+ Readiness only means something for a runtime that talks to a backend. A pure MCP server (`MCP_REMOTE_ENABLED` with no key — `STANDALONE_MCP_STREAM`) never connects or authenticates, so its `/ready` stays `503`: gate that one on `/health`, which is true as soon as it is serving.
53
+
54
+ > **Never point a `HEALTHCHECK` at `/ready`.** Readiness depends on a remote service, so gating liveness on it means one backend blip restarts your whole fleet — and restarting cannot fix a backend that is down. Use `/ready` to gate traffic, or to alert on a runtime that has been unready for longer than your longest planned outage.
55
+
56
+ Both endpoints are independent of the remote MCP endpoints: a runtime that serves no MCP endpoint (no `MCP_REMOTE_ENABLED`) is still healthcheckable. The container image defaults `REMOTE_PORT` to `3001`, so every runtime container has a working healthcheck out of the box.
57
+
58
+ > **Note:** `npx`-installed runtimes bind no port unless you set `REMOTE_PORT` yourself, and stdio mode (`USER_KEY`) never starts an HTTP server — it is spawned per client, so a shared port would collide.
49
59
 
50
60
  ### Docker Compose setup
51
61
 
@@ -54,16 +64,18 @@ services:
54
64
  runtime:
55
65
  image: your-runtime-image
56
66
  environment:
57
- REMOTE_PORT: "3001"
67
+ REMOTE_PORT: "3001" # web service (health/ready); the image defaults this
68
+ MCP_REMOTE_ENABLED: "true" # also serve the remote MCP endpoints on it
58
69
  RUNTIME_KEY: "<RUNTIME_API_KEY>"
59
70
  NATS_SERVERS: "nats:4222"
60
71
  healthcheck:
72
+ # Liveness, never readiness — see the note above.
61
73
  test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
62
74
  interval: 10s
63
75
  timeout: 5s
64
76
  retries: 5
65
- start_period: 60s # Allow time for NATS connect + auth
77
+ start_period: 30s # Only has to cover process startup, not the handshake
66
78
  restart: unless-stopped
67
79
  ```
68
80
 
69
- > **`start_period`**: Set this to at least 60s to allow enough time for the initial NATS connection and authentication handshake before Docker starts counting health check failures.
81
+ > **`start_period`**: `/health` answers as soon as the process binds its port, so this only needs to cover startup it does not have to wait out the NATS connection and authentication handshake.