@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 +141 -231
- package/dist/index.js +34 -10
- package/dist/index.js.map +1 -1
- package/examples/workflows/workflow.openrouterChat.json +1 -1
- package/package.json +26 -25
package/README.md
CHANGED
|
@@ -1,256 +1,166 @@
|
|
|
1
|
-
# Hashnet MCP
|
|
1
|
+
# HOL Hashnet MCP
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
##
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
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
|
-
##
|
|
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
|
-
|
|
19
|
+
cp .env.example .env # add REGISTRY_BROKER_API_KEY + URL
|
|
16
20
|
```
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
37
|
-
|
|
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
|
-
"
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
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
|
|
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
|
-
"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
"
|
|
129
|
-
|
|
130
|
-
"
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
- `
|
|
182
|
-
- `
|
|
183
|
-
- `
|
|
184
|
-
-
|
|
185
|
-
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
- `
|
|
190
|
-
- `
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
- `
|
|
194
|
-
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
- `
|
|
207
|
-
- `
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
},
|