@gethelio/proxy 0.11.0 → 0.12.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
@@ -15,12 +15,14 @@
15
15
 
16
16
  ---
17
17
 
18
- Helio is an MCP proxy that sits between your AI agents and the tools they use. Every tool call passes through Helio, which enforces policies, checks evidence, routes approvals, tracks spend, and records everything - **without changing your agent code or your MCP servers.**
18
+ Helio is an MCP proxy that sits between your AI agents and the tools they use. Every tool call passes through Helio, which enforces policies, checks evidence, routes approvals, caps cumulative spend, and records everything - **without changing your agent code or your MCP servers.**
19
19
 
20
20
  ```bash
21
21
  npx @gethelio/proxy init
22
22
  ```
23
23
 
24
+ `@gethelio/proxy` is the only Node package you install. It ships the proxy runtime and bundled dashboard UI assets together.
25
+
24
26
  ## Why Helio?
25
27
 
26
28
  Your agent just called an API you didn't expect. It spent money you didn't authorize. It modified a production record you can't easily undo.
@@ -31,26 +33,23 @@ Helio governs what agents **do to the rest of the world** across any MCP-compati
31
33
 
32
34
  ## How It Works
33
35
 
34
- ```
35
- ┌──────────────┐ ┌──────────────────────┐ ┌──────────────┐
36
- │ │ │ Helio │ │ │
37
- │ MCP Client │────▶│ │────▶│ MCP Server │
38
- │ (Agent) │◀────│ • Policy engine │◀────│ (Tools) │
39
- │ │ │ • Evidence grounding │ │ │
40
- └──────────────┘ │ • Approval workflows │ └──────────────┘
41
- │ • Rate & spend limits │
42
- Optional │ • Audit trail │
43
- ┌─────────┐ │ • Self-repair feedback│
44
- │ SDK │───▶│ │
45
- │ (thin) │ └──────────────────────┘
46
- └─────────┘
47
- ```
36
+ <p align="center">
37
+ <img src="https://raw.githubusercontent.com/gethelio/helio/main/docs/images/how-it-works.svg" alt="MCP clients send tool calls through Helio — which applies its policy engine, evidence grounding, approval workflows, cross-tool spend budgets, rate and spend limits, audit trail, and self-repair feedback — before forwarding them to MCP servers. An optional thin Python SDK connects to Helio over a sideband." width="900" />
38
+ </p>
48
39
 
49
40
  Two integration paths:
50
41
 
51
42
  1. **Proxy only**: Point your MCP client at Helio instead of your MCP server. Zero code changes. Immediate governance.
52
43
  2. **Proxy + SDK**: Add the thin Python SDK to annotate tool calls with evidence context and action dependencies. Richer governance, under 500 lines of code.
53
44
 
