@mclawnet/mcp-server 0.1.3 → 0.1.5
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 +44 -0
- package/dist/server.js +12 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/inbox.d.ts +74 -0
- package/dist/tools/inbox.d.ts.map +1 -0
- package/dist/tools/inbox.js +168 -0
- package/dist/tools/inbox.js.map +1 -0
- package/dist/tools/index.d.ts +584 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +17 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/plan-review.d.ts +62 -0
- package/dist/tools/plan-review.d.ts.map +1 -0
- package/dist/tools/plan-review.js +144 -0
- package/dist/tools/plan-review.js.map +1 -0
- package/dist/tools/task.d.ts +526 -0
- package/dist/tools/task.d.ts.map +1 -0
- package/dist/tools/task.js +823 -0
- package/dist/tools/task.js.map +1 -0
- package/package.json +6 -4
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { InboxRelayLike } from "./inbox.js";
|
|
2
|
+
export interface PlanReviewToolContext {
|
|
3
|
+
/**
|
|
4
|
+
* Optional override for the clawnet root (the user-home root, *not*
|
|
5
|
+
* `<home>/.clawnet`). When omitted, falls back to `CLAWNET_HOME` env var
|
|
6
|
+
* then `homedir()`. Plumbed in to keep tests on temp dirs in lockstep with
|
|
7
|
+
* the InboxStore the tool writes through.
|
|
8
|
+
*/
|
|
9
|
+
rootDir?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Optional in-process relay. When present, plan_review_submit fires
|
|
12
|
+
* `relay.deliver(swarmId, queenInstanceId)` after writing the message to
|
|
13
|
+
* disk so the queen wakes immediately. Failures are swallowed (best-effort).
|
|
14
|
+
*
|
|
15
|
+
* Cross-process MCP servers (the common case) leave this undefined; the
|
|
16
|
+
* agent-side `InboxWatcher` picks up the file change and triggers delivery
|
|
17
|
+
* via its own relay, where the swarm coordinator's interceptor consumes the
|
|
18
|
+
* `plan_review_result` envelope and forwards a normalized `plan_approved`
|
|
19
|
+
* / `plan_rejected` to the queen.
|
|
20
|
+
*/
|
|
21
|
+
relay?: InboxRelayLike;
|
|
22
|
+
}
|
|
23
|
+
export declare const PLAN_REVIEW_TOOL_NAMES: Set<string>;
|
|
24
|
+
export declare function getPlanReviewToolDefinitions(): {
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
inputSchema: {
|
|
28
|
+
type: "object";
|
|
29
|
+
properties: {
|
|
30
|
+
workDir: {
|
|
31
|
+
type: string;
|
|
32
|
+
description: string;
|
|
33
|
+
};
|
|
34
|
+
swarmId: {
|
|
35
|
+
type: string;
|
|
36
|
+
description: string;
|
|
37
|
+
};
|
|
38
|
+
from: {
|
|
39
|
+
type: string;
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
verdict: {
|
|
43
|
+
type: string;
|
|
44
|
+
enum: string[];
|
|
45
|
+
description: string;
|
|
46
|
+
};
|
|
47
|
+
body: {
|
|
48
|
+
type: string;
|
|
49
|
+
description: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
required: string[];
|
|
53
|
+
};
|
|
54
|
+
}[];
|
|
55
|
+
export declare function handlePlanReviewToolCall(name: string, args: Record<string, unknown>, context: PlanReviewToolContext): Promise<{
|
|
56
|
+
content: Array<{
|
|
57
|
+
type: "text";
|
|
58
|
+
text: string;
|
|
59
|
+
}>;
|
|
60
|
+
isError?: boolean;
|
|
61
|
+
}>;
|
|
62
|
+
//# sourceMappingURL=plan-review.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-review.d.ts","sourceRoot":"","sources":["../../src/tools/plan-review.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,eAAO,MAAM,sBAAsB,aAAkC,CAAC;AAEtE,wBAAgB,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0B3C;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAoBhF"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { readdirSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { createLogger } from "@mclawnet/logger";
|
|
6
|
+
import { InboxStore } from "@mclawnet/swarm";
|
|
7
|
+
import { projectRoot } from "@mclawnet/task";
|
|
8
|
+
const log = createLogger({ module: "mcp-server/tools/plan-review" });
|
|
9
|
+
export const PLAN_REVIEW_TOOL_NAMES = new Set(["plan_review_submit"]);
|
|
10
|
+
export function getPlanReviewToolDefinitions() {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
name: "plan_review_submit",
|
|
14
|
+
description: "Submit a plan review verdict from the reviewer. Writes a plan_review_result " +
|
|
15
|
+
"message to the queen's inbox; the swarm coordinator intercepts it to update " +
|
|
16
|
+
"planStatus and forward a normalized plan_approved/plan_rejected message to the queen. " +
|
|
17
|
+
"Restricted to reviewer instances: caller must pass `from` starting with 'reviewer'.",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
workDir: { type: "string", description: "Absolute path of the project working directory" },
|
|
22
|
+
swarmId: { type: "string", description: "Swarm id this review belongs to" },
|
|
23
|
+
from: { type: "string", description: "Caller instance id; must start with 'reviewer'" },
|
|
24
|
+
verdict: {
|
|
25
|
+
type: "string",
|
|
26
|
+
enum: ["approved", "rejected"],
|
|
27
|
+
description: "Verdict",
|
|
28
|
+
},
|
|
29
|
+
body: { type: "string", description: "Optional reviewer commentary forwarded to queen" },
|
|
30
|
+
},
|
|
31
|
+
required: ["workDir", "swarmId", "from", "verdict"],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
export async function handlePlanReviewToolCall(name, args, context) {
|
|
37
|
+
try {
|
|
38
|
+
log.info({ tool: name }, "MCP plan-review tool called");
|
|
39
|
+
switch (name) {
|
|
40
|
+
case "plan_review_submit":
|
|
41
|
+
return await handlePlanReviewSubmit(args, context);
|
|
42
|
+
default:
|
|
43
|
+
return {
|
|
44
|
+
content: [{ type: "text", text: JSON.stringify({ error: `Unknown tool: ${name}` }) }],
|
|
45
|
+
isError: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
51
|
+
log.error({ tool: name, err }, "MCP plan-review tool error");
|
|
52
|
+
return {
|
|
53
|
+
content: [{ type: "text", text: JSON.stringify({ error: message }) }],
|
|
54
|
+
isError: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve the queen instanceId for a swarm by scanning its inboxes directory
|
|
60
|
+
* for a `queen-*.json` file. Returns the first match (alphabetical by readdir),
|
|
61
|
+
* or null when the directory is missing or contains no queen inbox.
|
|
62
|
+
*
|
|
63
|
+
* We use the existence of the inbox file (not a snapshot lookup) because the
|
|
64
|
+
* MCP server runs out-of-process from the agent and has no live access to
|
|
65
|
+
* `SwarmInstance.roles`. The inbox file is the durable handshake.
|
|
66
|
+
*/
|
|
67
|
+
function resolveQueenInstanceId(workDir, swarmId, rootDir) {
|
|
68
|
+
const home = rootDir ?? process.env.CLAWNET_HOME ?? homedir();
|
|
69
|
+
const dir = join(projectRoot(workDir, home), "swarms", swarmId, "inboxes");
|
|
70
|
+
let entries;
|
|
71
|
+
try {
|
|
72
|
+
entries = readdirSync(dir);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
for (const entry of entries) {
|
|
78
|
+
if (entry.startsWith("queen-") && entry.endsWith(".json")) {
|
|
79
|
+
return entry.slice(0, -".json".length);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
async function handlePlanReviewSubmit(args, context) {
|
|
85
|
+
const workDir = args.workDir;
|
|
86
|
+
const swarmId = args.swarmId;
|
|
87
|
+
const from = args.from;
|
|
88
|
+
const verdictRaw = args.verdict;
|
|
89
|
+
const body = args.body;
|
|
90
|
+
if (!workDir)
|
|
91
|
+
throw new Error("workDir is required");
|
|
92
|
+
if (!swarmId)
|
|
93
|
+
throw new Error("swarmId is required");
|
|
94
|
+
if (!from)
|
|
95
|
+
throw new Error("from is required");
|
|
96
|
+
if (verdictRaw !== "approved" && verdictRaw !== "rejected") {
|
|
97
|
+
throw new Error(`invalid verdict: ${verdictRaw}`);
|
|
98
|
+
}
|
|
99
|
+
const verdict = verdictRaw;
|
|
100
|
+
if (!from.startsWith("reviewer")) {
|
|
101
|
+
return {
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
type: "text",
|
|
105
|
+
text: JSON.stringify({ error: "Only reviewer instances may submit plan review" }),
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
isError: true,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const queenInstanceId = resolveQueenInstanceId(workDir, swarmId, context.rootDir);
|
|
112
|
+
if (!queenInstanceId) {
|
|
113
|
+
return {
|
|
114
|
+
content: [
|
|
115
|
+
{
|
|
116
|
+
type: "text",
|
|
117
|
+
text: JSON.stringify({ error: `No queen inbox found in swarm ${swarmId}` }),
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
isError: true,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const msg = {
|
|
124
|
+
id: randomUUID(),
|
|
125
|
+
from,
|
|
126
|
+
type: "plan_review_result",
|
|
127
|
+
data: JSON.stringify({ verdict, body: body ?? "" }),
|
|
128
|
+
timestamp: Date.now(),
|
|
129
|
+
delivered: false,
|
|
130
|
+
};
|
|
131
|
+
await new InboxStore(workDir, swarmId, context.rootDir).append(queenInstanceId, msg);
|
|
132
|
+
if (context.relay) {
|
|
133
|
+
try {
|
|
134
|
+
await context.relay.deliver(swarmId, queenInstanceId);
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
log.warn({ err, swarmId, queen: queenInstanceId }, "plan-review relay deliver failed (best-effort)");
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
content: [{ type: "text", text: JSON.stringify({ submitted: true, queen: queenInstanceId }) }],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=plan-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-review.js","sourceRoot":"","sources":["../../src/tools/plan-review.ts"],"names":[],"mappings":"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"}
|