@rapidthoughtlabs/heku 0.2.0 → 0.3.1

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.
Files changed (4) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/README.md +361 -62
  3. package/dist/cli.js +431 -209
  4. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2026-06-11
11
+
12
+ ### Added
13
+ - **`heku update`** now updates registry-installed configs to their latest versions (instead of updating the heku binary). Accepts an optional target: `heku update github-http`, `heku update linear:graphql`, or `heku update @ns/linear` (all connector variants). Local credentials (`connector.env`) and overlays are preserved on update.
14
+ - **`one.registry_update`** MCP tool — same update logic callable by an LLM agent. Updates one config by `config_id` or all installed configs when no argument is passed.
15
+ - **`one.list_configs`** now returns `[{ id, name, description }]` objects instead of a flat array of IDs, so agents can identify the right config without an extra round-trip.
16
+
17
+ ### Changed
18
+ - Publish modal always shows the version field. New (unpublished) configs show an empty field with a "not published yet" hint; existing configs are pre-filled with the next patch version and show the current published version as a hint.
19
+ - Flat manifest (`search`, `list_configs`, `list_tools`, `invoke`) no longer prefixes tool descriptions with `[one]` — it was noise when only four tools are shown. Namespaced mode is unchanged.
20
+ - Discovery tool descriptions updated with explicit workflow steps and call examples for users without custom system prompts.
21
+
10
22
  ## [0.2.0] - 2026-06-09
11
23
 
12
24
  ### Changed
@@ -35,7 +47,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
35
47
  - Initial public release on npm as `@rapidthoughtlabs/mcpone`.
36
48
  - Single dynamic MCP server that turns JSON configs into working API tools.
37
49
 
38
- [Unreleased]: https://github.com/RapidThoughtLabs/heku/compare/v0.2.0...HEAD
50
+ [Unreleased]: https://github.com/RapidThoughtLabs/heku/compare/v0.3.0...HEAD
51
+ [0.3.0]: https://github.com/RapidThoughtLabs/heku/compare/v0.2.0...v0.3.0
39
52
  [0.2.0]: https://github.com/RapidThoughtLabs/heku/compare/v0.1.2...v0.2.0
40
53
  [0.1.2]: https://github.com/RapidThoughtLabs/heku/compare/v0.1.0...v0.1.2
41
54
  [0.1.0]: https://github.com/RapidThoughtLabs/heku/releases/tag/v0.1.0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # heku
2
2
 
3
- > One server. Any REST API. Any LLM.
3
+ > One server. Any API. Any LLM.
4
4
 
