@agent-workspace/mcp-server 0.2.1 → 0.5.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.
Files changed (54) hide show
  1. package/README.md +42 -5
  2. package/dist/index.d.ts +6 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +30 -568
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.test.d.ts +2 -0
  7. package/dist/index.test.d.ts.map +1 -0
  8. package/dist/index.test.js +726 -0
  9. package/dist/index.test.js.map +1 -0
  10. package/dist/tools/artifact.d.ts +6 -0
  11. package/dist/tools/artifact.d.ts.map +1 -0
  12. package/dist/tools/artifact.js +428 -0
  13. package/dist/tools/artifact.js.map +1 -0
  14. package/dist/tools/config.d.ts +6 -0
  15. package/dist/tools/config.d.ts.map +1 -0
  16. package/dist/tools/config.js +91 -0
  17. package/dist/tools/config.js.map +1 -0
  18. package/dist/tools/contract.d.ts +6 -0
  19. package/dist/tools/contract.d.ts.map +1 -0
  20. package/dist/tools/contract.js +233 -0
  21. package/dist/tools/contract.js.map +1 -0
  22. package/dist/tools/identity.d.ts +6 -0
  23. package/dist/tools/identity.d.ts.map +1 -0
  24. package/dist/tools/identity.js +91 -0
  25. package/dist/tools/identity.js.map +1 -0
  26. package/dist/tools/memory.d.ts +6 -0
  27. package/dist/tools/memory.d.ts.map +1 -0
  28. package/dist/tools/memory.js +145 -0
  29. package/dist/tools/memory.js.map +1 -0
  30. package/dist/tools/project.d.ts +6 -0
  31. package/dist/tools/project.d.ts.map +1 -0
  32. package/dist/tools/project.js +184 -0
  33. package/dist/tools/project.js.map +1 -0
  34. package/dist/tools/reputation.d.ts +6 -0
  35. package/dist/tools/reputation.d.ts.map +1 -0
  36. package/dist/tools/reputation.js +206 -0
  37. package/dist/tools/reputation.js.map +1 -0
  38. package/dist/tools/status.d.ts +6 -0
  39. package/dist/tools/status.d.ts.map +1 -0
  40. package/dist/tools/status.js +223 -0
  41. package/dist/tools/status.js.map +1 -0
  42. package/dist/tools/swarm.d.ts +6 -0
  43. package/dist/tools/swarm.d.ts.map +1 -0
  44. package/dist/tools/swarm.js +483 -0
  45. package/dist/tools/swarm.js.map +1 -0
  46. package/dist/tools/task.d.ts +6 -0
  47. package/dist/tools/task.d.ts.map +1 -0
  48. package/dist/tools/task.js +347 -0
  49. package/dist/tools/task.js.map +1 -0
  50. package/dist/utils.d.ts +23 -0
  51. package/dist/utils.d.ts.map +1 -0
  52. package/dist/utils.js +56 -0
  53. package/dist/utils.js.map +1 -0
  54. package/package.json +8 -2
