note-mcp-server 2.2.3 → 2.2.5

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.
Files changed (3) hide show
  1. package/README.md +8 -2
  2. package/index.js +58 -19
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -105,8 +105,8 @@ socialite_id=eyJpdiI6I…
105
105
 
106
106
  | 工具 | 說明 |
107
107
  |------|------|
108
- | `list_notes` | GET 列表,支援 `search` 關鍵字及 `limit`(預設 3) |
109
- | `read_note` | GET 單筆,支援 `c_id` 或 `last` |
108
+ | `list_notes` | GET 列表,支援 `search` / `tag` / `page` / `limit`(預設 10),每筆附 `note_url` |
109
+ | `read_note` | GET 單筆,支援 `c_id` 或 `last`,回傳附 `note_url` |
110
110
  | `create_note` | POST 新增,`content` 必填,`title` 可選 |
111
111
  | `update_note` | POST 修改,`c_id` 必填,支援 `content`、`title`、`append`、`prepend` |
112
112
  | `delete_note` | POST 刪除,`c_id` + `action=delete` |
@@ -115,6 +115,12 @@ socialite_id=eyJpdiI6I…
115
115
 
116
116
  完整 REST 行為請對你的 API 網址加上 **`/help`** 查官方說明。
117
117
 
118
+ 前台筆記網址格式:
119
+
120
+ ```text
121
+ {notes_url}/app/notes/content/{c_id}
122
+ ```
123
+
118
124
  ---
119
125
 
120
126
  ## 常見問題
package/index.js CHANGED
@@ -76,7 +76,7 @@ const APP_NAME = firstEnv("app_name", "APP_NAME", "notes_app_name", "NOTES_APP_N
76
76
  const server = new Server(
77
77
  {
78
78
  name: `note-mcp-server (${APP_NAME})`,
79
- version: "2.2.3",
79
+ version: "2.2.4",
80
80
  },
81
81
  {
82
82
  capabilities: {
@@ -109,30 +109,44 @@ function normalizeListPayload(data) {
109
109
  return [];
110
110
  }
111
111
 
112
+ function resolveNotesSiteBase() {
113
+ const fromEnv = firstEnv("notes_url", "NOTES_URL");
114
+ if (fromEnv) {
115
+ return stripTrailingSlashes(fromEnv);
116
+ }
117
+
118
+ // BASE_URL = {site}/api/notes/{socialite}/{token}
119
+ return stripTrailingSlashes(BASE_URL.replace(/\/api\/notes\/.*$/i, ""));
120
+ }
121
+
122
+ const NOTES_SITE_BASE = resolveNotesSiteBase();
123
+
124
+ function buildNoteUrl(cId) {
125
+ if (cId === undefined || cId === null || String(cId).trim() === "") {
126
+ return "";
127
+ }
128
+ return `${NOTES_SITE_BASE}/app/notes/content/${encodeURIComponent(String(cId))}`;
129
+ }
130
+
112
131
  server.setRequestHandler(ListToolsRequestSchema, async () => {
113
132
  return {
114
133
  tools: [
115
134
  {
116
135
  name: "list_notes",
117
- description: `列出 ${APP_NAME} 的筆記(GET 列表),支援 search 搜尋與 limit 截斷。`,
136
+ description: `列出或搜尋 ${APP_NAME} 中的筆記。支援關鍵字、標籤搜尋及分頁(預設每頁 10 筆)。回傳資料會附上 note_url(格式:${NOTES_SITE_BASE}/app/notes/content/{c_id})。`,
118
137
  inputSchema: {
119
138
  type: "object",
120
139
  properties: {
121
- search: {
122
- type: "string",
123
- description: "搜尋關鍵字(可選)",
124
- },
125
- limit: {
126
- type: "number",
127
- description: "最多回傳幾筆(預設 3)",
128
- default: 3,
129
- },
140
+ search: { type: "string", description: "搜尋關鍵字(可選)" },
141
+ tag: { type: "string", description: "搜尋標籤(可選,例如:打卡機)" },
142
+ page: { type: "number", description: "頁碼(可選,預設 1)" },
143
+ limit: { type: "number", description: "每頁幾筆(可選,預設 10)" },
130
144
  },
131
145
  },
132
146
  },
133
147
  {
134
148
  name: "read_note",
135
- description: `從 ${APP_NAME} 讀取單筆筆記(GET ?c_id=)。亦可傳 c_id=last 讀取最新一筆。`,
149
+ description: `從 ${APP_NAME} 讀取單筆筆記(GET ?c_id=)。亦可傳 c_id=last 讀取最新一筆。回傳資料會附上 note_url(格式:${NOTES_SITE_BASE}/app/notes/content/{c_id})。`,
136
150
  inputSchema: {
137
151
  type: "object",
138
152
  properties: {
@@ -227,15 +241,31 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
227
241
  try {
228
242
  switch (name) {
229
243
  case "list_notes": {
230
- const limit = Number(args.limit) > 0 ? Number(args.limit) : 3;
231
244
  const params = {};
232
- if (args.search) {
233
- params.search = args.search;
234
- }
245
+ if (args.search) params.search = args.search;
246
+ if (args.tag) params.tag = args.tag;
247
+ if (args.page) params.page = args.page;
248
+ params.limit = args.limit || 10;
249
+
235
250
  const response = await axios.get(BASE_URL, { params });
236
- const list = normalizeListPayload(response.data).slice(0, limit);
251
+ const payload =
252
+ response.data && typeof response.data === "object"
253
+ ? { ...response.data }
254
+ : response.data;
255
+
256
+ const notes = normalizeListPayload(payload);
257
+ if (Array.isArray(notes)) {
258
+ for (const note of notes) {
259
+ if (note && typeof note === "object" && note.c_id !== undefined) {
260
+ note.note_url = buildNoteUrl(note.c_id);
261
+ }
262
+ }
263
+ }
264
+
237
265
  return {
238
- content: [{ type: "text", text: JSON.stringify(list, null, 2) }],
266
+ content: [
267
+ { type: "text", text: JSON.stringify(payload, null, 2) },
268
+ ],
239
269
  };
240
270
  }
241
271
 
@@ -244,8 +274,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
244
274
  const response = await axios.get(BASE_URL, {
245
275
  params: { c_id: cId },
246
276
  });
277
+ const payload =
278
+ response.data && typeof response.data === "object"
279
+ ? { ...response.data }
280
+ : response.data;
281
+ if (payload && typeof payload === "object") {
282
+ const effectiveCid =
283
+ payload.c_id !== undefined ? payload.c_id : cId === "last" ? "" : cId;
284
+ payload.note_url = buildNoteUrl(effectiveCid);
285
+ }
247
286
  return {
248
- content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
287
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
249
288
  };
250
289
  }
251
290
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "note-mcp-server",
3
- "version": "2.2.3",
3
+ "version": "2.2.5",
4
4
  "description": "MCP (stdio) server for Notes API v2 — list/read/write notes, upload images, Web Push from Cursor and compatible clients.",
5
5
  "main": "index.js",
6
6
  "bin": {