@blurt-blockchain/blurt-mcp-server 0.4.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/CHANGELOG.md +118 -0
- package/LICENSE +682 -0
- package/README.md +117 -0
- package/SECURITY.md +107 -0
- package/dist/app.js +88 -0
- package/dist/buildServer.js +146 -0
- package/dist/contracts/registerBlurtTool.js +53 -0
- package/dist/contracts/toolRegistry.js +384 -0
- package/dist/resources/blurtResource.js +82 -0
- package/dist/server-stdio.js +37 -0
- package/dist/server.js +35 -0
- package/dist/tools/claimRewards.js +48 -0
- package/dist/tools/comment.js +58 -0
- package/dist/tools/compareAccounts.js +50 -0
- package/dist/tools/fetch.js +91 -0
- package/dist/tools/follow.js +39 -0
- package/dist/tools/getAccount.js +80 -0
- package/dist/tools/getAccountHistory.js +109 -0
- package/dist/tools/getAccountNotifications.js +40 -0
- package/dist/tools/getAccountPosts.js +130 -0
- package/dist/tools/getAccountRelationships.js +34 -0
- package/dist/tools/getAccountSubscriptions.js +50 -0
- package/dist/tools/getAccountWitnessVotes.js +46 -0
- package/dist/tools/getBlurtPrice.js +43 -0
- package/dist/tools/getChainStatus.js +94 -0
- package/dist/tools/getCommunity.js +75 -0
- package/dist/tools/getDelegations.js +37 -0
- package/dist/tools/getPendingRewards.js +53 -0
- package/dist/tools/getPost.js +88 -0
- package/dist/tools/getPostReblogs.js +29 -0
- package/dist/tools/getPostVotes.js +78 -0
- package/dist/tools/getPublications.js +109 -0
- package/dist/tools/getReferrals.js +39 -0
- package/dist/tools/getVoteValue.js +67 -0
- package/dist/tools/getWitness.js +46 -0
- package/dist/tools/listCommunities.js +90 -0
- package/dist/tools/listWitnesses.js +48 -0
- package/dist/tools/lookupAccounts.js +30 -0
- package/dist/tools/mute.js +39 -0
- package/dist/tools/post.js +42 -0
- package/dist/tools/readNotifications.js +35 -0
- package/dist/tools/reblog.js +39 -0
- package/dist/tools/search.js +189 -0
- package/dist/tools/subscribeCommunity.js +39 -0
- package/dist/tools/upvote.js +48 -0
- package/dist/utils/blurtUri.js +61 -0
- package/dist/utils/loadEnv.js +21 -0
- package/dist/utils/logger.js +63 -0
- package/dist/utils/price.js +21 -0
- package/dist/utils/rpc.js +126 -0
- package/dist/utils/signer.js +350 -0
- package/docs/adr/0001-neutral-infrastructure.md +50 -0
- package/docs/architecture.md +62 -0
- package/docs/cache-policy.md +42 -0
- package/docs/clients.md +78 -0
- package/docs/deployment.md +102 -0
- package/docs/development.md +51 -0
- package/docs/install-snippets.md +236 -0
- package/docs/load-testing.md +51 -0
- package/docs/operations.md +56 -0
- package/docs/release-provenance.md +63 -0
- package/docs/tools.generated.md +89 -0
- package/docs/tools.md +102 -0
- package/docs/usage.md +157 -0
- package/docs/write-operations.md +223 -0
- package/package.json +77 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Deployment guide
|
|
2
|
+
|
|
3
|
+
This guide covers deployment concerns that belong around the official Blurt MCP server, not inside it.
|
|
4
|
+
The application stays a small neutral MCP component: it exposes `/mcp`, `/healthz`, and `/readyz`; TLS,
|
|
5
|
+
public rate limiting, bot protection, and global abuse controls should normally live in infrastructure.
|
|
6
|
+
|
|
7
|
+
## HTTP surface
|
|
8
|
+
|
|
9
|
+
| Path | Method | Purpose |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `/mcp` | `POST` | Streamable HTTP MCP endpoint. Stateless; no session id. |
|
|
12
|
+
| `/mcp` | `GET`, `DELETE` | Returns `405`; not supported in stateless mode. |
|
|
13
|
+
| `/healthz` | `GET` | Cheap process liveness check. Does not touch upstream RPC. |
|
|
14
|
+
| `/readyz` | `GET` | Cheap readiness check with non-sensitive RPC configuration/readiness counters. |
|
|
15
|
+
|
|
16
|
+
The app has a `256kb` JSON request-body limit. MCP requests are small; large data is returned in
|
|
17
|
+
responses, not posted by clients.
|
|
18
|
+
|
|
19
|
+
## Recommended topology
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
Internet / client
|
|
23
|
+
-> reverse proxy / ingress / CDN
|
|
24
|
+
-> blurt-mcp-server HTTP process
|
|
25
|
+
-> Blurt RPC nodes, Nexus/Bridge API, price feed
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The public hosted endpoint should stay anonymous and read-only. Do not configure `BLURT_POSTING_KEY` on
|
|
29
|
+
a public HTTP deployment. HTTP signing is available only through the deliberately unsafe trusted-deployment
|
|
30
|
+
override documented in [write operations](./write-operations.md#advanced-unsafe-http-signing-for-trusted-deployments).
|
|
31
|
+
|
|
32
|
+
## Caddy example
|
|
33
|
+
|
|
34
|
+
```caddyfile
|
|
35
|
+
mcp.example.org {
|
|
36
|
+
encode zstd gzip
|
|
37
|
+
|
|
38
|
+
@mcp method POST
|
|
39
|
+
@mcp path /mcp
|
|
40
|
+
reverse_proxy @mcp 127.0.0.1:3000
|
|
41
|
+
|
|
42
|
+
@health path /healthz /readyz
|
|
43
|
+
reverse_proxy @health 127.0.0.1:3000
|
|
44
|
+
|
|
45
|
+
# Keep request bodies small; MCP JSON-RPC requests are tiny.
|
|
46
|
+
request_body {
|
|
47
|
+
max_size 256KB
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# Caddy rate limits require a plugin/module. If unavailable, apply rate limits
|
|
51
|
+
# at your CDN, load balancer, firewall, or hosting platform instead.
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## nginx example
|
|
56
|
+
|
|
57
|
+
```nginx
|
|
58
|
+
limit_req_zone $binary_remote_addr zone=blurt_mcp:10m rate=60r/m;
|
|
59
|
+
|
|
60
|
+
server {
|
|
61
|
+
listen 443 ssl http2;
|
|
62
|
+
server_name mcp.example.org;
|
|
63
|
+
|
|
64
|
+
client_max_body_size 256k;
|
|
65
|
+
|
|
66
|
+
location = /mcp {
|
|
67
|
+
limit_req zone=blurt_mcp burst=30 nodelay;
|
|
68
|
+
proxy_pass http://127.0.0.1:3000;
|
|
69
|
+
proxy_http_version 1.1;
|
|
70
|
+
proxy_set_header Host $host;
|
|
71
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
72
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
location = /healthz {
|
|
76
|
+
proxy_pass http://127.0.0.1:3000;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
location = /readyz {
|
|
80
|
+
proxy_pass http://127.0.0.1:3000;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Tune the rate-limit numbers for your own traffic and abuse profile. The example is intentionally coarse;
|
|
86
|
+
production limits should be validated against real usage.
|
|
87
|
+
|
|
88
|
+
## Production environment checklist
|
|
89
|
+
|
|
90
|
+
- `NODE_ENV=production` for JSON logs.
|
|
91
|
+
- `LOG_LEVEL=info` unless actively debugging.
|
|
92
|
+
- Multiple `BLURT_RPC_URLS` so the node checker can avoid unhealthy nodes.
|
|
93
|
+
- Reverse proxy terminates TLS and applies public rate limits.
|
|
94
|
+
- `/healthz` and `/readyz` are routed to monitoring.
|
|
95
|
+
- No posting key on public HTTP deployments.
|
|
96
|
+
- Secrets for stdio/private deployments are kept outside the repository.
|
|
97
|
+
|
|
98
|
+
## What is intentionally deferred
|
|
99
|
+
|
|
100
|
+
The app does not ship a full OpenTelemetry stack, built-in distributed rate limiter, WAF, dashboard,
|
|
101
|
+
alerting setup, or generic response cache. Those belong to deployment infrastructure until concrete
|
|
102
|
+
hosting requirements justify pulling a small part into the server itself.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Development
|
|
2
|
+
|
|
3
|
+
See [CONTRIBUTING.md](../CONTRIBUTING.md) for how to propose changes, and
|
|
4
|
+
[architecture.md](./architecture.md) for the design and project layout.
|
|
5
|
+
|
|
6
|
+
## Testing
|
|
7
|
+
|
|
8
|
+
Tests use the built-in Node test runner (`node:test`) executed through `tsx`.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm test # offline: URI/search routing, RPC resilience, write gating, operational endpoints
|
|
12
|
+
npm run test:live # live (in-memory): every tool against a real Blurt RPC node
|
|
13
|
+
npm run test:http # live (HTTP E2E): every tool over the real Streamable HTTP transport
|
|
14
|
+
npm run smoke:http # optional deployment smoke against MCP_URL or localhost:3000/mcp
|
|
15
|
+
npm run smoke:package # optional npm package/tarball smoke after build
|
|
16
|
+
npm run pack:check # build + npm pack --dry-run
|
|
17
|
+
npm run test:all # everything
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Three layers, by design:
|
|
21
|
+
|
|
22
|
+
- **Offline** (`test/uri`, `test/search`, `test/resilience`, `test/write`, `test/ops`) — deterministic, no
|
|
23
|
+
external network. Includes a resilience test that points the client at an unresponsive local mock to
|
|
24
|
+
assert the RPC transport degrades gracefully (guards against the dblurt transport regression),
|
|
25
|
+
write-gating tests (no write tools without a write context, capability profile resolution, default HTTP
|
|
26
|
+
read-only behavior and the explicit unsafe HTTP override), and operational endpoint tests (`/healthz`,
|
|
27
|
+
`/readyz`, request logging), and package-readiness assertions (scoped name, license, bins, files). Runs in CI on every push.
|
|
28
|
+
- **Live, in-memory** (`test/live`) — connects an in-memory MCP client to the server and calls every
|
|
29
|
+
tool against `BLURT_RPC_URLS`. Validates tool logic and `@beblurt/dblurt` integration.
|
|
30
|
+
- **Live, HTTP E2E** (`test/http`) — boots the real Express app on an ephemeral port and drives it
|
|
31
|
+
through the actual Streamable HTTP transport + shared client. This is the path the in-memory client
|
|
32
|
+
does not exercise, where transport/client bugs surface. Run after dependency or transport changes.
|
|
33
|
+
|
|
34
|
+
## Releasing
|
|
35
|
+
|
|
36
|
+
Versioning follows [Semantic Versioning](https://semver.org) and the changelog is generated from
|
|
37
|
+
[Conventional Commits](https://www.conventionalcommits.org) using
|
|
38
|
+
[`commit-and-tag-version`](https://github.com/absolute-version/commit-and-tag-version).
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm run release:dry # preview the bump + changelog without writing anything
|
|
42
|
+
npm run release # auto-bump from commits, update CHANGELOG.md, create an annotated tag
|
|
43
|
+
npm run release:minor # or force a specific bump
|
|
44
|
+
npm run release:major
|
|
45
|
+
|
|
46
|
+
git push --follow-tags origin main
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`feat:` bumps the minor, `fix:`/`perf:` bump the patch, and a `BREAKING CHANGE:` footer bumps the major.
|
|
50
|
+
The package is prepared for npm as `@blurt-blockchain/blurt-mcp-server`, but publication remains a
|
|
51
|
+
separate maintainer-authorized action. See [release/provenance notes](./release-provenance.md).
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Install snippets
|
|
2
|
+
|
|
3
|
+
Copy-paste examples for the official Blurt MCP package and hosted endpoint.
|
|
4
|
+
|
|
5
|
+
The hosted endpoint is anonymous and read-only:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
https://mcp.blurt-blockchain.com/mcp
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The npm package identity is:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
@blurt-blockchain/blurt-mcp-server
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Hosted remote HTTP
|
|
18
|
+
|
|
19
|
+
Use this when your client supports remote MCP / Streamable HTTP:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
https://mcp.blurt-blockchain.com/mcp
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
No private key is required and no write tools are exposed by the public hosted endpoint.
|
|
26
|
+
|
|
27
|
+
## Local stdio via npm package
|
|
28
|
+
|
|
29
|
+
Use this when your client launches a local MCP server process:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx -y -p @blurt-blockchain/blurt-mcp-server blurt-mcp-stdio
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
If your client expects command/args separately, use:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"command": "npx",
|
|
40
|
+
"args": ["-y", "-p", "@blurt-blockchain/blurt-mcp-server", "blurt-mcp-stdio"]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Local HTTP via npm package
|
|
45
|
+
|
|
46
|
+
Use this when you want to self-host the HTTP endpoint:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
PORT=3000 npx -y -p @blurt-blockchain/blurt-mcp-server blurt-mcp-server
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Then point remote-capable clients at:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
http://localhost:3000/mcp
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
For production HTTP deployments, see [deployment.md](./deployment.md).
|
|
59
|
+
|
|
60
|
+
## Bridge stdio-only clients to hosted HTTP
|
|
61
|
+
|
|
62
|
+
If a desktop client only supports stdio but you want the hosted read-only endpoint, bridge with
|
|
63
|
+
`mcp-remote`:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"command": "npx",
|
|
68
|
+
"args": ["-y", "mcp-remote", "https://mcp.blurt-blockchain.com/mcp"]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Tier-1 client snippets
|
|
73
|
+
|
|
74
|
+
### Claude Desktop
|
|
75
|
+
|
|
76
|
+
Hosted endpoint through `mcp-remote`:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"blurt": {
|
|
82
|
+
"command": "npx",
|
|
83
|
+
"args": ["-y", "mcp-remote", "https://mcp.blurt-blockchain.com/mcp"]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Fully local stdio package:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
"blurt": {
|
|
95
|
+
"command": "npx",
|
|
96
|
+
"args": ["-y", "-p", "@blurt-blockchain/blurt-mcp-server", "blurt-mcp-stdio"]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Claude Code
|
|
103
|
+
|
|
104
|
+
Remote HTTP:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
claude mcp add --transport http blurt https://mcp.blurt-blockchain.com/mcp
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Local stdio:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
claude mcp add blurt -- npx -y -p @blurt-blockchain/blurt-mcp-server blurt-mcp-stdio
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### OpenAI Codex
|
|
117
|
+
|
|
118
|
+
Remote HTTP in `~/.codex/config.toml`:
|
|
119
|
+
|
|
120
|
+
```toml
|
|
121
|
+
[mcp_servers.blurt]
|
|
122
|
+
url = "https://mcp.blurt-blockchain.com/mcp"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Local stdio:
|
|
126
|
+
|
|
127
|
+
```toml
|
|
128
|
+
[mcp_servers.blurt]
|
|
129
|
+
command = "npx"
|
|
130
|
+
args = ["-y", "-p", "@blurt-blockchain/blurt-mcp-server", "blurt-mcp-stdio"]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### VS Code / GitHub Copilot agent
|
|
134
|
+
|
|
135
|
+
`.vscode/mcp.json` using hosted HTTP:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"servers": {
|
|
140
|
+
"blurt": {
|
|
141
|
+
"type": "http",
|
|
142
|
+
"url": "https://mcp.blurt-blockchain.com/mcp"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Local stdio:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"servers": {
|
|
153
|
+
"blurt": {
|
|
154
|
+
"type": "stdio",
|
|
155
|
+
"command": "npx",
|
|
156
|
+
"args": ["-y", "-p", "@blurt-blockchain/blurt-mcp-server", "blurt-mcp-stdio"]
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Cursor
|
|
163
|
+
|
|
164
|
+
`.cursor/mcp.json` using hosted HTTP:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"mcpServers": {
|
|
169
|
+
"blurt": {
|
|
170
|
+
"url": "https://mcp.blurt-blockchain.com/mcp"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Local stdio:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"mcpServers": {
|
|
181
|
+
"blurt": {
|
|
182
|
+
"command": "npx",
|
|
183
|
+
"args": ["-y", "-p", "@blurt-blockchain/blurt-mcp-server", "blurt-mcp-stdio"]
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Gemini CLI
|
|
190
|
+
|
|
191
|
+
Hosted HTTP:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
gemini mcp add blurt https://mcp.blurt-blockchain.com/mcp
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Local stdio:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
gemini mcp add blurt -- npx -y -p @blurt-blockchain/blurt-mcp-server blurt-mcp-stdio
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Hermes Agent
|
|
204
|
+
|
|
205
|
+
`~/.hermes/config.yaml` example for hosted HTTP:
|
|
206
|
+
|
|
207
|
+
```yaml
|
|
208
|
+
mcp_servers:
|
|
209
|
+
blurt:
|
|
210
|
+
url: https://mcp.blurt-blockchain.com/mcp
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Local stdio:
|
|
214
|
+
|
|
215
|
+
```yaml
|
|
216
|
+
mcp_servers:
|
|
217
|
+
blurt:
|
|
218
|
+
command: npx
|
|
219
|
+
args: ["-y", "-p", "@blurt-blockchain/blurt-mcp-server", "blurt-mcp-stdio"]
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Open WebUI / LibreChat
|
|
223
|
+
|
|
224
|
+
Use the hosted Streamable HTTP endpoint where the admin UI/config accepts remote MCP servers:
|
|
225
|
+
|
|
226
|
+
```text
|
|
227
|
+
https://mcp.blurt-blockchain.com/mcp
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
For LibreChat-style YAML configurations, the exact schema depends on the deployed version; prefer the
|
|
231
|
+
client's current MCP documentation and use the hosted URL above or a self-hosted `/mcp` URL.
|
|
232
|
+
|
|
233
|
+
## Write tools
|
|
234
|
+
|
|
235
|
+
Write tools are not exposed by the public hosted endpoint. For local signing, configure the stdio package
|
|
236
|
+
entrypoint and follow [write operations](./write-operations.md). Use a posting key only.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# HTTP smoke and lightweight load checks
|
|
2
|
+
|
|
3
|
+
The repository includes a small HTTP smoke script for deployment validation. It is intentionally light:
|
|
4
|
+
it checks MCP connectivity and repeated `tools/list` calls without turning normal CI into a public-load
|
|
5
|
+
test against upstream Blurt services.
|
|
6
|
+
|
|
7
|
+
## Run against a local server
|
|
8
|
+
|
|
9
|
+
Start the server:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm run build
|
|
13
|
+
npm start
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
In another shell:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm run smoke:http
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
By default this targets `http://localhost:3000/mcp` and runs five `tools/list` iterations.
|
|
23
|
+
|
|
24
|
+
## Run against a hosted endpoint
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
MCP_URL=https://mcp.example.org/mcp MCP_SMOKE_ITERATIONS=10 npm run smoke:http
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Include one representative read
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
MCP_URL=https://mcp.example.org/mcp MCP_SMOKE_READ=1 npm run smoke:http
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This calls `get-chain-status` once after the `tools/list` loop. Use it sparingly on public endpoints;
|
|
37
|
+
it may touch upstream RPC/price dependencies.
|
|
38
|
+
|
|
39
|
+
## Output
|
|
40
|
+
|
|
41
|
+
The script emits JSON lines, for example:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{"event":"tools_list","iteration":1,"tool_count":25,"duration_ms":42}
|
|
45
|
+
{"event":"done","url":"http://localhost:3000/mcp","iterations":5,"include_read":false,"total_duration_ms":260}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## What this is not
|
|
49
|
+
|
|
50
|
+
This is not a full benchmark, distributed load test, or SLO proof. Heavy load testing should be run from
|
|
51
|
+
a controlled staging environment with permission and with upstream RPC impact in mind.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Public endpoint operations notes
|
|
2
|
+
|
|
3
|
+
These notes describe how to operate a public read-only Blurt MCP endpoint. They are not a hard SLO or an
|
|
4
|
+
on-call contract; those should be finalized only when hosting ownership, alerting, and maintenance
|
|
5
|
+
responsibilities are explicit.
|
|
6
|
+
|
|
7
|
+
## Service posture
|
|
8
|
+
|
|
9
|
+
The public endpoint is a best-effort, anonymous, read-only MCP service for public Blurt data. It should
|
|
10
|
+
not hold private keys and should not expose write tools. Write/signing deployments are private operator
|
|
11
|
+
responsibility.
|
|
12
|
+
|
|
13
|
+
## Dependencies
|
|
14
|
+
|
|
15
|
+
| Dependency | Used for | Degradation behavior |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| Blurt Layer 1 RPC nodes | accounts, balances, history, witnesses, votes, broadcasts in private write mode | Read tools depending on L1 may fail or become slow. Node checker keeps the client on healthy configured nodes when possible. |
|
|
18
|
+
| Nexus / Bridge API | ranked posts, account posts, communities, discussions and social L2 views | Nexus-backed tools may fail while L1 tools continue. |
|
|
19
|
+
| Price feed (`BLURT_PRICE_URL`) | BLURT/USD and BTC values | Price fields are best-effort; on-chain fields should still be returned where possible. |
|
|
20
|
+
| Reverse proxy / ingress | TLS, public rate limiting, body-size enforcement, host/origin filtering | Misconfiguration can expose the app directly or amplify abuse. |
|
|
21
|
+
|
|
22
|
+
## Health checks
|
|
23
|
+
|
|
24
|
+
- `/healthz`: process liveness. Use for container/process checks.
|
|
25
|
+
- `/readyz`: cheap readiness. Use for load balancers and monitoring. It reports non-sensitive RPC
|
|
26
|
+
counters and does not perform a heavy live RPC call on every request.
|
|
27
|
+
|
|
28
|
+
## Logging
|
|
29
|
+
|
|
30
|
+
In production (`NODE_ENV=production`) logs are JSON lines on `stderr`. The HTTP app logs method, path,
|
|
31
|
+
status and duration for requests, without request bodies or secrets. Collect logs at the process manager,
|
|
32
|
+
container runtime, or platform layer.
|
|
33
|
+
|
|
34
|
+
## Incident examples
|
|
35
|
+
|
|
36
|
+
| Symptom | Likely area | First checks |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| `/healthz` fails | process/container | process manager, container status, recent deploy logs |
|
|
39
|
+
| `/healthz` passes but `/readyz` fails | app readiness/config | env vars, configured RPC URL count, startup logs |
|
|
40
|
+
| MCP read tools slow/failing | upstream RPC or Nexus | node checker logs, configured RPC nodes, Nexus status |
|
|
41
|
+
| Price fields null | price feed | `BLURT_PRICE_URL`, external feed availability |
|
|
42
|
+
| High 4xx/429 at proxy | client misuse/abuse | reverse-proxy logs and rate-limit settings |
|
|
43
|
+
| High 5xx from app | app/runtime/upstream errors | app logs, recent commits, dependency status |
|
|
44
|
+
|
|
45
|
+
## Rollback and maintenance
|
|
46
|
+
|
|
47
|
+
- Keep deployments reproducible from a Git commit and package lockfile.
|
|
48
|
+
- Prefer blue/green or rolling deployment where the platform supports it.
|
|
49
|
+
- Validate `/healthz`, `/readyz`, and `npm run smoke:http` after deployment.
|
|
50
|
+
- Roll back to the previous known-good commit if the MCP transport or core read tools regress.
|
|
51
|
+
|
|
52
|
+
## SLO candidate, not a guarantee
|
|
53
|
+
|
|
54
|
+
A future official production service may define uptime and latency SLOs. Until monitoring, alerting,
|
|
55
|
+
incident ownership, and hosting budget are formalized, treat this document as operational guidance rather
|
|
56
|
+
than a public availability guarantee.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Release and provenance notes
|
|
2
|
+
|
|
3
|
+
This project can be prepared for npm publication from the repository, but publication remains a separate
|
|
4
|
+
maintainer-authorized action. Do not publish, tag, or bump versions as part of ordinary feature work unless
|
|
5
|
+
the maintainer explicitly requests a release.
|
|
6
|
+
|
|
7
|
+
## Package identity
|
|
8
|
+
|
|
9
|
+
Official npm package name:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
@blurt-blockchain/blurt-mcp-server
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Runtime bins after installation:
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
blurt-mcp-server
|
|
19
|
+
blurt-mcp-stdio
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Pre-publish checks
|
|
23
|
+
|
|
24
|
+
Run the normal validation suite first:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm run check:secrets
|
|
28
|
+
npm run docs:check
|
|
29
|
+
npm run typecheck
|
|
30
|
+
npm test
|
|
31
|
+
npm run build
|
|
32
|
+
npm run test:http
|
|
33
|
+
npm run test:live
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Then verify package contents and bin metadata:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm run pack:check
|
|
40
|
+
npm run smoke:package
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`pack:check` is dry-run only. `smoke:package` creates a temporary tarball, verifies expected runtime/docs
|
|
44
|
+
files and bin shebangs, then removes the tarball.
|
|
45
|
+
|
|
46
|
+
## Publication
|
|
47
|
+
|
|
48
|
+
Publication is intentionally not automated in package scripts. When a maintainer approves a release, decide
|
|
49
|
+
first:
|
|
50
|
+
|
|
51
|
+
- version bump and changelog impact;
|
|
52
|
+
- Git tag timing;
|
|
53
|
+
- npm account / organization access;
|
|
54
|
+
- OTP requirements;
|
|
55
|
+
- whether npm provenance is supported by the chosen CI path.
|
|
56
|
+
|
|
57
|
+
Then publish from a clean, validated commit using the selected release process.
|
|
58
|
+
|
|
59
|
+
## Provenance / signing
|
|
60
|
+
|
|
61
|
+
npm provenance or signing should be enabled only when the real release pipeline supports it end-to-end.
|
|
62
|
+
The repository currently prepares package metadata and pack validation, but does not pretend to produce a
|
|
63
|
+
provenance attestation. This avoids false security claims.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<!-- Generated from src/contracts/toolRegistry.ts. Do not edit by hand. Run npm run docs:tools. -->
|
|
2
|
+
|
|
3
|
+
# Generated tool contract reference
|
|
4
|
+
|
|
5
|
+
This file is generated from the Blurt MCP tool registry. It is the contract index for v1-candidate tool metadata: tool name, safety class, data source, cache hint, stability and short description.
|
|
6
|
+
|
|
7
|
+
Every tool result follows the standard structured-content envelope:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
{
|
|
11
|
+
data: unknown,
|
|
12
|
+
meta: {
|
|
13
|
+
contract: "blurt-mcp.tool-result.v1",
|
|
14
|
+
tool: string,
|
|
15
|
+
sources: Array<"layer1" | "nexus" | "external" | "mixed" | "mcp">,
|
|
16
|
+
retrieved_at: string,
|
|
17
|
+
freshness: { cache: "none" | "short" | "medium" | "external", ttl_seconds: number | null },
|
|
18
|
+
confidence: "high" | "medium" | "low",
|
|
19
|
+
caveats: string[]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Tool-specific `data` schemas remain intentionally broad during the P1 foundation step and will be tightened as the v1 contract matures.
|
|
25
|
+
|
|
26
|
+
| Tool | Title | Safety | Source | Cache | Stability | Description |
|
|
27
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
28
|
+
| `blurt-claim-rewards` | Claim rewards locally | write-local | layer1 | none | v1-candidate | Claim pending rewards using the configured local posting key. |
|
|
29
|
+
| `blurt-comment` | Comment locally | write-local | layer1 | none | v1-candidate | Broadcast a local posting-key comment/reply operation. |
|
|
30
|
+
| `blurt-follow` | Follow locally | write-local | layer1 | none | v1-candidate | Broadcast a local posting-key follow/unfollow custom_json. |
|
|
31
|
+
| `blurt-mute` | Mute locally | write-local | layer1 | none | v1-candidate | Broadcast a local posting-key mute/unmute custom_json. |
|
|
32
|
+
| `blurt-post` | Post locally | write-local | layer1 | none | v1-candidate | Broadcast a local posting-key top-level post operation. |
|
|
33
|
+
| `blurt-read-notifications` | Mark notifications read locally | write-local | layer1 | none | v1-candidate | Broadcast a local posting-key notification read marker. |
|
|
34
|
+
| `blurt-reblog` | Reblog locally | write-local | layer1 | none | v1-candidate | Broadcast a local posting-key reblog/undo custom_json. |
|
|
35
|
+
| `blurt-subscribe-community` | Subscribe to community locally | write-local | layer1 | none | v1-candidate | Broadcast a local posting-key community subscription custom_json. |
|
|
36
|
+
| `blurt-upvote` | Upvote locally | write-local | layer1 | none | v1-candidate | Broadcast a local posting-key vote operation. |
|
|
37
|
+
| `compare-accounts` | Compare accounts | read | mixed | short | v1-candidate | Side-by-side account metrics for stake, reach, output and rewards. |
|
|
38
|
+
| `fetch` | Fetch Blurt resource | read | mixed | short | v1-candidate | Resolve a blurt:// URI or shorthand id to raw JSON. |
|
|
39
|
+
| `get-account` | Get account profile and wallet summary | read | mixed | short | v1-candidate | Structured account identity, wallet, stake, witness vote count and rewards summary. |
|
|
40
|
+
| `get-account-history` | Get raw account operation history | read | layer1 | none | v1-candidate | Recent Layer 1 operations for an account, optionally filtered by operation type. |
|
|
41
|
+
| `get-account-notifications` | Get notifications | read | nexus | short | v1-candidate | Nexus notifications and unread count for an account. |
|
|
42
|
+
| `get-account-posts` | Get account-related posts | read | nexus | short | v1-candidate | Nexus account posts, blog, comments, replies, feed or payout items. |
|
|
43
|
+
| `get-account-relationships` | Get social relationship counts | read | layer1 | short | v1-candidate | Follower/following counts and samples for an account. |
|
|
44
|
+
| `get-account-subscriptions` | Get community subscriptions | read | nexus | medium | v1-candidate | Communities an account is subscribed to and its role in them. |
|
|
45
|
+
| `get-account-witness-votes` | Get account witness votes | read | layer1 | short | v1-candidate | Witnesses supported by an account and any witness proxy. |
|
|
46
|
+
| `get-blurt-price` | Get BLURT market price | read | external | external | v1-candidate | Current BLURT USD/BTC price from the configured public price feed. |
|
|
47
|
+
| `get-chain-status` | Get chain and market status | read | mixed | short | v1-candidate | Network, supply, reward and market dashboard for Blurt. |
|
|
48
|
+
| `get-community` | Get community details | read | nexus | medium | v1-candidate | Nexus details for a single Blurt community. |
|
|
49
|
+
| `get-delegations` | Get outgoing delegations | read | layer1 | short | v1-candidate | Outgoing Blurt Power delegations for an account. |
|
|
50
|
+
| `get-pending-rewards` | Get unclaimed rewards | read | mixed | short | v1-candidate | Pending reward balances currently claimable by an account. |
|
|
51
|
+
| `get-post` | Get post or discussion | read | nexus | short | v1-candidate | Nexus post summary or full discussion tree for an author/permlink. |
|
|
52
|
+
| `get-post-reblogs` | Get post reblogs | read | layer1 | short | v1-candidate | Accounts that reblogged a post. |
|
|
53
|
+
| `get-post-votes` | Get post votes | read | layer1 | short | v1-candidate | Layer 1 active votes on a post/comment ranked by rshares. |
|
|
54
|
+
| `get-publications` | Get ranked publications | read | nexus | short | v1-candidate | Nexus ranked posts for discovery by sort/tag. |
|
|
55
|
+
| `get-referrals` | Get referred accounts | read | nexus | medium | v1-candidate | beBlurt referral accounts and total count for a referrer. |
|
|
56
|
+
| `get-vote-value` | Estimate account vote value | read | mixed | short | v1-candidate | Estimated current upvote value for an account at a given weight. |
|
|
57
|
+
| `get-witness` | Get witness health | read | layer1 | short | v1-candidate | Layer 1 witness details and health summary for one account. |
|
|
58
|
+
| `list-communities` | List communities | read | nexus | medium | v1-candidate | Nexus community discovery by rank, newness or subscribers. |
|
|
59
|
+
| `list-witnesses` | List witnesses | read | layer1 | short | v1-candidate | Layer 1 witness ranking and production metadata. |
|
|
60
|
+
| `lookup-accounts` | Lookup account names | read | layer1 | medium | v1-candidate | Alphabetical account-name autocomplete by prefix. |
|
|
61
|
+
| `search` | Search Blurt resources | read | mcp | none | v1-candidate | Map a free-form query to blurt:// resource links. |
|
|
62
|
+
|
|
63
|
+
## Read-tool example prompts
|
|
64
|
+
|
|
65
|
+
- `compare-accounts`: Compare @nalexadre, @megadrive and @beblurt.
|
|
66
|
+
- `fetch`: Fetch blurt://account/nalexadre.
|
|
67
|
+
- `get-account`: Show me @nalexadre's Blurt account and wallet.
|
|
68
|
+
- `get-account-history`: Show the latest 10 transfer operations for @beblurt.
|
|
69
|
+
- `get-account-notifications`: Do I have recent Blurt notifications?
|
|
70
|
+
- `get-account-posts`: Show @nalexadre's latest posts.
|
|
71
|
+
- `get-account-relationships`: Who follows @nalexadre?
|
|
72
|
+
- `get-account-subscriptions`: Which communities does @nalexadre belong to?
|
|
73
|
+
- `get-account-witness-votes`: Which witnesses does @nalexadre vote for?
|
|
74
|
+
- `get-blurt-price`: What is the current BLURT price?
|
|
75
|
+
- `get-chain-status`: Give me a Blurt network health snapshot.
|
|
76
|
+
- `get-community`: Show details for community blurt-101010.
|
|
77
|
+
- `get-delegations`: Who does @beblurt delegate to?
|
|
78
|
+
- `get-pending-rewards`: How much can @nalexadre claim right now?
|
|
79
|
+
- `get-post`: Open nalexadre/how-ai-can-help-curation-on-blurt-1759501073717.
|
|
80
|
+
- `get-post-reblogs`: Who reblogged this post?
|
|
81
|
+
- `get-post-votes`: Who were the biggest voters on this post?
|
|
82
|
+
- `get-publications`: What is trending under #blurt?
|
|
83
|
+
- `get-referrals`: How many accounts did @beblurt refer?
|
|
84
|
+
- `get-vote-value`: How much is a 100% vote from @nalexadre worth?
|
|
85
|
+
- `get-witness`: Is @nalexadre's witness healthy?
|
|
86
|
+
- `list-communities`: What are the most popular Blurt communities?
|
|
87
|
+
- `list-witnesses`: List the top 10 Blurt witnesses.
|
|
88
|
+
- `lookup-accounts`: Find accounts starting with nale.
|
|
89
|
+
- `search`: Search for @nalexadre or posts:blurt.
|