@hol-org/hashnet-mcp 1.0.11 → 1.0.13

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
@@ -1,256 +1,166 @@
1
- # Hashnet MCP
1
+ # HOL Hashnet MCP
2
2
 
3
- Node/TypeScript Model Context Protocol server exposing the Hashgraph Online Registry Broker via FastMCP, with both stdio and SSE transports. See `AGENTS.md` for full contributor guidance.
3
+ Model Context Protocol (MCP) server for Hashgraph Online’s Registry Broker. It gives AI agents a first-class tool suite to discover, register, and chat with agents/servers on the Hashgraph network, plus workflow shortcuts for common journeys.
4
4
 
5
- ## Directory Layout
6
- - `src/` application source code. Core entrypoints (`mcp.ts`, `broker.ts`) live here.
7
- - `src/schemas/` shared zod schemas and SDK-driven types.
8
- - `src/transports/` stdio/SSE transport helpers plus bootstrap glue.
9
- - `tests/` Vitest specs mirroring the `src/` tree.
10
- - `examples/` – sample payloads, env snippets, and integration fixtures.
5
+ ## Why use this server?
6
+ - **Discovery & chat in one place**: Find UAIDs/agents/MCP servers, validate them, open chat sessions, and send messages via a single MCP endpoint.
7
+ - **Registration flows**: Request quotes, submit HCS-11 registrations, and wait for completion with built-in pipelines.
8
+ - **Ops & credits**: Inspect broker health/metrics, and manage credits (HBAR or X402), with guardrails for required approvals.
9
+ - **DX for agent platforms**: Ships both stdio (great for Claude Desktop) and HTTP streaming/SSE (great for Cursor/Claude Code/Codex).
11
10
 
12
- ## Getting Started
13
- ```
11
+ ## Quickstart
12
+ Prereqs: Node 18+, `pnpm` (or npm), and a broker API key.
13
+
14
+ You can get a API key at [hol.org/regsitry](https://hol.org/registry)
15
+
16
+ 1) Install deps and env:
17
+ ```bash
14
18
  pnpm install
15
- pnpm dev:stdio # once scripts are added
19
+ cp .env.example .env # add REGISTRY_BROKER_API_KEY + URL
16
20
  ```
17
- Copy `.env.example` to `.env` and fill in Registry Broker + Hedera credentials before running transports.
18
- All transports, workflows, and CLI scripts load `.env` automatically via `dotenv`, so once the file is populated you can run `pnpm dev:*`, `pnpm workflow:*`, or tests without re-exporting environment variables.
19
-
20
- ### Zero-touch Quickstart
21
+ 2) Run (HTTP streaming, default port 3333):
22
+ ```bash
23
+ npx @hol-org/hashnet-mcp@latest up --transport sse --port 3333
24
+ # or from source: pnpm dev:sse
21
25
  ```
26
+ 3) Point your MCP client at `http://localhost:3333/mcp/stream` (or `/mcp/sse` if it prefers SSE).
27
+
28
+ ### Zero-touch quickstart
29
+ ```bash
22
30
  pnpm quickstart
23
31
  ```
24
- The DX script will:
25
- 1. Copy `.env.example` (and let you inject your Registry Broker API key).
26
- 2. Install dependencies, build the project, and run smoke tests.
27
- 3. Launch the dev transport you choose (`sse` by default) with a stylized CLI experience.
28
-
29
- ## Logging & Health
30
- - `LOG_LEVEL` controls `pino` verbosity (`fatal`, `error`, `warn`, `info`, `debug`, `trace`).
31
- - Every tool invocation is logged with a requestId plus duration; SSE/stdio transport logs each HTTP request.
32
- - `/healthz` returns `{ status, uptime, tools }` so Fly.io/Cloud Run probes can verify readiness.
33
- - Optional rate limiting is enabled via the `BROKER_*` variables; point `BROKER_RATE_LIMIT_REDIS_URL` at your Redis cluster to queue requests across replicas.
34
- - `HTTP_STREAM_PORT` lets you pin the internal FastMCP HTTP-stream backend to a specific port (defaults to `PORT + 1`). External clients always connect to `http://<host>:PORT/mcp/stream` (Streamable HTTP) or `http://<host>:PORT/mcp/sse` (SSE fallback).
32
+ Guides you through copying `.env`, installing deps, running smoke checks, and launching your chosen transport (stdio or sse).
35
33
 
