@noelclaw/mcp 1.3.0 → 1.4.1

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.
@@ -94,7 +94,7 @@ async function handleHumanizerTool(name, args) {
94
94
  "Authorization": `Bearer ${apiKey}`,
95
95
  },
96
96
  body: JSON.stringify({
97
- model: "MiniMax-Text-01",
97
+ model: "MiniMax-M2.7",
98
98
  messages: [
99
99
  { role: "system", content: HUMANIZER_SYSTEM },
100
100
  { role: "user", content: userMsg },
@@ -109,7 +109,8 @@ async function handleHumanizerTool(name, args) {
109
109
  return { content: [{ type: "text", text: `API error: ${res.status} ${err.slice(0, 200)}` }], isError: true };
110
110
  }
111
111
  const data = await res.json();
112
- const output = data?.choices?.[0]?.message?.content?.trim();
112
+ const raw = data?.choices?.[0]?.message?.content ?? "";
113
+ const output = raw.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
113
114
  if (!output)
114
115
  return { content: [{ type: "text", text: "Empty response from model" }], isError: true };
115
116
  return { content: [{ type: "text", text: output }] };
@@ -33,38 +33,16 @@ async function handleMarketTool(name, args) {
33
33
  if (!parsed.success)
34
34
  return { content: [{ type: "text", text: `Invalid input: token ${parsed.error.issues[0].message}` }], isError: true };
35
35
  const { token } = parsed.data;
36
- const tokenQ = token ? `?token=${encodeURIComponent(token)}` : "";
37
- const data = await (0, convex_js_1.callConvex)(`/mcp/market${tokenQ}`, "GET", undefined, "get_market_data");
38
- const lines = [`**Market Data** — ${data.fetchedAt ?? new Date().toISOString()}`, ""];
39
- if (data.keyPrices) {
40
- lines.push("**Key Prices**");
41
- for (const [coin, info] of Object.entries(data.keyPrices)) {
42
- const price = info.usd?.toLocaleString("en-US", { style: "currency", currency: "USD" });
43
- const change = info.usd_24h_change?.toFixed(2);
44
- const sign = (info.usd_24h_change ?? 0) >= 0 ? "+" : "";
45
- lines.push(`• ${coin.toUpperCase()}: ${price} (${sign}${change}%)`);
46
- }
47
- lines.push("");
48
- }
49
- if (data.trending?.length) {
50
- lines.push("**Trending** (top 10)");
51
- for (const c of data.trending) {
52
- const ch = c.change24h?.toFixed(2);
53
- const sign = (c.change24h ?? 0) >= 0 ? "+" : "";
54
- lines.push(`• ${c.name} (${c.symbol?.toUpperCase()}) — rank #${c.rank ?? "?"} ${ch != null ? `${sign}${ch}%` : ""}`);
55
- }
56
- lines.push("");
57
- }
58
- if (data.top20?.length) {
59
- lines.push("**Top 20 by Market Cap**");
60
- lines.push("| # | Name | Price | 24h% |");
61
- lines.push("|---|------|-------|------|");
62
- for (const c of data.top20) {
63
- const price = c.price?.toLocaleString("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 4 });
64
- const ch = c.change24h?.toFixed(2);
65
- const sign = (c.change24h ?? 0) >= 0 ? "+" : "";
66
- lines.push(`| ${c.rank} | ${c.name} (${c.symbol?.toUpperCase()}) | ${price} | ${sign}${ch}% |`);
67
- }
36
+ const symbols = token ? [token.toUpperCase()] : ["BTC", "ETH", "SOL"];
37
+ const results = await Promise.all(symbols.map((s) => (0, convex_js_1.callConvex)(`/swarm/memory/read?key=market/${s}`, "GET", undefined, "get_market_data")));
38
+ const lines = [`**Market Data** — ${new Date().toISOString()}`, ""];
39
+ for (const d of results) {
40
+ if (d.error)
41
+ continue;
42
+ const price = d.price_usd?.toLocaleString("en-US", { style: "currency", currency: "USD" });
43
+ const ch = d.change_24h_pct?.toFixed(2);
44
+ const sign = (d.change_24h_pct ?? 0) >= 0 ? "+" : "";
45
+ lines.push(`• **${d.symbol}**: ${price} (${sign}${ch}%) — mcap $${(d.market_cap_usd / 1e9).toFixed(1)}B`);
68
46
  }
69
47
  return { content: [{ type: "text", text: lines.join("\n") }] };
70
48
  }
@@ -72,30 +50,22 @@ async function handleMarketTool(name, args) {
72
50
  const parsed = GetTokenDataSchema.safeParse(args);
73
51
  if (!parsed.success)
74
52
  return { content: [{ type: "text", text: `Invalid input: question ${parsed.error.issues[0].message}` }], isError: true };
75
- // Extract token symbol from natural-language question
76
53
  const q = parsed.data.question.toUpperCase();
77
54
  const KNOWN = ["BTC", "ETH", "SOL", "BNB", "USDT", "USDC", "XRP", "DOGE", "ADA", "AVAX", "DOT", "LINK", "UNI", "OP", "ARB", "HYPE", "PEPE", "SUI", "APT", "NEAR", "INJ", "TIA", "MATIC", "TON", "SHIB", "WIF", "BONK"];
78
- const found = KNOWN.find((t) => new RegExp(`\\b${t}\\b`).test(q));
79
- const tokenQ = found ? `?token=${found}` : "";
80
- const data = await (0, convex_js_1.callConvex)(`/mcp/market${tokenQ}`, "GET", undefined, "get_token_data");
81
- const lines = [`**Token Data** ${data.fetchedAt ?? new Date().toISOString()}`, ""];
82
- if (data.keyPrices) {
83
- lines.push("**Prices**");
84
- for (const [coin, info] of Object.entries(data.keyPrices)) {
85
- const price = info.usd?.toLocaleString("en-US", { style: "currency", currency: "USD" });
86
- const ch = (info.usd_24h_change ?? 0).toFixed(2);
87
- const sign = (info.usd_24h_change ?? 0) >= 0 ? "+" : "";
88
- lines.push(`• ${coin.toUpperCase()}: ${price} (${sign}${ch}%)`);
89
- }
90
- }
91
- if (data.trending?.length) {
92
- lines.push("", "**Trending**");
93
- for (const c of data.trending.slice(0, 5)) {
94
- const ch = c.change24h?.toFixed(2);
95
- const sign = (c.change24h ?? 0) >= 0 ? "+" : "";
96
- lines.push(`• ${c.symbol?.toUpperCase()} — #${c.rank ?? "?"} ${ch != null ? `${sign}${ch}%` : ""}`);
97
- }
98
- }
55
+ const found = KNOWN.find((t) => new RegExp(`\\b${t}\\b`).test(q)) ?? "BTC";
56
+ const data = await (0, convex_js_1.callConvex)(`/swarm/memory/read?key=market/${found}`, "GET", undefined, "get_token_data");
57
+ if (data.error)
58
+ return { content: [{ type: "text", text: `Error fetching ${found}: ${data.error}` }], isError: true };
59
+ const price = data.price_usd?.toLocaleString("en-US", { style: "currency", currency: "USD" });
60
+ const ch = data.change_24h_pct?.toFixed(2);
61
+ const sign = (data.change_24h_pct ?? 0) >= 0 ? "+" : "";
62
+ const lines = [
63
+ `**${data.symbol}** ${data.fetchedAt}`,
64
+ `Price: ${price} (${sign}${ch}% 24h)`,
65
+ `Market Cap: $${(data.market_cap_usd / 1e9).toFixed(2)}B`,
66
+ `Volume 24h: $${(data.volume_24h_usd / 1e9).toFixed(2)}B`,
67
+ `Source: ${data.source}`,
68
+ ];
99
69
  return { content: [{ type: "text", text: lines.join("\n") }] };
100
70
  }
101
71
  default:
@@ -134,7 +134,7 @@ async function handleMirosharkTool(name, args) {
134
134
  if (!simId)
135
135
  throw new Error("No simulation_id in create response");
136
136
  // Step 6: kick off agent preparation (async — don't block)
137
- const prepared = await miroJson("/miroshark/api/simulation/prepare", "POST", { simulation_id: simId });
137
+ const prepared = await miroJson("/miroshark/api/simulation/prepare", "POST", { simulation_id: simId, parallel_profile_count: 10 });
138
138
  const prepTaskId = prepared.task_id;
139
139
  return {
140
140
  content: [{
@@ -79,11 +79,10 @@ async function handleSwarmTool(name, args) {
79
79
  const data = await (0, convex_js_1.callConvex)("/swarm/start", "POST", { config: parsed.data.config }, "start_swarm");
80
80
  if (!data.success)
81
81
  return { content: [{ type: "text", text: `Failed: ${data.error}` }], isError: true };
82
- const agents = data.activeAgents ?? [];
83
82
  return {
84
83
  content: [{
85
84
  type: "text",
86
- text: [`🤖 **Swarm Started**`, `Status: ${data.status}`, `Active agents (${agents.length}): ${agents.join(", ")}`, ``, `Use \`get_swarm_status\` to monitor, \`stop_swarm\` to stop.`].join("\n"),
85
+ text: [`🤖 **Swarm Started**`, `Session ID: ${data.sessionId}`, `Started at: ${data.startedAt}`, ``, `Use \`get_swarm_status\` to monitor, \`stop_swarm\` to stop.`].join("\n"),
87
86
  }],
88
87
  };
89
88
  }
@@ -97,12 +96,12 @@ async function handleSwarmTool(name, args) {
97
96
  const data = await (0, convex_js_1.callConvex)("/swarm/status", "GET", undefined, "get_swarm_status");
98
97
  if (data.error)
99
98
  return { content: [{ type: "text", text: `Error: ${data.error}` }], isError: true };
100
- const job = data.job;
99
+ const session = data.session;
101
100
  const memory = data.memory ?? [];
102
101
  const scores = data.scores ?? [];
103
102
  const lines = [
104
103
  `🤖 **Swarm Status**`,
105
- job ? `Status: ${job.status} | Agents: ${(job.activeAgents ?? []).join(", ")}` : `No active swarm.`,
104
+ data.active && session ? `Status: active | Session: ${session.id}` : `No active swarm.`,
106
105
  ``,
107
106
  ];
108
107
  if (memory.length > 0) {
@@ -133,7 +132,7 @@ async function handleSwarmTool(name, args) {
133
132
  const parsed = GetMemorySchema.safeParse(args);
134
133
  if (!parsed.success)
135
134
  return { content: [{ type: "text", text: `Invalid input: key ${parsed.error.issues[0].message}` }], isError: true };
136
- const data = await (0, convex_js_1.callConvex)(`/swarm/memory?key=${encodeURIComponent(parsed.data.key)}`, "GET", undefined, "get_swarm_memory");
135
+ const data = await (0, convex_js_1.callConvex)(`/swarm/memory/read?key=${encodeURIComponent(parsed.data.key)}`, "GET", undefined, "get_swarm_memory");
137
136
  if (data.error)
138
137
  return { content: [{ type: "text", text: `Error: ${data.error}` }], isError: true };
139
138
  if (data.value === null || data.value === undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noelclaw/mcp",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "Noelclaw as an MCP skill — persistent memory, multi-agent coordination, scenario simulation, DeFi execution, and Sentinel-gated playbooks.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {