@noelclaw/mcp 1.0.0 → 1.2.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/README.md +7 -15
- package/dist/tools/miroshark.js +190 -79
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
Noelclaw as an MCP skill — persistent memory, multi-agent coordination, scenario simulation, DeFi execution, and Sentinel-gated playbooks. Works with Claude, Cursor, Hermes, Windsurf, and any MCP-compatible client.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx @noelclaw/mcp
|
|
8
|
+
npx @noelclaw/mcp
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
---
|
|
@@ -14,12 +14,12 @@ npx @noelclaw/mcp@latest
|
|
|
14
14
|
|
|
15
15
|
### Claude Code
|
|
16
16
|
```bash
|
|
17
|
-
claude mcp add noelclaw -- npx @noelclaw/mcp
|
|
17
|
+
claude mcp add noelclaw -- npx @noelclaw/mcp
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
Set your API key:
|
|
21
21
|
```bash
|
|
22
|
-
claude mcp add noelclaw -e NOELCLAW_API_KEY=noel_... -- npx @noelclaw/mcp
|
|
22
|
+
claude mcp add noelclaw -e NOELCLAW_API_KEY=noel_... -- npx @noelclaw/mcp
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
### Claude Desktop
|
|
@@ -30,7 +30,7 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (Mac) or
|
|
|
30
30
|
"mcpServers": {
|
|
31
31
|
"noelclaw": {
|
|
32
32
|
"command": "npx",
|
|
33
|
-
"args": ["@noelclaw/mcp
|
|
33
|
+
"args": ["@noelclaw/mcp"],
|
|
34
34
|
"env": {
|
|
35
35
|
"NOELCLAW_API_KEY": "noel_..."
|
|
36
36
|
}
|
|
@@ -45,7 +45,7 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (Mac) or
|
|
|
45
45
|
"mcpServers": {
|
|
46
46
|
"noelclaw": {
|
|
47
47
|
"command": "npx",
|
|
48
|
-
"args": ["@noelclaw/mcp
|
|
48
|
+
"args": ["@noelclaw/mcp"],
|
|
49
49
|
"env": {
|
|
50
50
|
"NOELCLAW_API_KEY": "noel_..."
|
|
51
51
|
}
|
|
@@ -60,7 +60,7 @@ mcp_servers:
|
|
|
60
60
|
noelclaw:
|
|
61
61
|
command: npx
|
|
62
62
|
args:
|
|
63
|
-
- "@noelclaw/mcp
|
|
63
|
+
- "@noelclaw/mcp"
|
|
64
64
|
env:
|
|
65
65
|
NOELCLAW_API_KEY: "noel_..."
|
|
66
66
|
```
|
|
@@ -175,13 +175,6 @@ Set `NOELCLAW_API_KEY` in your MCP config. That's it.
|
|
|
175
175
|
|-----|-------------|
|
|
176
176
|
| `NOELCLAW_API_KEY` | Your API key (`noel_...`) — get one at `POST https://api.noelclaw.com/auth/key` |
|
|
177
177
|
|
|
178
|
-
### MiroShark (optional)
|
|
179
|
-
|
|
180
|
-
| Var | Description |
|
|
181
|
-
|-----|-------------|
|
|
182
|
-
| `MIROSHARK_URL` | URL of your deployed MiroShark instance |
|
|
183
|
-
| `MIROSHARK_ADMIN_TOKEN` | Admin token set on your MiroShark deployment |
|
|
184
|
-
|
|
185
178
|
### BYOK (optional)
|
|
186
179
|
|
|
187
180
|
| Var | Used for |
|
|
@@ -234,7 +227,6 @@ get_noel_ledger
|
|
|
234
227
|
|-------|-----|
|
|
235
228
|
| Tools not appearing | Restart your MCP client after adding the config |
|
|
236
229
|
| `401 Unauthorized` | Check `NOELCLAW_API_KEY` is set — get one at `POST https://api.noelclaw.com/auth/key` |
|
|
237
|
-
| `miroshark_simulate` error | Set `MIROSHARK_URL` and `MIROSHARK_ADMIN_TOKEN` |
|
|
238
230
|
| Server starts but no response | Expected — server waits for MCP stdin, not HTTP |
|
|
239
231
|
|
|
240
232
|
---
|
|
@@ -242,5 +234,5 @@ get_noel_ledger
|
|
|
242
234
|
## Links
|
|
243
235
|
|
|
244
236
|
- npm: [npmjs.com/package/@noelclaw/mcp](https://npmjs.com/package/@noelclaw/mcp)
|
|
245
|
-
- GitHub: [github.com/noelclaw/
|
|
237
|
+
- GitHub: [github.com/noelclaw/mcp](https://github.com/noelclaw/mcp)
|
|
246
238
|
- Platform: [noelclaw.com](https://noelclaw.com)
|
package/dist/tools/miroshark.js
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MIROSHARK_TOOLS = void 0;
|
|
4
4
|
exports.handleMirosharkTool = handleMirosharkTool;
|
|
5
|
+
const CONVEX_SITE = process.env.NOELCLAW_CONVEX_URL ?? "https://api.noelclaw.com";
|
|
5
6
|
exports.MIROSHARK_TOOLS = [
|
|
6
7
|
{
|
|
7
8
|
name: "miroshark_simulate",
|
|
8
|
-
description: "Run a MiroShark multi-agent simulation. Describe
|
|
9
|
-
"Returns a
|
|
9
|
+
description: "Run a MiroShark multi-agent simulation. Describe any scenario in plain English — market crashes, policy changes, social events — and get back a running simulation with AI agents acting as market participants, analysts, and social actors. " +
|
|
10
|
+
"Handles the full setup automatically (knowledge graph, agent profiles). Returns a simulation_id to poll with miroshark_status.",
|
|
10
11
|
inputSchema: {
|
|
11
12
|
type: "object",
|
|
12
13
|
properties: {
|
|
@@ -14,21 +15,13 @@ exports.MIROSHARK_TOOLS = [
|
|
|
14
15
|
type: "string",
|
|
15
16
|
description: "Plain-English description of the scenario to simulate. E.g. 'What happens if ETH drops 20% and whale wallets start selling?'",
|
|
16
17
|
},
|
|
17
|
-
agents: {
|
|
18
|
-
type: "number",
|
|
19
|
-
description: "Number of agents in the simulation (default: 10, max: 50)",
|
|
20
|
-
},
|
|
21
|
-
steps: {
|
|
22
|
-
type: "number",
|
|
23
|
-
description: "Number of simulation steps to run (default: 5)",
|
|
24
|
-
},
|
|
25
18
|
},
|
|
26
19
|
required: ["scenario"],
|
|
27
20
|
},
|
|
28
21
|
},
|
|
29
22
|
{
|
|
30
23
|
name: "miroshark_status",
|
|
31
|
-
description: "Poll the status
|
|
24
|
+
description: "Poll the status of a MiroShark simulation. Returns preparation progress, running progress, or final results. Automatically starts the simulation when agent preparation completes.",
|
|
32
25
|
inputSchema: {
|
|
33
26
|
type: "object",
|
|
34
27
|
properties: {
|
|
@@ -41,71 +34,121 @@ exports.MIROSHARK_TOOLS = [
|
|
|
41
34
|
},
|
|
42
35
|
},
|
|
43
36
|
];
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
return {
|
|
37
|
+
// ── HTTP helpers ──────────────────────────────────────────────────────────────
|
|
38
|
+
function authHeaders() {
|
|
39
|
+
const key = process.env.NOELCLAW_API_KEY ?? process.env.NOELCLAW_SESSION_TOKEN;
|
|
40
|
+
return key ? { Authorization: `Bearer ${key}` } : {};
|
|
48
41
|
}
|
|
49
|
-
async function
|
|
50
|
-
const
|
|
51
|
-
if (!url)
|
|
52
|
-
throw new Error("MIROSHARK_URL not set");
|
|
53
|
-
if (!token)
|
|
54
|
-
throw new Error("MIROSHARK_ADMIN_TOKEN not set");
|
|
55
|
-
const res = await fetch(`${url}${path}`, {
|
|
42
|
+
async function miroJson(path, method, body, timeoutMs = 90000) {
|
|
43
|
+
const res = await fetch(`${CONVEX_SITE}${path}`, {
|
|
56
44
|
method,
|
|
57
|
-
headers: {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
45
|
+
headers: { ...authHeaders(), "Content-Type": "application/json" },
|
|
46
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
47
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
48
|
+
});
|
|
49
|
+
const text = await res.text();
|
|
50
|
+
if (!res.ok)
|
|
51
|
+
throw new Error(`MiroShark ${method} ${path} [${res.status}]: ${text.slice(0, 300)}`);
|
|
52
|
+
let json;
|
|
53
|
+
try {
|
|
54
|
+
json = JSON.parse(text);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new Error(`MiroShark non-JSON response: ${text.slice(0, 200)}`);
|
|
58
|
+
}
|
|
59
|
+
if (json.success === false)
|
|
60
|
+
throw new Error(`MiroShark error: ${json.error ?? JSON.stringify(json).slice(0, 300)}`);
|
|
61
|
+
return json.data ?? json;
|
|
62
|
+
}
|
|
63
|
+
async function miroForm(path, form, timeoutMs = 120000) {
|
|
64
|
+
// No Content-Type header — browser/fetch sets multipart boundary automatically
|
|
65
|
+
const res = await fetch(`${CONVEX_SITE}${path}`, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: authHeaders(),
|
|
68
|
+
body: form,
|
|
69
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
63
70
|
});
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
throw new Error(`MiroShark ${res.status}: ${
|
|
71
|
+
const text = await res.text();
|
|
72
|
+
if (!res.ok)
|
|
73
|
+
throw new Error(`MiroShark POST ${path} [${res.status}]: ${text.slice(0, 300)}`);
|
|
74
|
+
let json;
|
|
75
|
+
try {
|
|
76
|
+
json = JSON.parse(text);
|
|
67
77
|
}
|
|
68
|
-
|
|
78
|
+
catch {
|
|
79
|
+
throw new Error(`MiroShark non-JSON response: ${text.slice(0, 200)}`);
|
|
80
|
+
}
|
|
81
|
+
if (json.success === false)
|
|
82
|
+
throw new Error(`MiroShark error: ${json.error ?? JSON.stringify(json).slice(0, 300)}`);
|
|
83
|
+
return json.data ?? json;
|
|
84
|
+
}
|
|
85
|
+
async function pollUntilDone(taskPath, pollIntervalMs = 8000, maxWaitMs = 180000) {
|
|
86
|
+
const deadline = Date.now() + maxWaitMs;
|
|
87
|
+
while (Date.now() < deadline) {
|
|
88
|
+
await new Promise(r => setTimeout(r, pollIntervalMs));
|
|
89
|
+
const task = await miroJson(taskPath, "GET");
|
|
90
|
+
const s = (task.status ?? "").toLowerCase();
|
|
91
|
+
if (s === "completed" || s === "success")
|
|
92
|
+
return task;
|
|
93
|
+
if (s === "failed" || s === "error") {
|
|
94
|
+
throw new Error(`Task failed: ${task.error ?? task.message ?? s}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
throw new Error("Task timed out after 3 minutes");
|
|
69
98
|
}
|
|
99
|
+
// ── Tool handler ──────────────────────────────────────────────────────────────
|
|
70
100
|
async function handleMirosharkTool(name, args) {
|
|
71
101
|
const a = (args ?? {});
|
|
102
|
+
// ── miroshark_simulate ────────────────────────────────────────────────────
|
|
72
103
|
if (name === "miroshark_simulate") {
|
|
73
104
|
if (!a.scenario?.trim()) {
|
|
74
105
|
return { content: [{ type: "text", text: "scenario is required" }], isError: true };
|
|
75
106
|
}
|
|
76
|
-
const { url, token } = getConfig();
|
|
77
|
-
if (!url || !token) {
|
|
78
|
-
return {
|
|
79
|
-
content: [{ type: "text", text: "MiroShark not configured — set MIROSHARK_URL and MIROSHARK_ADMIN_TOKEN" }],
|
|
80
|
-
isError: true,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
107
|
try {
|
|
84
|
-
// Step 1:
|
|
85
|
-
const asked = await
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
108
|
+
// Step 1: convert plain-English question into a structured seed document
|
|
109
|
+
const asked = await miroJson("/miroshark/api/simulation/ask", "POST", { question: a.scenario });
|
|
110
|
+
const { title, seed_document, simulation_requirement } = asked;
|
|
111
|
+
// Step 2: generate knowledge-graph ontology from the seed document
|
|
112
|
+
const form = new FormData();
|
|
113
|
+
form.append("simulation_requirement", simulation_requirement ?? a.scenario);
|
|
114
|
+
form.append("project_name", (title ?? a.scenario).slice(0, 100));
|
|
115
|
+
form.append("url_docs", JSON.stringify([{
|
|
116
|
+
title: title ?? "Simulation Context",
|
|
117
|
+
url: "",
|
|
118
|
+
text: seed_document ?? a.scenario,
|
|
119
|
+
}]));
|
|
120
|
+
const ontology = await miroForm("/miroshark/api/graph/ontology/generate", form);
|
|
121
|
+
const projectId = ontology.project_id;
|
|
122
|
+
if (!projectId)
|
|
123
|
+
throw new Error("No project_id in ontology response");
|
|
124
|
+
// Step 3: kick off the async graph build
|
|
125
|
+
const built = await miroJson("/miroshark/api/graph/build", "POST", { project_id: projectId });
|
|
126
|
+
const graphTaskId = built.task_id;
|
|
127
|
+
if (!graphTaskId)
|
|
128
|
+
throw new Error("No task_id in graph build response");
|
|
129
|
+
// Step 4: wait for graph to finish (up to 3 min)
|
|
130
|
+
await pollUntilDone(`/miroshark/api/graph/task/${graphTaskId}`);
|
|
131
|
+
// Step 5: create simulation from the built graph
|
|
132
|
+
const created = await miroJson("/miroshark/api/simulation/create", "POST", { project_id: projectId });
|
|
92
133
|
const simId = created.simulation_id ?? created.id;
|
|
93
134
|
if (!simId)
|
|
94
|
-
throw new Error("No
|
|
95
|
-
// Step
|
|
96
|
-
await
|
|
97
|
-
|
|
98
|
-
await mirofetch(`/api/simulation/${simId}/start`, "POST", {});
|
|
135
|
+
throw new Error("No simulation_id in create response");
|
|
136
|
+
// Step 6: kick off agent preparation (async — don't block)
|
|
137
|
+
const prepared = await miroJson("/miroshark/api/simulation/prepare", "POST", { simulation_id: simId });
|
|
138
|
+
const prepTaskId = prepared.task_id;
|
|
99
139
|
return {
|
|
100
140
|
content: [{
|
|
101
141
|
type: "text",
|
|
102
142
|
text: [
|
|
103
|
-
|
|
143
|
+
`**MiroShark simulation queued** ✓`,
|
|
144
|
+
``,
|
|
104
145
|
`Scenario: ${a.scenario}`,
|
|
146
|
+
`Project: \`${projectId}\``,
|
|
105
147
|
`Simulation ID: \`${simId}\``,
|
|
106
|
-
`
|
|
148
|
+
`Status: preparing agents${prepTaskId ? ` (task: ${prepTaskId})` : ""}`,
|
|
107
149
|
``,
|
|
108
|
-
`Poll
|
|
150
|
+
`Agent preparation runs in the background. Poll progress with:`,
|
|
151
|
+
`\`miroshark_status simulation_id="${simId}"\``,
|
|
109
152
|
].join("\n"),
|
|
110
153
|
}],
|
|
111
154
|
};
|
|
@@ -114,38 +157,106 @@ async function handleMirosharkTool(name, args) {
|
|
|
114
157
|
return { content: [{ type: "text", text: `MiroShark error: ${err.message}` }], isError: true };
|
|
115
158
|
}
|
|
116
159
|
}
|
|
160
|
+
// ── miroshark_status ──────────────────────────────────────────────────────
|
|
117
161
|
if (name === "miroshark_status") {
|
|
118
162
|
if (!a.simulation_id?.trim()) {
|
|
119
163
|
return { content: [{ type: "text", text: "simulation_id is required" }], isError: true };
|
|
120
164
|
}
|
|
165
|
+
const simId = a.simulation_id.trim();
|
|
121
166
|
try {
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
lines.push("", `**Consensus:** ${data.results.consensus}`);
|
|
167
|
+
// Check if agents are still being prepared
|
|
168
|
+
const prepStatus = await miroJson("/miroshark/api/simulation/prepare/status", "POST", { simulation_id: simId }).catch(() => null);
|
|
169
|
+
const prepState = (prepStatus?.status ?? "").toLowerCase();
|
|
170
|
+
if (prepState === "processing" || prepState === "pending") {
|
|
171
|
+
const pct = prepStatus?.progress ?? 0;
|
|
172
|
+
const msg = prepStatus?.message ?? "preparing agents...";
|
|
173
|
+
return {
|
|
174
|
+
content: [{
|
|
175
|
+
type: "text",
|
|
176
|
+
text: [
|
|
177
|
+
`**MiroShark \`${simId}\`** — preparing agents`,
|
|
178
|
+
`Progress: ${pct}%`,
|
|
179
|
+
`${msg}`,
|
|
180
|
+
``,
|
|
181
|
+
`Poll again in a few seconds.`,
|
|
182
|
+
].join("\n"),
|
|
183
|
+
}],
|
|
184
|
+
};
|
|
141
185
|
}
|
|
142
|
-
|
|
143
|
-
|
|
186
|
+
// Agents ready (or prepare already done) — check run status
|
|
187
|
+
const runStatus = await miroJson(`/miroshark/api/simulation/${simId}/run-status`, "GET").catch(() => ({ runner_status: "idle" }));
|
|
188
|
+
const runnerStatus = (runStatus?.runner_status ?? "idle").toLowerCase();
|
|
189
|
+
// Auto-start the simulation when agents are ready but not yet running
|
|
190
|
+
if (runnerStatus === "idle" && (prepState === "ready" || prepState === "completed" || prepStatus?.already_prepared)) {
|
|
191
|
+
await miroJson("/miroshark/api/simulation/start", "POST", {
|
|
192
|
+
simulation_id: simId,
|
|
193
|
+
platform: "parallel",
|
|
194
|
+
});
|
|
195
|
+
return {
|
|
196
|
+
content: [{
|
|
197
|
+
type: "text",
|
|
198
|
+
text: [
|
|
199
|
+
`**MiroShark \`${simId}\`** — simulation started`,
|
|
200
|
+
``,
|
|
201
|
+
`Agents are now active. Poll again in ~15 seconds for progress.`,
|
|
202
|
+
`\`miroshark_status simulation_id="${simId}"\``,
|
|
203
|
+
].join("\n"),
|
|
204
|
+
}],
|
|
205
|
+
};
|
|
144
206
|
}
|
|
145
|
-
|
|
146
|
-
|
|
207
|
+
if (runnerStatus === "running") {
|
|
208
|
+
const round = runStatus.current_round ?? 0;
|
|
209
|
+
const total = runStatus.total_rounds ?? "?";
|
|
210
|
+
const pct = runStatus.progress_percent?.toFixed(1) ?? "0";
|
|
211
|
+
const twitterActs = runStatus.twitter_actions_count ?? 0;
|
|
212
|
+
const redditActs = runStatus.reddit_actions_count ?? 0;
|
|
213
|
+
return {
|
|
214
|
+
content: [{
|
|
215
|
+
type: "text",
|
|
216
|
+
text: [
|
|
217
|
+
`**MiroShark \`${simId}\`** — running`,
|
|
218
|
+
`Round: ${round} / ${total} (${pct}%)`,
|
|
219
|
+
`Actions: ${twitterActs} Twitter · ${redditActs} Reddit`,
|
|
220
|
+
``,
|
|
221
|
+
`Simulation in progress — poll again in ~15 seconds.`,
|
|
222
|
+
].join("\n"),
|
|
223
|
+
}],
|
|
224
|
+
};
|
|
147
225
|
}
|
|
148
|
-
|
|
226
|
+
if (runnerStatus === "completed" || runnerStatus === "stopped") {
|
|
227
|
+
// Fetch a sample of agent actions for the summary
|
|
228
|
+
const actionsData = await miroJson(`/miroshark/api/simulation/${simId}/actions?limit=10`, "GET").catch(() => ({ actions: [] }));
|
|
229
|
+
const actions = actionsData?.actions ?? [];
|
|
230
|
+
const lines = [
|
|
231
|
+
`**MiroShark \`${simId}\`** — ${runnerStatus}`,
|
|
232
|
+
``,
|
|
233
|
+
`Rounds completed: ${runStatus.current_round ?? "?"}`,
|
|
234
|
+
`Total actions: ${runStatus.total_actions_count ?? actions.length}`,
|
|
235
|
+
];
|
|
236
|
+
if (actions.length > 0) {
|
|
237
|
+
lines.push("", "**Sample agent activity:**");
|
|
238
|
+
for (const act of actions.slice(0, 8)) {
|
|
239
|
+
const who = act.agent_name ?? act.agent_id ?? "agent";
|
|
240
|
+
const what = act.action_type ?? act.type ?? "action";
|
|
241
|
+
const content = act.content ?? act.text ?? "";
|
|
242
|
+
lines.push(`• **${who}** [${what}]${content ? `: ${String(content).slice(0, 80)}` : ""}`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
lines.push("", `Full transcript: \`miroshark_status\` returns results above.`);
|
|
246
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
247
|
+
}
|
|
248
|
+
// Fallback: unknown state
|
|
249
|
+
return {
|
|
250
|
+
content: [{
|
|
251
|
+
type: "text",
|
|
252
|
+
text: [
|
|
253
|
+
`**MiroShark \`${simId}\`** — status: ${runnerStatus || "unknown"}`,
|
|
254
|
+
prepState ? `Prepare state: ${prepState}` : "",
|
|
255
|
+
``,
|
|
256
|
+
`If agents are still preparing, poll again shortly.`,
|
|
257
|
+
].filter(Boolean).join("\n"),
|
|
258
|
+
}],
|
|
259
|
+
};
|
|
149
260
|
}
|
|
150
261
|
catch (err) {
|
|
151
262
|
return { content: [{ type: "text", text: `MiroShark error: ${err.message}` }], isError: true };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noelclaw/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
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": {
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
],
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
|
30
|
-
"url": "git+https://github.com/noelclaw/
|
|
30
|
+
"url": "git+https://github.com/noelclaw/mcp.git"
|
|
31
31
|
},
|
|
32
|
-
"homepage": "https://github.com/noelclaw/
|
|
32
|
+
"homepage": "https://github.com/noelclaw/mcp#readme",
|
|
33
33
|
"bugs": {
|
|
34
|
-
"url": "https://github.com/noelclaw/
|
|
34
|
+
"url": "https://github.com/noelclaw/mcp/issues"
|
|
35
35
|
},
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"files": [
|