36
- ## MCP Client Configuration
37
- Claude Desktop (stdio):
34
+ ## Architecture (mental model)
35
+ ```
36
+ Client (Cursor / Claude Code / Claude Desktop / Codex)
37
+ │ stdio (dev:stdio) or HTTP stream/SSE (dev:sse)
38
+
39
+ Hashnet MCP (FastMCP)
40
+ ├─ mcp.ts (tools + schemas + instructions)
41
+ ├─ workflows/* (pipelines like discovery, registration, chat)
42
+ └─ broker.ts (RegistryBrokerClient wrapper + rate limits)
43
+
44
+ Hashgraph Online Registry Broker API
45
+ ```
38
46
 
47
+ ## MCP client setup
48
+ ### Cursor / Claude Code (HTTP)
39
49
  ```json
40
50
  {
41
- "hashnet": {
42
- "type": "stdio",
43
- "command": "npx",
44
- "args": [
45
- "-y",
46
- "@hol-org/hashnet-mcp",
47
- "up"
48
- ],
49
- "env": {
50
- "REGISTRY_BROKER_API_KEY": "x",
51
- "REGISTRY_BROKER_API_URL": "https://registry.hashgraphonline.com/api/v1"
51
+ "mcpServers": {
52
+ "hashnet-mcp": {
53
+ "enabled": true,
54
+ "type": "http",
55
+ "url": "http://localhost:3333/mcp/stream"
52
56
  }
53
57
  }
54
58
  }
55
59
  ```
60
+ Use `"type": "sse"` if your build expects it.
56
61
 
57
- Claude Code / Cursor (HTTP streaming): point the client at `https://<host>/mcp/stream` once deployed (see `deploy/README.md`). Use `pnpm dev:sse` locally to expose the same endpoint at `http://localhost:3333/mcp/stream`. SSE fallback remains available at `/mcp/sse` for clients that still require it.
58
-
59
- Local CLI runner (no global install): `pnpm cli:up -- --transport sse` (runs TS directly). Built bundle: `pnpm build && node dist/cli/up.js up --transport sse`. Global/NPX: `npx @hol-org/hashnet-mcp up --transport sse`.
60
-
61
- #### Claude Code auto-install
62
- - `pnpm claude:install --endpoint http://localhost:3333/mcp/stream` — adds/updates the MCP entry inside Claude Code’s config (`~/Library/Application Support/Claude/claude_code_config.json` on macOS; `%APPDATA%\Claude\claude_code_config.json` on Windows; `~/.config/Claude/claude_code_config.json` on Linux).
63
- - Pass `--name <id>` to customize the MCP server handle or `--config <path>` if your Claude Code build stores config elsewhere.
64
- - Use `--force` to overwrite an existing entry, `--dry-run` to preview changes, and `--skip-backup` to avoid writing a `.bak` file next to the config.
65
- - After running the script, restart Claude Code so the client discovers the new `hol.*` tool catalog automatically.
66
-
67
- #### Cursor auto-install
68
- - `pnpm cursor:install --endpoint http://localhost:3333/mcp/stream` — writes/updates the `modelContextProtocol.servers` array inside Cursor’s `settings.json` (`~/Library/Application Support/Cursor/User/settings.json` on macOS; `%APPDATA%\Cursor\User\settings.json` on Windows; `~/.config/Cursor/User/settings.json` on Linux).
69
- - Use `--name <id>` to change the MCP handle, `--config <path>` to point at a custom settings file, and `--force` if you need to replace an existing server entry.
70
- - Add `--dry-run` to preview the merged JSON. Once applied, restart Cursor so the MCP list refreshes and exposes the `hol.*` commands.
71
-
72
- ### Workflow Helpers
73
- Run `pnpm workflow:list` to see the live catalog (the script reads `src/workflows/index.ts`, so it never goes stale). Each workflow’s golden-path payload lives under `examples/workflows/`—copy one, replace the placeholder UAIDs/keys, and pass it to `pnpm workflow:run <workflow> --payload <file>`.
74
-
75
- **Discovery & Ops**
76
- - `workflow.discovery` – `hol.search` + `hol.vectorSearch` (`examples/workflows/workflow.discovery.json`)
77
- - `workflow.erc8004Discovery` – ERC-8004 search + namespace lookup (`examples/workflows/workflow.erc8004Discovery.json`)
78
- - `workflow.opsCheck` – Stats/metrics/protocol snapshot (`examples/workflows/workflow.opsCheck.json`)
79
- - `workflow.registryBrokerShowcase` – Discovery + analytics + optional chat (`examples/workflows/workflow.registryBrokerShowcase.json`)
80
-
81
- **Registration Pipelines**
82
- - `workflow.registerMcp` – Quote → register → wait (`examples/workflows/workflow.registerMcp.json`)
83
- - `workflow.registerAgentAdvanced` – Additional registries + optional update + HITL credit top-up (`examples/workflows/workflow.registerAgentAdvanced.json`)
84
- - `workflow.registerAgentErc8004` – ERC-8004 network resolution + optional ledger verification (`examples/workflows/workflow.registerAgentErc8004.json`)
85
- - `workflow.erc8004X402` – ERC-8004 registration funded via X402 with follow-up chat (`examples/workflows/workflow.erc8004X402.json`)
86
- - `workflow.x402Registration` – General-purpose registration paid for by X402 credits (`examples/workflows/workflow.x402Registration.json`)
87
- - `workflow.fullRegistration` – Discovery → registration → chat → ops composite (`examples/workflows/workflow.fullRegistration.json`)
88
-
89
- **Credit & Ledger Utilities**
90
- - `workflow.ledgerAuth` – Create + verify ledger challenges (`examples/workflows/workflow.ledgerAuth.json`)
91
- - `workflow.x402TopUp` – Buy credits via X402 (`examples/workflows/workflow.x402TopUp.json`)
92
- - `workflow.historyTopUp` – Chat + history compaction + automatic HBAR purchases on 402s (`examples/workflows/workflow.historyTopUp.json`)
93
-
94
- **Chat & Interop**
95
- - `workflow.chatSmoke` – Session lifecycle validation (`examples/workflows/workflow.chatSmoke.json`)
96
- - `workflow.openrouterChat` – Discover an OpenRouter UAID and send an authenticated message (`examples/workflows/workflow.openrouterChat.json`)
97
- - `workflow.agentverseBridge` – Relay between a local UAID and Agentverse (`examples/workflows/workflow.agentverseBridge.json`)
98
-
99
- Common CLI patterns:
100
-
101
- ```
102
- pnpm workflow:list
103
- pnpm workflow:run workflow.registerAgentAdvanced --payload examples/workflows/workflow.registerAgentAdvanced.json
104
- pnpm workflow:run workflow.openrouterChat --payload examples/workflows/workflow.openrouterChat.json --endpoint https://host/mcp/stream
105
- pnpm workflow:register
106
- pnpm workflow:register:advanced
107
- pnpm workflow:register:erc8004
108
- ```
109
-
110
- `workflow:run` spawns the local server (if needed) and prints a structured pipeline report. Use `--endpoint https://host/mcp/stream` to target a remote deployment; add `--reuse-server` to skip spawning when pointing at an already-running localhost instance.
111
-
112
- `pnpm workflow:register` flow:
113
- 1. CLI prompts for display name, alias, description, MCP URL, chat message, and report path.
114
- 2. Runs `workflow.registerMcp`, `workflow.chatSmoke`, `workflow.opsCheck` sequentially.
115
- 3. Saves `workflow-register-report.json` (configurable) containing:
116
- - `uaid`
117
- - Pipeline traces (steps, dry-run flag, UAID context)
118
- - Claude config snippet with your MCP URL
119
- - Raw pipeline results (registration/chat/ops)
120
-
121
- **Sample report snippet**
122
-
62
+ ### Claude Desktop (stdio)
123
63
  ```json
124
64
  {
125
- "uaid": "uaid:registry:abcd-1234",
126
- "claudeConfig": {
127
- "mcpServers": {
128
- "hashnet": {
129
- "command": "npx",
130
- "args": ["@hol-org/hashnet-mcp@latest", "up"]
65
+ "mcpServers": {
66
+ "hashnet": {
67
+ "type": "stdio",
68
+ "command": "npx",
69
+ "args": [
70
+ "-y",
71
+ "@hol-org/hashnet-mcp",
72
+ "up"
73
+ ],
74
+ "env": {
75
+ "REGISTRY_BROKER_API_URL": "https://registry.hashgraphonline.com/api/v1",
76
+ "REGISTRY_BROKER_API_KEY": "<your HOL API key>"
131
77
  }
132
78
  }
133
- },
134
- "pipelines": [
135
- {
136
- "name": "workflow.registerMcp",
137
- "steps": [
138
- { "id": "hol.getRegistrationQuote", "durationMs": 812 },
139
- { "id": "hol.registerAgent", "durationMs": 1420 }
140
- ]
141
- }
142
- ]
79
+ }
143
80
  }
144
81
  ```
145
82
 
