@mandujs/mcp 0.37.3 → 0.37.4

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.
@@ -0,0 +1,443 @@
1
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
+ import path from "path";
3
+ import {
4
+ buildAgentApplyReport,
5
+ buildAgentContext,
6
+ buildAgentPlan,
7
+ buildAgentRepairReport,
8
+ buildAgentSyncReport,
9
+ buildAgentVerifyReport,
10
+ writeAgentApplyReport,
11
+ writeAgentManifest,
12
+ writeAgentPlan,
13
+ writeAgentRepairReport,
14
+ writeAgentVerifyReport,
15
+ } from "@mandujs/core/agent";
16
+
17
+ interface AgentContextInput {
18
+ cwd?: unknown;
19
+ includeDiagnose?: unknown;
20
+ includeGit?: unknown;
21
+ writeManifest?: unknown;
22
+ }
23
+
24
+ interface AgentVerifyInput {
25
+ cwd?: unknown;
26
+ changedOnly?: unknown;
27
+ includeDiagnose?: unknown;
28
+ includeGit?: unknown;
29
+ includeGuard?: unknown;
30
+ includeContract?: unknown;
31
+ staged?: unknown;
32
+ base?: unknown;
33
+ writeReport?: unknown;
34
+ }
35
+
36
+ interface AgentPlanInput {
37
+ cwd?: unknown;
38
+ intent?: unknown;
39
+ writePlan?: unknown;
40
+ }
41
+
42
+ interface AgentApplyInput {
43
+ cwd?: unknown;
44
+ from?: unknown;
45
+ dryRun?: unknown;
46
+ writeReport?: unknown;
47
+ }
48
+
49
+ interface AgentSyncInput {
50
+ cwd?: unknown;
51
+ target?: unknown;
52
+ dryRun?: unknown;
53
+ }
54
+
55
+ interface AgentRepairInput {
56
+ cwd?: unknown;
57
+ from?: unknown;
58
+ apply?: unknown;
59
+ writeReport?: unknown;
60
+ }
61
+
62
+ function boolOrDefault(value: unknown, fallback: boolean): boolean {
63
+ if (value === undefined) return fallback;
64
+ if (typeof value === "boolean") return value;
65
+ return fallback;
66
+ }
67
+
68
+ function resolveCwd(projectRoot: string, value: unknown): string {
69
+ const root = path.resolve(projectRoot);
70
+ const resolved =
71
+ typeof value === "string" && value.length > 0
72
+ ? path.resolve(root, value)
73
+ : root;
74
+ if (resolved !== root && !resolved.startsWith(root + path.sep)) {
75
+ throw new Error("cwd must stay inside the MCP project root");
76
+ }
77
+ return resolved;
78
+ }
79
+
80
+ async function runAgentContext(
81
+ projectRoot: string,
82
+ input: AgentContextInput,
83
+ ) {
84
+ const cwd = resolveCwd(projectRoot, input.cwd);
85
+ const context = await buildAgentContext(cwd, {
86
+ includeDiagnose: boolOrDefault(input.includeDiagnose, true),
87
+ includeGit: boolOrDefault(input.includeGit, true),
88
+ });
89
+
90
+ if (boolOrDefault(input.writeManifest, false)) {
91
+ const { path, manifest } = await writeAgentManifest(cwd, context);
92
+ return {
93
+ ...context,
94
+ manifest: {
95
+ path,
96
+ written: true,
97
+ schemaVersion: manifest.schemaVersion,
98
+ },
99
+ };
100
+ }
101
+
102
+ return context;
103
+ }
104
+
105
+ async function runAgentPlan(
106
+ projectRoot: string,
107
+ input: AgentPlanInput,
108
+ ) {
109
+ const cwd = resolveCwd(projectRoot, input.cwd);
110
+ const intent = typeof input.intent === "string" ? input.intent.trim() : "";
111
+ if (!intent) {
112
+ throw new Error("intent is required for mandu.agent.plan");
113
+ }
114
+
115
+ const plan = buildAgentPlan({ intent });
116
+
117
+ if (boolOrDefault(input.writePlan, false)) {
118
+ const { path, plan: written } = await writeAgentPlan(cwd, plan);
119
+ return {
120
+ ...written,
121
+ plan: {
122
+ path,
123
+ written: true,
124
+ schemaVersion: written.schemaVersion,
125
+ },
126
+ };
127
+ }
128
+
129
+ return plan;
130
+ }
131
+
132
+ async function runAgentApply(
133
+ projectRoot: string,
134
+ input: AgentApplyInput,
135
+ ) {
136
+ const cwd = resolveCwd(projectRoot, input.cwd);
137
+ const report = await buildAgentApplyReport(cwd, {
138
+ from: typeof input.from === "string" && input.from.length > 0 ? input.from : undefined,
139
+ dryRun: boolOrDefault(input.dryRun, true),
140
+ });
141
+
142
+ if (boolOrDefault(input.writeReport, false)) {
143
+ const { path, report: written } = await writeAgentApplyReport(cwd, report);
144
+ return {
145
+ ...written,
146
+ report: {
147
+ path,
148
+ written: true,
149
+ schemaVersion: written.schemaVersion,
150
+ },
151
+ };
152
+ }
153
+
154
+ return report;
155
+ }
156
+
157
+ async function runAgentVerify(
158
+ projectRoot: string,
159
+ input: AgentVerifyInput,
160
+ ) {
161
+ const cwd = resolveCwd(projectRoot, input.cwd);
162
+ const report = await buildAgentVerifyReport(cwd, {
163
+ changedOnly: boolOrDefault(input.changedOnly, true),
164
+ includeDiagnose: boolOrDefault(input.includeDiagnose, true),
165
+ includeGit: boolOrDefault(input.includeGit, true),
166
+ includeGuard: boolOrDefault(input.includeGuard, true),
167
+ includeContract: boolOrDefault(input.includeContract, true),
168
+ staged: boolOrDefault(input.staged, false),
169
+ base: typeof input.base === "string" && input.base.length > 0 ? input.base : undefined,
170
+ });
171
+
172
+ if (boolOrDefault(input.writeReport, false)) {
173
+ const { path, report: written } = await writeAgentVerifyReport(cwd, report);
174
+ return {
175
+ ...written,
176
+ report: {
177
+ path,
178
+ written: true,
179
+ schemaVersion: written.schemaVersion,
180
+ },
181
+ };
182
+ }
183
+
184
+ return report;
185
+ }
186
+
187
+ async function runAgentRepair(
188
+ projectRoot: string,
189
+ input: AgentRepairInput,
190
+ ) {
191
+ const cwd = resolveCwd(projectRoot, input.cwd);
192
+ const report = await buildAgentRepairReport(cwd, {
193
+ from: typeof input.from === "string" && input.from.length > 0 ? input.from : undefined,
194
+ apply: boolOrDefault(input.apply, false),
195
+ });
196
+
197
+ if (boolOrDefault(input.writeReport, false)) {
198
+ const { path, report: written } = await writeAgentRepairReport(cwd, report);
199
+ return {
200
+ ...written,
201
+ report: {
202
+ path,
203
+ written: true,
204
+ schemaVersion: written.schemaVersion,
205
+ },
206
+ };
207
+ }
208
+
209
+ return report;
210
+ }
211
+
212
+ async function runAgentSync(
213
+ projectRoot: string,
214
+ input: AgentSyncInput,
215
+ ) {
216
+ const cwd = resolveCwd(projectRoot, input.cwd);
217
+ const target =
218
+ input.target === "codex" ||
219
+ input.target === "claude" ||
220
+ input.target === "gemini" ||
221
+ input.target === "all"
222
+ ? input.target
223
+ : "all";
224
+ return buildAgentSyncReport(cwd, {
225
+ target,
226
+ dryRun: boolOrDefault(input.dryRun, false),
227
+ });
228
+ }
229
+
230
+ export const agentToolDefinitions: Tool[] = [
231
+ {
232
+ name: "mandu.agent.context",
233
+ description:
234
+ "Official agent-core entry point. Returns one structured project context for Codex/Claude/Gemini: project metadata, routes/APIs, partials/islands, slots/contracts, guard summary, diagnostics, git state, and the canonical context -> plan -> apply -> verify -> repair workflow.",
235
+ annotations: {
236
+ readOnlyHint: true,
237
+ },
238
+ inputSchema: {
239
+ type: "object",
240
+ properties: {
241
+ cwd: {
242
+ type: "string",
243
+ description: "Project directory to inspect. Defaults to the MCP project root.",
244
+ },
245
+ includeDiagnose: {
246
+ type: "boolean",
247
+ description: "Include diagnose summary and normalized diagnostics. Defaults to true.",
248
+ },
249
+ includeGit: {
250
+ type: "boolean",
251
+ description: "Include git branch and changed-file summary. Defaults to true.",
252
+ },
253
+ writeManifest: {
254
+ type: "boolean",
255
+ description:
256
+ "Write .mandu/agent-manifest.json while building context. Defaults to false.",
257
+ },
258
+ },
259
+ required: [],
260
+ },
261
+ },
262
+ {
263
+ name: "mandu.agent.plan",
264
+ description:
265
+ "Official agent-core planning entry point. Converts a natural-language Mandu task into a conservative domain plan with files to inspect, files likely to create, preferred MCP/domain tools, risks, and verification commands.",
266
+ annotations: {
267
+ readOnlyHint: true,
268
+ },
269
+ inputSchema: {
270
+ type: "object",
271
+ properties: {
272
+ cwd: {
273
+ type: "string",
274
+ description: "Project directory to plan against. Defaults to the MCP project root.",
275
+ },
276
+ intent: {
277
+ type: "string",
278
+ description: "Natural-language task request, for example: add authenticated dashboard.",
279
+ },
280
+ writePlan: {
281
+ type: "boolean",
282
+ description: "Write .mandu/agent-plan.json while planning. Defaults to false.",
283
+ },
284
+ },
285
+ required: ["intent"],
286
+ },
287
+ },
288
+ {
289
+ name: "mandu.agent.apply",
290
+ description:
291
+ "Official agent-core apply preview. Reads an agent plan and returns ordered intent-level actions. This initial implementation is dry-run only and does not mutate project files.",
292
+ annotations: {
293
+ readOnlyHint: true,
294
+ },
295
+ inputSchema: {
296
+ type: "object",
297
+ properties: {
298
+ cwd: {
299
+ type: "string",
300
+ description: "Project directory. Defaults to the MCP project root.",
301
+ },
302
+ from: {
303
+ type: "string",
304
+ description: "Plan path relative to cwd. Defaults to .mandu/agent-plan.json.",
305
+ },
306
+ dryRun: {
307
+ type: "boolean",
308
+ description: "Return a dry-run action report. Defaults to true.",
309
+ },
310
+ writeReport: {
311
+ type: "boolean",
312
+ description: "Write .mandu/agent-apply.json. Defaults to false.",
313
+ },
314
+ },
315
+ required: [],
316
+ },
317
+ },
318
+ {
319
+ name: "mandu.agent.verify",
320
+ description:
321
+ "Official agent-core verification entry point. Returns one structured report that combines changed files, diagnose, route manifest, guard, contract consistency, normalized diagnostics, and suggested follow-up commands.",
322
+ annotations: {
323
+ readOnlyHint: true,
324
+ },
325
+ inputSchema: {
326
+ type: "object",
327
+ properties: {
328
+ cwd: {
329
+ type: "string",
330
+ description: "Project directory to verify. Defaults to the MCP project root.",
331
+ },
332
+ changedOnly: {
333
+ type: "boolean",
334
+ description: "Filter guard/contract findings to changed files when git data exists. Defaults to true.",
335
+ },
336
+ includeDiagnose: {
337
+ type: "boolean",
338
+ description: "Run diagnose and include normalized diagnose diagnostics. Defaults to true.",
339
+ },
340
+ includeGit: {
341
+ type: "boolean",
342
+ description: "Collect git changed files. Defaults to true.",
343
+ },
344
+ includeGuard: {
345
+ type: "boolean",
346
+ description: "Run architecture guard if the routes manifest is available. Defaults to true.",
347
+ },
348
+ includeContract: {
349
+ type: "boolean",
350
+ description: "Run contract/slot consistency checks if the routes manifest is available. Defaults to true.",
351
+ },
352
+ staged: {
353
+ type: "boolean",
354
+ description: "Use staged changes only. Defaults to false.",
355
+ },
356
+ base: {
357
+ type: "string",
358
+ description: "Optional git base ref for changed-file detection.",
359
+ },
360
+ writeReport: {
361
+ type: "boolean",
362
+ description: "Write .mandu/agent-verify.json while verifying. Defaults to false.",
363
+ },
364
+ },
365
+ required: [],
366
+ },
367
+ },
368
+ {
369
+ name: "mandu.agent.repair",
370
+ description:
371
+ "Official agent-core repair entry point. Reads an agent verify report and returns structured next actions. It does not execute shell commands; apply mode only handles safe typed patch candidates.",
372
+ annotations: {
373
+ readOnlyHint: false,
374
+ },
375
+ inputSchema: {
376
+ type: "object",
377
+ properties: {
378
+ cwd: {
379
+ type: "string",
380
+ description: "Project directory. Defaults to the MCP project root.",
381
+ },
382
+ from: {
383
+ type: "string",
384
+ description: "Verify report path relative to cwd. Defaults to .mandu/agent-verify.json.",
385
+ },
386
+ apply: {
387
+ type: "boolean",
388
+ description: "Apply safe typed patch candidates only. Defaults to false.",
389
+ },
390
+ writeReport: {
391
+ type: "boolean",
392
+ description: "Write .mandu/agent-repair.json. Defaults to false.",
393
+ },
394
+ },
395
+ required: [],
396
+ },
397
+ },
398
+ {
399
+ name: "mandu.agent.sync",
400
+ description:
401
+ "Official agent sync helper. Writes or previews Codex, Claude Code, and Gemini CLI workflow artifacts under .mandu/agent-sync so each agent follows the same Mandu agent loop and MCP profile guidance.",
402
+ annotations: {
403
+ readOnlyHint: false,
404
+ },
405
+ inputSchema: {
406
+ type: "object",
407
+ properties: {
408
+ cwd: {
409
+ type: "string",
410
+ description: "Project directory. Defaults to the MCP project root.",
411
+ },
412
+ target: {
413
+ type: "string",
414
+ enum: ["codex", "claude", "gemini", "all"],
415
+ description: "Agent target to sync. Defaults to all.",
416
+ },
417
+ dryRun: {
418
+ type: "boolean",
419
+ description: "Preview files without writing. Defaults to false.",
420
+ },
421
+ },
422
+ required: [],
423
+ },
424
+ },
425
+ ];
426
+
427
+ export function agentTools(projectRoot: string) {
428
+ const handlers: Record<string, (args: Record<string, unknown>) => Promise<unknown>> = {
429
+ "mandu.agent.context": async (args) =>
430
+ runAgentContext(projectRoot, args as AgentContextInput),
431
+ "mandu.agent.plan": async (args) =>
432
+ runAgentPlan(projectRoot, args as AgentPlanInput),
433
+ "mandu.agent.apply": async (args) =>
434
+ runAgentApply(projectRoot, args as AgentApplyInput),
435
+ "mandu.agent.verify": async (args) =>
436
+ runAgentVerify(projectRoot, args as AgentVerifyInput),
437
+ "mandu.agent.repair": async (args) =>
438
+ runAgentRepair(projectRoot, args as AgentRepairInput),
439
+ "mandu.agent.sync": async (args) =>
440
+ runAgentSync(projectRoot, args as AgentSyncInput),
441
+ };
442
+ return handlers;
443
+ }
@@ -11,8 +11,9 @@ import { mcpToolRegistry } from "../registry/mcp-tool-registry.js";
11
11
  import { moduleToPlugins } from "../adapters/tool-adapter.js";
