@cpenned/mcp 0.1.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/LICENSE +21 -0
- package/README.md +83 -0
- package/dist/client.js +60 -0
- package/dist/client.js.map +1 -0
- package/dist/config.js +16 -0
- package/dist/config.js.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/result.js +25 -0
- package/dist/result.js.map +1 -0
- package/dist/server.js +8 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/ai.js +49 -0
- package/dist/tools/ai.js.map +1 -0
- package/dist/tools/gardens.js +82 -0
- package/dist/tools/gardens.js.map +1 -0
- package/dist/tools/index.js +21 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/keys.js +56 -0
- package/dist/tools/keys.js.map +1 -0
- package/dist/tools/lists.js +66 -0
- package/dist/tools/lists.js.map +1 -0
- package/dist/tools/projects.js +132 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/render.js +68 -0
- package/dist/tools/render.js.map +1 -0
- package/dist/tools/schemas.js +37 -0
- package/dist/tools/schemas.js.map +1 -0
- package/dist/tools/tags.js +69 -0
- package/dist/tools/tags.js.map +1 -0
- package/dist/tools/tasks.js +188 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/ui.js +86 -0
- package/dist/tools/ui.js.map +1 -0
- package/dist/tools/views.js +77 -0
- package/dist/tools/views.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Project tools: single + batch CRUD and multi-get. Projects live in exactly
|
|
2
|
+
// one garden and share the unified status machine with tasks.
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { runTool } from "../result.js";
|
|
5
|
+
import { dateField, idempotencyKey, reviewIntervalSchema, statusEnum, whenSchema, } from "./schemas.js";
|
|
6
|
+
const csv = (a) => a?.length ? a.join(",") : undefined;
|
|
7
|
+
const projectFields = {
|
|
8
|
+
gardenId: z.string().describe("Garden the project belongs to (required on create)"),
|
|
9
|
+
name: z.string(),
|
|
10
|
+
notes: z.string().optional().describe("Markdown"),
|
|
11
|
+
when: whenSchema.optional(),
|
|
12
|
+
deferDate: dateField.optional(),
|
|
13
|
+
deadline: dateField.optional(),
|
|
14
|
+
estimateMinutes: z.number().optional(),
|
|
15
|
+
reviewInterval: reviewIntervalSchema.optional(),
|
|
16
|
+
};
|
|
17
|
+
const createProjectSchema = z.object({ ...projectFields, idempotencyKey });
|
|
18
|
+
export function createProject(client, args) {
|
|
19
|
+
const { idempotencyKey: key, ...body } = args;
|
|
20
|
+
return client.post("/v1/projects", body, { idempotencyKey: key });
|
|
21
|
+
}
|
|
22
|
+
const listProjectsSchema = z.object({
|
|
23
|
+
ids: z.array(z.string()).optional().describe("Multi-get by id; ignores other filters"),
|
|
24
|
+
gardenId: z.string().optional(),
|
|
25
|
+
status: z.array(statusEnum).optional(),
|
|
26
|
+
deferred: z.enum(["respect", "all"]).optional(),
|
|
27
|
+
deadlineBefore: dateField.optional(),
|
|
28
|
+
deadlineAfter: dateField.optional(),
|
|
29
|
+
dueForReview: z.boolean().optional(),
|
|
30
|
+
includeCanceled: z.boolean().optional(),
|
|
31
|
+
sort: z.string().optional(),
|
|
32
|
+
limit: z.number().int().positive().optional(),
|
|
33
|
+
cursor: z.string().optional(),
|
|
34
|
+
});
|
|
35
|
+
export function listProjects(client, args) {
|
|
36
|
+
return client.get("/v1/projects", {
|
|
37
|
+
ids: csv(args.ids),
|
|
38
|
+
gardenId: args.gardenId,
|
|
39
|
+
status: csv(args.status),
|
|
40
|
+
deferred: args.deferred,
|
|
41
|
+
deadlineBefore: args.deadlineBefore,
|
|
42
|
+
deadlineAfter: args.deadlineAfter,
|
|
43
|
+
dueForReview: args.dueForReview,
|
|
44
|
+
includeCanceled: args.includeCanceled,
|
|
45
|
+
sort: args.sort,
|
|
46
|
+
limit: args.limit,
|
|
47
|
+
cursor: args.cursor,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const getProjectSchema = z.object({ id: z.string() });
|
|
51
|
+
export function getProject(client, args) {
|
|
52
|
+
return client.get(`/v1/projects/${args.id}`);
|
|
53
|
+
}
|
|
54
|
+
const updateProjectSchema = z.object({
|
|
55
|
+
id: z.string(),
|
|
56
|
+
status: statusEnum.optional(),
|
|
57
|
+
name: z.string().optional(),
|
|
58
|
+
notes: z.string().optional(),
|
|
59
|
+
gardenId: z.string().optional(),
|
|
60
|
+
when: whenSchema.optional(),
|
|
61
|
+
deferDate: dateField.nullable().optional().describe("null clears the defer date"),
|
|
62
|
+
deadline: dateField.nullable().optional().describe("null clears the deadline"),
|
|
63
|
+
estimateMinutes: z.number().optional(),
|
|
64
|
+
reviewInterval: reviewIntervalSchema
|
|
65
|
+
.nullable()
|
|
66
|
+
.optional()
|
|
67
|
+
.describe("null clears the review cadence"),
|
|
68
|
+
});
|
|
69
|
+
export function updateProject(client, args) {
|
|
70
|
+
const { id, ...patch } = args;
|
|
71
|
+
return client.patch(`/v1/projects/${id}`, patch);
|
|
72
|
+
}
|
|
73
|
+
const deleteProjectSchema = z.object({ id: z.string() });
|
|
74
|
+
export function deleteProject(client, args) {
|
|
75
|
+
return client.del(`/v1/projects/${args.id}`);
|
|
76
|
+
}
|
|
77
|
+
const createProjectsSchema = z.object({
|
|
78
|
+
projects: z.array(z.object(projectFields)),
|
|
79
|
+
partial: z.boolean().optional(),
|
|
80
|
+
idempotencyKey,
|
|
81
|
+
});
|
|
82
|
+
export function createProjects(client, args) {
|
|
83
|
+
return client.post("/v1/projects/batch", { items: args.projects, partial: args.partial }, { idempotencyKey: args.idempotencyKey });
|
|
84
|
+
}
|
|
85
|
+
const updateProjectsSchema = z.object({
|
|
86
|
+
projects: z.array(updateProjectSchema),
|
|
87
|
+
partial: z.boolean().optional(),
|
|
88
|
+
});
|
|
89
|
+
export function updateProjects(client, args) {
|
|
90
|
+
return client.patch("/v1/projects/batch", {
|
|
91
|
+
items: args.projects,
|
|
92
|
+
partial: args.partial,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
export function registerProjectTools(server, client) {
|
|
96
|
+
server.registerTool("create_project", {
|
|
97
|
+
title: "Create project",
|
|
98
|
+
description: "Create a project in a garden.",
|
|
99
|
+
inputSchema: createProjectSchema.shape,
|
|
100
|
+
}, (args) => runTool(() => createProject(client, args)));
|
|
101
|
+
server.registerTool("list_projects", {
|
|
102
|
+
title: "List projects",
|
|
103
|
+
description: "List/filter projects, or multi-get by ids.",
|
|
104
|
+
inputSchema: listProjectsSchema.shape,
|
|
105
|
+
}, (args) => runTool(() => listProjects(client, args)));
|
|
106
|
+
server.registerTool("get_project", {
|
|
107
|
+
title: "Get project",
|
|
108
|
+
description: "Fetch one project by id.",
|
|
109
|
+
inputSchema: getProjectSchema.shape,
|
|
110
|
+
}, (args) => runTool(() => getProject(client, args)));
|
|
111
|
+
server.registerTool("update_project", {
|
|
112
|
+
title: "Update project",
|
|
113
|
+
description: "Patch project fields and/or drive its status.",
|
|
114
|
+
inputSchema: updateProjectSchema.shape,
|
|
115
|
+
}, (args) => runTool(() => updateProject(client, args)));
|
|
116
|
+
server.registerTool("delete_project", {
|
|
117
|
+
title: "Delete project",
|
|
118
|
+
description: "Soft-delete (drop) a project.",
|
|
119
|
+
inputSchema: deleteProjectSchema.shape,
|
|
120
|
+
}, (args) => runTool(() => deleteProject(client, args)));
|
|
121
|
+
server.registerTool("create_projects", {
|
|
122
|
+
title: "Create projects (batch)",
|
|
123
|
+
description: "Create many projects in one transaction (or partial).",
|
|
124
|
+
inputSchema: createProjectsSchema.shape,
|
|
125
|
+
}, (args) => runTool(() => createProjects(client, args)));
|
|
126
|
+
server.registerTool("update_projects", {
|
|
127
|
+
title: "Update projects (batch)",
|
|
128
|
+
description: "Patch many projects by id in one transaction (or partial).",
|
|
129
|
+
inputSchema: updateProjectsSchema.shape,
|
|
130
|
+
}, (args) => runTool(() => updateProjects(client, args)));
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Pure HTML rendering for the read-only MCPUI views. User/AI content (titles,
|
|
2
|
+
// names) is escaped before interpolation - these strings are untrusted and end
|
|
3
|
+
// up inside an iframe. Kept pure (no SDK, no I/O) so the markup is unit-tested
|
|
4
|
+
// directly. Inline write actions come in a later sub-stage.
|
|
5
|
+
export function escapeHtml(value) {
|
|
6
|
+
return String(value ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
7
|
+
}
|
|
8
|
+
function isoDay(ms) {
|
|
9
|
+
if (typeof ms !== "number")
|
|
10
|
+
return "";
|
|
11
|
+
const d = new Date(ms);
|
|
12
|
+
return Number.isNaN(d.getTime()) ? "" : d.toISOString().slice(0, 10);
|
|
13
|
+
}
|
|
14
|
+
function rows(items) {
|
|
15
|
+
if (!items.length)
|
|
16
|
+
return `<tr><td colspan="5" class="empty">Nothing here.</td></tr>`;
|
|
17
|
+
return items
|
|
18
|
+
.map((it) => {
|
|
19
|
+
const label = escapeHtml(it.title ?? it.name ?? "(untitled)");
|
|
20
|
+
return `<tr>
|
|
21
|
+
<td>${label}</td>
|
|
22
|
+
<td><span class="status ${escapeHtml(it.status)}">${escapeHtml(it.status)}</span></td>
|
|
23
|
+
<td>${escapeHtml(it.when?.type ?? "")}</td>
|
|
24
|
+
<td>${escapeHtml(it.priority ?? "")}</td>
|
|
25
|
+
<td>${escapeHtml(isoDay(it.deadline) || isoDay(it.nextReviewAt))}</td>
|
|
26
|
+
</tr>`;
|
|
27
|
+
})
|
|
28
|
+
.join("");
|
|
29
|
+
}
|
|
30
|
+
export function section(heading, items) {
|
|
31
|
+
return `<section>
|
|
32
|
+
<h2>${escapeHtml(heading)} <span class="count">${items.length}</span></h2>
|
|
33
|
+
<table>
|
|
34
|
+
<thead><tr><th>Title</th><th>Status</th><th>When</th><th>Priority</th><th>Date</th></tr></thead>
|
|
35
|
+
<tbody>${rows(items)}</tbody>
|
|
36
|
+
</table>
|
|
37
|
+
</section>`;
|
|
38
|
+
}
|
|
39
|
+
export function htmlDoc(title, body) {
|
|
40
|
+
return `<!doctype html>
|
|
41
|
+
<html lang="en">
|
|
42
|
+
<head>
|
|
43
|
+
<meta charset="utf-8" />
|
|
44
|
+
<title>${escapeHtml(title)}</title>
|
|
45
|
+
<style>
|
|
46
|
+
:root { font-family: system-ui, sans-serif; color: #1a1a1a; }
|
|
47
|
+
body { margin: 0; padding: 16px; }
|
|
48
|
+
h1 { font-size: 18px; margin: 0 0 12px; }
|
|
49
|
+
h2 { font-size: 14px; margin: 16px 0 6px; text-transform: uppercase; letter-spacing: .04em; color: #555; }
|
|
50
|
+
.count { color: #999; font-weight: 400; }
|
|
51
|
+
table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
|
52
|
+
th, td { text-align: left; padding: 6px 8px; border-bottom: 1px solid #eee; }
|
|
53
|
+
th { color: #888; font-weight: 500; }
|
|
54
|
+
.empty { color: #aaa; font-style: italic; }
|
|
55
|
+
.status { font-size: 11px; padding: 1px 6px; border-radius: 8px; background: #eee; }
|
|
56
|
+
.status.in_progress { background: #fde68a; }
|
|
57
|
+
.status.done { background: #bbf7d0; }
|
|
58
|
+
.status.canceled { background: #fecaca; }
|
|
59
|
+
.status.backlog { background: #e5e7eb; }
|
|
60
|
+
</style>
|
|
61
|
+
</head>
|
|
62
|
+
<body>
|
|
63
|
+
<h1>${escapeHtml(title)}</h1>
|
|
64
|
+
${body}
|
|
65
|
+
</body>
|
|
66
|
+
</html>`;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/tools/render.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,+EAA+E;AAC/E,+EAA+E;AAC/E,4DAA4D;AAC5D,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAChC,UAAU,EACV,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CACvE,CAAC,CACQ,CACd,CAAC;AACJ,CAAC;AAaD,SAAS,MAAM,CAAC,EAAW;IACzB,IAAI,OAAO,EAAE,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IACvB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,IAAI,CAAC,KAAa;IACzB,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,2DAA2D,CAAC;IACtF,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QACV,MAAM,KAAK,GAAG,UAAU,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC;QAC9D,OAAO;YACD,KAAK;gCACe,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC;YACnE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;YAC/B,UAAU,CAAC,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC;YAC7B,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;UAC5D,CAAC;IACP,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe,EAAE,KAAa;IACpD,OAAO;UACC,UAAU,CAAC,OAAO,CAAC,wBAAwB,KAAK,CAAC,MAAM;;;eAGlD,IAAI,CAAC,KAAK,CAAC;;aAEb,CAAC;AACd,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,IAAY;IACjD,OAAO;;;;SAIA,UAAU,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;MAmBpB,UAAU,CAAC,KAAK,CAAC;EACrB,IAAI;;QAEE,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Shared Zod fragments mirroring the /v1 field shapes. These give the model
|
|
2
|
+
// typed, described inputs; the API + guard layer remain the real validator, so
|
|
3
|
+
// these stay permissive (e.g. dates accept epoch ms OR natural language) and a
|
|
4
|
+
// rejected value surfaces as an API error mapped to an MCP tool error.
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
export const statusEnum = z.enum(["backlog", "todo", "in_progress", "done", "canceled"]);
|
|
7
|
+
export const priorityEnum = z.enum(["none", "low", "medium", "high"]);
|
|
8
|
+
export const whenEnum = z.enum(["today", "anytime", "someday"]);
|
|
9
|
+
export const whenSchema = z
|
|
10
|
+
.object({ type: whenEnum })
|
|
11
|
+
.describe("Intent bucket: today / anytime / someday (no date)");
|
|
12
|
+
export const dateField = z
|
|
13
|
+
.union([z.number(), z.string()])
|
|
14
|
+
.describe("Epoch milliseconds, or an ISO / natural-language date like 'friday'");
|
|
15
|
+
export const recurrenceSchema = z.object({
|
|
16
|
+
mode: z.enum(["on_completion", "on_schedule"]),
|
|
17
|
+
frequency: z.enum(["day", "week", "month", "year"]),
|
|
18
|
+
interval: z.number().int().positive(),
|
|
19
|
+
byWeekday: z
|
|
20
|
+
.array(z.number().int().min(0).max(6))
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("Weekly only: 0=Sun .. 6=Sat"),
|
|
23
|
+
});
|
|
24
|
+
export const reviewIntervalSchema = z.object({
|
|
25
|
+
value: z.number().int().positive(),
|
|
26
|
+
unit: z.enum(["day", "week", "month"]),
|
|
27
|
+
});
|
|
28
|
+
export const checklistItemSchema = z.object({
|
|
29
|
+
title: z.string(),
|
|
30
|
+
done: z.boolean().optional(),
|
|
31
|
+
order: z.number().optional(),
|
|
32
|
+
});
|
|
33
|
+
export const idempotencyKey = z
|
|
34
|
+
.string()
|
|
35
|
+
.optional()
|
|
36
|
+
.describe("Optional Idempotency-Key so a retried create does not duplicate");
|
|
37
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/tools/schemas.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,+EAA+E;AAC/E,+EAA+E;AAC/E,uEAAuE;AACvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AACzF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AACtE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAEhE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;KAC1B,QAAQ,CAAC,oDAAoD,CAAC,CAAC;AAElE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC;KACvB,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;KAC/B,QAAQ,CAAC,qEAAqE,CAAC,CAAC;AAEnF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;IAC9C,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACrC,SAAS,EAAE,CAAC;SACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACrC,QAAQ,EAAE;SACV,QAAQ,CAAC,6BAA6B,CAAC;CAC3C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAClC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC5B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,QAAQ,CAAC,iEAAiE,CAAC,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Tag tools: flat, vault-scoped labels. The API exposes create / list / get /
|
|
2
|
+
// update / delete (delete detaches the tag from every task first).
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { runTool } from "../result.js";
|
|
5
|
+
import { idempotencyKey } from "./schemas.js";
|
|
6
|
+
const createTagSchema = z.object({
|
|
7
|
+
name: z.string(),
|
|
8
|
+
color: z.string().optional(),
|
|
9
|
+
idempotencyKey,
|
|
10
|
+
});
|
|
11
|
+
export function createTag(client, args) {
|
|
12
|
+
const { idempotencyKey: key, ...body } = args;
|
|
13
|
+
return client.post("/v1/tags", body, { idempotencyKey: key });
|
|
14
|
+
}
|
|
15
|
+
const listTagsSchema = z.object({
|
|
16
|
+
ids: z.array(z.string()).optional(),
|
|
17
|
+
limit: z.number().int().positive().optional(),
|
|
18
|
+
});
|
|
19
|
+
export function listTags(client, args) {
|
|
20
|
+
return client.get("/v1/tags", {
|
|
21
|
+
ids: args.ids?.length ? args.ids.join(",") : undefined,
|
|
22
|
+
limit: args.limit,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const getTagSchema = z.object({ id: z.string() });
|
|
26
|
+
export function getTag(client, args) {
|
|
27
|
+
return client.get(`/v1/tags/${args.id}`);
|
|
28
|
+
}
|
|
29
|
+
const updateTagSchema = z.object({
|
|
30
|
+
id: z.string(),
|
|
31
|
+
name: z.string().optional(),
|
|
32
|
+
color: z.string().optional(),
|
|
33
|
+
});
|
|
34
|
+
export function updateTag(client, args) {
|
|
35
|
+
const { id, ...patch } = args;
|
|
36
|
+
return client.patch(`/v1/tags/${id}`, patch);
|
|
37
|
+
}
|
|
38
|
+
const deleteTagSchema = z.object({ id: z.string() });
|
|
39
|
+
export function deleteTag(client, args) {
|
|
40
|
+
return client.del(`/v1/tags/${args.id}`);
|
|
41
|
+
}
|
|
42
|
+
export function registerTagTools(server, client) {
|
|
43
|
+
server.registerTool("create_tag", {
|
|
44
|
+
title: "Create tag",
|
|
45
|
+
description: "Create a vault-scoped tag.",
|
|
46
|
+
inputSchema: createTagSchema.shape,
|
|
47
|
+
}, (args) => runTool(() => createTag(client, args)));
|
|
48
|
+
server.registerTool("list_tags", {
|
|
49
|
+
title: "List tags",
|
|
50
|
+
description: "List tags, or multi-get by ids.",
|
|
51
|
+
inputSchema: listTagsSchema.shape,
|
|
52
|
+
}, (args) => runTool(() => listTags(client, args)));
|
|
53
|
+
server.registerTool("get_tag", {
|
|
54
|
+
title: "Get tag",
|
|
55
|
+
description: "Fetch one tag by id.",
|
|
56
|
+
inputSchema: getTagSchema.shape,
|
|
57
|
+
}, (args) => runTool(() => getTag(client, args)));
|
|
58
|
+
server.registerTool("update_tag", {
|
|
59
|
+
title: "Update tag",
|
|
60
|
+
description: "Rename or recolor a tag.",
|
|
61
|
+
inputSchema: updateTagSchema.shape,
|
|
62
|
+
}, (args) => runTool(() => updateTag(client, args)));
|
|
63
|
+
server.registerTool("delete_tag", {
|
|
64
|
+
title: "Delete tag",
|
|
65
|
+
description: "Delete a tag, detaching it from every task.",
|
|
66
|
+
inputSchema: deleteTagSchema.shape,
|
|
67
|
+
}, (args) => runTool(() => deleteTag(client, args)));
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/tools/tags.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// Task tools: single + batch CRUD, multi-get, and tag attach/detach. Each is a
|
|
2
|
+
// thin call to /v1; the API enforces ownership, the status machine, and all
|
|
3
|
+
// other guards.
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { runTool } from "../result.js";
|
|
6
|
+
import { checklistItemSchema, dateField, idempotencyKey, priorityEnum, recurrenceSchema, reviewIntervalSchema, statusEnum, whenEnum, whenSchema, } from "./schemas.js";
|
|
7
|
+
const csv = (a) => a?.length ? a.join(",") : undefined;
|
|
8
|
+
const taskFields = {
|
|
9
|
+
gardenId: z.string().describe("Garden the task belongs to (required on create)"),
|
|
10
|
+
projectId: z.string().optional().describe("Project within the same garden"),
|
|
11
|
+
title: z.string(),
|
|
12
|
+
notes: z.string().optional().describe("Markdown"),
|
|
13
|
+
when: whenSchema.optional(),
|
|
14
|
+
deferDate: dateField.optional(),
|
|
15
|
+
deadline: dateField.optional(),
|
|
16
|
+
priority: priorityEnum.optional(),
|
|
17
|
+
estimateMinutes: z.number().optional(),
|
|
18
|
+
checklist: z.array(checklistItemSchema).optional(),
|
|
19
|
+
recurrence: recurrenceSchema.optional(),
|
|
20
|
+
reviewInterval: reviewIntervalSchema.optional(),
|
|
21
|
+
tagIds: z.array(z.string()).optional(),
|
|
22
|
+
};
|
|
23
|
+
const createTaskSchema = z.object({ ...taskFields, idempotencyKey });
|
|
24
|
+
export function createTask(client, args) {
|
|
25
|
+
const { idempotencyKey: key, ...body } = args;
|
|
26
|
+
return client.post("/v1/tasks", body, { idempotencyKey: key });
|
|
27
|
+
}
|
|
28
|
+
const listTasksSchema = z.object({
|
|
29
|
+
ids: z.array(z.string()).optional().describe("Multi-get by id; ignores other filters"),
|
|
30
|
+
gardenId: z.string().optional(),
|
|
31
|
+
projectId: z.string().optional(),
|
|
32
|
+
status: z.array(statusEnum).optional(),
|
|
33
|
+
priority: z.array(priorityEnum).optional(),
|
|
34
|
+
when: z.array(whenEnum).optional(),
|
|
35
|
+
tag: z.array(z.string()).optional().describe("Tag ids to filter by"),
|
|
36
|
+
deferred: z
|
|
37
|
+
.enum(["respect", "all"])
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("respect hides future-deferred; default all"),
|
|
40
|
+
deferBefore: dateField.optional(),
|
|
41
|
+
deferAfter: dateField.optional(),
|
|
42
|
+
deadlineBefore: dateField.optional(),
|
|
43
|
+
deadlineAfter: dateField.optional(),
|
|
44
|
+
dueForReview: z.boolean().optional(),
|
|
45
|
+
q: z.string().optional().describe("Substring text filter"),
|
|
46
|
+
includeCanceled: z.boolean().optional(),
|
|
47
|
+
sort: z
|
|
48
|
+
.string()
|
|
49
|
+
.optional()
|
|
50
|
+
.describe("field:dir,field:dir; primary must be index-backed"),
|
|
51
|
+
limit: z.number().int().positive().optional(),
|
|
52
|
+
cursor: z.string().optional(),
|
|
53
|
+
});
|
|
54
|
+
export function listTasks(client, args) {
|
|
55
|
+
return client.get("/v1/tasks", {
|
|
56
|
+
ids: csv(args.ids),
|
|
57
|
+
gardenId: args.gardenId,
|
|
58
|
+
projectId: args.projectId,
|
|
59
|
+
status: csv(args.status),
|
|
60
|
+
priority: csv(args.priority),
|
|
61
|
+
when: csv(args.when),
|
|
62
|
+
tag: csv(args.tag),
|
|
63
|
+
deferred: args.deferred,
|
|
64
|
+
deferBefore: args.deferBefore,
|
|
65
|
+
deferAfter: args.deferAfter,
|
|
66
|
+
deadlineBefore: args.deadlineBefore,
|
|
67
|
+
deadlineAfter: args.deadlineAfter,
|
|
68
|
+
dueForReview: args.dueForReview,
|
|
69
|
+
q: args.q,
|
|
70
|
+
includeCanceled: args.includeCanceled,
|
|
71
|
+
sort: args.sort,
|
|
72
|
+
limit: args.limit,
|
|
73
|
+
cursor: args.cursor,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const getTaskSchema = z.object({ id: z.string() });
|
|
77
|
+
export function getTask(client, args) {
|
|
78
|
+
return client.get(`/v1/tasks/${args.id}`);
|
|
79
|
+
}
|
|
80
|
+
const updateTaskSchema = z.object({
|
|
81
|
+
id: z.string(),
|
|
82
|
+
status: statusEnum
|
|
83
|
+
.optional()
|
|
84
|
+
.describe("Drives the status machine; completing a recurring task spawns the next"),
|
|
85
|
+
title: z.string().optional(),
|
|
86
|
+
notes: z.string().optional(),
|
|
87
|
+
gardenId: z.string().optional(),
|
|
88
|
+
projectId: z.string().nullable().optional().describe("null clears the project"),
|
|
89
|
+
when: whenSchema.optional(),
|
|
90
|
+
deferDate: dateField.nullable().optional().describe("null clears the defer date"),
|
|
91
|
+
deadline: dateField.nullable().optional().describe("null clears the deadline"),
|
|
92
|
+
priority: priorityEnum.optional(),
|
|
93
|
+
estimateMinutes: z.number().optional(),
|
|
94
|
+
checklist: z
|
|
95
|
+
.array(checklistItemSchema)
|
|
96
|
+
.optional()
|
|
97
|
+
.describe("Replaces the whole checklist"),
|
|
98
|
+
recurrence: recurrenceSchema.nullable().optional().describe("null clears recurrence"),
|
|
99
|
+
reviewInterval: reviewIntervalSchema
|
|
100
|
+
.nullable()
|
|
101
|
+
.optional()
|
|
102
|
+
.describe("null clears the review cadence"),
|
|
103
|
+
});
|
|
104
|
+
export function updateTask(client, args) {
|
|
105
|
+
const { id, ...patch } = args;
|
|
106
|
+
return client.patch(`/v1/tasks/${id}`, patch);
|
|
107
|
+
}
|
|
108
|
+
const deleteTaskSchema = z.object({ id: z.string() });
|
|
109
|
+
export function deleteTask(client, args) {
|
|
110
|
+
return client.del(`/v1/tasks/${args.id}`);
|
|
111
|
+
}
|
|
112
|
+
const createTasksSchema = z.object({
|
|
113
|
+
tasks: z.array(z.object(taskFields)).describe("Tasks to create"),
|
|
114
|
+
partial: z
|
|
115
|
+
.boolean()
|
|
116
|
+
.optional()
|
|
117
|
+
.describe("Best-effort per-item instead of all-or-nothing"),
|
|
118
|
+
idempotencyKey,
|
|
119
|
+
});
|
|
120
|
+
export function createTasks(client, args) {
|
|
121
|
+
return client.post("/v1/tasks/batch", { items: args.tasks, partial: args.partial }, { idempotencyKey: args.idempotencyKey });
|
|
122
|
+
}
|
|
123
|
+
const updateTasksSchema = z.object({
|
|
124
|
+
tasks: z
|
|
125
|
+
.array(updateTaskSchema)
|
|
126
|
+
.describe("Patches; each item is { id, ...fields to change } — same fields as update"),
|
|
127
|
+
partial: z.boolean().optional(),
|
|
128
|
+
});
|
|
129
|
+
export function updateTasks(client, args) {
|
|
130
|
+
return client.patch("/v1/tasks/batch", { items: args.tasks, partial: args.partial });
|
|
131
|
+
}
|
|
132
|
+
const taskTagsSchema = z.object({ id: z.string(), tagIds: z.array(z.string()) });
|
|
133
|
+
export function addTaskTags(client, args) {
|
|
134
|
+
return client.post(`/v1/tasks/${args.id}/tags`, { tagIds: args.tagIds });
|
|
135
|
+
}
|
|
136
|
+
export function removeTaskTags(client, args) {
|
|
137
|
+
return client.request("DELETE", `/v1/tasks/${args.id}/tags`, {
|
|
138
|
+
body: { tagIds: args.tagIds },
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
export function registerTaskTools(server, client) {
|
|
142
|
+
server.registerTool("create_task", {
|
|
143
|
+
title: "Create task",
|
|
144
|
+
description: "Create a task (must belong to a garden).",
|
|
145
|
+
inputSchema: createTaskSchema.shape,
|
|
146
|
+
}, (args) => runTool(() => createTask(client, args)));
|
|
147
|
+
server.registerTool("list_tasks", {
|
|
148
|
+
title: "List tasks",
|
|
149
|
+
description: "List/filter tasks, or multi-get by ids. Cursor-paginated.",
|
|
150
|
+
inputSchema: listTasksSchema.shape,
|
|
151
|
+
}, (args) => runTool(() => listTasks(client, args)));
|
|
152
|
+
server.registerTool("get_task", {
|
|
153
|
+
title: "Get task",
|
|
154
|
+
description: "Fetch one task by id (full detail).",
|
|
155
|
+
inputSchema: getTaskSchema.shape,
|
|
156
|
+
}, (args) => runTool(() => getTask(client, args)));
|
|
157
|
+
server.registerTool("update_task", {
|
|
158
|
+
title: "Update task",
|
|
159
|
+
description: "Patch task fields and/or drive its status.",
|
|
160
|
+
inputSchema: updateTaskSchema.shape,
|
|
161
|
+
}, (args) => runTool(() => updateTask(client, args)));
|
|
162
|
+
server.registerTool("delete_task", {
|
|
163
|
+
title: "Delete task",
|
|
164
|
+
description: "Soft-delete (drop) a task.",
|
|
165
|
+
inputSchema: deleteTaskSchema.shape,
|
|
166
|
+
}, (args) => runTool(() => deleteTask(client, args)));
|
|
167
|
+
server.registerTool("create_tasks", {
|
|
168
|
+
title: "Create tasks (batch)",
|
|
169
|
+
description: "Create many tasks in one transaction (or partial).",
|
|
170
|
+
inputSchema: createTasksSchema.shape,
|
|
171
|
+
}, (args) => runTool(() => createTasks(client, args)));
|
|
172
|
+
server.registerTool("update_tasks", {
|
|
173
|
+
title: "Update tasks (batch)",
|
|
174
|
+
description: "Patch many tasks by id in one transaction (or partial).",
|
|
175
|
+
inputSchema: updateTasksSchema.shape,
|
|
176
|
+
}, (args) => runTool(() => updateTasks(client, args)));
|
|
177
|
+
server.registerTool("add_task_tags", {
|
|
178
|
+
title: "Add task tags",
|
|
179
|
+
description: "Attach tags to a task.",
|
|
180
|
+
inputSchema: taskTagsSchema.shape,
|
|
181
|
+
}, (args) => runTool(() => addTaskTags(client, args)));
|
|
182
|
+
server.registerTool("remove_task_tags", {
|
|
183
|
+
title: "Remove task tags",
|
|
184
|
+
description: "Detach tags from a task.",
|
|
185
|
+
inputSchema: taskTagsSchema.shape,
|
|
186
|
+
}, (args) => runTool(() => removeTaskTags(client, args)));
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/ui.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Read-only MCPUI view resources: a UI client renders these as HTML; a plain
|
|
2
|
+
// client still gets the underlying data via get_view / get_reviews. Each tool
|
|
3
|
+
// fetches from /v1 and returns a ui:// resource. Inline write actions (complete,
|
|
4
|
+
// defer, reschedule from the UI) are a later sub-stage.
|
|
5
|
+
import { createUIResource } from "@mcp-ui/server";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { errorResult } from "../result.js";
|
|
8
|
+
import { htmlDoc, section } from "./render.js";
|
|
9
|
+
async function uiResult(uri, html) {
|
|
10
|
+
const resource = await createUIResource({
|
|
11
|
+
uri,
|
|
12
|
+
content: { type: "rawHtml", htmlString: html },
|
|
13
|
+
encoding: "text",
|
|
14
|
+
});
|
|
15
|
+
return { content: [resource] };
|
|
16
|
+
}
|
|
17
|
+
const VIEW_TITLES = {
|
|
18
|
+
today: "Today",
|
|
19
|
+
upcoming: "Upcoming",
|
|
20
|
+
anytime: "Anytime",
|
|
21
|
+
someday: "Someday",
|
|
22
|
+
overdue: "Overdue",
|
|
23
|
+
};
|
|
24
|
+
const viewUiSchema = z.object({
|
|
25
|
+
view: z.enum(["today", "upcoming", "anytime", "someday", "overdue"]),
|
|
26
|
+
tz: z.string().optional(),
|
|
27
|
+
limit: z.number().int().positive().optional(),
|
|
28
|
+
});
|
|
29
|
+
export async function viewUi(client, args) {
|
|
30
|
+
try {
|
|
31
|
+
const data = await client.get(`/v1/views/${args.view}`, {
|
|
32
|
+
tz: args.tz,
|
|
33
|
+
limit: args.limit,
|
|
34
|
+
});
|
|
35
|
+
const title = VIEW_TITLES[args.view];
|
|
36
|
+
const html = htmlDoc(title, section(title, data.items ?? []));
|
|
37
|
+
return uiResult(`ui://open-brain/view/${args.view}`, html);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return errorResult(error);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const reviewQueueUiSchema = z.object({ gardenId: z.string().optional() });
|
|
44
|
+
export async function reviewQueueUi(client, args) {
|
|
45
|
+
try {
|
|
46
|
+
const data = await client.get("/v1/reviews", {
|
|
47
|
+
gardenId: args.gardenId,
|
|
48
|
+
});
|
|
49
|
+
const html = htmlDoc("Review queue", section("Tasks", data.tasks ?? []) + section("Projects", data.projects ?? []));
|
|
50
|
+
return uiResult("ui://open-brain/reviews", html);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return errorResult(error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const gardenBoardUiSchema = z.object({ gardenId: z.string() });
|
|
57
|
+
export async function gardenBoardUi(client, args) {
|
|
58
|
+
try {
|
|
59
|
+
const garden = await client.get(`/v1/gardens/${args.gardenId}`);
|
|
60
|
+
// The garden review endpoint returns all non-canceled items under the garden.
|
|
61
|
+
const board = await client.get(`/v1/gardens/${args.gardenId}/review`);
|
|
62
|
+
const html = htmlDoc(`Garden: ${garden.name ?? args.gardenId}`, section("Projects", board.projects ?? []) + section("Tasks", board.tasks ?? []));
|
|
63
|
+
return uiResult(`ui://open-brain/garden/${args.gardenId}`, html);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
return errorResult(error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function registerUiTools(server, client) {
|
|
70
|
+
server.registerTool("ui_view", {
|
|
71
|
+
title: "View (UI)",
|
|
72
|
+
description: "Render a computed view (today/upcoming/anytime/someday/overdue) as an HTML UI.",
|
|
73
|
+
inputSchema: viewUiSchema.shape,
|
|
74
|
+
}, (args) => viewUi(client, args));
|
|
75
|
+
server.registerTool("ui_review_queue", {
|
|
76
|
+
title: "Review queue (UI)",
|
|
77
|
+
description: "Render the due-review queue (tasks + projects) as an HTML UI.",
|
|
78
|
+
inputSchema: reviewQueueUiSchema.shape,
|
|
79
|
+
}, (args) => reviewQueueUi(client, args));
|
|
80
|
+
server.registerTool("ui_garden_board", {
|
|
81
|
+
title: "Garden board (UI)",
|
|
82
|
+
description: "Render a garden's projects and tasks as an HTML board.",
|
|
83
|
+
inputSchema: gardenBoardUiSchema.shape,
|
|
84
|
+
}, (args) => gardenBoardUi(client, args));
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/tools/ui.ts"],"names":[],"mappings":"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"}
|