coinopai-mcp 1.2.4 → 1.2.6

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
@@ -177,7 +177,7 @@ Not currently listed on Smithery. Use the `npx` install flow shown above until a
177
177
 
178
178
  ### Registry status
179
179
 
180
- The current official MCP Registry entry remains `io.github.clawdbotworker/coinopai-mcp` until a refreshed public submission is published.
180
+ Prepared MCP Registry identity: `io.github.forgemeshlabs/coinopai-mcp`. Refresh the public directory submission after publishing this package so old `clawdbotworker` entries stop being canonical.
181
181
 
182
182
  ---
183
183
 
@@ -314,7 +314,7 @@ Infrastructure for monetized agent ecosystems.
314
314
  |---------|------|---------|
315
315
  | [affiliate-router-mcp](https://github.com/forgemeshlabs/affiliate-router-mcp) | Vendor-neutral monetization routing | `npm i affiliate-router-mcp` |
316
316
  | **coinopai-mcp** | Paid crypto intelligence (this package) | `npm i coinopai-mcp` |
317
- | [coinopai-imagegen](https://github.com/forgemeshlabs/coinopai-imagegen) | Paid image generation service | `npm i coinopai-imagegen` |
317
+ | [forgemesh-imagegen](https://github.com/forgemeshlabs/imagegen-mcp) | Paid image generation MCP | `npm i forgemesh-imagegen` |
318
318
 
319
319
  Each package works standalone. No shared dependency required.
320
320
 
package/index.js CHANGED
@@ -25,8 +25,12 @@ const USDC_ABI = parseAbi([
25
25
  ]);
26
26
  // Paths with registered Pyrimid product IDs — other paths fall back to standard x402
27
27
  const PYRIMID_PRODUCTS = {
28
- "/api/kronos/signals": { productId: 1n, priceUsdc: 50000n },
29
- "/api/kronos/decision": { productId: 2n, priceUsdc: 150000n },
28
+ "/api/kronos/signals": { productId: 1n, priceUsdc: 50000n },
29
+ "/api/kronos/decision": { productId: 2n, priceUsdc: 150000n },
30
+ "/api/kronos/preflight": { productId: 4n, priceUsdc: 50000n },
31
+ "/api/kronos/audit": { productId: 5n, priceUsdc: 70000n },
32
+ "/api/kronos/risk": { productId: 6n, priceUsdc: 20000n },
33
+ "/api/kronos/history": { productId: 7n, priceUsdc: 50000n },
30
34
  };
31
35
  const IMAGEGEN_URL = "https://imagegen.coinopai.com";
32
36
  const PYRIMID_PRODUCTS_IMAGEGEN = {
@@ -141,8 +145,9 @@ const sleep = (ms) => new Promise(r => setTimeout(r, ms));
141
145
 
142
146
  // Pyrimid affiliate flow — approve + routePayment on-chain, then retry with tx hash
143
147
  async function callPyrimid(account, path, affiliateId, baseUrl, products) {
144
- const product = products[path];
145
- if (!product) throw new Error(`No Pyrimid product registered for ${path}`);
148
+ const pathname = new URL(path, baseUrl).pathname;
149
+ const product = products[pathname];
150
+ if (!product) throw new Error(`No Pyrimid product registered for ${pathname}`);
146
151
  const url = baseUrl + path;
147
152
  const transport = http();
148
153
  const publicClient = createPublicClient({ chain: base, transport });
@@ -175,10 +180,16 @@ async function callPaid(ctx, path, affiliateId, opts = {}) {
175
180
  const { httpClient, account } = ctx;
176
181
  const baseUrl = opts.baseUrl || BASE_URL;
177
182
  const pyrimidProducts = opts.pyrimidProducts || PYRIMID_PRODUCTS;
183
+ const pathname = new URL(path, baseUrl).pathname;
178
184
 
179
- // Use Pyrimid affiliate flow when affiliate_id present and product is registered
180
- if (affiliateId && pyrimidProducts[path]) {
181
- return callPyrimid(account, path, affiliateId, baseUrl, pyrimidProducts);
185
+ // Use Pyrimid affiliate flow when affiliate_id present and product is registered.
186
+ // Fall back to direct x402 if the affiliate route is unavailable or not yet cataloged.
187
+ if (affiliateId && pyrimidProducts[pathname]) {
188
+ try {
189
+ return await callPyrimid(account, path, affiliateId, baseUrl, pyrimidProducts);
190
+ } catch (_) {
191
+ affiliateId = null;
192
+ }
182
193
  }
183
194
 
184
195
  // Standard x402 EIP-3009 flow
@@ -212,15 +223,13 @@ async function callPaid(ctx, path, affiliateId, opts = {}) {
212
223
 
213
224
  async function main() {
214
225
  let ctx;
215
- try {
216
- ctx = buildHttpClient();
217
- } catch (e) {
218
- process.stderr.write("[coinopai-mcp] " + e.message + "\n");
219
- process.exit(1);
226
+ function getPaymentContext() {
227
+ if (!ctx) ctx = buildHttpClient();
228
+ return ctx;
220
229
  }
221
230
 
222
231
  const server = new Server(
223
- { name: "coinopai-mcp", version: "1.2.1" },
232
+ { name: "coinopai-mcp", version: "1.2.6" },
224
233
  { capabilities: { tools: {} } }
225
234
  );
226
235
 
@@ -231,36 +240,37 @@ async function main() {
231
240
  try {
232
241
  // Affiliate ID: tool arg takes precedence, then env fallback, then none
233
242
  const affiliateId = args.affiliate_id || process.env.PYRIMID_AFFILIATE_ID || null;
243
+ const paymentContext = getPaymentContext();
234
244
  let data;
235
245
  switch (name) {
236
246
  // Low-value utility endpoints — no affiliate routing
237
247
  case "search_agent_automations":
238
- data = await callPaid(ctx, `/api/search?q=${encodeURIComponent(args.query || "")}&limit=${args.limit || 20}`, null);
248
+ data = await callPaid(paymentContext, `/api/search?q=${encodeURIComponent(args.query || "")}&limit=${args.limit || 20}`, null);
239
249
  break;
240
250
  case "get_agent_automation":
241
- data = await callPaid(ctx, `/api/automation/${encodeURIComponent(args.slug)}`, null);
251
+ data = await callPaid(paymentContext, `/api/automation/${encodeURIComponent(args.slug)}`, null);
242
252
  break;
243
253
  case "list_automation_categories":
244
- data = await callPaid(ctx, "/api/categories", null);
254
+ data = await callPaid(paymentContext, "/api/categories", null);
245
255
  break;
246
256
  case "get_crypto_risk":
247
- data = await callPaid(ctx, "/api/kronos/risk", null);
257
+ data = await callPaid(paymentContext, "/api/kronos/risk", affiliateId);
248
258
  break;
249
259
  // High-value endpoints — affiliate routing enabled
250
260
  case "get_crypto_signals":
251
- data = await callPaid(ctx, "/api/kronos/signals", affiliateId);
261
+ data = await callPaid(paymentContext, "/api/kronos/signals", affiliateId);
252
262
  break;
253
263
  case "get_crypto_signal_history":
254
- data = await callPaid(ctx, `/api/kronos/history?hours=${args.hours || 24}`, affiliateId);
264
+ data = await callPaid(paymentContext, `/api/kronos/history?hours=${args.hours || 24}`, affiliateId);
255
265
  break;
256
266
  case "get_crypto_decision":
257
- data = await callPaid(ctx, `/api/kronos/decision?symbol=${encodeURIComponent(args.symbol || "BTC")}`, affiliateId);
267
+ data = await callPaid(paymentContext, `/api/kronos/decision?symbol=${encodeURIComponent(args.symbol || "BTC")}`, affiliateId);
258
268
  break;
259
269
  case "check_trade_preflight":
260
- data = await callPaid(ctx, `/api/kronos/preflight?symbol=${encodeURIComponent(args.symbol || "BTC")}`, affiliateId);
270
+ data = await callPaid(paymentContext, `/api/kronos/preflight?symbol=${encodeURIComponent(args.symbol || "BTC")}`, affiliateId);
261
271
  break;
262
272
  case "audit_trade_decision":
263
- data = await callPaid(ctx, `/api/kronos/audit?decision_id=${encodeURIComponent(args.decision_id)}&window=${encodeURIComponent(args.window || "4h")}`, affiliateId);
273
+ data = await callPaid(paymentContext, `/api/kronos/audit?decision_id=${encodeURIComponent(args.decision_id)}&window=${encodeURIComponent(args.window || "4h")}`, affiliateId);
264
274
  break;
265
275
  default:
266
276
  throw new Error("Unknown tool: " + name);
@@ -273,6 +283,9 @@ async function main() {
273
283
 
274
284
  const transport = new StdioServerTransport();
275
285
  await server.connect(transport);
286
+ process.stdin.resume();
287
+ process.stdin.on("end", () => process.exit(0));
288
+ setInterval(() => {}, 1 << 30);
276
289
  }
277
290
 
278
291
  main();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "coinopai-mcp",
3
- "version": "1.2.4",
4
- "mcpName": "io.github.clawdbotworker/coinopai-mcp",
3
+ "version": "1.2.6",
4
+ "mcpName": "io.github.forgemeshlabs/coinopai-mcp",
5
5
  "description": "MCP server for CoinOpAI — agent automation prompts and crypto signals via x402 micropayments on Base",
6
6
  "main": "index.js",
7
7
  "bin": {
package/server.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
- "name": "io.github.clawdbotworker/coinopai-mcp",
3
+ "name": "io.github.forgemeshlabs/coinopai-mcp",
4
4
  "description": "Kronos crypto signals + trade decisions + 819 automation prompts. x402 micropayments, USDC/Base.",
5
5
  "repository": {
6
6
  "url": "https://github.com/forgemeshlabs/coinopai-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "1.2.4",
9
+ "version": "1.2.6",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "coinopai-mcp",
14
- "version": "1.2.4",
14
+ "version": "1.2.6",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },