keepsake-mcp 1.12.0 → 1.13.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/README.md +6 -6
- package/build/tools.js +19 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -143,7 +143,7 @@ rather than in the chat, which disappears.
|
|
|
143
143
|
### Entries (Interactions)
|
|
144
144
|
| Tool | Description |
|
|
145
145
|
|------|-------------|
|
|
146
|
-
| `list_entries` | List interactions (calls, emails, meetings, etc.) |
|
|
146
|
+
| `list_entries` | List interactions (calls, emails, meetings, etc.) — filter by type, contact, company, page (`tag_id`), dates |
|
|
147
147
|
| `create_entry` | Log a new interaction — supports `#tag#` and `[[tag]]` syntax |
|
|
148
148
|
| `update_entry` | Update an interaction |
|
|
149
149
|
| `delete_entry` | Delete an interaction |
|
|
@@ -151,7 +151,7 @@ rather than in the chat, which disappears.
|
|
|
151
151
|
### Tasks
|
|
152
152
|
| Tool | Description |
|
|
153
153
|
|------|-------------|
|
|
154
|
-
| `list_tasks` | List tasks
|
|
154
|
+
| `list_tasks` | List tasks — filter by status, date, company, page (`tag_id`) |
|
|
155
155
|
| `get_task` | Get a task with its tags, contacts, companies and linked notes |
|
|
156
156
|
| `create_task` | Create a task — supports `#tag#` and `[[tag]]` syntax |
|
|
157
157
|
| `update_task` | Update task fields |
|
|
@@ -165,12 +165,12 @@ rather than in the chat, which disappears.
|
|
|
165
165
|
### QuickNotes
|
|
166
166
|
| Tool | Description |
|
|
167
167
|
|------|-------------|
|
|
168
|
-
| `list_notes` | List notes
|
|
168
|
+
| `list_notes` | List notes — filter by pinned/archived, day, company, page (`tag_id`) |
|
|
169
169
|
| `get_note` | Get one note by ID with its tags, contacts, tasks and linked notes |
|
|
170
170
|
| `create_note` | Create a note — supports `#tag#` and `[[tag]]` syntax |
|
|
171
171
|
| `update_note` | Update note content |
|
|
172
172
|
| `delete_note` | Soft-delete (or permanent) |
|
|
173
|
-
| `pin_note` | Pin
|
|
173
|
+
| `pin_note` | Pin as a post-it (short reference always at hand) |
|
|
174
174
|
| `archive_note` | Archive a note |
|
|
175
175
|
| `restore_note` | Restore a deleted/archived note |
|
|
176
176
|
|
|
@@ -206,7 +206,7 @@ Material kept *alongside* a note without entering its text — an idea, a refere
|
|
|
206
206
|
| `list_tags` | List tags (lightweight — ordering arrays omitted), with optional name search (`q`) |
|
|
207
207
|
| `get_tag` | Get a tag by ID with all properties, including `tasks_order` (section markers `h:<header_id>`) |
|
|
208
208
|
| `create_tag` | Create a new tag |
|
|
209
|
-
| `update_tag` | Update a tag (name, description, color, icon,
|
|
209
|
+
| `update_tag` | Update a tag (name, description, color, icon, favorite, order of tasks and sections via `tasks_order`) |
|
|
210
210
|
| `delete_tag` | Permanently delete a tag and all its links |
|
|
211
211
|
| `get_tag_items` | Get items linked to a tag — filter by `types`/`status`, `summary` mode, task `sections` included |
|
|
212
212
|
| `link_tag` | Link any entity to a tag |
|
|
@@ -217,7 +217,7 @@ Material kept *alongside* a note without entering its text — an idea, a refere
|
|
|
217
217
|
|------|-------------|
|
|
218
218
|
| `list_task_headers` | List all task headers (section separators) |
|
|
219
219
|
| `get_task_header` | Get a task header by ID |
|
|
220
|
-
| `create_task_header` | Create a task header (section) |
|
|
220
|
+
| `create_task_header` | Create a task header (section) — insert `h:<id>` in the tag's `tasks_order` to place it |
|
|
221
221
|
| `update_task_header` | Update a task header (name, description, collapsed) |
|
|
222
222
|
| `delete_task_header` | Permanently delete a task header |
|
|
223
223
|
|
package/build/tools.js
CHANGED
|
@@ -295,7 +295,7 @@ export function registerAllTools(server, fetchApi) {
|
|
|
295
295
|
// ENTRIES (Interactions)
|
|
296
296
|
// ===========================================================================
|
|
297
297
|
server.registerTool("list_entries", {
|
|
298
|
-
description: "List interaction entries (calls, emails, meetings, events, etc.). Supports filtering by type, contact, and date range.",
|
|
298
|
+
description: "List interaction entries (calls, emails, meetings, events, etc.). Supports filtering by type, contact, company, tag (page) and date range.",
|
|
299
299
|
inputSchema: {
|
|
300
300
|
type: z
|
|
301
301
|
.enum(["call", "email", "meeting", "event", "gift", "letter", "message", "log", "other"])
|
|
@@ -303,14 +303,15 @@ export function registerAllTools(server, fetchApi) {
|
|
|
303
303
|
.describe("Filter by entry type"),
|
|
304
304
|
contact_id: z.string().uuid().optional().describe("Filter by associated contact ID"),
|
|
305
305
|
company_id: z.string().uuid().optional().describe("Only entries where this company is a participant"),
|
|
306
|
+
tag_id: z.string().uuid().optional().describe("Only entries linked to this tag (page)"),
|
|
306
307
|
from: z.string().optional().describe("Start date (YYYY-MM-DD)"),
|
|
307
308
|
to: z.string().optional().describe("End date (YYYY-MM-DD)"),
|
|
308
309
|
limit: z.number().int().positive().optional().describe("Max results (default 20)"),
|
|
309
310
|
offset: z.number().int().nonnegative().optional().describe("Pagination offset"),
|
|
310
311
|
},
|
|
311
312
|
annotations: { title: "List entries", readOnlyHint: true, openWorldHint: false },
|
|
312
|
-
}, async ({ type, contact_id, company_id, from, to, limit, offset }) => {
|
|
313
|
-
return toContent(await fetchApi(`/entries${qs({ type, contact_id, company_id, from, to, limit, offset })}`));
|
|
313
|
+
}, async ({ type, contact_id, company_id, tag_id, from, to, limit, offset }) => {
|
|
314
|
+
return toContent(await fetchApi(`/entries${qs({ type, contact_id, company_id, tag_id, from, to, limit, offset })}`));
|
|
314
315
|
});
|
|
315
316
|
server.registerTool("create_entry", {
|
|
316
317
|
description: "An ENTRY is a dated interaction log tied to contacts. Records something that happened (call, meeting, email…) on a specific date.\n\nCreate a new interaction entry. Content supports #tag# and [[tag]] syntax for automatic tag linking.",
|
|
@@ -377,7 +378,7 @@ export function registerAllTools(server, fetchApi) {
|
|
|
377
378
|
// TASKS
|
|
378
379
|
// ===========================================================================
|
|
379
380
|
server.registerTool("list_tasks", {
|
|
380
|
-
description: "List tasks. Filter by status (pending/completed), date_type, or
|
|
381
|
+
description: "List tasks. Filter by status (pending/completed), date_type, specific date, company, or tag (page) — e.g. tag_id + status=pending lists a project's open tasks.",
|
|
381
382
|
inputSchema: {
|
|
382
383
|
status: z.enum(["pending", "completed"]).optional().describe("Filter by status"),
|
|
383
384
|
date_type: z
|
|
@@ -386,12 +387,13 @@ export function registerAllTools(server, fetchApi) {
|
|
|
386
387
|
.describe("Filter by date type: specific (has a due date), asap (do as soon as possible), one_day (someday/no rush)"),
|
|
387
388
|
date: z.string().optional().describe("Filter by specific date (YYYY-MM-DD)"),
|
|
388
389
|
company_id: z.string().uuid().optional().describe("Only tasks linked directly to this company"),
|
|
390
|
+
tag_id: z.string().uuid().optional().describe("Only tasks linked to this tag (page)"),
|
|
389
391
|
limit: z.number().int().positive().optional().describe("Max results (default 20)"),
|
|
390
392
|
offset: z.number().int().nonnegative().optional().describe("Pagination offset"),
|
|
391
393
|
},
|
|
392
394
|
annotations: { title: "List tasks", readOnlyHint: true, openWorldHint: false },
|
|
393
|
-
}, async ({ status, date_type, date, company_id, limit, offset }) => {
|
|
394
|
-
return toContent(await fetchApi(`/tasks${qs({ status, date_type, date, company_id, limit, offset })}`));
|
|
395
|
+
}, async ({ status, date_type, date, company_id, tag_id, limit, offset }) => {
|
|
396
|
+
return toContent(await fetchApi(`/tasks${qs({ status, date_type, date, company_id, tag_id, limit, offset })}`));
|
|
395
397
|
});
|
|
396
398
|
server.registerTool("get_task", {
|
|
397
399
|
description: "Get a single task by ID, with its tags, linked contacts (contact_ids), linked companies (company_ids) and linked notes (note_ids). Use it when you already know which task you need instead of listing everything.",
|
|
@@ -540,7 +542,7 @@ export function registerAllTools(server, fetchApi) {
|
|
|
540
542
|
// QUICK NOTES
|
|
541
543
|
// ===========================================================================
|
|
542
544
|
server.registerTool("list_notes", {
|
|
543
|
-
description: "List notes. QuickNotes (inbox, not yet archived) and Notes (archived, permanent). Filter by pinned or archived status, or by the day(s) a note is linked to (`date`, or `date_from`/`date_to`) — e.g. \"what did I note for tomorrow?\". Each note carries `dates`, the days it is linked to.",
|
|
545
|
+
description: "List notes. QuickNotes (inbox, not yet archived) and Notes (archived, permanent). Filter by pinned or archived status, by tag (page) with `tag_id`, or by the day(s) a note is linked to (`date`, or `date_from`/`date_to`) — e.g. \"what did I note for tomorrow?\". Each note carries `dates`, the days it is linked to.",
|
|
544
546
|
inputSchema: {
|
|
545
547
|
pinned: z.boolean().optional().describe("Filter pinned notes only"),
|
|
546
548
|
archived: z.boolean().optional().describe("Filter by status: true = Notes (archived/permanent), false = QuickNotes (inbox)"),
|
|
@@ -548,12 +550,13 @@ export function registerAllTools(server, fetchApi) {
|
|
|
548
550
|
date_from: z.string().optional().describe("Only notes linked to a day on or after this date (YYYY-MM-DD)"),
|
|
549
551
|
date_to: z.string().optional().describe("Only notes linked to a day on or before this date (YYYY-MM-DD)"),
|
|
550
552
|
company_id: z.string().uuid().optional().describe("Only notes linked directly to this company"),
|
|
553
|
+
tag_id: z.string().uuid().optional().describe("Only notes linked to this tag (page)"),
|
|
551
554
|
limit: z.number().int().positive().optional().describe("Max results (default 20)"),
|
|
552
555
|
offset: z.number().int().nonnegative().optional().describe("Pagination offset"),
|
|
553
556
|
},
|
|
554
557
|
annotations: { title: "List notes", readOnlyHint: true, openWorldHint: false },
|
|
555
|
-
}, async ({ pinned, archived, date, date_from, date_to, company_id, limit, offset }) => {
|
|
556
|
-
return toContent(await fetchApi(`/notes${qs({ pinned, archived, date, date_from, date_to, company_id, limit, offset })}`));
|
|
558
|
+
}, async ({ pinned, archived, date, date_from, date_to, company_id, tag_id, limit, offset }) => {
|
|
559
|
+
return toContent(await fetchApi(`/notes${qs({ pinned, archived, date, date_from, date_to, company_id, tag_id, limit, offset })}`));
|
|
557
560
|
});
|
|
558
561
|
server.registerTool("get_note", {
|
|
559
562
|
description: "Get a single note by ID, including its tags, linked contacts, linked tasks, linked notes and the days it is linked to (`dates`). Use this when the user points you at one specific note (e.g. gives you its URL — the UUID is the last path segment) instead of listing everything.",
|
|
@@ -624,7 +627,7 @@ export function registerAllTools(server, fetchApi) {
|
|
|
624
627
|
return toContent(await fetchApi(`/notes/${id}${query}`, "DELETE"));
|
|
625
628
|
});
|
|
626
629
|
server.registerTool("pin_note", {
|
|
627
|
-
description: "Pin a QuickNote or Note so it
|
|
630
|
+
description: "Pin a QuickNote or Note so it stays in view. A pin is a POST-IT: a short reference the user wants always at hand (gate code, hotel room number, Wi-Fi password). Do not pin a note just because it is important — meeting prep is linked to its day, project material to a tag, actions become tasks. Pin only when the user asks or the note is clearly such a post-it.",
|
|
628
631
|
inputSchema: {
|
|
629
632
|
id: z.string().uuid().describe("Note UUID"),
|
|
630
633
|
},
|
|
@@ -809,14 +812,17 @@ export function registerAllTools(server, fetchApi) {
|
|
|
809
812
|
return toContent(await fetchApi("/tags", "POST", body));
|
|
810
813
|
});
|
|
811
814
|
server.registerTool("update_tag", {
|
|
812
|
-
description: "Update an existing tag. Only send the fields you want to change. Supports name, description, color, icon,
|
|
815
|
+
description: "Update an existing tag. Only send the fields you want to change. Supports name, description, color, icon, favorite status, and the order of the page's tasks and sections (tasks_order).",
|
|
813
816
|
inputSchema: {
|
|
814
817
|
id: z.string().uuid().describe("Tag UUID"),
|
|
815
818
|
name: z.string().optional().describe("Tag name"),
|
|
816
819
|
description: z.string().optional().describe("Tag description"),
|
|
817
820
|
color: z.string().optional().describe("Tag color (e.g. 'blue', 'red', 'green')"),
|
|
818
821
|
icon: z.string().optional().describe("Tag icon (emoji or icon name)"),
|
|
819
|
-
|
|
822
|
+
tasks_order: z
|
|
823
|
+
.array(z.string())
|
|
824
|
+
.optional()
|
|
825
|
+
.describe("Full display order of the page's tasks: task ids and \"h:<header_id>\" entries for sections, top to bottom. Read the current one with get_tag, insert or move entries, send the whole array back. Tasks listed after a section belong to it."),
|
|
820
826
|
is_favorite: z.boolean().optional().describe("Whether the tag is a favorite"),
|
|
821
827
|
},
|
|
822
828
|
annotations: { title: "Update tag", destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
@@ -881,7 +887,7 @@ export function registerAllTools(server, fetchApi) {
|
|
|
881
887
|
return toContent(await fetchApi(`/task-headers/${id}`));
|
|
882
888
|
});
|
|
883
889
|
server.registerTool("create_task_header", {
|
|
884
|
-
description: "Create a new task header (section separator).
|
|
890
|
+
description: "Create a new task header (section separator). To show it on a tag page, insert \"h:<header_id>\" into that tag's tasks_order (get_tag, then update_tag) where the section should start: the tasks listed after it belong to that section.",
|
|
885
891
|
inputSchema: {
|
|
886
892
|
name: z.string().describe("Header name"),
|
|
887
893
|
description: z.string().optional().describe("Optional description below the header"),
|