auxilo-mcp 0.2.0 → 0.7.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.
Files changed (3) hide show
  1. package/README.md +40 -5
  2. package/mcp-server.js +254 -1
  3. package/package.json +7 -2
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Agent capability discovery and knowledge marketplace. Find the right tool for any task. Learn from what other agents already figured out.
4
4
 
5
- **Live API**: `https://3000-725fa3fea775ba39db5a2e3703fa4557.life.conway.tech`
5
+ **Live API**: `https://api.auxilo.io`
6
6
 
7
7
  ## What it does
8
8
 
@@ -18,13 +18,13 @@ Auxilo solves two problems for AI agents:
18
18
 
19
19
  ```bash
20
20
  # Free — check what's available
21
- curl https://3000-725fa3fea775ba39db5a2e3703fa4557.life.conway.tech/categories
21
+ curl https://api.auxilo.io/categories
22
22
 
23
23
  # Free — marketplace stats
24
- curl https://3000-725fa3fea775ba39db5a2e3703fa4557.life.conway.tech/knowledge/stats
24
+ curl https://api.auxilo.io/knowledge/stats
25
25
 
26
26
  # Free — submit a learning
27
- curl -X POST https://3000-725fa3fea775ba39db5a2e3703fa4557.life.conway.tech/learn \
27
+ curl -X POST https://api.auxilo.io/learn \
28
28
  -H "Content-Type: application/json" \
29
29
  -d '{
30
30
  "title": "E2B sessions timeout after 5 min idle",
@@ -60,7 +60,9 @@ Add to your Claude Desktop config (`claude_desktop_config.json`):
60
60
 
61
61
  Then ask Claude: *"Search Auxilo for an email API"* or *"Find knowledge about Firecrawl rate limits"*
62
62
 
63
- **MCP Tools:**
63
+ **MCP Tools (v0.7.0):**
64
+
65
+ *Auxilo Core*
64
66
  - `auxilo_discover` — Search the skills registry
65
67
  - `auxilo_skill` — Get full details for a specific skill
66
68
  - `auxilo_categories` — List all categories
@@ -70,6 +72,23 @@ Then ask Claude: *"Search Auxilo for an email API"* or *"Find knowledge about Fi
70
72
  - `auxilo_unlock` — Read full learning content
71
73
  - `auxilo_rate` — Rate a learning after using it
72
74
  - `auxilo_contributor` — Check contributor earnings
75
+ - `auxilo_verify_wallet` — Wallet ownership verification flow
76
+ - `auxilo_withdraw` — Request withdrawal of earned USDC
77
+ - `auxilo_settlements` — Check settlement history for a wallet
78
+ - `auxilo_link_wallet` — Link a verified wallet to your account
79
+ - `auxilo_account_earnings` — View earnings for your authenticated account
80
+
81
+ *Renderly (v0.7.0 — new)*
82
+ - `renderly_markdown` — Convert any public URL to clean markdown ($0.001)
83
+ - `renderly_extract` — Extract structured data from any URL ($0.001)
84
+ - `renderly_readable` — Get plain readable text from any URL ($0.0005)
85
+ - `renderly_llms_txt` — Get the LLM-readable Renderly service description (free)
86
+ - `renderly_health` — Check Renderly service health (free)
87
+ - `renderly_pricing` — Get Renderly pricing info (free)
88
+
89
+ *Stats (v0.7.0 — new)*
90
+ - `get_stats` — Registry statistics (alias, free)
91
+ - `get_knowledge_stats` — Knowledge marketplace statistics (free)
73
92
 
74
93
  ## Skill categories
75
94
 
@@ -134,6 +153,22 @@ GET /.well-known/agent.json
134
153
  | GET | `/knowledge/:id` | Dynamic (min $0.005) | Unlock full learning (price set by contributor) |
135
154
  | POST | `/knowledge/:id/rate` | Free | Rate a learning |
136
155
  | GET | `/contributor/:wallet` | Free | Contributor earnings |
156
+ | POST | `/auth/magic-link` | Free | Request magic link login |
157
+ | GET | `/auth/verify` | Free | Verify magic link token, returns JWT |
158
+ | GET | `/account/dashboard` | Free | Account overview (requires JWT) |
159
+ | POST | `/account/api-keys` | Free | Create API key (requires JWT) |
160
+ | GET | `/account/earnings` | Free | Earnings with pending balance (requires JWT) |
161
+ | POST | `/admin/stage-key` | Free | Stage new wallet key for rotation (admin) |
162
+
163
+ ## Production infrastructure
164
+
165
+ The live API runs on Conway Cloud with PM2 process management:
166
+
167
+ - **Health monitoring** — `/health` returns uptime, catalog size, and timestamp
168
+ - **Graceful shutdown** — In-flight requests complete before exit; new requests get 503
169
+ - **Auto-restart** — PM2 restarts the process on crash with exponential backoff
170
+ - **Rate limiting** — Persistent across restarts (state saved to disk)
171
+ - **Key rotation** — Zero-downtime wallet key staging via `/admin/stage-key`
137
172
 
138
173
  ## Running locally
139
174
 
package/mcp-server.js CHANGED
@@ -10,7 +10,7 @@ const {
10
10
  const AUXILO_BASE = 'https://3000-725fa3fea775ba39db5a2e3703fa4557.life.conway.tech';
11
11
 
12
12
  const server = new Server(
13
- { name: 'auxilo', version: '0.2.0' },
13
+ { name: 'auxilo', version: '0.7.0' },
14
14
  { capabilities: { tools: {} } }
15
15
  );
16
16
 
@@ -126,6 +126,42 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
126
126
  required: ['id', 'helpfulness'],
127
127
  },
128
128
  },
129
+ {
130
+ name: 'auxilo_verify_wallet',
131
+ description: 'Wallet ownership verification flow. If signature is omitted, returns a challenge string. Sign the challenge with your wallet and call again with signature to complete verification.',
132
+ inputSchema: {
133
+ type: 'object',
134
+ properties: {
135
+ wallet: { type: 'string', description: 'Wallet address (0x...)' },
136
+ signature: { type: 'string', description: 'Optional: cryptographic signature of the challenge' }
137
+ },
138
+ required: ['wallet']
139
+ }
140
+ },
141
+ {
142
+ name: 'auxilo_withdraw',
143
+ description: 'Request withdrawal of earned USDC. Requires a valid cryptographic signature of: "auxilo-withdraw-{wallet}-{amount}-{timestamp}".',
144
+ inputSchema: {
145
+ type: 'object',
146
+ properties: {
147
+ wallet: { type: 'string', description: 'Verified contributor wallet address (0x...)' },
148
+ signature: { type: 'string', description: 'Signature of the withdrawal payload' },
149
+ timestamp: { type: 'number', description: 'Unix timestamp in milliseconds (must be within 5 mins of server time)' }
150
+ },
151
+ required: ['wallet', 'signature', 'timestamp']
152
+ }
153
+ },
154
+ {
155
+ name: 'auxilo_settlements',
156
+ description: 'Check settlement history and processing status for withdrawals on a given wallet. Free.',
157
+ inputSchema: {
158
+ type: 'object',
159
+ properties: {
160
+ wallet: { type: 'string', description: 'Contributor wallet address (0x...)' },
161
+ },
162
+ required: ['wallet']
163
+ }
164
+ },
129
165
  {
130
166
  name: 'auxilo_contributor',
131
167
  description: 'Check earnings for a contributor wallet. Shows total earned, per-learning breakdown. Free.',
@@ -137,6 +173,90 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
137
173
  required: ['wallet'],
138
174
  },
139
175
  },
176
+ {
177
+ name: 'auxilo_link_wallet',
178
+ description: 'Link a verified wallet address to your Auxilo account. Requires session JWT (from magic link login) and the wallet must have been previously verified via auxilo_verify_wallet. One wallet per account. Required to withdraw earnings.',
179
+ inputSchema: {
180
+ type: 'object',
181
+ properties: {
182
+ wallet: { type: 'string', description: 'Verified wallet address (0x...) to link to your account' },
183
+ session_token: { type: 'string', description: 'JWT session token from /auth/verify (Bearer token)' },
184
+ },
185
+ required: ['wallet', 'session_token'],
186
+ },
187
+ },
188
+ {
189
+ name: 'auxilo_account_earnings',
190
+ description: 'View earnings for your authenticated Auxilo account. Requires session JWT. Returns total gross, contributor share, pending balance, total withdrawn, and whether withdrawal is available (can_withdraw). Free.',
191
+ inputSchema: {
192
+ type: 'object',
193
+ properties: {
194
+ session_token: { type: 'string', description: 'JWT session token from /auth/verify (Bearer token)' },
195
+ },
196
+ required: ['session_token'],
197
+ },
198
+ },
199
+ {
200
+ name: 'renderly_markdown',
201
+ description: 'Convert any public URL to clean markdown. Strips navigation, ads, and boilerplate — returns only the meaningful content. Costs $0.001 USDC via x402 or API key.',
202
+ inputSchema: {
203
+ type: 'object',
204
+ properties: {
205
+ url: { type: 'string', description: 'Public URL to convert to markdown' },
206
+ x_payment: { type: 'string', description: 'x402 payment header' },
207
+ },
208
+ required: ['url'],
209
+ },
210
+ },
211
+ {
212
+ name: 'renderly_extract',
213
+ description: 'Extract structured data from any public URL — title, description, headings, links, images, and meta tags. Costs $0.001 USDC via x402 or API key.',
214
+ inputSchema: {
215
+ type: 'object',
216
+ properties: {
217
+ url: { type: 'string', description: 'Public URL to extract structured data from' },
218
+ x_payment: { type: 'string', description: 'x402 payment header' },
219
+ },
220
+ required: ['url'],
221
+ },
222
+ },
223
+ {
224
+ name: 'renderly_readable',
225
+ description: 'Get plain readable text from any public URL — no markdown formatting, no HTML, just the content. Costs $0.0005 USDC via x402 or API key.',
226
+ inputSchema: {
227
+ type: 'object',
228
+ properties: {
229
+ url: { type: 'string', description: 'Public URL to extract readable text from' },
230
+ x_payment: { type: 'string', description: 'x402 payment header' },
231
+ },
232
+ required: ['url'],
233
+ },
234
+ },
235
+ {
236
+ name: 'renderly_llms_txt',
237
+ description: 'Get the LLM-readable service description for Renderly — what it does, endpoints, and usage. Free.',
238
+ inputSchema: { type: 'object', properties: {} },
239
+ },
240
+ {
241
+ name: 'renderly_health',
242
+ description: 'Check Renderly service health status. Free.',
243
+ inputSchema: { type: 'object', properties: {} },
244
+ },
245
+ {
246
+ name: 'renderly_pricing',
247
+ description: 'Get Renderly pricing information for all endpoints. Free.',
248
+ inputSchema: { type: 'object', properties: {} },
249
+ },
250
+ {
251
+ name: 'get_stats',
252
+ description: 'Get Auxilo registry statistics — catalog size, skill types, and query volume. Free.',
253
+ inputSchema: { type: 'object', properties: {} },
254
+ },
255
+ {
256
+ name: 'get_knowledge_stats',
257
+ description: 'Get knowledge marketplace statistics — total learnings, unlocks, contributors, and top categories. Free.',
258
+ inputSchema: { type: 'object', properties: {} },
259
+ },
140
260
  ],
141
261
  }));
142
262
 
@@ -263,11 +383,144 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
263
383
  return text(await resp.json());
264
384
  }
265
385
 
386
+ case 'auxilo_verify_wallet': {
387
+ const url = args.signature ? `${AUXILO_BASE}/wallet/verify` : `${AUXILO_BASE}/wallet/challenge`;
388
+ const resp = await fetch(url, {
389
+ method: 'POST',
390
+ headers: { 'Content-Type': 'application/json' },
391
+ body: JSON.stringify(args)
392
+ });
393
+ return text(await resp.json());
394
+ }
395
+
396
+ case 'auxilo_withdraw': {
397
+ const resp = await fetch(`${AUXILO_BASE}/withdraw`, {
398
+ method: 'POST',
399
+ headers: { 'Content-Type': 'application/json' },
400
+ body: JSON.stringify(args)
401
+ });
402
+ return text(await resp.json());
403
+ }
404
+
405
+ case 'auxilo_settlements': {
406
+ const resp = await fetch(`${AUXILO_BASE}/contributor/${args.wallet}/settlements`);
407
+ return text(await resp.json());
408
+ }
409
+
266
410
  case 'auxilo_contributor': {
267
411
  const resp = await fetch(`${AUXILO_BASE}/contributor/${args.wallet}`);
268
412
  return text(await resp.json());
269
413
  }
270
414
 
415
+ case 'auxilo_link_wallet': {
416
+ const resp = await fetch(`${AUXILO_BASE}/account/link-wallet`, {
417
+ method: 'POST',
418
+ headers: {
419
+ 'Content-Type': 'application/json',
420
+ 'Authorization': `Bearer ${args.session_token}`,
421
+ },
422
+ body: JSON.stringify({ wallet: args.wallet }),
423
+ });
424
+ return text(await resp.json());
425
+ }
426
+
427
+ case 'auxilo_account_earnings': {
428
+ const resp = await fetch(`${AUXILO_BASE}/account/earnings`, {
429
+ headers: {
430
+ 'Authorization': `Bearer ${args.session_token}`,
431
+ },
432
+ });
433
+ return text(await resp.json());
434
+ }
435
+
436
+ case 'renderly_markdown': {
437
+ const headers = { 'Content-Type': 'application/json' };
438
+ if (args.x_payment) headers['X-Payment'] = args.x_payment;
439
+
440
+ const resp = await fetch(`${AUXILO_BASE}/renderly/markdown`, {
441
+ method: 'POST',
442
+ headers,
443
+ body: JSON.stringify({ url: args.url }),
444
+ });
445
+ const data = await resp.json();
446
+ if (resp.status === 402) {
447
+ return text({
448
+ status: 'payment_required',
449
+ cost: '$0.001 USDC on Base',
450
+ http_endpoint: `${AUXILO_BASE}/renderly/markdown`,
451
+ payment_details: data,
452
+ });
453
+ }
454
+ return text(data);
455
+ }
456
+
457
+ case 'renderly_extract': {
458
+ const headers = { 'Content-Type': 'application/json' };
459
+ if (args.x_payment) headers['X-Payment'] = args.x_payment;
460
+
461
+ const resp = await fetch(`${AUXILO_BASE}/renderly/extract`, {
462
+ method: 'POST',
463
+ headers,
464
+ body: JSON.stringify({ url: args.url }),
465
+ });
466
+ const data = await resp.json();
467
+ if (resp.status === 402) {
468
+ return text({
469
+ status: 'payment_required',
470
+ cost: '$0.001 USDC on Base',
471
+ http_endpoint: `${AUXILO_BASE}/renderly/extract`,
472
+ payment_details: data,
473
+ });
474
+ }
475
+ return text(data);
476
+ }
477
+
478
+ case 'renderly_readable': {
479
+ const headers = { 'Content-Type': 'application/json' };
480
+ if (args.x_payment) headers['X-Payment'] = args.x_payment;
481
+
482
+ const resp = await fetch(`${AUXILO_BASE}/renderly/readable`, {
483
+ method: 'POST',
484
+ headers,
485
+ body: JSON.stringify({ url: args.url }),
486
+ });
487
+ const data = await resp.json();
488
+ if (resp.status === 402) {
489
+ return text({
490
+ status: 'payment_required',
491
+ cost: '$0.0005 USDC on Base',
492
+ http_endpoint: `${AUXILO_BASE}/renderly/readable`,
493
+ payment_details: data,
494
+ });
495
+ }
496
+ return text(data);
497
+ }
498
+
499
+ case 'renderly_llms_txt': {
500
+ const resp = await fetch(`${AUXILO_BASE}/renderly/llms.txt`);
501
+ return text(await resp.json());
502
+ }
503
+
504
+ case 'renderly_health': {
505
+ const resp = await fetch(`${AUXILO_BASE}/renderly/health`);
506
+ return text(await resp.json());
507
+ }
508
+
509
+ case 'renderly_pricing': {
510
+ const resp = await fetch(`${AUXILO_BASE}/renderly/pricing`);
511
+ return text(await resp.json());
512
+ }
513
+
514
+ case 'get_stats': {
515
+ const resp = await fetch(`${AUXILO_BASE}/stats`);
516
+ return text(await resp.json());
517
+ }
518
+
519
+ case 'get_knowledge_stats': {
520
+ const resp = await fetch(`${AUXILO_BASE}/knowledge/stats`);
521
+ return text(await resp.json());
522
+ }
523
+
271
524
  default:
272
525
  return { content: [{ type: 'text', text: `Unknown tool: ${name}` }], isError: true };
273
526
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auxilo-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.7.0",
4
4
  "description": "MCP server for Auxilo — Agent Capability Discovery & Knowledge Marketplace",
5
5
  "main": "mcp-server.js",
6
6
  "bin": {
@@ -30,6 +30,11 @@
30
30
  "homepage": "https://auxilo.io",
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
- "@modelcontextprotocol/sdk": "^1.0.0"
33
+ "@modelcontextprotocol/sdk": "^1.0.0",
34
+ "stripe": "^17.0.0",
35
+ "viem": "^2.46.3"
36
+ },
37
+ "devDependencies": {
38
+ "proxyquire": "^2.1.3"
34
39
  }
35
40
  }