45
+ ### Enforcement grades
46
+
47
+ Helio governs at the strongest grade each path physically allows, and records it per call:
48
+
49
+ - **Structural** (stdio MCP) — Helio owns the only path to the tool; the agent cannot route around it.
50
+ - **Network** (HTTP MCP) — structural given you control the upstream's egress.
51
+ - **Host-enforced** (hook adapters via the [adapter API](https://github.com/gethelio/helio/blob/main/docs/adapter-api.md), e.g. OpenClaw) — for frameworks that run tools in-process and expose hooks rather than an MCP transport. The framework's hook gate enforces; Helio decides. This is a cooperative, lower grade than the proxy path, and Helio labels it as such rather than overclaiming. Helio's decisions still cannot be evicted from the agent's context or prompt-injected, and any attempt to route around them is visible in the audit trail.
52
+
54
53
  ## Quick Start (5 minutes)
55
54
 
56
55
  ### 1. Install
@@ -59,33 +58,38 @@ Two integration paths:
59
58
  npx @gethelio/proxy init
60
59
  ```
61
60
 
61
+ This single package includes the built-in dashboard UI bundle.
62
+
62
63
  ### 2. Configure
63
64
 
64
- Create a `helio.yaml` in your project root:
65
+ `npx @gethelio/proxy init` already created a `helio.yaml` in your project root. Open it (e.g. `nano helio.yaml`, or in your editor) and point `upstream.url` at your existing MCP server. Helio proxies a single upstream MCP server.
66
+
67
+ > **Heads up — Helio starts in audit-only mode.** `init` scaffolds the `policies` section **commented out**, so out of the box Helio runs with `default: allow` and **zero rules**: it records every tool call to the audit trail but **blocks nothing**. Uncomment and edit `policies` (or paste your own rules) to start enforcing. See the [Policy Guide](https://github.com/gethelio/helio/blob/main/docs/policies.md) for rule syntax.
68
+
69
+ The block below is an **illustrative target** — not the file `init` writes — showing policies, budgets, audit, and a dashboard secret:
65
70
 
66
71
  ```yaml
67
72
  version: '1'
68
73
 
69
74
  upstream:
70
- url: 'http://localhost:3001/mcp' # Your existing MCP server
75
+ url: 'http://localhost:8080/mcp' # Your existing MCP server
76
+ transport: streamable-http # streamable-http (default), sse, or stdio
71
77
 
72
78
  listen:
73
79
  port: 3000 # Helio listens here
74
80
 
81
+ session:
82
+ identity: # Ordered identity sources; first match wins
83
+ - source: header
84
+ name: x-helio-session-id # Agent harnesses set this once per run
85
+ - source: legacy_header # Verbatim Mcp-Session-Id (deprecation window)
86
+ on_unresolved: deny # deny | anonymous
87
+
75
88
  policies:
76
89
  default: allow
77
90
 
91
+ # These rules match on tool-name globs (deny / rate-limit / spend-limit):
78
92
  rules:
79
- # Require approval for write operations
80
- - match:
81
- tool: '*'
82
- annotations:
83
- readOnlyHint: false
84
- action: require_approval
85
- approval:
86
- channel: dashboard
87
- timeout: 300s
88
-
89
93
  # Block destructive operations
90
94
  - match:
91
95
  tool: 'delete_*'
@@ -137,18 +141,23 @@ audit:
137
141
  dashboard:
138
142
  enabled: true
139
143
  port: 3100
140
- # Required whenever any rule uses `require_approval`. Generate with:
141
- # openssl rand -hex 32
142
144
  api_secret: '${HELIO_DASHBOARD_SECRET}'
143
145
  ```
144
146
 
145
- If you use the `${HELIO_DASHBOARD_SECRET}` placeholder above, set it before `start`:
147
+ Omitted fields like `listen.host`, `dashboard.host`, and `audit.path` fall back to safe defaults (`127.0.0.1` for both hosts — loopback only — and `./helio-audit.db`). The [Configuration Reference](https://github.com/gethelio/helio/blob/main/docs/configuration.md) is the authoritative list of every field, its default, and the canonical section order.
146
148
 
147
- ```bash
148
- export HELIO_DASHBOARD_SECRET="$(openssl rand -hex 32)"
149
- ```
149
+ If your upstream requires a static credential (for example `Authorization: Bearer …` on a hosted MCP server), set [`upstream.headers`](https://github.com/gethelio/helio/blob/main/docs/configuration.md#static-request-headers) — values support `${VAR}` interpolation so secrets stay out of the file.
150
+
151
+ No MCP server to test against? Helio ships a zero-dependency echo server you can run in one command — see the [Getting Started guide](https://github.com/gethelio/helio/blob/main/docs/getting-started.md#no-mcp-server-to-test-with).
152
+
153
+ About `dashboard.api_secret`:
154
+
155
+ - **If you ran `npx @gethelio/proxy init`**, your `helio.yaml` already contains a generated `api_secret` (a literal 32-byte hex value, also printed when you ran `init`). It's set — skip this step.
156
+ - **If you authored `helio.yaml` by hand** using the `${HELIO_DASHBOARD_SECRET}` placeholder shown above, set the variable before `start`:
150
157
 
151
- > **Host binding defaults.** `helio start` binds `listen.host` and `dashboard.host` to `127.0.0.1` by default (the `helio init` template writes this value, and the schema defaults to it). Do **not** flip either to `0.0.0.0` without putting an authenticating reverse proxy in front — the MCP edge has no authentication at all, and the dashboard sideband's bearer is a shared secret, not a user session. The [Docker quickstart](https://github.com/gethelio/helio/tree/main/docker) inverts this layering: inside the container the bundled config binds `0.0.0.0` (correct for the container's virtual network) and Compose's `ports:` map publishes both ports back to `127.0.0.1` on the host.
158
+ ```bash
159
+ export HELIO_DASHBOARD_SECRET="$(openssl rand -hex 32)"
160
+ ```
152
161
 
153
162
  ### 3. Start Helio
154
163
 
@@ -168,15 +177,27 @@ npx @gethelio/proxy start
168
177
  }
169
178
  ```
170
179
 
180
+ **No agent handy?** You don't need one to see Helio work. Point the official [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector) at `http://localhost:3000/mcp` (run `npx @modelcontextprotocol/inspector`, transport: Streamable HTTP — Inspector connects through its own local backend, which sends no `Origin` header; a browser-sent `Origin` is rejected by design), or send a call straight through the proxy from the terminal:
181
+
182
+ ```bash
183
+ curl -s -X POST http://localhost:3000/mcp \
184
+ -H 'Content-Type: application/json' \
185
+ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_weather","arguments":{"city":"London"}}}'
186
+ ```
187
+
188
+ Either way the call appears in the dashboard with its policy decision. (`get_weather` is one of the demo tools in Helio's [echo server](https://github.com/gethelio/helio/blob/main/docs/getting-started.md#no-mcp-server-to-test-with).)
189
+
171
190
  ### 5. Open the dashboard
172
191
 
173
192
  ```
174
193
  http://localhost:3100
175
194
  ```
176
195
 
177
- That's it. Every tool call now passes through Helio. This includes full audit trail, approval workflows, rate limits, and spend controls.
196
+ If prompted, log in with the `dashboard.api_secret` that `init` generated (also printed when you ran it).
197
+
198
+ That's it. Every tool call now passes through Helio with a full audit trail, rate limits, and spend controls.
178
199
 
179
- > **Notification transport semantics (v0.1).** For JSON-RPC notifications (requests with no `id`), Helio's `streamable-http` endpoint returns `HTTP 202 Accepted` with an empty body after forwarding upstream fire-and-forget. For the legacy `sse` transport, POST requests also return `202` with empty body and response payloads are delivered on the SSE stream. For correlated (non-notification) requests, Helio now requires upstream JSON-RPC responses to include an `id`; missing-id upstream replies are wrapped as protocol-invalid upstream errors.
200
+ Want human-in-the-loop approvals for write operations? See [docs/approvals.md](https://github.com/gethelio/helio/blob/main/docs/approvals.md) for the full Slack and dashboard approval flow, or copy [examples/slack-approvals/](https://github.com/gethelio/helio/tree/main/examples/slack-approvals) as a starting point.
180
201
 
181
202
  ## Features
182
203
 
@@ -200,12 +221,11 @@ Cumulative cross-tool spend enforcement: one depleting pot aggregates spend acro
200
221
 
201
222
  ```yaml
202
223
  budgets:
203
- - name: agent-payments
224
+ - name: daily-cap
204
225
  limit: 50
205
226
  currency: USD
206
- window: session
207
- key: session
208
- on_exceed: require_approval # or: deny
227
+ window: 24h
228
+ on_exceed: require_approval # a breach becomes a human decision
209
229
  contributors:
210
230
  - match:
211
231
  tool: 'stripe_*'
@@ -215,6 +235,8 @@ budgets:
215
235
  field: '$.total'
216
236
  ```
217
237
 
238
+ Budgets govern tools that expose what they are spending in an argument field. Watch the full flow — live depletion, breach, break-glass approval, the approved overage landing in the ledger — in the [Docker quickstart demo](https://github.com/gethelio/helio/blob/main/docker/README.md#break-the-budget) or the runnable [budgets example](https://github.com/gethelio/helio/tree/main/examples/budgets).
239
+
218
240
  ### Evidence Grounding
219
241
 
220
242
  Require proof before high-stakes actions. A refund requires a prior order lookup. A deployment requires a passing test run. The optional SDK marks tool outputs as evidence; the proxy enforces evidence requirements.
@@ -239,15 +261,15 @@ with HelioContext() as ctx:
239
261
  ctx.mark_evidence("orders.lookup", "order_data", result)
240
262
  ```
241
263
 
242
- The SDK talks to the proxy over the sideband API (default `127.0.0.1:3200`; bind host is configurable via `sdk.host`). On every `helio start` the proxy generates a fresh 32-byte hex token and prints it to stderr:
264
+ The SDK talks to the proxy over the sideband API (default `127.0.0.1:3200`; bind host is configurable via `sdk.host`). When the SDK sideband is enabled (`sdk.enabled: true`, off by default), the proxy generates a fresh 32-byte hex token on every `helio start` and prints it to stderr:
243
265
 
244
266
  ```
245
267
  SDK sideband listening on http://127.0.0.1:3200
246
- SDK token (pass as HELIO_SDK_TOKEN env var to your SDK clients):
268
+ SDK token (generated per-boot HELIO_SDK_TOKEN; pass as HELIO_SDK_TOKEN env var to your SDK clients):
247
269
  3f9c2b...d8a1
248
270
  ```
249
271
 
250
- Pass the same value to the SDK process via `HELIO_SDK_TOKEN` and the SDK automatically attaches `Authorization: Bearer <token>` to every sideband call. The sideband also rejects any request carrying a non-null `Origin` header, so a malicious local HTML file cannot talk to it through a browser. Operators who need a stable token across restarts can set `HELIO_SDK_TOKEN` explicitly in the proxy's environment — the proxy respects a pre-set value instead of regenerating one.
272
+ Pass the same value to the SDK process via `HELIO_SDK_TOKEN` and the SDK automatically attaches `Authorization: Bearer <token>` to every sideband call. The sideband also rejects any request carrying a non-null `Origin` header, so a malicious local HTML file cannot talk to it through a browser. Operators who need a stable token across restarts can set `HELIO_SDK_TOKEN` explicitly in the proxy's environment — the proxy respects a pre-set value instead of regenerating one, and does not echo it to stderr.
251
273
 
252
274
  ### Self-Repair Feedback
253
275
 
@@ -278,7 +300,6 @@ policies:
278
300
  ### Approval Workflows
279
301
 
280
302
  Route sensitive actions to Slack, webhook, or the Helio dashboard. Configurable timeout and escalation, plus a dashboard-only break-glass override (REST API and dashboard UI; not exposed as a Slack button).
281
- If a channel delivery fails, Helio logs an operational warning and emits an `approval_notification_failed` dashboard event so operators can investigate without losing the underlying pending ticket.
282
303
 
283
304
  ### Rate & Spend Limits
284
305
 
@@ -290,6 +311,15 @@ Every tool call recorded: timestamp, agent identity, tool name, inputs, policy d
290
311
 
291
312
  ## How Helio Compares
292
313
 
314
+ The `2026-07-28` MCP revision made the protocol itself stateless: no handshake, no
315
+ protocol-level sessions, cross-call state carried as handles the model passes between
316
+ tools. That pattern works for application state and fails for governance state,
317
+ because a budget key the model can see is a budget key the model can change. Helio
318
+ keeps session identity, budgets, and evidence in the proxy, outside the agent's
319
+ context, which is why those controls still mean something after the protocol
320
+ stopped tracking sessions. See
321
+ [stateless protocol, stateful governance](https://github.com/gethelio/helio/blob/main/docs/policies.md#stateless-protocol-stateful-governance).
322
+
293
323
  | | Helio | Obot | Cerbos | Built-in (Anthropic / OpenAI) | Framework (LangChain / CrewAI) |
294
324
  | -------------------------------------------- | ---------------------------------------- | ------------------------------ | --------------------------------- | ------------------------------------- | ----------------------------------- |
295
325
  | **What it governs** | Per-call actions with cross-call state | Which tools/MCPs are reachable | App-level authorization decisions | Agent permissions inside one platform | Agent behavior inside one framework |
@@ -334,7 +364,7 @@ Ready-made configurations for common patterns:
334
364
  - **[Basic](https://github.com/gethelio/helio/tree/main/examples/basic)**: Deny destructive operations, allow everything else
335
365
  - **[Slack Approvals](https://github.com/gethelio/helio/tree/main/examples/slack-approvals)**: Route destructive actions to Slack
336
366
  - **[Spend Limits](https://github.com/gethelio/helio/tree/main/examples/spend-limits)**: Govern payment tool usage
337
- - **[Budgets](https://github.com/gethelio/helio/tree/main/examples/budgets)**: One cross-tool budget across Stripe and PayPal tools, with break-glass overage approvals
367
+ - **[Budgets](https://github.com/gethelio/helio/tree/main/examples/budgets)**: A cross-tool budget across Stripe and PayPal tools with break-glass overage approvals, paired with a category cap that only charges calls declaring their spend category
338
368
 
339
369
  ## Contributing
340
370