@gethelio/proxy 0.11.1 → 0.13.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 +76 -45
- package/dist/cli.js +3878 -1786
- package/dist/dashboard-assets/assets/index-BUdEZ-VN.js +128 -0
- package/dist/dashboard-assets/assets/index-DtnT1Y9r.css +1 -0
- package/dist/dashboard-assets/index.html +2 -2
- package/dist/index.d.ts +744 -41
- package/dist/index.js +3405 -1568
- package/package.json +7 -7
- package/dist/dashboard-assets/assets/index-CPoQ6xns.css +0 -1
- package/dist/dashboard-assets/assets/index-D19fYKEH.js +0 -128
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,
|
|
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
|
-
|
|
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
|
-
|
|
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. The singular `upstream:` form stays fully supported; to govern more than one MCP server, declare a named `upstreams:` list in its place (set exactly one of the two). Tool sets are never merged: each named upstream is served at its own `/mcp/<name>` door. See the [Configuration Reference](https://github.com/gethelio/helio/blob/main/docs/configuration.md#upstreams).
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
224
|
+
- name: daily-cap
|
|
204
225
|
limit: 50
|
|
205
226
|
currency: USD
|
|
206
|
-
window:
|
|
207
|
-
|
|
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`).
|
|
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,8 @@ 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)**:
|
|
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
|
|
368
|
+
- **[Multi-Upstream](https://github.com/gethelio/helio/tree/main/examples/multi-upstream)**: Two named upstreams behind one proxy, with a door-scoped rate limit and budget
|
|
338
369
|
|
|
339
370
|
## Contributing
|
|
340
371
|
|