5
5
  **heku** is a single dynamic [Model Context Protocol](https://modelcontextprotocol.io) server that turns JSON config files into working API tools. No code to write — drop a config, and your LLM gets the tools instantly.
6
6
 
@@ -8,13 +8,21 @@ Stop building one MCP server per API. Build one config.
8
8
 
9
9
  ---
10
10
 
11
+ ## Try it now
12
+
13
+ **[console.rapidthoughtlabs.space](https://console.rapidthoughtlabs.space)** — hosted console you can point at any running heku instance. Connect, browse configs, chat with your tools, and inspect the system prompt — no local build needed.
14
+
15
+ **[app.rapidthoughtlabs.space](https://app.rapidthoughtlabs.space)** — **heku hub**, the online registry for browsing, installing, and publishing heku configs. Find community-built connectors for GitHub, Slack, Linear, and more — or publish your own.
16
+
17
+ ---
18
+
11
19
  ## Features
12
20
 
13
- - **7 connector types** — HTTP, gRPC, GraphQL, CLI, File, child-MCP, and Internal (self-management)
21
+ - **8 connector types** — 4 standard (HTTP, GraphQL, gRPC, child-MCP) + 4 experimental (CLI, File, SQL, MongoDB)
14
22
  - **Hot-reload** — add or edit a config, tools update live without restart
15
23
  - **Auto-discovery** — gRPC reflection, GraphQL introspection, and child MCP tool listing fill in tools automatically
16
24
  - **Built-in console UI** — React dashboard for chat, config editing, and registry browsing
17
- - **Registry** — publish and install community configs from [mcp.rapidthoughtlabs.space](https://mcp.rapidthoughtlabs.space)
25
+ - **heku hub** — publish and install community configs from [app.rapidthoughtlabs.space](https://app.rapidthoughtlabs.space)
18
26
  - **Auth handled** — bearer, basic, API key, and OAuth2 with `.env`-based credential management
19
27
  - **Self-managing** — the server can create and edit its own configs via internal tools
20
28
 
@@ -39,12 +47,13 @@ heku start
39
47
 
40
48
  ## Quick start
41
49
 
42
- Create a config in `mcp-configs/mcp.github.json`:
50
+ Create `mcp-configs/mcp.github.json`:
43
51
 
44
52
  ```json
45
53
  {
46
- "id": "github",
54
+ "id": "github-http",
47
55
  "name": "GitHub API",
56
+ "description": "Manage GitHub repos, issues, and pull requests",
48
57
  "connector": {
49
58
  "type": "http",
50
59
  "base_url": "https://api.github.com",
@@ -64,33 +73,327 @@ Create a config in `mcp-configs/mcp.github.json`:
64
73
  }
65
74
  ```
66
75
 
67
- Set your token:
68
-
69
76
  ```bash
70
- heku auth setup github
77
+ heku auth setup github-http # writes GITHUB_TOKEN to .env
78
+ heku start
71
79
  ```
72
80
 
73
- Start the server:
81
+ Your LLM now has a `github-http.list_repos` tool.
74
82
 
75
- ```bash
76
- heku start
83
+ ---
84
+
85
+ ## Connectors
86
+
87
+ Tool names follow the pattern `config_id.tool_name` — e.g. `github-http.list_repos`, `linear-graphql.create_issue`.
88
+
89
+ ### Standard
90
+
91
+ #### `http` — REST API
92
+
93
+ Define each endpoint as a tool. Supports `path`, `query`, `body`, and `header` params.
94
+
95
+ ```json
96
+ {
97
+ "id": "stripe-http",
98
+ "name": "Stripe",
99
+ "connector": {
100
+ "type": "http",
101
+ "base_url": "https://api.stripe.com/v1",
102
+ "auth": { "type": "bearer", "token_env": "STRIPE_API_KEY" }
103
+ },
104
+ "tools": [
105
+ {
106
+ "name": "list_customers",
107
+ "description": "List Stripe customers with optional filters",
108
+ "method": "GET",
109
+ "path": "/customers",
110
+ "params": [
111
+ { "name": "limit", "type": "number", "required": false, "location": "query", "description": "Max results (1–100)" },
112
+ { "name": "email", "type": "string", "required": false, "location": "query", "description": "Filter by email address" }
113
+ ]
114
+ },
115
+ {
116
+ "name": "create_customer",
117
+ "description": "Create a new Stripe customer",
118
+ "method": "POST",
119
+ "path": "/customers",
120
+ "params": [
121
+ { "name": "email", "type": "string", "required": true, "location": "body", "description": "Customer email" },
122
+ { "name": "name", "type": "string", "required": false, "location": "body", "description": "Full name" }
123
+ ]
124
+ }
125
+ ]
126
+ }
127
+ ```
128
+
129
+ **Tool fields:** `name`, `description`, `method` (`GET`/`POST`/`PUT`/`PATCH`/`DELETE`), `path` (supports `{{param}}` placeholders), `params[]`, `body_template?`, `response_map?`, `error_map?`
130
+
131
+ **Param locations:** `path` · `query` · `body` · `header`
132
+
133
+ ---
134
+
135
+ #### `graphql` — GraphQL API
136
+
137
+ Tools are auto-discovered via introspection. Set `tools: []`.
138
+
139
+ ```json
140
+ {
141
+ "id": "linear-graphql",
142
+ "name": "Linear",
143
+ "connector": {
144
+ "type": "graphql",
145
+ "endpoint": "https://api.linear.app/graphql",
146
+ "auth": { "type": "bearer", "token_env": "LINEAR_API_KEY" },
147
+ "include_mutations": true,
148
+ "include_queries": true
149
+ },
150
+ "tools": []
151
+ }
152
+ ```
153
+
154
+ **Connector fields:** `endpoint`, `auth?`, `introspect?` (default `true`), `include_mutations?` (default `true`), `include_queries?` (default `true`), `headers?`, `timeout_ms?`
155
+
156
+ ---
157
+
158
+ #### `grpc` — gRPC service
159
+
160
+ Tools are auto-discovered via server reflection or a `.proto` file. Set `tools: []`.
161
+
162
+ ```json
163
+ {
164
+ "id": "myservice-grpc",
165
+ "name": "My gRPC Service",
166
+ "connector": {
167
+ "type": "grpc",
168
+ "endpoint": "localhost:50051",
169
+ "reflection": true,
170
+ "tls": false
171
+ },
172
+ "tools": []
173
+ }
174
+ ```
175
+
176
+ Or with a proto file:
177
+
178
+ ```json
179
+ {
180
+ "connector": {
181
+ "type": "grpc",
182
+ "endpoint": "grpc.example.com:443",
183
+ "proto_path": "./protos/service.proto",
184
+ "tls": true,
185
+ "auth": { "type": "bearer", "token_env": "GRPC_TOKEN" }
186
+ }
187
+ }
188
+ ```
189
+
190
+ **Connector fields:** `endpoint`, `reflection?` or `proto_path?` (one required), `tls?` (`true`/`false` or cert object), `auth?`, `metadata?`, `service_filter?`, `timeout_ms?`
191
+
192
+ ---
193
+
194
+ #### `mcp` — child MCP server
195
+
196
+ Spawn any existing MCP server (stdio or SSE) and proxy its tools through heku. Tools are auto-discovered. Set `tools: []`.
197
+
198
+ ```json
199
+ {
200
+ "id": "filesystem-mcp",
201
+ "name": "Filesystem MCP",
202
+ "connector": {
203
+ "type": "mcp",
204
+ "transport": "stdio",
205
+ "command": "npx",
206
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
207
+ "install_command": "npm",
208
+ "install_args": ["install", "-g", "@modelcontextprotocol/server-filesystem"]
209
+ },
210
+ "tools": []
211
+ }
212
+ ```
213
+
214
+ SSE transport:
215
+
216
+ ```json
217
+ {
218
+ "connector": {
219
+ "type": "mcp",
220
+ "transport": "sse",
221
+ "url": "http://localhost:8080/sse"
222
+ }
223
+ }
224
+ ```
225
+
226
+ **Connector fields:** `transport` (`stdio`/`sse`), `command?` + `args?` + `env?` (stdio), `url?` (sse), `install_command?`, `install_args?`, `install_cwd?`, `install_env?`, `install_timeout_ms?`, `active?`
227
+
228
+ > **Note:** `mcp` configs cannot be published to the registry — they reference local processes.
229
+
230
+ ---
231
+
232
+ ### Experimental
233
+
234
+ > These connector types are functional but their config schema and behaviour may change in future releases.
235
+
236
+ ---
237
+
238
+ #### `cli` — shell command
239
+
240
+ Wrap any CLI tool as an MCP tool. Use `args_template` for positional args or `stdin_template` to pipe input.
241
+
242
+ ```json
243
+ {
244
+ "id": "git-cli",
245
+ "name": "Git",
246
+ "connector": { "type": "cli" },
247
+ "tools": [
248
+ {
249
+ "name": "log",
250
+ "description": "Show recent git commits",
251
+ "args_template": ["git", "log", "--oneline", "-{{limit}}"],
252
+ "params": [
253
+ { "name": "limit", "type": "number", "required": false, "description": "Number of commits to show" }
254
+ ],
255
+ "output_as": "text"
256
+ },
257
+ {
258
+ "name": "diff",
259
+ "description": "Show unstaged changes",
260
+ "command": "git diff",
261
+ "params": [],
262
+ "output_as": "text"
263
+ }
264
+ ]
265
+ }
266
+ ```
267
+
268
+ **Tool fields:** `name`, `description`, `params[]`, `command?` (string) or `args_template?` (array), `stdin_template?`, `output_as?` (`"text"` | `"json"`)
269
+
270
+ ---
271
+
272
+ #### `file` — filesystem
273
+
274
+ Read, write, append, delete, or list files. `path_template` supports `{{param}}` placeholders.
275
+
276
+ ```json
277
+ {
278
+ "id": "notes-file",
279
+ "name": "Notes",
280
+ "connector": { "type": "file" },
281
+ "tools": [
282
+ {
283
+ "name": "read_note",
284
+ "description": "Read a note by name",
285
+ "operation": "read",
286
+ "path_template": "/home/user/notes/{{name}}.md",
287
+ "params": [
288
+ { "name": "name", "type": "string", "required": true, "description": "Note filename without extension" }
289
+ ]
290
+ },
291
+ {
292
+ "name": "save_note",
293
+ "description": "Save or overwrite a note",
294
+ "operation": "write",
295
+ "path_template": "/home/user/notes/{{name}}.md",
296
+ "content_template": "{{content}}",
297
+ "params": [
298
+ { "name": "name", "type": "string", "required": true, "description": "Note filename without extension" },
299
+ { "name": "content", "type": "string", "required": true, "description": "Note content" }
300
+ ]
301
+ }
302
+ ]
303
+ }
304
+ ```
305
+
306
+ **Tool fields:** `name`, `description`, `params[]`, `operation` (`read`/`write`/`append`/`delete`/`list`), `path_template`, `content_template?` (required for `write`/`append`)
307
+
308
+ ---
309
+
310
+ #### `sql` — relational database
311
+
312
+ Named SQL queries with `:param` placeholders. Supports PostgreSQL, MySQL, and SQLite.
313
+
314
+ ```json
315
+ {
316
+ "id": "analytics-sql",
317
+ "name": "Analytics DB",
318
+ "connector": {
319
+ "type": "sql",
320
+ "dialect": "postgres",
321
+ "connection_string_env": "DATABASE_URL"
322
+ },
323
+ "tools": [
324
+ {
325
+ "name": "active_users",
326
+ "description": "Count active users in a date range",
327
+ "sql": "SELECT COUNT(*) as count FROM users WHERE created_at BETWEEN :from AND :to AND active = true",
328
+ "params": [
329
+ { "name": "from", "type": "string", "required": true, "description": "Start date (ISO 8601)" },
330
+ { "name": "to", "type": "string", "required": true, "description": "End date (ISO 8601)" }
331
+ ],
332
+ "max_rows": 1
333
+ }
334
+ ]
335
+ }
77
336
  ```
78
337
 
79
- Your LLM now has a `github.list_repos` tool. That's it.
338
+ **Connector fields:** `dialect` (`postgres`/`mysql`/`sqlite`), `connection_string_env?` or field-based (`host`, `port`, `database`, `username_env`, `password_env`), `ssl?`, `pool_max?`
339
+
340
+ **Tool fields:** `name`, `description`, `params[]`, `sql` (`:name` placeholders only — no `{{}}`, no `?`, no `$N`), `max_rows?` (1–10000), `timeout_ms?`
80
341
 
81
342
  ---
82
343
 
83
- ## Connector types
344
+ #### `mongodb` — MongoDB
345
+
346
+ Document operations with JSON templates. Placeholders use `{{param}}` in templates.
347
+
348
+ ```json
349
+ {
350
+ "id": "catalog-mongo",
351
+ "name": "Product Catalog",
352
+ "connector": {
353
+ "type": "mongodb",
354
+ "database": "catalog",
355
+ "connection_string_env": "MONGO_URI"
356
+ },
357
+ "tools": [
358
+ {
359
+ "name": "find_products",
360
+ "description": "Search products by category and price range",
361
+ "collection": "products",
362
+ "operation": "find",
363
+ "filter_template": { "category": "{{category}}", "price": { "$lte": "{{max_price}}" } },
364
+ "params": [
365
+ { "name": "category", "type": "string", "required": true, "description": "Product category" },
366
+ { "name": "max_price", "type": "number", "required": false, "description": "Maximum price" }
367
+ ],
368
+ "max_rows": 50
369
+ }
370
+ ]
371
+ }
372
+ ```
373
+
374
+ **Connector fields:** `database`, `connection_string_env?` or `host?`+`port?`, `auth_source?`, `tls?`
375
+
376
+ **Tool fields:** `name`, `description`, `params[]`, `collection`, `operation` (`find`/`findOne`/`aggregate`/`insertOne`/`insertMany`/`updateOne`/`updateMany`/`deleteOne`/`deleteMany`/`countDocuments`/`distinct`), plus operation-specific templates: `filter_template`, `update_template`, `document_template`, `documents_template`, `pipeline_template`, `projection?`, `sort?`, `max_rows?`, `limit?`, `timeout_ms?`
377
+
378
+ ---
84
379
 
85
- | Type | Use case |
380
+ ## Auth types
381
+
382
+ All credentials read from environment variables — `heku auth setup` writes them to `.env`:
383
+
384
+ | Type | Header |
86
385
  |---|---|
87
- | `http` | REST APIs define method, path, params, response mapping |
88
- | `grpc` | gRPC services — load via `.proto` file or server reflection; tools auto-discovered |
89
- | `graphql` | GraphQL APIs introspection-based auto-discovery, or define operations manually |
90
- | `cli` | Wrap any shell command as a tool with templated args/stdin |
91
- | `file` | Filesystem operations: read, write, append, delete, list |
92
- | `mcp` | Spawn another MCP server (stdio or SSE) and proxy its tools through heku |
93
- | `internal` | heku's own management surface — create configs, install from registry, set auth |
386
+ | `bearer` | `Authorization: Bearer {token}` |
387
+ | `basic` | `Authorization: Basic base64(user:token)` |
388
+ | `api_key` | Custom header, e.g. `X-API-Key` |
389
+ | `oauth2_static` | Pre-acquired OAuth2 access token |
390
+
391
+ ```json
392
+ { "type": "bearer", "token_env": "GITHUB_TOKEN" }
393
+ { "type": "api_key", "key_env": "MY_KEY", "header_name": "X-Api-Key" }
394
+ { "type": "basic", "username_env": "MY_USER", "token_env": "MY_PASS" }
395
+ { "type": "oauth2_static","token_env": "MY_OAUTH_TOKEN" }
396
+ ```
94
397
 
95
398
  ---
96
399
 
@@ -119,43 +422,17 @@ heku update Update heku to the latest version
119
422
  heku help Show usage
120
423
  ```
121
424
 
122
- Run with `--http` to start the console UI alongside the stdio server:
425
+ Start with the console UI:
123
426
 
124
427
  ```bash
125
428
  heku start --http --port 3456
126
429
  ```
127
430
 
128
- ---
129
-
130
- ## Configuration
131
-
132
- ### Config file shape
133
-
134
- Configs live in `mcp-configs/mcp.{id}.json`:
135
-
136
- ```typescript
137
- {
138
- id: string; // becomes the tool namespace prefix
139
- name: string;
140
- description?: string; // shown to the LLM
141
- connector: ConnectorConfig; // one of 7 types
142
- tools: ToolDef[]; // empty for auto-discovery (grpc/graphql/mcp)
143
- overlays?: { // override tool descriptions without editing the config
144
- [toolName: string]: { description?: string }
145
- };
146
- }
147
- ```
148
-
149
- ### Auth types
150
-
151
- All credentials read from environment variables — `heku auth setup` writes them to `.env`:
431
+ Then open **[console.rapidthoughtlabs.space](https://console.rapidthoughtlabs.space)** and connect to `http://localhost:3456`.
152
432
 
153
- - **`bearer`** — `Authorization: Bearer {token}`
154
- - **`basic`** — base64(username:token)
155
- - **`api_key`** — custom header (e.g. `X-API-Key`)
156
- - **`oauth2_static`** — pre-acquired OAuth2 access token
433
+ ---
157
434
 
158
- ### System config (optional)
435
+ ## System config (optional)
159
436
 
160
437
  Drop `heku.config.json` in your config directory:
161
438
 
@@ -163,7 +440,7 @@ Drop `heku.config.json` in your config directory:
163
440
  {
164
441
  "log_level": "info",
165
442
  "rate_limits": {
166
- "github": { "requests_per_minute": 60 }
443
+ "github-http": { "requests_per_minute": 60 }
167
444
  },
168
445
  "self_config": true
169
446
  }
@@ -173,28 +450,27 @@ Drop `heku.config.json` in your config directory:
173
450
 
174
451
  ## Console UI
175
452
 
176
- The dashboard is a React + Vite app that talks to the heku server:
453
+ The dashboard is a React + Vite app available hosted at **[console.rapidthoughtlabs.space](https://console.rapidthoughtlabs.space)** or embedded when you run `heku start --http`.
177
454
 
178
- - **Chat** — test tools through a model of your choice
455
+ - **Chat** — test tools through a model of your choice (OpenAI, Together AI)
179
456
  - **Configs** — visual editor for connector and tool definitions
457
+ - **Prompts** — inspect the system prompt layers and token counts
180
458
  - **Registry** — browse, install, and publish configs
181
- - **Auth** — see credential status across all configs at a glance
182
-
183
- Built with React 19, TailwindCSS v4, Zustand, and the MCP SDK.
459
+ - **Auth** — credential status across all configs at a glance
184
460
 
185
461
  ---
186
462
 
187
- ## Registry
463
+ ## heku hub
188
464
 
189
- [**mcp.rapidthoughtlabs.space**](https://mcp.rapidthoughtlabs.space) is the default registry for sharing configs.
465
+ **[app.rapidthoughtlabs.space](https://app.rapidthoughtlabs.space)** is the default registry for sharing configs — browse community connectors, install with one command, and publish your own.
190
466
 
191
467
  ```bash
192
468
  heku install @rtl/github
193
469
  heku install @rtl/slack@1.2.0
194
- heku publish my-config.json
470
+ heku publish mcp-configs/mcp.stripe-http.json
195
471
  ```
196
472
 
197
- Use `--registry` to point at a different one.
473
+ Use `--registry <url>` to point at a self-hosted registry.
198
474
 
199
475
  ---
200
476
 
@@ -227,7 +503,30 @@ mcp-configs/ Local config files (gitignored)
227
503
 
228
504
  ## Tech stack
229
505
 
230
- TypeScript · Node.js (ESM) · `@modelcontextprotocol/sdk` · Express · React 19 · Vite · TailwindCSS · Zustand · `@grpc/grpc-js` · GraphQL · tsup · Vitest
506
+ TypeScript · Node.js (ESM) · `@modelcontextprotocol/sdk` · Express · React 19 · Vite · Zustand · `@grpc/grpc-js` · GraphQL · tsup · Vitest
507
+
508
+ ---
509
+
510
+ ## Changelog
511
+
512
+ ### 0.3.1
513
+ - Renamed meta-tool namespace from `mcp.one.*` to `heku.*` across all connectors, prompts, and client code
514
+ - Fixed deployed console manifest style switcher (settings API calls now use the correct bridge base URL)
515
+ - Fixed prompt page config catalog not refreshing when heku connects after page load
516
+ - Markdown rendering in the demo chat — assistant responses now render formatted text
517
+ - Config catalog descriptions now show in composed prompt preview; falls back to display name when description is absent
518
+ - Dual manifest preview in Prompts page — flat and namespaced styles with separate token counts
519
+ - heku server version now reads from `package.json` at runtime in dev mode instead of showing `0.0.0-dev`
520
+
521
+ ### 0.3.0
522
+ - Registry versioning overhaul — semver-based publish/install flow
523
+ - CLI registry commands: `install`, `uninstall`, `fork`, `publish`
524
+ - Console registry browser tab
525
+
526
+ ### 0.2.x
527
+ - SQL and MongoDB connector types (experimental)
528
+ - Config write lock — block LLM agents from mutating configs
529
+ - Hot-reload watcher improvements
231
530
 
232
531
  ---
233
532