@artyfacts/mcp-server 1.1.5 → 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/dist/chunk-MQM6RARV.js +654 -0
- package/dist/index.cjs +21 -0
- package/dist/index.js +1 -1
- package/dist/server.cjs +21 -0
- package/dist/server.js +1 -1
- package/package.json +1 -1
- package/src/server.ts +21 -0
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
// src/server.ts
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import {
|
|
5
|
+
CallToolRequestSchema,
|
|
6
|
+
ListToolsRequestSchema
|
|
7
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
8
|
+
var ARTYFACTS_TOOLS = [
|
|
9
|
+
// Organization tools
|
|
10
|
+
{
|
|
11
|
+
name: "get_organization",
|
|
12
|
+
description: "Get details about the current organization",
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {},
|
|
16
|
+
required: []
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
// Project tools
|
|
20
|
+
{
|
|
21
|
+
name: "list_projects",
|
|
22
|
+
description: "List all projects in the organization",
|
|
23
|
+
inputSchema: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
limit: { type: "number", description: "Max results (default 50)" },
|
|
27
|
+
offset: { type: "number", description: "Pagination offset" }
|
|
28
|
+
},
|
|
29
|
+
required: []
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "get_project",
|
|
34
|
+
description: "Get details about a specific project",
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
project_id: { type: "string", description: "Project ID" }
|
|
39
|
+
},
|
|
40
|
+
required: ["project_id"]
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
// Artifact tools
|
|
44
|
+
{
|
|
45
|
+
name: "list_artifacts",
|
|
46
|
+
description: "List artifacts, optionally filtered by project",
|
|
47
|
+
inputSchema: {
|
|
48
|
+
type: "object",
|
|
49
|
+
properties: {
|
|
50
|
+
project_id: { type: "string", description: "Filter by project" },
|
|
51
|
+
type: { type: "string", description: "Filter by type (goal, spec, research, etc.)" },
|
|
52
|
+
status: { type: "string", description: "Filter by status" },
|
|
53
|
+
limit: { type: "number", description: "Max results" }
|
|
54
|
+
},
|
|
55
|
+
required: []
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "get_artifact",
|
|
60
|
+
description: "Get a specific artifact by ID",
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: "object",
|
|
63
|
+
properties: {
|
|
64
|
+
artifact_id: { type: "string", description: "Artifact ID" }
|
|
65
|
+
},
|
|
66
|
+
required: ["artifact_id"]
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "create_artifact",
|
|
71
|
+
description: "Create a new artifact (document, goal, spec, etc.)",
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: "object",
|
|
74
|
+
properties: {
|
|
75
|
+
title: { type: "string", description: "Artifact title" },
|
|
76
|
+
type: { type: "string", description: "Artifact type: goal, spec, research, report, experiment, decision, doc" },
|
|
77
|
+
content: { type: "string", description: "Markdown content" },
|
|
78
|
+
goal_id: { type: "string", description: "The goal UUID this artifact belongs to \u2014 always pass this when working on a task" },
|
|
79
|
+
parent_id: { type: "string", description: "Parent artifact ID for nested artifacts" },
|
|
80
|
+
tags: { type: "array", items: { type: "string" }, description: "Tags for categorization" }
|
|
81
|
+
},
|
|
82
|
+
required: ["title", "type"]
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "update_artifact",
|
|
87
|
+
description: "Update an existing artifact",
|
|
88
|
+
inputSchema: {
|
|
89
|
+
type: "object",
|
|
90
|
+
properties: {
|
|
91
|
+
artifact_id: { type: "string", description: "Artifact ID" },
|
|
92
|
+
title: { type: "string", description: "New title" },
|
|
93
|
+
content: { type: "string", description: "New content" },
|
|
94
|
+
status: { type: "string", description: "New status" }
|
|
95
|
+
},
|
|
96
|
+
required: ["artifact_id"]
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
// Section tools
|
|
100
|
+
{
|
|
101
|
+
name: "list_sections",
|
|
102
|
+
description: "List sections of an artifact",
|
|
103
|
+
inputSchema: {
|
|
104
|
+
type: "object",
|
|
105
|
+
properties: {
|
|
106
|
+
artifact_id: { type: "string", description: "Artifact ID" }
|
|
107
|
+
},
|
|
108
|
+
required: ["artifact_id"]
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "get_section",
|
|
113
|
+
description: "Get a specific section",
|
|
114
|
+
inputSchema: {
|
|
115
|
+
type: "object",
|
|
116
|
+
properties: {
|
|
117
|
+
artifact_id: { type: "string", description: "Artifact ID" },
|
|
118
|
+
section_id: { type: "string", description: "Section ID" }
|
|
119
|
+
},
|
|
120
|
+
required: ["artifact_id", "section_id"]
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "create_section",
|
|
125
|
+
description: "Create a new section on an artifact",
|
|
126
|
+
inputSchema: {
|
|
127
|
+
type: "object",
|
|
128
|
+
properties: {
|
|
129
|
+
artifact_id: { type: "string", description: "Artifact ID" },
|
|
130
|
+
section_id: { type: "string", description: "Section identifier (slug)" },
|
|
131
|
+
heading: { type: "string", description: "Section heading" },
|
|
132
|
+
content: { type: "string", description: "Markdown content" },
|
|
133
|
+
type: { type: "string", description: "Type: content, task, decision, blocker" },
|
|
134
|
+
position: { type: "number", description: "Order position" }
|
|
135
|
+
},
|
|
136
|
+
required: ["artifact_id", "section_id", "heading", "content"]
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "update_section",
|
|
141
|
+
description: "Update an existing section",
|
|
142
|
+
inputSchema: {
|
|
143
|
+
type: "object",
|
|
144
|
+
properties: {
|
|
145
|
+
artifact_id: { type: "string", description: "Artifact ID" },
|
|
146
|
+
section_id: { type: "string", description: "Section ID" },
|
|
147
|
+
heading: { type: "string", description: "New heading" },
|
|
148
|
+
content: { type: "string", description: "New content" },
|
|
149
|
+
task_status: { type: "string", description: "Task status if type=task" }
|
|
150
|
+
},
|
|
151
|
+
required: ["artifact_id", "section_id"]
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: "delete_section",
|
|
156
|
+
description: "Delete a section",
|
|
157
|
+
inputSchema: {
|
|
158
|
+
type: "object",
|
|
159
|
+
properties: {
|
|
160
|
+
artifact_id: { type: "string", description: "Artifact ID" },
|
|
161
|
+
section_id: { type: "string", description: "Section ID" }
|
|
162
|
+
},
|
|
163
|
+
required: ["artifact_id", "section_id"]
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
// Task tools
|
|
167
|
+
{
|
|
168
|
+
name: "list_tasks",
|
|
169
|
+
description: "List tasks (sections with type=task)",
|
|
170
|
+
inputSchema: {
|
|
171
|
+
type: "object",
|
|
172
|
+
properties: {
|
|
173
|
+
artifact_id: { type: "string", description: "Filter by artifact" },
|
|
174
|
+
status: { type: "string", description: "Filter by status: pending, in_progress, done, blocked" },
|
|
175
|
+
assignee: { type: "string", description: "Filter by assignee agent" }
|
|
176
|
+
},
|
|
177
|
+
required: []
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: "claim_task",
|
|
182
|
+
description: "Claim a task for the current agent",
|
|
183
|
+
inputSchema: {
|
|
184
|
+
type: "object",
|
|
185
|
+
properties: {
|
|
186
|
+
task_id: { type: "string", description: "Task ID (section UUID)" }
|
|
187
|
+
},
|
|
188
|
+
required: ["task_id"]
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: "complete_task",
|
|
193
|
+
description: "Mark a task as complete. Always pass output_artifact_id if you created an artifact. Always pass output_references listing every entity you created or touched.",
|
|
194
|
+
inputSchema: {
|
|
195
|
+
type: "object",
|
|
196
|
+
properties: {
|
|
197
|
+
task_id: { type: "string", description: "Task ID" },
|
|
198
|
+
output_text: { type: "string", description: "Completion summary / what was done" },
|
|
199
|
+
output_url: { type: "string", description: "URL to deliverable (PR, doc, etc.)" },
|
|
200
|
+
output_artifact_id: { type: "string", description: "UUID of the primary artifact produced by this task" },
|
|
201
|
+
output_references: {
|
|
202
|
+
type: "array",
|
|
203
|
+
description: "All entities created or interacted with: artifacts, tasks, agents, goals",
|
|
204
|
+
items: {
|
|
205
|
+
type: "object",
|
|
206
|
+
properties: {
|
|
207
|
+
type: { type: "string", description: "artifact | task | agent | goal" },
|
|
208
|
+
id: { type: "string", description: "Entity UUID" },
|
|
209
|
+
title: { type: "string", description: "Display name for the reference card" },
|
|
210
|
+
subtitle: { type: "string", description: "Optional: type label, status, role, etc." }
|
|
211
|
+
},
|
|
212
|
+
required: ["type", "id", "title"]
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
required: ["task_id"]
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: "block_task",
|
|
221
|
+
description: "Mark a task as blocked",
|
|
222
|
+
inputSchema: {
|
|
223
|
+
type: "object",
|
|
224
|
+
properties: {
|
|
225
|
+
task_id: { type: "string", description: "Task ID" },
|
|
226
|
+
reason: { type: "string", description: "Why it is blocked" },
|
|
227
|
+
blocker_type: { type: "string", description: "Type: decision, dependency, resource, external" }
|
|
228
|
+
},
|
|
229
|
+
required: ["task_id", "reason"]
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: "report_progress",
|
|
234
|
+
description: 'Report what you are currently doing on a task. Call this at meaningful milestones so your work is visible in the platform (e.g., "Analyzed 12 PRs, now writing the summary section", "Completed API design, starting implementation"). This is how your progress appears to humans watching the work.',
|
|
235
|
+
inputSchema: {
|
|
236
|
+
type: "object",
|
|
237
|
+
properties: {
|
|
238
|
+
task_id: { type: "string", description: "Task ID" },
|
|
239
|
+
message: { type: "string", description: "What you are doing right now \u2014 be specific and human-readable" },
|
|
240
|
+
metadata: { type: "object", description: "Optional extra context (step number, percentage, etc.)" }
|
|
241
|
+
},
|
|
242
|
+
required: ["task_id", "message"]
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: "create_task",
|
|
247
|
+
description: "Create a new task under a goal. Use this to create actionable tasks \u2014 NOT create_artifact or create_section.",
|
|
248
|
+
inputSchema: {
|
|
249
|
+
type: "object",
|
|
250
|
+
properties: {
|
|
251
|
+
goal_id: { type: "string", description: "The goal UUID this task belongs to (required)" },
|
|
252
|
+
title: { type: "string", description: "Task title" },
|
|
253
|
+
description: { type: "string", description: "Task description / what needs to be done" },
|
|
254
|
+
priority: { type: "string", description: "Priority: low, medium, high, urgent" },
|
|
255
|
+
assigned_to: { type: "string", description: "Agent UUID to assign the task to" },
|
|
256
|
+
depends_on: { type: "array", items: { type: "string" }, description: "List of task UUIDs this task depends on" },
|
|
257
|
+
estimated_minutes: { type: "number", description: "Estimated time in minutes" }
|
|
258
|
+
},
|
|
259
|
+
required: ["goal_id", "title"]
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
// Agent tools
|
|
263
|
+
{
|
|
264
|
+
name: "list_agents",
|
|
265
|
+
description: "List all agents in the organization",
|
|
266
|
+
inputSchema: {
|
|
267
|
+
type: "object",
|
|
268
|
+
properties: {
|
|
269
|
+
status: { type: "string", description: "Filter by status: active, inactive" }
|
|
270
|
+
},
|
|
271
|
+
required: []
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
name: "get_agent",
|
|
276
|
+
description: "Get details about an agent",
|
|
277
|
+
inputSchema: {
|
|
278
|
+
type: "object",
|
|
279
|
+
properties: {
|
|
280
|
+
agent_id: { type: "string", description: "Agent ID" }
|
|
281
|
+
},
|
|
282
|
+
required: ["agent_id"]
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
name: "create_agent",
|
|
287
|
+
description: "Register a new AI agent with role, capabilities, and permissions",
|
|
288
|
+
inputSchema: {
|
|
289
|
+
type: "object",
|
|
290
|
+
properties: {
|
|
291
|
+
agentId: { type: "string", description: 'Unique agent ID (e.g., "engineering-agent", "qa-agent")' },
|
|
292
|
+
name: { type: "string", description: "Agent display name" },
|
|
293
|
+
role: { type: "string", description: "Role: pm, engineering, qa, research, content, design" },
|
|
294
|
+
description: { type: "string", description: "What this agent does - detailed description" },
|
|
295
|
+
capabilities: { type: "array", items: { type: "string" }, description: 'List of capabilities (e.g., ["code-review", "testing", "debugging"])' },
|
|
296
|
+
permissions: {
|
|
297
|
+
type: "object",
|
|
298
|
+
description: "Permission settings",
|
|
299
|
+
properties: {
|
|
300
|
+
write: { type: "boolean", description: "Can create/edit artifacts" },
|
|
301
|
+
delete: { type: "boolean", description: "Can delete artifacts" },
|
|
302
|
+
delegate_tasks: { type: "boolean", description: "Can assign tasks to other agents" }
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
systemPrompt: { type: "string", description: "System prompt for the agent" },
|
|
306
|
+
reportsToAgentId: { type: "string", description: 'Agent ID or UUID of the parent agent this agent reports to. Use agent slugs like "chief-of-staff" for readability.' }
|
|
307
|
+
},
|
|
308
|
+
required: ["agentId", "name", "role", "description"]
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: "update_agent",
|
|
313
|
+
description: "Update an agent",
|
|
314
|
+
inputSchema: {
|
|
315
|
+
type: "object",
|
|
316
|
+
properties: {
|
|
317
|
+
agent_id: { type: "string", description: "Agent ID" },
|
|
318
|
+
name: { type: "string", description: "New name" },
|
|
319
|
+
status: { type: "string", description: "New status" },
|
|
320
|
+
config: { type: "object", description: "Updated config" }
|
|
321
|
+
},
|
|
322
|
+
required: ["agent_id"]
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
// Inbox tools (human-in-the-loop)
|
|
326
|
+
{
|
|
327
|
+
name: "create_inbox_item",
|
|
328
|
+
description: "Request human approval, a decision, or an answer before proceeding. Automatically blocks the task. Use for agent creation, risky actions, or anything requiring human sign-off.",
|
|
329
|
+
inputSchema: {
|
|
330
|
+
type: "object",
|
|
331
|
+
properties: {
|
|
332
|
+
task_id: { type: "string", description: "UUID of the task being blocked (required)" },
|
|
333
|
+
type: { type: "string", description: "Type: approval, decision, question" },
|
|
334
|
+
title: { type: "string", description: "Short summary shown to the human in the inbox" },
|
|
335
|
+
content: { type: "string", description: "Full context and details for the human" },
|
|
336
|
+
action: { type: "string", description: "Action to auto-execute if approved (e.g. agent.create)" },
|
|
337
|
+
action_payload: { type: "object", description: "Data for the action (e.g. full agent spec for agent.create)" },
|
|
338
|
+
options: { type: "array", description: "Options for decision type: [{id, label, description}]" }
|
|
339
|
+
},
|
|
340
|
+
required: ["task_id", "type", "title"]
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
name: "list_inbox",
|
|
345
|
+
description: "List pending inbox items (approvals, decisions, questions) waiting for human resolution.",
|
|
346
|
+
inputSchema: {
|
|
347
|
+
type: "object",
|
|
348
|
+
properties: {
|
|
349
|
+
status: { type: "string", description: "Filter by status: pending (default), resolved" },
|
|
350
|
+
type: { type: "string", description: "Filter by type: approval, decision, question" },
|
|
351
|
+
limit: { type: "number", description: "Max results (default 50)" }
|
|
352
|
+
},
|
|
353
|
+
required: []
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
name: "resolve_inbox",
|
|
358
|
+
description: "Resolve an inbox item from the agent side. Humans resolve via the UI \u2014 only use this for automated resolution.",
|
|
359
|
+
inputSchema: {
|
|
360
|
+
type: "object",
|
|
361
|
+
properties: {
|
|
362
|
+
item_id: { type: "string", description: "Inbox item UUID" },
|
|
363
|
+
approved: { type: "boolean", description: "For approvals: true to approve, false to deny" },
|
|
364
|
+
chosen_option: { type: "string", description: "For decisions: the selected option ID" },
|
|
365
|
+
answer: { type: "string", description: "For questions: the answer text" },
|
|
366
|
+
notes: { type: "string", description: "Optional notes" }
|
|
367
|
+
},
|
|
368
|
+
required: ["item_id"]
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
// Search tools
|
|
372
|
+
{
|
|
373
|
+
name: "search_artifacts",
|
|
374
|
+
description: "Search artifacts by text query",
|
|
375
|
+
inputSchema: {
|
|
376
|
+
type: "object",
|
|
377
|
+
properties: {
|
|
378
|
+
query: { type: "string", description: "Search query" },
|
|
379
|
+
type: { type: "string", description: "Filter by type" },
|
|
380
|
+
limit: { type: "number", description: "Max results" }
|
|
381
|
+
},
|
|
382
|
+
required: ["query"]
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
// Context tools
|
|
386
|
+
{
|
|
387
|
+
name: "get_task_context",
|
|
388
|
+
description: "Get full context for a task (org, project, artifact, related sections)",
|
|
389
|
+
inputSchema: {
|
|
390
|
+
type: "object",
|
|
391
|
+
properties: {
|
|
392
|
+
task_id: { type: "string", description: "Task ID" }
|
|
393
|
+
},
|
|
394
|
+
required: ["task_id"]
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
];
|
|
398
|
+
var ArtyfactsApiClient = class {
|
|
399
|
+
constructor(baseUrl, apiKey, agentId) {
|
|
400
|
+
this.baseUrl = baseUrl;
|
|
401
|
+
this.apiKey = apiKey;
|
|
402
|
+
this.agentId = agentId;
|
|
403
|
+
}
|
|
404
|
+
async request(method, path, body) {
|
|
405
|
+
const url = `${this.baseUrl}${path}`;
|
|
406
|
+
const headers = {
|
|
407
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
408
|
+
"Content-Type": "application/json"
|
|
409
|
+
};
|
|
410
|
+
if (this.agentId) {
|
|
411
|
+
headers["X-Agent-Id"] = this.agentId;
|
|
412
|
+
}
|
|
413
|
+
const response = await fetch(url, {
|
|
414
|
+
method,
|
|
415
|
+
headers,
|
|
416
|
+
body: body ? JSON.stringify(body) : void 0
|
|
417
|
+
});
|
|
418
|
+
if (!response.ok) {
|
|
419
|
+
const error = await response.json().catch(() => ({ error: "Request failed" }));
|
|
420
|
+
throw new Error(error.error || `HTTP ${response.status}: ${response.statusText}`);
|
|
421
|
+
}
|
|
422
|
+
return response.json();
|
|
423
|
+
}
|
|
424
|
+
get(path) {
|
|
425
|
+
return this.request("GET", path);
|
|
426
|
+
}
|
|
427
|
+
getAgentId() {
|
|
428
|
+
return this.agentId;
|
|
429
|
+
}
|
|
430
|
+
post(path, body) {
|
|
431
|
+
return this.request("POST", path, body);
|
|
432
|
+
}
|
|
433
|
+
patch(path, body) {
|
|
434
|
+
return this.request("PATCH", path, body);
|
|
435
|
+
}
|
|
436
|
+
delete(path) {
|
|
437
|
+
return this.request("DELETE", path);
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
var toolHandlers = {
|
|
441
|
+
// Organization
|
|
442
|
+
get_organization: (client) => client.get("/org"),
|
|
443
|
+
// Projects
|
|
444
|
+
list_projects: (client, args) => {
|
|
445
|
+
const params = new URLSearchParams();
|
|
446
|
+
if (args.limit) params.set("limit", String(args.limit));
|
|
447
|
+
if (args.offset) params.set("offset", String(args.offset));
|
|
448
|
+
return client.get(`/projects?${params}`);
|
|
449
|
+
},
|
|
450
|
+
get_project: (client, args) => client.get(`/projects/${args.project_id}`),
|
|
451
|
+
// Artifacts
|
|
452
|
+
list_artifacts: (client, args) => {
|
|
453
|
+
const params = new URLSearchParams();
|
|
454
|
+
if (args.project_id) params.set("project_id", String(args.project_id));
|
|
455
|
+
if (args.type) params.set("type", String(args.type));
|
|
456
|
+
if (args.status) params.set("status", String(args.status));
|
|
457
|
+
if (args.limit) params.set("limit", String(args.limit));
|
|
458
|
+
return client.get(`/artifacts?${params}`);
|
|
459
|
+
},
|
|
460
|
+
get_artifact: (client, args) => client.get(`/artifacts/${args.artifact_id}`),
|
|
461
|
+
create_artifact: (client, args) => {
|
|
462
|
+
const envelope = {
|
|
463
|
+
aah_version: "0.3",
|
|
464
|
+
artifact: {
|
|
465
|
+
id: args.id || `artifact-${Date.now()}`,
|
|
466
|
+
title: args.title,
|
|
467
|
+
type: args.type || "document/sectioned",
|
|
468
|
+
artifact_type: args.artifact_type || args.type || "doc",
|
|
469
|
+
goal_id: args.goal_id,
|
|
470
|
+
parent_id: args.parent_id,
|
|
471
|
+
tags: args.tags
|
|
472
|
+
},
|
|
473
|
+
content: args.content ? {
|
|
474
|
+
media_type: "text/markdown",
|
|
475
|
+
body: args.content
|
|
476
|
+
} : void 0,
|
|
477
|
+
source: {
|
|
478
|
+
agent_id: client.getAgentId() || "mcp-agent"
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
return client.post("/artifacts", envelope);
|
|
482
|
+
},
|
|
483
|
+
update_artifact: (client, args) => {
|
|
484
|
+
const { artifact_id, ...body } = args;
|
|
485
|
+
return client.patch(`/artifacts/${artifact_id}`, body);
|
|
486
|
+
},
|
|
487
|
+
// Sections
|
|
488
|
+
list_sections: (client, args) => client.get(`/artifacts/${args.artifact_id}/sections`),
|
|
489
|
+
get_section: (client, args) => client.get(`/artifacts/${args.artifact_id}/sections/${args.section_id}`),
|
|
490
|
+
create_section: (client, args) => {
|
|
491
|
+
const { artifact_id, section_id, ...rest } = args;
|
|
492
|
+
const body = { id: section_id, ...rest };
|
|
493
|
+
return client.post(`/artifacts/${artifact_id}/sections`, body);
|
|
494
|
+
},
|
|
495
|
+
update_section: (client, args) => {
|
|
496
|
+
const { artifact_id, section_id, ...body } = args;
|
|
497
|
+
return client.patch(`/artifacts/${artifact_id}/sections/${section_id}`, body);
|
|
498
|
+
},
|
|
499
|
+
delete_section: (client, args) => client.delete(`/artifacts/${args.artifact_id}/sections/${args.section_id}`),
|
|
500
|
+
// Tasks
|
|
501
|
+
list_tasks: (client, args) => {
|
|
502
|
+
const params = new URLSearchParams();
|
|
503
|
+
if (args.artifact_id) params.set("artifact_id", String(args.artifact_id));
|
|
504
|
+
if (args.status) params.set("status", String(args.status));
|
|
505
|
+
if (args.assignee) params.set("assignee", String(args.assignee));
|
|
506
|
+
return client.get(`/tasks?${params}`);
|
|
507
|
+
},
|
|
508
|
+
claim_task: (client, args) => client.post(`/tasks/${args.task_id}/claim`),
|
|
509
|
+
complete_task: (client, args) => {
|
|
510
|
+
const { task_id, ...body } = args;
|
|
511
|
+
return client.post(`/tasks/${task_id}/complete`, body);
|
|
512
|
+
},
|
|
513
|
+
block_task: (client, args) => {
|
|
514
|
+
const { task_id, ...body } = args;
|
|
515
|
+
return client.post(`/tasks/${task_id}/block`, body);
|
|
516
|
+
},
|
|
517
|
+
report_progress: (client, args) => {
|
|
518
|
+
const { task_id, message, metadata } = args;
|
|
519
|
+
return client.post(`/tasks/${task_id}/activity`, {
|
|
520
|
+
type: "progress",
|
|
521
|
+
content: message,
|
|
522
|
+
metadata: metadata ?? {}
|
|
523
|
+
});
|
|
524
|
+
},
|
|
525
|
+
create_task: (client, args) => {
|
|
526
|
+
const { goal_id, title, description, priority, assigned_to, depends_on, estimated_minutes } = args;
|
|
527
|
+
return client.post("/tasks", { goal_id, title, description, priority, assigned_to, depends_on, estimated_minutes });
|
|
528
|
+
},
|
|
529
|
+
// Agents
|
|
530
|
+
list_agents: (client, args) => {
|
|
531
|
+
const params = new URLSearchParams();
|
|
532
|
+
if (args.status) params.set("status", String(args.status));
|
|
533
|
+
return client.get(`/agents?${params}`);
|
|
534
|
+
},
|
|
535
|
+
get_agent: (client, args) => client.get(`/agents/${args.agent_id}`),
|
|
536
|
+
create_agent: (client, args) => {
|
|
537
|
+
const body = {
|
|
538
|
+
agentId: args.agentId,
|
|
539
|
+
name: args.name,
|
|
540
|
+
role: args.role,
|
|
541
|
+
description: args.description,
|
|
542
|
+
reportsToAgentId: args.reportsToAgentId,
|
|
543
|
+
permissions: args.permissions || { write: true, delete: false, delegate_tasks: false },
|
|
544
|
+
metadata: {
|
|
545
|
+
capabilities: args.capabilities || [],
|
|
546
|
+
systemPrompt: args.systemPrompt,
|
|
547
|
+
createdVia: "mcp"
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
return client.post("/agents", body);
|
|
551
|
+
},
|
|
552
|
+
update_agent: (client, args) => {
|
|
553
|
+
const { agent_id, ...body } = args;
|
|
554
|
+
return client.patch(`/agents/${agent_id}`, body);
|
|
555
|
+
},
|
|
556
|
+
// Inbox (human-in-the-loop)
|
|
557
|
+
create_inbox_item: (client, args) => {
|
|
558
|
+
const { task_id, type, title, content, action, action_payload, options } = args;
|
|
559
|
+
return client.post("/inbox", { task_id, type, title, content, action, action_payload, options });
|
|
560
|
+
},
|
|
561
|
+
list_inbox: (client, args) => {
|
|
562
|
+
const params = new URLSearchParams();
|
|
563
|
+
if (args.status) params.set("status", String(args.status));
|
|
564
|
+
if (args.type) params.set("type", String(args.type));
|
|
565
|
+
if (args.limit) params.set("limit", String(args.limit));
|
|
566
|
+
return client.get(`/inbox?${params}`);
|
|
567
|
+
},
|
|
568
|
+
resolve_inbox: (client, args) => {
|
|
569
|
+
const { item_id, ...body } = args;
|
|
570
|
+
return client.post(`/inbox/${item_id}/resolve`, body);
|
|
571
|
+
},
|
|
572
|
+
// Search
|
|
573
|
+
search_artifacts: (client, args) => {
|
|
574
|
+
const params = new URLSearchParams();
|
|
575
|
+
params.set("q", String(args.query));
|
|
576
|
+
if (args.type) params.set("type", String(args.type));
|
|
577
|
+
if (args.limit) params.set("limit", String(args.limit));
|
|
578
|
+
return client.get(`/search?${params}`);
|
|
579
|
+
},
|
|
580
|
+
// Context
|
|
581
|
+
get_task_context: (client, args) => client.get(`/tasks/${args.task_id}/context`)
|
|
582
|
+
};
|
|
583
|
+
var ArtyfactsMcpServer = class {
|
|
584
|
+
server;
|
|
585
|
+
client;
|
|
586
|
+
config;
|
|
587
|
+
constructor(config) {
|
|
588
|
+
this.config = config;
|
|
589
|
+
this.client = new ArtyfactsApiClient(
|
|
590
|
+
config.baseUrl || "https://artyfacts.dev/api/v1",
|
|
591
|
+
config.apiKey,
|
|
592
|
+
config.agentId
|
|
593
|
+
);
|
|
594
|
+
this.server = new Server(
|
|
595
|
+
{
|
|
596
|
+
name: config.name || "artyfacts-mcp",
|
|
597
|
+
version: config.version || "1.0.0"
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
capabilities: {
|
|
601
|
+
tools: {}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
);
|
|
605
|
+
this.setupHandlers();
|
|
606
|
+
}
|
|
607
|
+
setupHandlers() {
|
|
608
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
609
|
+
return { tools: ARTYFACTS_TOOLS };
|
|
610
|
+
});
|
|
611
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
612
|
+
const { name, arguments: args } = request.params;
|
|
613
|
+
const handler = toolHandlers[name];
|
|
614
|
+
if (!handler) {
|
|
615
|
+
return {
|
|
616
|
+
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
617
|
+
isError: true
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
try {
|
|
621
|
+
const result = await handler(this.client, args || {});
|
|
622
|
+
return {
|
|
623
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
624
|
+
};
|
|
625
|
+
} catch (error) {
|
|
626
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
627
|
+
return {
|
|
628
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
629
|
+
isError: true
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
async start() {
|
|
635
|
+
const transport = new StdioServerTransport();
|
|
636
|
+
await this.server.connect(transport);
|
|
637
|
+
console.error(`Artyfacts MCP server running (${ARTYFACTS_TOOLS.length} tools)`);
|
|
638
|
+
}
|
|
639
|
+
getServer() {
|
|
640
|
+
return this.server;
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
function createMcpServer(config) {
|
|
644
|
+
return new ArtyfactsMcpServer(config);
|
|
645
|
+
}
|
|
646
|
+
async function startServer(server) {
|
|
647
|
+
await server.start();
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
export {
|
|
651
|
+
ArtyfactsMcpServer,
|
|
652
|
+
createMcpServer,
|
|
653
|
+
startServer
|
|
654
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -254,6 +254,19 @@ var ARTYFACTS_TOOLS = [
|
|
|
254
254
|
required: ["task_id", "reason"]
|
|
255
255
|
}
|
|
256
256
|
},
|
|
257
|
+
{
|
|
258
|
+
name: "report_progress",
|
|
259
|
+
description: 'Report what you are currently doing on a task. Call this at meaningful milestones so your work is visible in the platform (e.g., "Analyzed 12 PRs, now writing the summary section", "Completed API design, starting implementation"). This is how your progress appears to humans watching the work.',
|
|
260
|
+
inputSchema: {
|
|
261
|
+
type: "object",
|
|
262
|
+
properties: {
|
|
263
|
+
task_id: { type: "string", description: "Task ID" },
|
|
264
|
+
message: { type: "string", description: "What you are doing right now \u2014 be specific and human-readable" },
|
|
265
|
+
metadata: { type: "object", description: "Optional extra context (step number, percentage, etc.)" }
|
|
266
|
+
},
|
|
267
|
+
required: ["task_id", "message"]
|
|
268
|
+
}
|
|
269
|
+
},
|
|
257
270
|
{
|
|
258
271
|
name: "create_task",
|
|
259
272
|
description: "Create a new task under a goal. Use this to create actionable tasks \u2014 NOT create_artifact or create_section.",
|
|
@@ -526,6 +539,14 @@ var toolHandlers = {
|
|
|
526
539
|
const { task_id, ...body } = args;
|
|
527
540
|
return client.post(`/tasks/${task_id}/block`, body);
|
|
528
541
|
},
|
|
542
|
+
report_progress: (client, args) => {
|
|
543
|
+
const { task_id, message, metadata } = args;
|
|
544
|
+
return client.post(`/tasks/${task_id}/activity`, {
|
|
545
|
+
type: "progress",
|
|
546
|
+
content: message,
|
|
547
|
+
metadata: metadata ?? {}
|
|
548
|
+
});
|
|
549
|
+
},
|
|
529
550
|
create_task: (client, args) => {
|
|
530
551
|
const { goal_id, title, description, priority, assigned_to, depends_on, estimated_minutes } = args;
|
|
531
552
|
return client.post("/tasks", { goal_id, title, description, priority, assigned_to, depends_on, estimated_minutes });
|
package/dist/index.js
CHANGED
package/dist/server.cjs
CHANGED
|
@@ -252,6 +252,19 @@ var ARTYFACTS_TOOLS = [
|
|
|
252
252
|
required: ["task_id", "reason"]
|
|
253
253
|
}
|
|
254
254
|
},
|
|
255
|
+
{
|
|
256
|
+
name: "report_progress",
|
|
257
|
+
description: 'Report what you are currently doing on a task. Call this at meaningful milestones so your work is visible in the platform (e.g., "Analyzed 12 PRs, now writing the summary section", "Completed API design, starting implementation"). This is how your progress appears to humans watching the work.',
|
|
258
|
+
inputSchema: {
|
|
259
|
+
type: "object",
|
|
260
|
+
properties: {
|
|
261
|
+
task_id: { type: "string", description: "Task ID" },
|
|
262
|
+
message: { type: "string", description: "What you are doing right now \u2014 be specific and human-readable" },
|
|
263
|
+
metadata: { type: "object", description: "Optional extra context (step number, percentage, etc.)" }
|
|
264
|
+
},
|
|
265
|
+
required: ["task_id", "message"]
|
|
266
|
+
}
|
|
267
|
+
},
|
|
255
268
|
{
|
|
256
269
|
name: "create_task",
|
|
257
270
|
description: "Create a new task under a goal. Use this to create actionable tasks \u2014 NOT create_artifact or create_section.",
|
|
@@ -524,6 +537,14 @@ var toolHandlers = {
|
|
|
524
537
|
const { task_id, ...body } = args;
|
|
525
538
|
return client.post(`/tasks/${task_id}/block`, body);
|
|
526
539
|
},
|
|
540
|
+
report_progress: (client, args) => {
|
|
541
|
+
const { task_id, message, metadata } = args;
|
|
542
|
+
return client.post(`/tasks/${task_id}/activity`, {
|
|
543
|
+
type: "progress",
|
|
544
|
+
content: message,
|
|
545
|
+
metadata: metadata ?? {}
|
|
546
|
+
});
|
|
547
|
+
},
|
|
527
548
|
create_task: (client, args) => {
|
|
528
549
|
const { goal_id, title, description, priority, assigned_to, depends_on, estimated_minutes } = args;
|
|
529
550
|
return client.post("/tasks", { goal_id, title, description, priority, assigned_to, depends_on, estimated_minutes });
|
package/dist/server.js
CHANGED
package/package.json
CHANGED
package/src/server.ts
CHANGED
|
@@ -262,6 +262,19 @@ const ARTYFACTS_TOOLS: Tool[] = [
|
|
|
262
262
|
required: ['task_id', 'reason'],
|
|
263
263
|
},
|
|
264
264
|
},
|
|
265
|
+
{
|
|
266
|
+
name: 'report_progress',
|
|
267
|
+
description: 'Report what you are currently doing on a task. Call this at meaningful milestones so your work is visible in the platform (e.g., "Analyzed 12 PRs, now writing the summary section", "Completed API design, starting implementation"). This is how your progress appears to humans watching the work.',
|
|
268
|
+
inputSchema: {
|
|
269
|
+
type: 'object',
|
|
270
|
+
properties: {
|
|
271
|
+
task_id: { type: 'string', description: 'Task ID' },
|
|
272
|
+
message: { type: 'string', description: 'What you are doing right now — be specific and human-readable' },
|
|
273
|
+
metadata: { type: 'object', description: 'Optional extra context (step number, percentage, etc.)' },
|
|
274
|
+
},
|
|
275
|
+
required: ['task_id', 'message'],
|
|
276
|
+
},
|
|
277
|
+
},
|
|
265
278
|
{
|
|
266
279
|
name: 'create_task',
|
|
267
280
|
description: 'Create a new task under a goal. Use this to create actionable tasks — NOT create_artifact or create_section.',
|
|
@@ -552,6 +565,14 @@ const toolHandlers: Record<string, ToolHandler> = {
|
|
|
552
565
|
const { task_id, ...body } = args;
|
|
553
566
|
return client.post(`/tasks/${task_id}/block`, body);
|
|
554
567
|
},
|
|
568
|
+
report_progress: (client, args) => {
|
|
569
|
+
const { task_id, message, metadata } = args;
|
|
570
|
+
return client.post(`/tasks/${task_id}/activity`, {
|
|
571
|
+
type: 'progress',
|
|
572
|
+
content: message,
|
|
573
|
+
metadata: metadata ?? {},
|
|
574
|
+
});
|
|
575
|
+
},
|
|
555
576
|
create_task: (client, args) => {
|
|
556
577
|
const { goal_id, title, description, priority, assigned_to, depends_on, estimated_minutes } = args;
|
|
557
578
|
return client.post('/tasks', { goal_id, title, description, priority, assigned_to, depends_on, estimated_minutes });
|