146
- During `workflow.registerMcp`, the CLI always attempts to spend the API key’s existing credits first. Only if the broker rejects the registration with a 402 does the script fetch the latest quote, show the required/available credits plus the estimated ℏ charge, and ask for HITL approval before calling `purchaseCreditsWithHbar`. It then polls the quote endpoint until the newly purchased credits appear so you never pay without seeing the balance update. Set `BROKER_AUTO_TOP_UP=1` if you need the “fire-and-forget” auto top-up behaviour with no prompts.
147
-
148
- #### Workflow Environment Requirements
149
- - Every workflow requires `REGISTRY_BROKER_API_KEY`. Discovery/ops flows can run with just that variable.
150
- - Registration workflows (`workflow.register*`, `workflow.fullRegistration`) will prompt for purchases when credits are low. Provide `HEDERA_ACCOUNT_ID` + `HEDERA_PRIVATE_KEY` to allow automatic HBAR-based top-ups; otherwise the pipeline aborts on 402.
151
- - X402 flows (`workflow.x402*`, `workflow.erc8004X402`) also need an EVM private key plus any ledger verification payloads referenced in the sample JSON.
152
- - Chat/interop flows (`workflow.chatSmoke`, `workflow.agentverseBridge`, `workflow.openrouterChat`, `workflow.historyTopUp`) require valid UAIDs and, when applicable, bearer tokens for the downstream service.
153
- - `examples/workflows/*.json` files include clearly named placeholders (e.g., `0xYOUR_EVM_PRIVATE_KEY`). Replace them before running `workflow:run`; keeping them as-is will cause schema validation or broker auth failures.
154
-
155
- ### Hol Tool Catalog
156
- These FastMCP tools are available everywhere the server runs (CLI, Claude Desktop, Claude Code, Cursor, or any MCP-compliant client).
157
-
158
- | Tool | Purpose |
159
- | --- | --- |
160
- | `hol.search.help` | Markdown primer that documents filters and usage for search-heavy agents. |
161
- | `hol.search` | Keyword search across the Registry Broker catalog with filtering and sorting controls. |
162
- | `hol.vectorSearch` | Embedding-backed discovery endpoint for semantic matches. |
163
- | `hol.resolveUaid` | Look up metadata and trust status for a UAID or alias. |
164
- | `hol.closeUaidConnection` | Forcibly closes any active UAID tunnel after ops or chat completes. |
165
- | `hol.getRegistrationQuote` | Fetch cost + prerequisites before registering a new agent. |
166
- | `hol.registerAgent` | Submit a signed registration payload to the broker. |
167
- | `hol.waitForRegistrationCompletion` | Poll the broker until a registration attempt succeeds, fails, or times out. |
168
- | `hol.chat.createSession` | Start a chat session scoped to a UAID. |
169
- | `hol.chat.sendMessage` | Send a broker-routed chat message within an existing session. |
170
- | `hol.chat.history` | Retrieve the message transcript for observability or resume flows. |
171
- | `hol.chat.compact` | Truncate chat history while preserving a fixed number of recent entries. |
172
- | `hol.chat.end` | End the active session and release broker-side resources. |
173
- | `hol.listProtocols` | Enumerate known Registry Broker protocols plus transport metadata. |
174
- | `hol.detectProtocol` | Inspect headers/body to auto-detect which broker protocol applies. |
175
- | `hol.stats` | Aggregate registry stats (totals, growth, health). |
176
- | `hol.metricsSummary` | Pull summarized broker metrics for dashboards. |
177
- | `hol.dashboardStats` | Fetch the dashboard-friendly stats bundle used by ops workflows. |
178
- | `hol.credits.balance` | Return API key, Hedera, and (optionally) X402 credit balances from `/credits/balance`. |
179
-
180
- #### Invoking Tools from the CLI
181
- - `pnpm test:tools` — boot the SSE transport on `http://localhost:3333/mcp/stream` and run every `hol.*` tool with sample payloads (set `TEST_UAID`, `TEST_CHAT_UAID`, `TEST_REGISTRATION_ATTEMPT_ID` so UAID/chat steps execute instead of skipping). No need to append `--spawn`; the script already starts/stops the local server.
182
- - `pnpm test:tools:mock` — smoke-test the CLI against the bundled mock MCP server (no registry/Broker access required). Useful for CI to verify the harness exits cleanly with code 0.
183
- - `pnpm test:tools --endpoint https://host/mcp/stream` — hit a remote deployment without spawning a local server; combine with `--port <n>` when using `--spawn` to change the local port.
184
- - Use `TEST_UAID=<uaid> TEST_CHAT_UAID=<uaid> pnpm test:tools --spawn` to pass environment variables inline; the harness reports missing vars and skips dependent tools if they are not provided.
185
- - Set `BROKER_PROTOCOL_TOOLS=1` if your API key has access to the `/protocols` + `/detect-protocol` endpoints; otherwise those scenarios are skipped (the staging broker currently returns 404 for those routes).
186
- - For ad-hoc calls, point `scripts/run-tool-suite.ts` at any MCP endpoint (`tsx scripts/run-tool-suite.ts --endpoint ...`) and edit the scenarios array to focus on a subset of tools or custom payloads.
187
-
188
- ### Workflow Environment Requirements
189
- - `REGISTRY_BROKER_API_URL` / `REGISTRY_BROKER_API_KEY` base URL + key for the Registry Broker API (staging/testnet supported).
190
- - `HEDERA_ACCOUNT_ID` / `HEDERA_PRIVATE_KEY` optional; only required if you want the CLI to purchase credits on your behalf when the API key runs dry.
191
- - `WORKFLOW_DRY_RUN=1` – skip state-changing steps (quote-only, no registration).
192
- - `BROKER_E2E=1` – opt in to real broker calls inside CI/e2e scripts (otherwise the mock broker is used where possible).
193
- - `BROKER_AUTO_TOP_UP=1` – opt in to automatic broker purchases without prompts (defaults to `0`, which enables HITL confirmation).
194
- - Tool-suite fixtures (optional): `TEST_UAID`, `TEST_CHAT_UAID`, `TEST_REGISTRATION_ATTEMPT_ID`, and `BROKER_PROTOCOL_TOOLS`. Populate these in `.env` (see `.env.example`) so `pnpm test:tools` can run UAID/chat flows locally and skip protocol checks unless your API key has access. Leave them blank to let the suite auto-discover UAIDs/attempt IDs from preceding steps.
195
-
196
- Each workflow definition lists its required env vars and the pipeline runner will fail fast (before touching the broker) if any are missing. Restart the MCP server after changing credentials so FastMCP snapshots the updated environment.
197
-
198
- ## NPX Quick Start
199
- ```
200
- npx @hol-org/hashnet-mcp up --transport sse
201
- ```
202
- The CLI verifies Node ≥18, installs dependencies (preferring pnpm), copies `.env.example` if needed, and launches the requested transport. Pass `--install-only` to skip auto-start. See `AGENTS.md` for advanced flags.
203
-
204
- ## Deployment
205
- - `deploy/fly.toml` – Fly.io app manifest exposing `/mcp/stream`.
206
- - `deploy/Dockerfile` – Cloud Run-ready image that builds the project and runs `node dist/index.js`.
207
- - `deploy/README.md` step-by-step instructions for both targets.
208
-
209
- ## Architecture Overview
210
-
211
- ```
212
- [ CLI / Agent ]
213
-
214
-
215
- ┌──────────────────────┐
216
- │ MCP Gateway (Hono) │
217
- /mcp/stream & /mcp/sse│
218
- └─────────┬────────────┘
219
- proxies HTTP stream traffic
220
- ┌─────────▼────────────┐
221
- │ FastMCP / mcp.ts │ ← registers `hol.*` + `workflow.*` tools
222
- │ ├─ broker.ts │ ← wraps RegistryBrokerClient
223
- │ └─ workflows/ │ ← pipeline definitions + registry
224
- └─────────┬────────────┘
225
-
226
-
227
- ┌──────────────────────┐
228
- Workflow Pipelines │
229
- │ (discovery/register/ │
230
- │ chat/ops/full) │
231
- └──────────────────────┘
232
- ```
233
-
234
- - `src/workflows/pipeline.ts` implements the reusable pipeline engine (steps, hooks, dry-run).
235
- - `src/workflows/*.ts` define domain workflows; importing `src/workflows/index.ts` registers them.
236
- - MCP tools (`workflow.*`) simply call the registered pipelines and return structured reports.
237
-
238
- ## Examples
239
- - `examples/agent-registration-request.json` mirrors the stricter schema used by `hol.registerAgent` and `hol.getRegistrationQuote`.
240
-
241
- ## Testing & Automation
242
- - `pnpm test --run --coverage` — runs Vitest in CI mode with V8 coverage, ensuring `src/mcp.ts` and `src/broker.ts` stay above the 90% branch threshold.
243
- - `pnpm test:run` — quick single-pass test run without coverage.
244
- - `pnpm test:tools` — spins up the HTTP-stream gateway (unless one is already running) and exercises every MCP tool end-to-end via the official MCP client (Streamable HTTP transport). Set `TEST_UAID`, `TEST_CHAT_UAID`, and `TEST_REGISTRATION_ATTEMPT_ID` if you want UAID-specific flows to run instead of being skipped.
245
- - `pnpm workflow:list` / `pnpm workflow:run <name>` — inspect and execute the built-in pipelines (use `examples/workflows/*.json` for payloads).
246
- - `pnpm workflow:register` — prompts for metadata, runs the registration/chat/ops pipelines, and writes a JSON report (UAID, Claude config snippet, workflow traces).
247
- - `pnpm workflow:register:advanced` — guided version of the advanced workflow (additional registries + optional credit purchasing prompts).
248
- - `pnpm workflow:register:erc8004` — helper around the ERC-8004 workflow (ledger prompts + X402/X-Ledger guidance).
249
- - `pnpm mock:broker` — boot a lightweight mock Registry Broker for CI/testing without external dependencies.
83
+ ## Commands
84
+ - Dev transports: `pnpm dev:stdio` (stdio), `pnpm dev:sse` (HTTP stream/SSE)
85
+ - Build / prod: `pnpm build` then `pnpm start`
86
+ - NPX runner: `npx @hol-org/hashnet-mcp up --transport sse --port 3333`
87
+ - Local TS runner: `pnpm cli:up -- --transport sse`
88
+ - Guided DX: `pnpm quickstart` (env copy deps smoke launch)
89
+ - Workflows: `pnpm workflow:list`, `pnpm workflow:run <name> --payload examples/workflows/<file>.json`
90
+ - Tests: `pnpm test --run --coverage`
91
+
92
+ ## Tooling at a glance
93
+ Categories are exposed as MCP tools (`hol.*`) plus workflows (`workflow.*`):
94
+ - **Discovery**: `hol.search`, `hol.vectorSearch`, `hol.registrySearchByNamespace`, `hol.resolveUaid`
95
+ - **Registration**: `hol.getRegistrationQuote`, `hol.registerAgent`, `hol.waitForRegistrationCompletion`, `hol.updateAgent`
96
+ - **Chat**: `hol.chat.createSession` (uaid or agentUrl), `hol.chat.sendMessage` (sessionId or uaid/agentUrl; auto-creates session), `hol.chat.history`, `hol.chat.compact`, `hol.chat.end`, `hol.closeUaidConnection`
97
+ - **Protocols/Ops**: `hol.listProtocols`, `hol.detectProtocol`, `hol.stats`, `hol.metricsSummary`, `hol.dashboardStats`, `hol.websocketStats`
98
+ - **Credits**: `hol.credits.balance`, `hol.purchaseCredits.hbar`, `hol.x402.minimums`, `hol.x402.buyCredits`
99
+ - **Ledger**: `hol.ledger.challenge`, `hol.ledger.authenticate`
100
+ - **Workflows** (pipelines): discovery, registration, full registration, chat smoke, ops check, ERC-8004 and X402 helpers, OpenRouter chat, registry showcase, Agentverse bridge. See `examples/workflows/` for payloads.
101
+
102
+ ## Usage patterns
103
+ - **Discovery**: `workflow.discovery { query?, limit? }` or `hol.search` with filters (`capabilities`, `metadata`, `type=ai-agents|mcp-servers`).
104
+ - **Registration**: `workflow.registerMcp { payload }` (quote register wait) or `workflow.fullRegistration` to add discovery/chat/ops.
105
+ - **Chat**: Start with `hol.chat.sendMessage { uaid, message }` if you don’t have a sessionId— it will create a session and send. Otherwise use `hol.chat.createSession` then `hol.chat.sendMessage { sessionId, message }`. Manage with `hol.chat.history/compact/end`.
106
+ - **Ops/Health**: `workflow.opsCheck` or the `hol.stats`/`hol.metricsSummary`/`hol.dashboardStats` trio.
107
+ - **Credits**: Always check `hol.credits.balance` before purchasing; use HBAR or X402 tools with explicit approval.
108
+
109
+ ## Tool catalog (what each does)
110
+ **Discovery**
111
+ - `hol.search` keyword discovery with filters (capabilities, metadata, type).
112
+ - `hol.vectorSearch` semantic similarity search for agents.
113
+ - `hol.registrySearchByNamespace` search within a specific registry.
114
+ - `hol.resolveUaid` resolve + validate + connection status for a UAID.
115
+ - `hol.closeUaidConnection` force-close a UAID connection.
116
+
117
+ **Registration**
118
+ - `hol.getRegistrationQuote` — cost estimate for a registration payload.
119
+ - `hol.registerAgent` — submit HCS-11 registration.
120
+ - `hol.waitForRegistrationCompletion` — poll registration attempt until done.
121
+ - `hol.updateAgent` update an existing registration payload.
122
+ - `hol.additionalRegistries` catalog of additional registries/networks.
123
+
124
+ **Chat**
125
+ - `hol.chat.createSession` open a session by `uaid` or `agentUrl`.
126
+ - `hol.chat.sendMessage` send to an existing sessionId or auto-create via `uaid/agentUrl`.
127
+ - `hol.chat.history` / `hol.chat.compact` / `hol.chat.end` manage chat lifecycle.
128
+
129
+ **Protocols / Ops**
130
+ - `hol.listProtocols`, `hol.detectProtocol` inspect/route inbound payloads.
131
+ - `hol.stats`, `hol.metricsSummary`, `hol.dashboardStats`, `hol.websocketStats` broker health/metrics.
132
+
133
+ **Credits**
134
+ - `hol.credits.balance` — check balances (API key + optional Hedera/X402).
135
+ - `hol.purchaseCredits.hbar` buy credits with HBAR.
136
+ - `hol.x402.minimums`, `hol.x402.buyCredits` — X402 purchase helpers.
137
+
138
+ **Ledger**
139
+ - `hol.ledger.challenge` create ledger verification challenge.
140
+ - `hol.ledger.authenticate` — verify challenge (sets ledger API key).
141
+
142
+ **Workflows (pipelines)**
143
+ - Discovery: `workflow.discovery`, `workflow.erc8004Discovery`
144
+ - Registration: `workflow.registerMcp`, `workflow.fullRegistration`, `workflow.erc8004X402`, `workflow.x402Registration`, `workflow.registerAgentErc8004`
145
+ - Chat/Ops: `workflow.chatSmoke`, `workflow.opsCheck`, `workflow.registryBrokerShowcase`, `workflow.openrouterChat`, `workflow.agentverseBridge`
146
+ - Utilities: see `examples/workflows/` for payloads and `pnpm workflow:list`
147
+
148
+ ## Environment
149
+ Set in `.env` or your process:
150
+ - `REGISTRY_BROKER_API_URL` (default `https://registry.hashgraphonline.com/api/v1`)
151
+ - `REGISTRY_BROKER_API_KEY` (required for live broker)
152
+ - Optional: `HEDERA_ACCOUNT_ID`, `HEDERA_PRIVATE_KEY` (auto top-up), `LOG_LEVEL`, `PORT`, `HTTP_STREAM_PORT`, `BROKER_*` rate limit vars, `WORKFLOW_DRY_RUN`, `BROKER_AUTO_TOP_UP`.
153
+
154
+ ## Testing & quality
155
+ - Run once with coverage: `pnpm test --run --coverage`
156
+ - Tool E2E (real broker): `pnpm test:tools` (set test UAIDs or rely on discovery)
157
+ - Tool E2E (mock): `pnpm test:tools:mock`
158
+
159
+ ## Deploy
160
+ - Builds to `dist/` via `tsup`. Prod entry: `dist/index.js`, CLI bin: `dist/cli/up.js`.
161
+ - Deploy docs for Fly/Cloud Run under `deploy/`. Health probe at `/healthz`.
162
+
163
+ ## Logging & observability
164
+ - `pino` structured logs; set `LOG_LEVEL=fatal|error|warn|info|debug|trace`.
165
+ - Each tool call logs requestId + duration. SSE/HTTP transport logs requests. Credits/registration calls surface broker status/body on failure.
250
166
 
