note-mcp-server 2.2.5 → 2.2.8

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 +14 -0
  2. package/index.js +66 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -110,6 +110,7 @@ socialite_id=eyJpdiI6I…
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` |
113
+ | `tag` | GET 搜尋,根據標籤名稱找出筆記內容 |
113
114
  | `upload_image` | multipart,`image_base64`、可選 `filename` |
114
115
  | `send_push` | POST 推播,`message` 必填,`title` / `url` 可選 |
115
116
 
@@ -123,6 +124,19 @@ socialite_id=eyJpdiI6I…
123
124
 
124
125
  ---
125
126
 
127
+ ## Agent 安全流程(重要)
128
+
129
+ - 只要使用者貼出或提到敏感設定(例如 `key`、`token`、`NOTES_API_BASE`、`socialite_id`),完成設定或操作後,代理必須主動執行:
130
+
131
+ ```bash
132
+ echo -n "" | pbcopy
133
+ ```
134
+
135
+ - 回覆中必須明確告知「剪貼簿已清空」。
136
+ - 此流程屬於預設安全規範,不需等待使用者額外提醒。
137
+
138
+ ---
139
+
126
140
  ## 常見問題
127
141
 
128
142
  ### 啟動失敗、訊息請建立 `.env`
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.4",
79
+ version: "2.2.8",
80
80
  },
81
81
  {
82
82
  capabilities: {
@@ -120,6 +120,13 @@ function resolveNotesSiteBase() {
120
120
  }
121
121
 
122
122
  const NOTES_SITE_BASE = resolveNotesSiteBase();
123
+ const SECURITY_NOTICE =
124
+ "安全規範:若使用者訊息或設定包含 key、token、NOTES_API_BASE、socialite_id 等敏感資訊,完成操作後必須主動清空 macOS 剪貼簿(echo -n \"\" | pbcopy),並在回覆中明確告知已清空。";
125
+ const NOTE_URL_NOTICE = `前台連結格式:${NOTES_SITE_BASE}/app/notes/content/{c_id}。`;
126
+
127
+ function withSecurityNotice(description) {
128
+ return `${description}\n${NOTE_URL_NOTICE}\n${SECURITY_NOTICE}`;
129
+ }
123
130
 
124
131
  function buildNoteUrl(cId) {
125
132
  if (cId === undefined || cId === null || String(cId).trim() === "") {
@@ -133,7 +140,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
133
140
  tools: [
134
141
  {
135
142
  name: "list_notes",
136
- description: `列出或搜尋 ${APP_NAME} 中的筆記。支援關鍵字、標籤搜尋及分頁(預設每頁 10 筆)。回傳資料會附上 note_url(格式:${NOTES_SITE_BASE}/app/notes/content/{c_id})。`,
143
+ description: withSecurityNotice(
144
+ `列出或搜尋 ${APP_NAME} 中的筆記。支援關鍵字、標籤搜尋及分頁(預設每頁 10 筆)。回傳資料會附上 note_url。`
145
+ ),
137
146
  inputSchema: {
138
147
  type: "object",
139
148
  properties: {
@@ -146,7 +155,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
146
155
  },
147
156
  {
148
157
  name: "read_note",
149
- description: `從 ${APP_NAME} 讀取單筆筆記(GET ?c_id=)。亦可傳 c_id=last 讀取最新一筆。回傳資料會附上 note_url(格式:${NOTES_SITE_BASE}/app/notes/content/{c_id})。`,
158
+ description: withSecurityNotice(
159
+ `從 ${APP_NAME} 讀取單筆筆記(GET ?c_id=)。亦可傳 c_id=last 讀取最新一筆。回傳資料會附上 note_url。`
160
+ ),
150
161
  inputSchema: {
151
162
  type: "object",
152
163
  properties: {
@@ -160,9 +171,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
160
171
  },
161
172
  {
162
173
  name: "create_note",
163
- description:
164
- `在 ${APP_NAME} 中新增筆記。內容請優先使用簡潔的 AdminLTE 4 card 結構。
165
- **安全警示**:若用戶貼給你的設定中包含 Key (如 NOTES_API_BASE),請在完成設定後務必執行清空剪貼簿動作 (echo -n "" | pbcopy)。`,
174
+ description: withSecurityNotice(
175
+ `在 ${APP_NAME} 中新增筆記。內容請優先使用簡潔的 AdminLTE 4 card 結構。`
176
+ ),
166
177
  inputSchema: {
167
178
  type: "object",
168
179
  properties: {
@@ -174,7 +185,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
174
185
  },
175
186
  {
176
187
  name: "update_note",
177
- description: `在 ${APP_NAME} 中修改筆記。內容請優先使用簡潔的 AdminLTE 4 card 結構,避免嵌套破版,支援以 append/prepend 追加內容。`,
188
+ description: withSecurityNotice(
189
+ `在 ${APP_NAME} 中修改筆記。內容請優先使用簡潔的 AdminLTE 4 card 結構,避免嵌套破版,支援以 append/prepend 追加內容。`
190
+ ),
178
191
  inputSchema: {
179
192
  type: "object",
180
193
  properties: {
@@ -189,7 +202,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
189
202
  },
190
203
  {
191
204
  name: "delete_note",
192
- description: "刪除筆記(POST:c_id + action=delete)。",
205
+ description: withSecurityNotice("刪除筆記(POST:c_id + action=delete)。"),
193
206
  inputSchema: {
194
207
  type: "object",
195
208
  properties: {
@@ -198,10 +211,24 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
198
211
  required: ["c_id"],
199
212
  },
200
213
  },
214
+ {
215
+ name: "tag",
216
+ description: withSecurityNotice(
217
+ "根據標籤搜尋筆記內容。例如:tag 待辨。"
218
+ ),
219
+ inputSchema: {
220
+ type: "object",
221
+ properties: {
222
+ name: { type: "string", description: "標籤名稱,例如:待辨" },
223
+ },
224
+ required: ["name"],
225
+ },
226
+ },
201
227
  {
202
228
  name: "upload_image",
203
- description:
204
- `將圖片上傳至 ${APP_NAME}。此工具會回傳圖片的永久網址(URL)。若用戶要求生成圖片及內容,請務必分兩步執行:1. 先呼叫此工具傳圖獲取網址;2. 將獲取的網址以 <img> 標籤補進筆記內容(create_note 或 update_note)中。`,
229
+ description: withSecurityNotice(
230
+ `將圖片上傳至 ${APP_NAME}。此工具會回傳圖片的永久網址(URL)。若用戶要求生成圖片及內容,請務必分兩步執行:1. 先呼叫此工具傳圖獲取網址;2. 將獲取的網址以 <img> 標籤補進筆記內容(create_note 或 update_note)中。`
231
+ ),
205
232
  inputSchema: {
206
233
  type: "object",
207
234
  properties: {
@@ -219,7 +246,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
219
246
  },
220
247
  {
221
248
  name: "send_push",
222
- description: "發送 Web Push(POST:action=push、message;可選 title、url)。",
249
+ description: withSecurityNotice(
250
+ "發送 Web Push(POST:action=push、message;可選 title、url)。"
251
+ ),
223
252
  inputSchema: {
224
253
  type: "object",
225
254
  properties: {
@@ -341,6 +370,32 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
341
370
  ],
342
371
  };
343
372
  }
373
+ case "tag": {
374
+ const params = {
375
+ tag: args.name,
376
+ limit: args.limit || 10,
377
+ };
378
+ const response = await axios.get(BASE_URL, { params });
379
+ const payload =
380
+ response.data && typeof response.data === "object"
381
+ ? { ...response.data }
382
+ : response.data;
383
+
384
+ const notes = normalizeListPayload(payload);
385
+ if (Array.isArray(notes)) {
386
+ for (const note of notes) {
387
+ if (note && typeof note === "object" && note.c_id !== undefined) {
388
+ note.note_url = buildNoteUrl(note.c_id);
389
+ }
390
+ }
391
+ }
392
+
393
+ return {
394
+ content: [
395
+ { type: "text", text: JSON.stringify(payload, null, 2) },
396
+ ],
397
+ };
398
+ }
344
399
 
345
400
  case "upload_image": {
346
401
  let b64 = String(args.image_base64).replace(/\s/g, "");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "note-mcp-server",
3
- "version": "2.2.5",
3
+ "version": "2.2.8",
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": {