12
12
  import { type McpProfile, getProfileCategories } from "../profiles.js";
13
13
 
14
- // 도구 모듈 export
15
- export { specTools, specToolDefinitions } from "./spec.js";
14
+ // 도구 모듈 export
15
+ export { agentTools, agentToolDefinitions } from "./agent.js";
16
+ export { specTools, specToolDefinitions } from "./spec.js";
16
17
  export { generateTools, generateToolDefinitions } from "./generate.js";
17
18
  export { transactionTools, transactionToolDefinitions } from "./transaction.js";
18
19
  export { historyTools, historyToolDefinitions } from "./history.js";
@@ -85,8 +86,9 @@ export {
85
86
  extractContractToolDefinitions,
86
87
  } from "./extract-contract.js";
87
88
 
88
- // 도구 모듈 import (등록용)
89
- import { specTools, specToolDefinitions } from "./spec.js";
89
+ // 도구 모듈 import (등록용)
90
+ import { agentTools, agentToolDefinitions } from "./agent.js";
91
+ import { specTools, specToolDefinitions } from "./spec.js";
90
92
  import { generateTools, generateToolDefinitions } from "./generate.js";
91
93
  import { transactionTools, transactionToolDefinitions } from "./transaction.js";
92
94
  import { historyTools, historyToolDefinitions } from "./history.js";
@@ -189,7 +191,8 @@ export interface ToolModule {
189
191
  * 빌트인 도구 모듈 목록
190
192
  */
191
193
  export const TOOL_MODULES: ToolModule[] = [
192
- { category: "spec", definitions: specToolDefinitions, handlers: specTools },
194
+ { category: "agent", definitions: agentToolDefinitions, handlers: agentTools },
195
+ { category: "spec", definitions: specToolDefinitions, handlers: specTools },
193
196
  { category: "generate", definitions: generateToolDefinitions, handlers: generateTools },
194
197
  { category: "transaction", definitions: transactionToolDefinitions, handlers: transactionTools },
195
198
  { category: "history", definitions: historyToolDefinitions, handlers: historyTools },