251
- ## Adding New Workflows
252
- 1. Create `src/workflows/<name>.ts` exporting a factory that calls `registerPipeline()` with metadata (description, input schema, required env vars).
253
- 2. Import the module inside `src/workflows/index.ts` so the pipeline registers at startup.
254
- 3. Wire an MCP tool in `src/mcp.ts` (define a `zod` schema, call `runPipeline`, and convert the result with `formatPipelineResult`).
255
- 4. Add Vitest coverage in `tests/workflows/<name>.spec.ts` plus CLI smoke coverage if pipelines should be runnable via `workflow:run`.
256
- 5. Update README/AGENTS describing the workflow, logging fields, and any CLI flags so downstream agents know how to trigger it.
package/dist/index.js CHANGED
@@ -111,14 +111,17 @@ var config = {
111
111
  };
112
112
 
113
113
  // src/broker.ts
114
+ var autoTopUpConfig = config.autoTopUpEnabled ? {
115
+ accountId: config.hederaAccountId,
116
+ privateKey: config.hederaPrivateKey,
117
+ memo: "mcp-autotopup"
118
+ } : void 0;
114
119
  var broker = new RegistryBrokerClient({
115
120
  baseUrl: config.registryBrokerUrl,
116
121
  apiKey: config.registryBrokerApiKey,
117
- registrationAutoTopUp: config.autoTopUpEnabled ? {
118
- accountId: config.hederaAccountId,
119
- privateKey: config.hederaPrivateKey,
120
- memo: "mcp-autotopup"
121
- } : void 0
122
+ fetchImplementation: undiciFetch,
123
+ registrationAutoTopUp: autoTopUpConfig,
124
+ historyAutoTopUp: autoTopUpConfig
122
125
  });