@@ -0,0 +1,347 @@
1
+ import { readFile, writeFile, readdir, mkdir, access } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import matter from "gray-matter";
4
+ import * as z from "zod";
5
+ import { AWP_VERSION, CDP_VERSION, PROJECTS_DIR } from "@agent-workspace/core";
6
+ import { getWorkspaceRoot, getAgentDid, analyzeGraph, getTaskSlug, } from "@agent-workspace/utils";
7
+ /**
8
+ * Check if a file exists at the given path.
9
+ */
10
+ async function fileExists(path) {
11
+ try {
12
+ await access(path);
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ /**
20
+ * Register task-related tools: create, update, list
21
+ */
22
+ export function registerTaskTools(server) {
23
+ // --- Tool: awp_task_create ---
24
+ server.registerTool("awp_task_create", {
25
+ title: "Create Task",
26
+ description: "Create a new task within a project.",
27
+ inputSchema: {
28
+ projectSlug: z.string().describe("Project slug"),
29
+ taskSlug: z.string().describe("Task slug"),
30
+ title: z.string().optional().describe("Task title"),
31
+ assignee: z.string().optional().describe("Assignee agent DID"),
32
+ assigneeSlug: z.string().optional().describe("Assignee reputation profile slug"),
33
+ priority: z.string().optional().describe("Priority (low, medium, high, critical)"),
34
+ deadline: z.string().optional().describe("Deadline (ISO 8601 or YYYY-MM-DD)"),
35
+ blockedBy: z.array(z.string()).optional().describe("Task IDs that block this task"),
36
+ outputArtifact: z.string().optional().describe("Output artifact slug"),
37
+ contractSlug: z.string().optional().describe("Associated contract slug"),
38
+ tags: z.array(z.string()).optional().describe("Tags"),
39
+ },
40
+ }, async ({ projectSlug, taskSlug, title, assignee, assigneeSlug, priority, deadline, blockedBy, outputArtifact, contractSlug, tags, }) => {
41
+ const root = getWorkspaceRoot();
42
+ // Check project exists
43
+ const projPath = join(root, PROJECTS_DIR, `${projectSlug}.md`);
44
+ let projData;
45
+ try {
46
+ const raw = await readFile(projPath, "utf-8");
47
+ projData = matter(raw);
48
+ }
49
+ catch {
50
+ return {
51
+ content: [{ type: "text", text: `Project "${projectSlug}" not found.` }],
52
+ isError: true,
53
+ };
54
+ }
55
+ const taskDir = join(root, PROJECTS_DIR, projectSlug, "tasks");
56
+ await mkdir(taskDir, { recursive: true });
57
+ const taskPath = join(taskDir, `${taskSlug}.md`);
58
+ if (await fileExists(taskPath)) {
59
+ return {
60
+ content: [
61
+ {
62
+ type: "text",
63
+ text: `Task "${taskSlug}" already exists in project "${projectSlug}".`,
64
+ },
65
+ ],
66
+ isError: true,
67
+ };
68
+ }
69
+ const did = await getAgentDid(root);
70
+ const now = new Date().toISOString();
71
+ const taskTitle = title ||
72
+ taskSlug
73
+ .split("-")
74
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
75
+ .join(" ");
76
+ const data = {
77
+ awp: AWP_VERSION,
78
+ cdp: CDP_VERSION,
79
+ type: "task",
80
+ id: `task:${projectSlug}/${taskSlug}`,
81
+ projectId: `project:${projectSlug}`,
82
+ title: taskTitle,
83
+ status: "pending",
84
+ priority: priority || "medium",
85
+ created: now,
86
+ blockedBy: blockedBy || [],
87
+ blocks: [],
88
+ lastModified: now,
89
+ modifiedBy: did,
90
+ };
91
+ if (assignee)
92
+ data.assignee = assignee;
93
+ if (assigneeSlug)
94
+ data.assigneeSlug = assigneeSlug;
95
+ if (deadline)
96
+ data.deadline = deadline;
97
+ if (outputArtifact)
98
+ data.outputArtifact = outputArtifact;
99
+ if (contractSlug)
100
+ data.contractSlug = contractSlug;
101
+ if (tags?.length)
102
+ data.tags = tags;
103
+ const body = `\n# ${taskTitle}\n\n`;
104
+ const output = matter.stringify(body, data);
105
+ await writeFile(taskPath, output, "utf-8");
106
+ // Update project counts
107
+ projData.data.taskCount = (projData.data.taskCount || 0) + 1;
108
+ const projOutput = matter.stringify(projData.content, projData.data);
109
+ await writeFile(projPath, projOutput, "utf-8");
110
+ return {
111
+ content: [
112
+ {
113
+ type: "text",
114
+ text: `Created task "${taskSlug}" in project "${projectSlug}" (status: pending)`,
115
+ },
116
+ ],
117
+ };
118
+ });
119
+ // --- Tool: awp_task_update ---
120
+ server.registerTool("awp_task_update", {
121
+ title: "Update Task",
122
+ description: "Update a task's status, assignee, or other fields.",
123
+ inputSchema: {
124
+ projectSlug: z.string().describe("Project slug"),
125
+ taskSlug: z.string().describe("Task slug"),
126
+ status: z
127
+ .string()
128
+ .optional()
129
+ .describe("New status (pending, in-progress, blocked, review, completed, cancelled)"),
130
+ assignee: z.string().optional().describe("New assignee DID"),
131
+ assigneeSlug: z.string().optional().describe("New assignee reputation slug"),
132
+ },
133
+ }, async ({ projectSlug, taskSlug, status: newStatus, assignee, assigneeSlug }) => {
134
+ const root = getWorkspaceRoot();
135
+ const taskPath = join(root, PROJECTS_DIR, projectSlug, "tasks", `${taskSlug}.md`);
136
+ let taskData;
137
+ try {
138
+ const raw = await readFile(taskPath, "utf-8");
139
+ taskData = matter(raw);
140
+ }
141
+ catch {
142
+ return {
143
+ content: [
144
+ {
145
+ type: "text",
146
+ text: `Task "${taskSlug}" not found in project "${projectSlug}".`,
147
+ },
148
+ ],
149
+ isError: true,
150
+ };
151
+ }
152
+ const did = await getAgentDid(root);
153
+ const now = new Date().toISOString();
154
+ const changes = [];
155
+ if (newStatus) {
156
+ taskData.data.status = newStatus;
157
+ changes.push(`status → ${newStatus}`);
158
+ }
159
+ if (assignee) {
160
+ taskData.data.assignee = assignee;
161
+ changes.push(`assignee → ${assignee}`);
162
+ }
163
+ if (assigneeSlug) {
164
+ taskData.data.assigneeSlug = assigneeSlug;
165
+ changes.push(`assigneeSlug → ${assigneeSlug}`);
166
+ }
167
+ taskData.data.lastModified = now;
168
+ taskData.data.modifiedBy = did;
169
+ const output = matter.stringify(taskData.content, taskData.data);
170
+ await writeFile(taskPath, output, "utf-8");
171
+ // Update project counts if status changed
172
+ if (newStatus) {
173
+ const projPath = join(root, PROJECTS_DIR, `${projectSlug}.md`);
174
+ try {
175
+ const projRaw = await readFile(projPath, "utf-8");
176
+ const projData = matter(projRaw);
177
+ // Recount completed tasks
178
+ const taskDir = join(root, PROJECTS_DIR, projectSlug, "tasks");
179
+ let taskCount = 0;
180
+ let completedCount = 0;
181
+ try {
182
+ const taskFiles = await readdir(taskDir);
183
+ for (const tf of taskFiles.filter((t) => t.endsWith(".md"))) {
184
+ try {
185
+ const tRaw = await readFile(join(taskDir, tf), "utf-8");
186
+ const { data: tData } = matter(tRaw);
187
+ if (tData.type === "task") {
188
+ taskCount++;
189
+ if (tData.status === "completed")
190
+ completedCount++;
191
+ }
192
+ }
193
+ catch {
194
+ /* skip */
195
+ }
196
+ }
197
+ }
198
+ catch {
199
+ /* no tasks */
200
+ }
201
+ projData.data.taskCount = taskCount;
202
+ projData.data.completedCount = completedCount;
203
+ const projOutput = matter.stringify(projData.content, projData.data);
204
+ await writeFile(projPath, projOutput, "utf-8");
205
+ }
206
+ catch {
207
+ /* project not found */
208
+ }
209
+ }
210
+ return {
211
+ content: [
212
+ { type: "text", text: `Updated task "${taskSlug}": ${changes.join(", ")}` },
213
+ ],
214
+ };
215
+ });
216
+ // --- Tool: awp_task_list ---
217
+ server.registerTool("awp_task_list", {
218
+ title: "List Tasks",
219
+ description: "List all tasks for a project with optional status and assignee filters.",
220
+ inputSchema: {
221
+ projectSlug: z.string().describe("Project slug"),
222
+ status: z.string().optional().describe("Filter by status"),
223
+ assigneeSlug: z.string().optional().describe("Filter by assignee slug"),
224
+ },
225
+ }, async ({ projectSlug, status: statusFilter, assigneeSlug }) => {
226
+ const root = getWorkspaceRoot();
227
+ const taskDir = join(root, PROJECTS_DIR, projectSlug, "tasks");
228
+ let files;
229
+ try {
230
+ files = await readdir(taskDir);
231
+ }
232
+ catch {
233
+ return {
234
+ content: [{ type: "text", text: JSON.stringify({ tasks: [] }, null, 2) }],
235
+ };
236
+ }
237
+ const tasks = [];
238
+ for (const f of files.filter((f) => f.endsWith(".md")).sort()) {
239
+ try {
240
+ const raw = await readFile(join(taskDir, f), "utf-8");
241
+ const { data } = matter(raw);
242
+ if (data.type !== "task")
243
+ continue;
244
+ if (statusFilter && data.status !== statusFilter)
245
+ continue;
246
+ if (assigneeSlug && data.assigneeSlug !== assigneeSlug)
247
+ continue;
248
+ const blockedBy = data.blockedBy;
249
+ const blocks = data.blocks;
250
+ tasks.push({
251
+ slug: f.replace(/\.md$/, ""),
252
+ title: data.title,
253
+ status: data.status,
254
+ assigneeSlug: data.assigneeSlug,
255
+ priority: data.priority,
256
+ deadline: data.deadline,
257
+ blockedBy: blockedBy || [],
258
+ blocks: blocks || [],
259
+ });
260
+ }
261
+ catch {
262
+ /* skip */
263
+ }
264
+ }
265
+ return {
266
+ content: [{ type: "text", text: JSON.stringify({ tasks }, null, 2) }],
267
+ };
268
+ });
269
+ // --- Tool: awp_task_graph ---
270
+ server.registerTool("awp_task_graph", {
271
+ title: "Analyze Task Dependencies",
272
+ description: "Analyze task dependency graph: topological order, cycles, critical path, blocked tasks",
273
+ inputSchema: {
274
+ projectSlug: z.string().describe("Project slug"),
275
+ },
276
+ }, async ({ projectSlug }) => {
277
+ const root = getWorkspaceRoot();
278
+ const taskDir = join(root, PROJECTS_DIR, projectSlug, "tasks");
279
+ // Load all tasks
280
+ let files;
281
+ try {
282
+ files = await readdir(taskDir);
283
+ }
284
+ catch {
285
+ return {
286
+ content: [
287
+ {
288
+ type: "text",
289
+ text: JSON.stringify({
290
+ error: `No tasks found for project "${projectSlug}"`,
291
+ isValid: true,
292
+ sorted: [],
293
+ cycles: [],
294
+ criticalPath: [],
295
+ blocked: {},
296
+ }, null, 2),
297
+ },
298
+ ],
299
+ };
300
+ }
301
+ const taskNodes = [];
302
+ for (const f of files.filter((f) => f.endsWith(".md")).sort()) {
303
+ try {
304
+ const raw = await readFile(join(taskDir, f), "utf-8");
305
+ const { data } = matter(raw);
306
+ if (data.type !== "task")
307
+ continue;
308
+ const blockedBy = data.blockedBy;
309
+ const blocks = data.blocks;
310
+ taskNodes.push({
311
+ id: data.id,
312
+ blockedBy: blockedBy || [],
313
+ blocks: blocks || [],
314
+ status: data.status,
315
+ });
316
+ }
317
+ catch {
318
+ /* skip */
319
+ }
320
+ }
321
+ // Run graph analysis
322
+ const analysis = analyzeGraph(taskNodes);
323
+ // Format output
324
+ const result = {
325
+ projectSlug,
326
+ taskCount: taskNodes.length,
327
+ isValid: analysis.isValid,
328
+ sorted: analysis.sorted?.map((id) => ({
329
+ id,
330
+ slug: getTaskSlug(id),
331
+ })),
332
+ cycles: analysis.cycles.map((cycle) => cycle.map((id) => getTaskSlug(id))),
333
+ criticalPath: analysis.criticalPath.map((id) => ({
334
+ id,
335
+ slug: getTaskSlug(id),
336
+ })),
337
+ blocked: Object.fromEntries(Array.from(analysis.blocked.entries()).map(([taskId, blockers]) => [
338
+ getTaskSlug(taskId),
339
+ blockers.map((b) => getTaskSlug(b)),
340
+ ])),
341
+ };
342
+ return {
343
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
344
+ };
345
+ });
346
+ }
347
+ //# sourceMappingURL=task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/tools/task.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Security and validation utilities for the AWP MCP server.
3
+ * Extracted to allow unit testing without server initialization side effects.
4
+ */
5
+ /** Maximum file size allowed (1MB) */
6
+ export declare const MAX_FILE_SIZE: number;
7
+ /** Pattern for valid slugs */
8
+ export declare const SLUG_PATTERN: RegExp;
9
+ /**
10
+ * Validate that a path is within the workspace root (prevents directory traversal).
11
+ * Returns the normalized absolute path if valid, or throws an error.
12
+ */
13
+ export declare function validatePath(root: string, targetPath: string): string;
14
+ /**
15
+ * Validate and sanitize a slug.
16
+ * Slugs must be lowercase alphanumeric with hyphens, not starting with hyphen.
17
+ */
18
+ export declare function validateSlug(slug: string): string;
19
+ /**
20
+ * Read a file with size limit check.
21
+ */
22
+ export declare function safeReadFile(path: string): Promise<string>;
23
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,sCAAsC;AACtC,eAAO,MAAM,aAAa,QAAc,CAAC;AAEzC,8BAA8B;AAC9B,eAAO,MAAM,YAAY,QAAyB,CAAC;AAMnD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAUrE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYjD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMhE"}
package/dist/utils.js ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Security and validation utilities for the AWP MCP server.
3
+ * Extracted to allow unit testing without server initialization side effects.
4
+ */
5
+ import { stat } from "node:fs/promises";
6
+ import { readFile } from "node:fs/promises";
7
+ import { resolve, relative, isAbsolute } from "node:path";
8
+ // =============================================================================
9
+ // Security Constants
10
+ // =============================================================================
11
+ /** Maximum file size allowed (1MB) */
12
+ export const MAX_FILE_SIZE = 1024 * 1024;
13
+ /** Pattern for valid slugs */
14
+ export const SLUG_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
15
+ // =============================================================================
16
+ // Security Utilities
17
+ // =============================================================================
18
+ /**
19
+ * Validate that a path is within the workspace root (prevents directory traversal).
20
+ * Returns the normalized absolute path if valid, or throws an error.
21
+ */
22
+ export function validatePath(root, targetPath) {
23
+ const normalized = resolve(root, targetPath);
24
+ const rel = relative(root, normalized);
25
+ // Prevent directory traversal
26
+ if (rel.startsWith("..") || isAbsolute(rel)) {
27
+ throw new Error(`Path traversal detected: ${targetPath}`);
28
+ }
29
+ return normalized;
30
+ }
31
+ /**
32
+ * Validate and sanitize a slug.
33
+ * Slugs must be lowercase alphanumeric with hyphens, not starting with hyphen.
34
+ */
35
+ export function validateSlug(slug) {
36
+ const trimmed = slug.trim().toLowerCase();
37
+ if (!SLUG_PATTERN.test(trimmed)) {
38
+ throw new Error(`Invalid slug: "${slug}". Must be lowercase alphanumeric with hyphens, not starting with hyphen.`);
39
+ }
40
+ // Additional safety: limit length
41
+ if (trimmed.length > 100) {
42
+ throw new Error(`Slug too long: max 100 characters`);
43
+ }
44
+ return trimmed;
45
+ }
46
+ /**
47
+ * Read a file with size limit check.
48
+ */
49
+ export async function safeReadFile(path) {
50
+ const stats = await stat(path);
51
+ if (stats.size > MAX_FILE_SIZE) {
52
+ throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE})`);
53
+ }
54
+ return readFile(path, "utf-8");
55
+ }
56
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE1D,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEhF,sCAAsC;AACtC,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzC,8BAA8B;AAC9B,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAEnD,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,UAAkB;IAC3D,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAEvC,8BAA8B;IAC9B,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,4BAA4B,UAAU,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,kBAAkB,IAAI,2EAA2E,CAClG,CAAC;IACJ,CAAC;IACD,kCAAkC;IAClC,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,IAAI,GAAG,aAAa,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,CAAC,IAAI,gBAAgB,aAAa,GAAG,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-workspace/mcp-server",
3
- "version": "0.2.1",
3
+ "version": "0.5.0",
4
4
  "description": "MCP server exposing Agent Workspace Protocol operations — plug any AWP workspace into any MCP client",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -35,12 +35,18 @@
35
35
  "scripts": {
36
36
  "build": "tsc",
37
37
  "dev": "tsc --watch",
38
+ "lint": "eslint src/",
39
+ "test": "vitest run",
40
+ "test:watch": "vitest",
38
41
  "typecheck": "tsc --noEmit",
39
42
  "prepublishOnly": "npm run build"
40
43
  },
41
44
  "dependencies": {
42
- "@agent-workspace/core": "0.2.1",
45
+ "@agent-workspace/core": "0.5.0",
46
+ "@agent-workspace/utils": "0.5.0",
43
47
  "@modelcontextprotocol/sdk": "^1.0.0",
48
+ "ajv": "^8.17.1",
49
+ "ajv-formats": "^3.0.1",
44
50
  "gray-matter": "^4.0.3",
45
51
  "zod": "^4.3.6"
46
52
  },