@chriscurrycc/memos-mcp 0.1.1 → 1.0.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.
@@ -1,59 +1,152 @@
1
1
  import { z } from "zod";
2
- export const registerMemoTools = (server, client) => {
3
- server.tool("list_memos", "List memos with optional filtering and pagination", {
4
- pageSize: z.number().int().min(1).max(100).default(20).describe("Number of memos per page"),
5
- pageToken: z.string().optional().describe("Page token for pagination"),
6
- filter: z.string().optional().describe("CEL filter expression, e.g. \"visibilities == ['PUBLIC']\""),
7
- state: z.enum(["NORMAL", "ARCHIVED"]).optional().describe("Filter by memo state"),
8
- }, async ({ pageSize, pageToken, filter, state }) => {
9
- const params = { pageSize: String(pageSize) };
10
- if (pageToken)
11
- params.pageToken = pageToken;
12
- // Auto-inject creator filter so the API returns PRIVATE memos
13
- const currentUser = await client.getCurrentUser();
14
- const creatorFilter = `creator == "${currentUser}"`;
15
- const filters = [creatorFilter];
16
- if (filter)
17
- filters.push(filter);
18
- if (state) {
19
- filters.push(`row_status == "${state === "ARCHIVED" ? "ARCHIVED" : "ACTIVE"}"`);
2
+ import { summarizeMemo } from "./utils.js";
3
+ function parseToUnixTimestamp(isoString, paramName) {
4
+ const date = new Date(isoString);
5
+ if (isNaN(date.getTime())) {
6
+ throw new Error(`Invalid date format for ${paramName}. Use ISO 8601 format (e.g., "2025-01-01" or "2025-01-01T00:00:00Z").`);
7
+ }
8
+ return Math.floor(date.getTime() / 1000);
9
+ }
10
+ function buildCelFilter(opts) {
11
+ const parts = [`creator == "${opts.creator}"`];
12
+ if (opts.query) {
13
+ const escaped = opts.query.replace(/"/g, '\\"');
14
+ parts.push(`content_search == ["${escaped}"]`);
15
+ }
16
+ if (opts.tags?.length) {
17
+ const tagList = opts.tags.map((t) => `"${t.replace(/"/g, '\\"')}"`).join(", ");
18
+ parts.push(`tag_search == [${tagList}]`);
19
+ }
20
+ if (opts.visibility?.length) {
21
+ const visList = opts.visibility.map((v) => `"${v}"`).join(", ");
22
+ parts.push(`visibilities == [${visList}]`);
23
+ }
24
+ if (opts.state) {
25
+ parts.push(`row_status == "${opts.state === "ARCHIVED" ? "ARCHIVED" : "ACTIVE"}"`);
26
+ }
27
+ if (opts.pinned !== undefined) {
28
+ parts.push(`pinned == ${opts.pinned}`);
29
+ }
30
+ if (opts.startDate) {
31
+ parts.push(`display_time_after == ${parseToUnixTimestamp(opts.startDate, "startDate")}`);
32
+ }
33
+ if (opts.endDate) {
34
+ parts.push(`display_time_before == ${parseToUnixTimestamp(opts.endDate, "endDate")}`);
35
+ }
36
+ if (opts.hasLink)
37
+ parts.push(`has_link == true`);
38
+ if (opts.hasTaskList)
39
+ parts.push(`has_task_list == true`);
40
+ if (opts.hasCode)
41
+ parts.push(`has_code == true`);
42
+ if (opts.hasIncompleteTasks)
43
+ parts.push(`has_incomplete_tasks == true`);
44
+ if (opts.random)
45
+ parts.push(`random == true`);
46
+ return parts.join(" && ");
47
+ }
48
+ async function resolveToNumericId(client, id) {
49
+ if (/^\d+$/.test(id)) {
50
+ return parseInt(id, 10);
51
+ }
52
+ const memo = await client.get(`/api/v1/memos:by-uid/${id}`);
53
+ const match = memo.name.match(/^memos\/(\d+)$/);
54
+ if (!match)
55
+ throw new Error(`Unexpected memo name format: ${memo.name}`);
56
+ return parseInt(match[1], 10);
57
+ }
58
+ function cleanMemo(memo) {
59
+ const { name, nodes, snippet, creator, ...rest } = memo;
60
+ const id = name?.match(/^memos\/(\d+)$/)?.[1];
61
+ if (id)
62
+ rest.id = Number(id);
63
+ for (const key of ["resources", "relations", "reactions"]) {
64
+ if (Array.isArray(rest[key]) && rest[key].length === 0) {
65
+ delete rest[key];
20
66
  }
21
- params.filter = filters.join(" && ");
67
+ }
68
+ return rest;
69
+ }
70
+ export const registerMemoTools = (server, client, options) => {
71
+ const visibilityEnum = z.enum(["PRIVATE", "PROTECTED", "PUBLIC"]);
72
+ server.registerTool("list_memos", {
73
+ description: "Search and list memos. All filters are optional and combined with AND logic.",
74
+ inputSchema: {
75
+ query: z.string().optional().describe("Keyword search in memo content"),
76
+ tags: z.array(z.string()).optional().describe("Filter by tags, e.g. [\"project\", \"todo\"]"),
77
+ visibility: z.array(visibilityEnum).optional().describe("Filter by visibility levels"),
78
+ state: z.enum(["NORMAL", "ARCHIVED"]).optional().describe("Filter by memo state"),
79
+ pinned: z.boolean().optional().describe("Filter by pinned status"),
80
+ startDate: z.string().optional().describe("Return memos after this date (ISO 8601, e.g. \"2025-01-01\")"),
81
+ endDate: z.string().optional().describe("Return memos before this date (ISO 8601, e.g. \"2025-03-01\")"),
82
+ hasLink: z.boolean().optional().describe("Filter to memos containing links"),
83
+ hasTaskList: z.boolean().optional().describe("Filter to memos containing task lists"),
84
+ hasCode: z.boolean().optional().describe("Filter to memos containing code blocks"),
85
+ hasIncompleteTasks: z.boolean().optional().describe("Filter to memos with incomplete tasks"),
86
+ random: z.boolean().optional().describe("Return results in random order"),
87
+ pageSize: z.number().int().min(1).max(100).default(20).describe("Number of memos per page"),
88
+ pageToken: z.string().optional().describe("Token for fetching the next page"),
89
+ },
90
+ annotations: { readOnlyHint: true, openWorldHint: false },
91
+ }, async (args) => {
92
+ const currentUser = await client.getCurrentUser();
93
+ const filter = buildCelFilter({ creator: currentUser, ...args });
94
+ const params = {
95
+ pageSize: String(args.pageSize),
96
+ filter,
97
+ };
98
+ if (args.pageToken)
99
+ params.pageToken = args.pageToken;
22
100
  const result = await client.get("/api/v1/memos", params);
23
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
101
+ const summaries = (result.memos || []).map((m) => summarizeMemo(m));
102
+ const output = { memos: summaries };
103
+ if (result.nextPageToken)
104
+ output.nextPageToken = result.nextPageToken;
105
+ return { content: [{ type: "text", text: JSON.stringify(output, null, 2) }] };
24
106
  });
25
- server.tool("get_memo", "Get a single memo by ID", {
26
- id: z.number().int().describe("Memo ID"),
107
+ server.registerTool("get_memo", {
108
+ description: "Get a single memo by its numeric ID or UID string (the ID from the memo URL).",
109
+ inputSchema: {
110
+ id: z.string().min(1).describe("Memo identifier. Numeric ID (e.g. \"42\") or UID string (e.g. \"AjF4AQJayxvDj2mrWzFWuP\")"),
111
+ },
112
+ annotations: { readOnlyHint: true, openWorldHint: false },
27
113
  }, async ({ id }) => {
28
- const memo = await client.get(`/api/v1/memos/${id}`);
29
- return { content: [{ type: "text", text: JSON.stringify(memo, null, 2) }] };
30
- });
31
- server.tool("search_memos", "Search memos by keyword in content", {
32
- query: z.string().min(1).describe("Search keyword"),
33
- pageSize: z.number().int().min(1).max(100).default(20).describe("Number of results"),
34
- }, async ({ query, pageSize }) => {
35
- const currentUser = await client.getCurrentUser();
36
- const filter = `creator == "${currentUser}" && content_search == ["${query.replace(/"/g, '\\"')}"]`;
37
- const result = await client.get("/api/v1/memos", {
38
- pageSize: String(pageSize),
39
- filter,
40
- });
41
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
114
+ const path = /^\d+$/.test(id)
115
+ ? `/api/v1/memos/${id}`
116
+ : `/api/v1/memos:by-uid/${id}`;
117
+ const memo = await client.get(path);
118
+ const cleaned = cleanMemo(memo);
119
+ return { content: [{ type: "text", text: JSON.stringify(cleaned, null, 2) }] };
42
120
  });
43
- server.tool("create_memo", "Create a new memo", {
44
- content: z.string().min(1).describe("Memo content in markdown"),
45
- visibility: z.enum(["PRIVATE", "PROTECTED", "PUBLIC"]).default("PRIVATE").describe("Memo visibility"),
121
+ server.registerTool("create_memo", {
122
+ description: "Create a new memo with markdown content.",
123
+ inputSchema: {
124
+ content: z.string().min(1).describe("Memo content in markdown. Tags can be included with #tagname syntax"),
125
+ visibility: visibilityEnum.optional().describe("Memo visibility. Omit to use the configured default"),
126
+ },
127
+ annotations: { destructiveHint: false, openWorldHint: false },
46
128
  }, async ({ content, visibility }) => {
47
- const memo = await client.post("/api/v1/memos", { content, visibility });
48
- return { content: [{ type: "text", text: JSON.stringify(memo, null, 2) }] };
129
+ const memo = await client.post("/api/v1/memos", {
130
+ content,
131
+ visibility: visibility ?? options.defaultVisibility,
132
+ });
133
+ const id = memo.name?.match(/^memos\/(\d+)$/)?.[1];
134
+ const result = { id: id ? Number(id) : undefined, uid: memo.uid, visibility: memo.visibility };
135
+ return { content: [{ type: "text", text: JSON.stringify(result) }] };
49
136
  });
50
- server.tool("update_memo", "Update an existing memo", {
51
- id: z.number().int().describe("Memo ID"),
52
- content: z.string().optional().describe("New content"),
53
- visibility: z.enum(["PRIVATE", "PROTECTED", "PUBLIC"]).optional().describe("New visibility"),
54
- pinned: z.boolean().optional().describe("Pin or unpin the memo"),
55
- state: z.enum(["NORMAL", "ARCHIVED"]).optional().describe("Archive or restore the memo"),
56
- }, async ({ id, content, visibility, pinned, state }) => {
137
+ server.registerTool("update_memo", {
138
+ description: "Update an existing memo. Only the fields you provide will be modified.",
139
+ inputSchema: {
140
+ id: z.string().min(1).describe("Memo identifier. Numeric ID or UID string"),
141
+ content: z.string().optional().describe("New memo content in markdown"),
142
+ visibility: visibilityEnum.optional().describe("New visibility level"),
143
+ pinned: z.boolean().optional().describe("Pin or unpin the memo"),
144
+ state: z.enum(["NORMAL", "ARCHIVED"]).optional().describe("Set to ARCHIVED to archive, NORMAL to restore"),
145
+ preserveUpdateTime: z.boolean().optional().describe("When true, the memo's update time will not change. Use for formatting or style-only edits"),
146
+ },
147
+ annotations: { destructiveHint: false, idempotentHint: true, openWorldHint: false },
148
+ }, async ({ id, content, visibility, pinned, state, preserveUpdateTime }) => {
149
+ const numericId = await resolveToNumericId(client, id);
57
150
  const body = {};
58
151
  const updateMaskPaths = [];
59
152
  if (content !== undefined) {
@@ -72,15 +165,33 @@ export const registerMemoTools = (server, client) => {
72
165
  body.rowStatus = state === "ARCHIVED" ? "ARCHIVED" : "ACTIVE";
73
166
  updateMaskPaths.push("row_status");
74
167
  }
75
- const memo = await client.patch(`/api/v1/memos/${id}`, body, {
168
+ if (updateMaskPaths.length === 0) {
169
+ return {
170
+ content: [
171
+ {
172
+ type: "text",
173
+ text: "No fields to update. Provide at least one of: content, visibility, pinned, state.",
174
+ },
175
+ ],
176
+ };
177
+ }
178
+ const params = {
76
179
  updateMask: updateMaskPaths.join(","),
77
- });
78
- return { content: [{ type: "text", text: JSON.stringify(memo, null, 2) }] };
180
+ };
181
+ if (preserveUpdateTime)
182
+ params.preserveUpdateTime = "true";
183
+ await client.patch(`/api/v1/memos/${numericId}`, body, params);
184
+ return { content: [{ type: "text", text: `Memo ${id} updated.` }] };
79
185
  });
80
- server.tool("delete_memo", "Permanently delete a memo", {
81
- id: z.number().int().describe("Memo ID to delete"),
186
+ server.registerTool("delete_memo", {
187
+ description: "Permanently delete a memo. This action cannot be undone.",
188
+ inputSchema: {
189
+ id: z.string().min(1).describe("Memo identifier. Numeric ID or UID string"),
190
+ },
191
+ annotations: { destructiveHint: true, idempotentHint: true, openWorldHint: false },
82
192
  }, async ({ id }) => {
83
- await client.delete(`/api/v1/memos/${id}`);
193
+ const numericId = await resolveToNumericId(client, id);
194
+ await client.delete(`/api/v1/memos/${numericId}`);
84
195
  return { content: [{ type: "text", text: `Memo ${id} deleted.` }] };
85
196
  });
86
197
  };
@@ -1 +1 @@
1
- {"version":3,"file":"memos.js","sourceRoot":"","sources":["../../src/tools/memos.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memos.js","sourceRoot":"","sources":["../../src/tools/memos.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../../src/tools/relations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,eAAO,MAAM,qBAAqB,GAAI,QAAQ,SAAS,EAAE,QAAQ,WAAW,SAmE3E,CAAC"}
1
+ {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../../src/tools/relations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAiE3C,eAAO,MAAM,qBAAqB,GAAI,QAAQ,SAAS,EAAE,QAAQ,WAAW,SAiG3E,CAAC"}
@@ -1,40 +1,125 @@
1
1
  import { z } from "zod";
2
- export const registerRelationTools = (server, client) => {
3
- server.tool("list_memo_relations", "List relations of a memo (references and comments)", {
4
- id: z.number().int().describe("Memo ID"),
5
- }, async ({ id }) => {
2
+ async function resolveToNumericId(client, id) {
3
+ if (/^\d+$/.test(id)) {
4
+ return parseInt(id, 10);
5
+ }
6
+ const memo = await client.get(`/api/v1/memos:by-uid/${id}`);
7
+ const match = memo.name.match(/^memos\/(\d+)$/);
8
+ if (!match)
9
+ throw new Error(`Unexpected memo name format: ${memo.name}`);
10
+ return parseInt(match[1], 10);
11
+ }
12
+ function extractId(memoRef) {
13
+ const name = typeof memoRef === "string" ? memoRef : memoRef?.name;
14
+ if (!name || typeof name !== "string")
15
+ return undefined;
16
+ const match = name.match(/^memos\/(\d+)$/);
17
+ return match ? parseInt(match[1], 10) : undefined;
18
+ }
19
+ async function buildRelationGraph(client, startId, maxDepth) {
20
+ const visited = new Set();
21
+ const edges = [];
22
+ const edgeSet = new Set();
23
+ const queue = [{ id: startId, depth: 0 }];
24
+ while (queue.length > 0) {
25
+ const { id, depth } = queue.shift();
26
+ if (visited.has(id))
27
+ continue;
28
+ visited.add(id);
6
29
  const result = await client.get(`/api/v1/memos/${id}/relations`);
7
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
30
+ for (const r of result.relations || []) {
31
+ const fromId = extractId(r.memo);
32
+ const toId = extractId(r.relatedMemo);
33
+ if (fromId === undefined || toId === undefined)
34
+ continue;
35
+ const edgeKey = `${fromId}->${toId}:${r.type}`;
36
+ if (edgeSet.has(edgeKey))
37
+ continue;
38
+ edgeSet.add(edgeKey);
39
+ edges.push({ from: fromId, to: toId, type: r.type });
40
+ const neighborId = fromId === id ? toId : fromId;
41
+ if (depth < maxDepth && !visited.has(neighborId)) {
42
+ queue.push({ id: neighborId, depth: depth + 1 });
43
+ }
44
+ }
45
+ }
46
+ return { nodes: [...visited], edges };
47
+ }
48
+ export const registerRelationTools = (server, client) => {
49
+ server.registerTool("list_memo_relations", {
50
+ description: [
51
+ "List relations of a memo. Returns edges with direction (from → to) and type.",
52
+ "- depth=1 (default): direct relations only.",
53
+ "- depth=2+: recursively expand related memos to build a relation graph.",
54
+ "Each edge shows {from, to, type}. Use get_memo to inspect specific nodes.",
55
+ ].join(" "),
56
+ inputSchema: {
57
+ id: z.string().min(1).describe("Memo identifier. Numeric ID or UID string"),
58
+ depth: z.number().int().min(1).max(5).default(1).describe("How many levels deep to traverse. 1 = direct relations, 2+ = recursive graph"),
59
+ },
60
+ annotations: { readOnlyHint: true, openWorldHint: false },
61
+ }, async ({ id, depth }) => {
62
+ const numericId = await resolveToNumericId(client, id);
63
+ const { nodes, edges } = await buildRelationGraph(client, numericId, depth);
64
+ if (edges.length === 0) {
65
+ return { content: [{ type: "text", text: "No relations found." }] };
66
+ }
67
+ const output = {
68
+ startNode: numericId,
69
+ nodes,
70
+ edges,
71
+ };
72
+ return { content: [{ type: "text", text: JSON.stringify(output, null, 2) }] };
8
73
  });
9
- server.tool("set_memo_relations", "Set relations for a memo (replaces all existing relations)", {
10
- id: z.number().int().describe("Memo ID"),
11
- relations: z
12
- .array(z.object({
13
- relatedMemoId: z.number().int().describe("Related memo ID"),
14
- type: z.enum(["REFERENCE", "COMMENT"]).describe("Relation type"),
15
- }))
16
- .describe("List of relations to set"),
17
- }, async ({ id, relations }) => {
74
+ server.registerTool("set_memo_relations", {
75
+ description: [
76
+ "Add or remove REFERENCE relations for a memo.",
77
+ "- action=\"add\": add new references without affecting existing ones.",
78
+ "- action=\"remove\": remove specific references.",
79
+ "Note: COMMENT relations are managed by the system and cannot be modified here.",
80
+ ].join(" "),
81
+ inputSchema: {
82
+ id: z.string().min(1).describe("Memo identifier. Numeric ID or UID string"),
83
+ action: z.enum(["add", "remove"]).describe("Whether to add or remove relations"),
84
+ targetIds: z.array(z.string().min(1)).min(1).describe("IDs of memos to add/remove as references. Numeric IDs or UID strings"),
85
+ },
86
+ annotations: { destructiveHint: false, idempotentHint: true, openWorldHint: false },
87
+ }, async ({ id, action, targetIds }) => {
88
+ const numericId = await resolveToNumericId(client, id);
89
+ const resolvedTargets = await Promise.all(targetIds.map((t) => resolveToNumericId(client, t)));
90
+ const current = await client.get(`/api/v1/memos/${numericId}/relations`);
91
+ const existing = (current.relations || []).filter((r) => extractId(r.memo) === numericId && r.type === "REFERENCE");
92
+ let finalIds;
93
+ if (action === "add") {
94
+ const existingIds = new Set(existing.map((r) => extractId(r.relatedMemo)));
95
+ finalIds = [
96
+ ...existing.map((r) => extractId(r.relatedMemo)),
97
+ ...resolvedTargets.filter((t) => !existingIds.has(t)),
98
+ ];
99
+ }
100
+ else {
101
+ const removeSet = new Set(resolvedTargets);
102
+ finalIds = existing
103
+ .map((r) => extractId(r.relatedMemo))
104
+ .filter((rid) => !removeSet.has(rid));
105
+ }
18
106
  const body = {
19
- relations: relations.map((r) => ({
20
- memo: `memos/${id}`,
21
- relatedMemo: `memos/${r.relatedMemoId}`,
22
- type: r.type,
107
+ relations: finalIds.map((targetId) => ({
108
+ memo: { name: `memos/${numericId}` },
109
+ relatedMemo: { name: `memos/${targetId}` },
110
+ type: "REFERENCE",
23
111
  })),
24
112
  };
25
- const result = await client.patch(`/api/v1/memos/${id}/relations`, body);
26
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
27
- });
28
- server.tool("delete_memo_relation", "Remove a specific relation from a memo", {
29
- id: z.number().int().describe("Memo ID"),
30
- relatedMemoId: z.number().int().describe("Related memo ID to unlink"),
31
- type: z.enum(["REFERENCE", "COMMENT"]).describe("Relation type to remove"),
32
- }, async ({ id, relatedMemoId, type }) => {
33
- // Get current relations, filter out the target, set remaining
34
- const current = await client.get(`/api/v1/memos/${id}/relations`);
35
- const remaining = (current.relations || []).filter((r) => !(r.relatedMemo === `memos/${relatedMemoId}` && r.type === type));
36
- const result = await client.patch(`/api/v1/memos/${id}/relations`, { relations: remaining });
37
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
113
+ await client.patch(`/api/v1/memos/${numericId}/relations`, body);
114
+ const verb = action === "add" ? "added" : "removed";
115
+ return {
116
+ content: [
117
+ {
118
+ type: "text",
119
+ text: `${resolvedTargets.length} reference(s) ${verb}. Memo ${id} now has ${finalIds.length} outgoing reference(s).`,
120
+ },
121
+ ],
122
+ };
38
123
  });
39
124
  };
40
125
  //# sourceMappingURL=relations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"relations.js","sourceRoot":"","sources":["../../src/tools/relations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relations.js","sourceRoot":"","sources":["../../src/tools/relations.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/tools/resources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,eAAO,MAAM,qBAAqB,GAAI,QAAQ,SAAS,EAAE,QAAQ,WAAW,SAmD3E,CAAC"}
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/tools/resources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAkB3C,eAAO,MAAM,qBAAqB,GAAI,QAAQ,SAAS,EAAE,QAAQ,WAAW,SAiE3E,CAAC"}
@@ -1,28 +1,89 @@
1
1
  import { z } from "zod";
2
+ function summarizeResource(res) {
3
+ const name = res.name;
4
+ const id = name?.match(/^resources\/(\d+)$/)?.[1];
5
+ const summary = {
6
+ id: id ? Number(id) : undefined,
7
+ uid: res.uid,
8
+ filename: res.filename,
9
+ type: res.type,
10
+ size: res.size,
11
+ };
12
+ if (res.externalLink)
13
+ summary.externalLink = res.externalLink;
14
+ if (res.memo)
15
+ summary.memo = res.memo;
16
+ return summary;
17
+ }
2
18
  export const registerResourceTools = (server, client) => {
3
- server.tool("list_resources", "List all resources (attachments)", {}, async () => {
19
+ server.registerTool("list_resources", {
20
+ description: "List all resources (attachments) owned by the current user.",
21
+ annotations: { readOnlyHint: true, openWorldHint: false },
22
+ }, async () => {
4
23
  const result = await client.get("/api/v1/resources");
5
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
24
+ const summaries = (result.resources || []).map((r) => summarizeResource(r));
25
+ return { content: [{ type: "text", text: JSON.stringify(summaries, null, 2) }] };
6
26
  });
7
- server.tool("get_resource", "Get a resource by ID", {
8
- id: z.number().int().describe("Resource ID"),
9
- }, async ({ id }) => {
10
- const resource = await client.get(`/api/v1/resources/${id}`);
11
- return { content: [{ type: "text", text: JSON.stringify(resource, null, 2) }] };
27
+ server.registerTool("upload_resource", {
28
+ description: "Upload a file as a resource. The file content must be base64 encoded. Optionally link it to a memo.",
29
+ inputSchema: {
30
+ filename: z.string().min(1).describe("File name with extension, e.g. \"photo.jpg\""),
31
+ contentBase64: z.string().min(1).describe("File content as a base64 encoded string"),
32
+ type: z.string().optional().describe("MIME type, e.g. \"image/jpeg\". Auto-detected from extension if omitted"),
33
+ memoId: z.number().int().optional().describe("Memo ID to link this resource to"),
34
+ },
35
+ annotations: { destructiveHint: false, openWorldHint: false },
36
+ }, async ({ filename, contentBase64, type, memoId }) => {
37
+ const mimeType = type ?? guessMimeType(filename);
38
+ const body = {
39
+ filename,
40
+ content: contentBase64,
41
+ type: mimeType,
42
+ };
43
+ if (memoId !== undefined) {
44
+ body.memo = `memos/${memoId}`;
45
+ }
46
+ const resource = await client.post("/api/v1/resources", body);
47
+ const id = resource.name?.match(/^resources\/(\d+)$/)?.[1];
48
+ return {
49
+ content: [
50
+ {
51
+ type: "text",
52
+ text: `Resource uploaded: id=${id}, filename="${resource.filename}"`,
53
+ },
54
+ ],
55
+ };
12
56
  });
13
- server.tool("delete_resource", "Delete a resource", {
14
- id: z.number().int().describe("Resource ID"),
57
+ server.registerTool("delete_resource", {
58
+ description: "Delete a resource permanently.",
59
+ inputSchema: {
60
+ id: z.number().int().describe("Resource ID"),
61
+ },
62
+ annotations: { destructiveHint: true, idempotentHint: true, openWorldHint: false },
15
63
  }, async ({ id }) => {
16
64
  await client.delete(`/api/v1/resources/${id}`);
17
65
  return { content: [{ type: "text", text: `Resource ${id} deleted.` }] };
18
66
  });
19
- server.tool("link_resource_to_memo", "Link resources to a memo", {
20
- memoId: z.number().int().describe("Memo ID"),
21
- resourceIds: z.array(z.number().int()).min(1).describe("Resource IDs to link"),
22
- }, async ({ memoId, resourceIds }) => {
23
- const resources = resourceIds.map((id) => ({ name: `resources/${id}` }));
24
- const result = await client.patch(`/api/v1/memos/${memoId}/resources`, { resources });
25
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
26
- });
27
67
  };
68
+ const MIME_MAP = {
69
+ jpg: "image/jpeg",
70
+ jpeg: "image/jpeg",
71
+ png: "image/png",
72
+ gif: "image/gif",
73
+ webp: "image/webp",
74
+ svg: "image/svg+xml",
75
+ pdf: "application/pdf",
76
+ mp3: "audio/mpeg",
77
+ mp4: "video/mp4",
78
+ webm: "video/webm",
79
+ txt: "text/plain",
80
+ md: "text/markdown",
81
+ json: "application/json",
82
+ csv: "text/csv",
83
+ zip: "application/zip",
84
+ };
85
+ function guessMimeType(filename) {
86
+ const ext = filename.split(".").pop()?.toLowerCase() ?? "";
87
+ return MIME_MAP[ext] ?? "application/octet-stream";
88
+ }
28
89
  //# sourceMappingURL=resources.js.map