123
126
  var brokerLimiter = createLimiter();
124
127
  function createLimiter() {
@@ -150,7 +153,8 @@ function createLimiter() {
150
153
  }
151
154
  async function withBroker(task, label) {
152
155
  const run = async () => {
153
- if (!config.registryBrokerApiKey) {
156
+ const isLocal = config.registryBrokerUrl.includes("localhost") || config.registryBrokerUrl.includes("127.0.0.1");
157
+ if (!config.registryBrokerApiKey && !isLocal) {
154
158
  throw new Error("REGISTRY_BROKER_API_KEY is required to call the registry broker. Set it in your environment or .env file.");
155
159
  }
156
160
  try {
@@ -580,7 +584,15 @@ var chatDefinition = {
580
584
  allowDuringDryRun: true,
581
585
  run: async ({ context }) => {
582
586
  if (!context.sessionId) throw new Error("Missing chat session");
583
- return withBroker((client) => client.chat.compactHistory({ sessionId: context.sessionId, preserveEntries: 2 }));
587
+ try {
588
+ return await withBroker((client) => client.chat.compactHistory({ sessionId: context.sessionId, preserveEntries: 2 }));
589
+ } catch (error) {
590
+ const message = error instanceof Error ? error.message.toLowerCase() : "";
591
+ if (message.includes("authenticated account required") || message.includes("insufficient credits")) {
592
+ return { skipped: true, reason: "history compaction requires authenticated account" };
593
+ }
594
+ throw error;
595
+ }
584
596
  }
585
597
  },
586
598
  {
@@ -727,6 +739,12 @@ var openRouterChatDefinition = {
727
739
  throw new Error(`Model ${input.modelId} not found in registry ${input.registry ?? "openrouter"}`);
728
740
  }
729
741
  context.uaid = result.hits[0].uaid;
742
+ const endpoints = result.hits[0].endpoints;
743
+ if (Array.isArray(endpoints)) {
744
+ context.agentUrl = endpoints.find((endpoint) => typeof endpoint === "string" && endpoint.length > 0);
745
+ } else if (endpoints && typeof endpoints === "object") {
746
+ context.agentUrl = Object.values(endpoints).find((value) => typeof value === "string" && value.length > 0);
747
+ }
730
748
  return result.hits[0];
731
749
  }
732
750
  },
@@ -736,7 +754,12 @@ var openRouterChatDefinition = {
736
754
  if (!context.uaid) throw new Error("UAID missing from discovery step");
737
755
  const auth = input.authToken ? { type: "bearer", token: input.authToken } : void 0;
738
756
  const response = await withBroker(
739
- (client) => client.chat.createSession({ uaid: context.uaid, historyTtlSeconds: input.historyTtlSeconds ?? 900, auth })
757
+ (client) => client.chat.createSession({
758
+ uaid: context.uaid,
759
+ agentUrl: context.agentUrl,
760
+ historyTtlSeconds: input.historyTtlSeconds ?? 900,
761
+ auth
762
+ })
740
763
  );
741
764
  context.sessionId = response.sessionId;
742
765
  return response;
@@ -748,7 +771,7 @@ var openRouterChatDefinition = {
748
771
  if (!context.sessionId) throw new Error("Missing chat session");
749
772
  const auth = input.authToken ? { type: "bearer", token: input.authToken } : void 0;
750
773
  return withBroker(
751
- (client) => client.chat.sendMessage({ sessionId: context.sessionId, auth, message: input.message })
774
+ (client) => client.chat.sendMessage({ sessionId: context.sessionId, auth, message: input.message, agentUrl: context.agentUrl })
752
775
  );
753
776
  }
754
777
  },
@@ -1577,7 +1600,8 @@ var toolDefinitions = [
1577
1600
  sessionId,
1578
1601
  message: input.message,
1579
1602
  auth: input.auth,
1580
- streaming: input.streaming
1603
+ streaming: input.streaming,
1604
+ agentUrl
1581
1605
  });
1582
1606
  }, "hol.chat.sendMessage")
1583
1607
  },