@agent-workspace/mcp-server 0.4.0 → 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.
- package/dist/index.d.ts +5 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -1836
- package/dist/index.js.map +1 -1
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +726 -0
- package/dist/index.test.js.map +1 -0
- package/dist/tools/artifact.d.ts +6 -0
- package/dist/tools/artifact.d.ts.map +1 -0
- package/dist/tools/artifact.js +428 -0
- package/dist/tools/artifact.js.map +1 -0
- package/dist/tools/config.d.ts +6 -0
- package/dist/tools/config.d.ts.map +1 -0
- package/dist/tools/config.js +91 -0
- package/dist/tools/config.js.map +1 -0
- package/dist/tools/contract.d.ts +6 -0
- package/dist/tools/contract.d.ts.map +1 -0
- package/dist/tools/contract.js +233 -0
- package/dist/tools/contract.js.map +1 -0
- package/dist/tools/identity.d.ts +6 -0
- package/dist/tools/identity.d.ts.map +1 -0
- package/dist/tools/identity.js +91 -0
- package/dist/tools/identity.js.map +1 -0
- package/dist/tools/memory.d.ts +6 -0
- package/dist/tools/memory.d.ts.map +1 -0
- package/dist/tools/memory.js +145 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/project.d.ts +6 -0
- package/dist/tools/project.d.ts.map +1 -0
- package/dist/tools/project.js +184 -0
- package/dist/tools/project.js.map +1 -0
- package/dist/tools/reputation.d.ts +6 -0
- package/dist/tools/reputation.d.ts.map +1 -0
- package/dist/tools/reputation.js +206 -0
- package/dist/tools/reputation.js.map +1 -0
- package/dist/tools/status.d.ts +6 -0
- package/dist/tools/status.d.ts.map +1 -0
- package/dist/tools/status.js +223 -0
- package/dist/tools/status.js.map +1 -0
- package/dist/tools/swarm.d.ts +6 -0
- package/dist/tools/swarm.d.ts.map +1 -0
- package/dist/tools/swarm.js +483 -0
- package/dist/tools/swarm.js.map +1 -0
- package/dist/tools/task.d.ts +6 -0
- package/dist/tools/task.d.ts.map +1 -0
- package/dist/tools/task.js +347 -0
- package/dist/tools/task.js.map +1 -0
- package/dist/utils.d.ts +23 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +56 -0
- package/dist/utils.js.map +1 -0
- package/package.json +3 -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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"}
|
package/dist/utils.d.ts
ADDED
|
@@ -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.
|
|
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",
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"prepublishOnly": "npm run build"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@agent-workspace/core": "0.
|
|
45
|
+
"@agent-workspace/core": "0.5.0",
|
|
46
|
+
"@agent-workspace/utils": "0.5.0",
|
|
46
47
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
47
48
|
"ajv": "^8.17.1",
|
|
48
49
|
"ajv-formats": "^3.0.1",
|