keepsake-mcp 1.4.0 → 1.6.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 +5 -4
- package/build/tools.js +26 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,7 +100,7 @@ Add to `.cursor/mcp.json` in your project:
|
|
|
100
100
|
}
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
## Available tools (
|
|
103
|
+
## Available tools (63)
|
|
104
104
|
|
|
105
105
|
### Contacts
|
|
106
106
|
| Tool | Description |
|
|
@@ -148,6 +148,7 @@ Add to `.cursor/mcp.json` in your project:
|
|
|
148
148
|
| Tool | Description |
|
|
149
149
|
|------|-------------|
|
|
150
150
|
| `list_notes` | List notes (filter by pinned/archived) |
|
|
151
|
+
| `get_note` | Get one note by ID with its tags, contacts, tasks and linked notes |
|
|
151
152
|
| `create_note` | Create a note — supports `#tag#` and `[[tag]]` syntax |
|
|
152
153
|
| `update_note` | Update note content |
|
|
153
154
|
| `delete_note` | Soft-delete (or permanent) |
|
|
@@ -165,12 +166,12 @@ Add to `.cursor/mcp.json` in your project:
|
|
|
165
166
|
### Tags
|
|
166
167
|
| Tool | Description |
|
|
167
168
|
|------|-------------|
|
|
168
|
-
| `list_tags` | List
|
|
169
|
-
| `get_tag` | Get a tag by ID with all properties
|
|
169
|
+
| `list_tags` | List tags (lightweight — ordering arrays omitted), with optional name search (`q`) |
|
|
170
|
+
| `get_tag` | Get a tag by ID with all properties, including `tasks_order` (section markers `h:<header_id>`) |
|
|
170
171
|
| `create_tag` | Create a new tag |
|
|
171
172
|
| `update_tag` | Update a tag (name, description, color, icon, view mode, favorite) |
|
|
172
173
|
| `delete_tag` | Permanently delete a tag and all its links |
|
|
173
|
-
| `get_tag_items` | Get
|
|
174
|
+
| `get_tag_items` | Get items linked to a tag — filter by `types`/`status`, `summary` mode, task `sections` included |
|
|
174
175
|
| `link_tag` | Link any entity to a tag |
|
|
175
176
|
| `unlink_tag` | Remove a tag link |
|
|
176
177
|
|
package/build/tools.js
CHANGED
|
@@ -380,6 +380,15 @@ export function registerAllTools(server, fetchApi) {
|
|
|
380
380
|
}, async ({ pinned, archived, limit, offset }) => {
|
|
381
381
|
return toContent(await fetchApi(`/notes${qs({ pinned, archived, limit, offset })}`));
|
|
382
382
|
});
|
|
383
|
+
server.registerTool("get_note", {
|
|
384
|
+
description: "Get a single note by ID, including its tags, linked contacts, linked tasks and linked notes. 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.",
|
|
385
|
+
inputSchema: {
|
|
386
|
+
id: z.string().uuid().describe("Note UUID (last segment of the note URL)"),
|
|
387
|
+
},
|
|
388
|
+
annotations: { title: "Get note", readOnlyHint: true, openWorldHint: false },
|
|
389
|
+
}, async ({ id }) => {
|
|
390
|
+
return toContent(await fetchApi(`/notes/${id}`));
|
|
391
|
+
});
|
|
383
392
|
server.registerTool("create_note", {
|
|
384
393
|
description: "Create a new QuickNote in the Inbox. QuickNotes are temporary captures — use archive_note to transform one into a permanent Note.\n\nContent supports #tag# and [[tag]] for automatic tag linking.",
|
|
385
394
|
inputSchema: {
|
|
@@ -488,17 +497,18 @@ export function registerAllTools(server, fetchApi) {
|
|
|
488
497
|
// TAGS
|
|
489
498
|
// ===========================================================================
|
|
490
499
|
server.registerTool("list_tags", {
|
|
491
|
-
description: "List
|
|
500
|
+
description: "List tags (lightweight: the manual tasks_order arrays are omitted — use get_tag for a tag's full ordering). Tags organize contacts, entries, tasks, notes, and companies. Use q to find a tag by name.",
|
|
492
501
|
inputSchema: {
|
|
502
|
+
q: z.string().optional().describe("Filter by name (case-insensitive substring match)"),
|
|
493
503
|
limit: z.number().int().positive().optional().describe("Max results (default 50)"),
|
|
494
504
|
offset: z.number().int().nonnegative().optional().describe("Pagination offset"),
|
|
495
505
|
},
|
|
496
506
|
annotations: { title: "List tags", readOnlyHint: true, openWorldHint: false },
|
|
497
|
-
}, async ({ limit, offset }) => {
|
|
498
|
-
return toContent(await fetchApi(`/tags${qs({ limit, offset })}`));
|
|
507
|
+
}, async ({ q, limit, offset }) => {
|
|
508
|
+
return toContent(await fetchApi(`/tags${qs({ q, limit, offset })}`));
|
|
499
509
|
});
|
|
500
510
|
server.registerTool("get_tag", {
|
|
501
|
-
description: "Get a single tag by ID with all its properties (name, description, color, icon, view mode, favorite status).",
|
|
511
|
+
description: "Get a single tag by ID with all its properties (name, description, color, icon, view mode, favorite status). Includes tasks_order, the manual ordering of the tag page's task list, where entries of the form \"h:<header_id>\" are section separators (see list_task_headers).",
|
|
502
512
|
inputSchema: {
|
|
503
513
|
id: z.string().uuid().describe("Tag UUID"),
|
|
504
514
|
},
|
|
@@ -507,13 +517,22 @@ export function registerAllTools(server, fetchApi) {
|
|
|
507
517
|
return toContent(await fetchApi(`/tags/${id}`));
|
|
508
518
|
});
|
|
509
519
|
server.registerTool("get_tag_items", {
|
|
510
|
-
description: "Get
|
|
520
|
+
description: "Get items linked to a tag. By default returns every type in full — on large tags that can be a huge response, so prefer types/status/summary to narrow it (e.g. types=['tasks'], status='pending', summary=true to review a project's open tasks). When tasks are included, the response also contains `sections`: the tag page's task sections with their task_ids (header_id null = tasks outside any section).",
|
|
511
521
|
inputSchema: {
|
|
512
522
|
id: z.string().uuid().describe("Tag UUID"),
|
|
523
|
+
types: z
|
|
524
|
+
.array(z.enum(["contacts", "entries", "tasks", "notes", "companies"]))
|
|
525
|
+
.optional()
|
|
526
|
+
.describe("Only fetch these item types (default: all)"),
|
|
527
|
+
status: z.enum(["pending", "completed"]).optional().describe("Filter tasks by status"),
|
|
528
|
+
summary: z
|
|
529
|
+
.boolean()
|
|
530
|
+
.optional()
|
|
531
|
+
.describe("Return lightweight items (ids, titles, excerpts) instead of full rows — recommended unless full content is needed"),
|
|
513
532
|
},
|
|
514
533
|
annotations: { title: "Get tag items", readOnlyHint: true, openWorldHint: false },
|
|
515
|
-
}, async ({ id }) => {
|
|
516
|
-
return toContent(await fetchApi(`/tags/${id}/items`));
|
|
534
|
+
}, async ({ id, types, status, summary }) => {
|
|
535
|
+
return toContent(await fetchApi(`/tags/${id}/items${qs({ types: types?.join(","), status, summary })}`));
|
|
517
536
|
});
|
|
518
537
|
server.registerTool("create_tag", {
|
|
519
538
|
description: "A TAG is a thematic grouping space. Syntax: #name# or [[name]]. Groups notes, entries, tasks, and contacts.\n\nCreate a new tag. If a tag with the same name already exists, returns the existing tag.",
|