@chriscurrycc/memos-mcp 0.1.0 → 0.2.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 CHANGED
@@ -14,17 +14,18 @@ Enables AI assistants (Claude Code, Claude Desktop, Cursor, etc.) to read and wr
14
14
  - A running Memos instance
15
15
  - A Memos access token (Settings → Access Tokens)
16
16
 
17
- ### Claude Code
17
+ ### Environment Variables
18
18
 
19
- ```bash
20
- claude mcp add memos -- npx @chriscurrycc/memos-mcp
21
- ```
19
+ | Variable | Required | Description |
20
+ |----------|----------|-------------|
21
+ | `MEMOS_URL` | Yes | Your Memos instance URL |
22
+ | `MEMOS_TOKEN` | Yes | Memos access token |
23
+ | `MEMOS_DEFAULT_VISIBILITY` | No | Default visibility for new memos (`PRIVATE`, `PROTECTED`, `PUBLIC`). Defaults to `PRIVATE` |
22
24
 
23
- Then set environment variables:
25
+ ### Claude Code
24
26
 
25
27
  ```bash
26
- export MEMOS_URL=https://your-memos-instance.com
27
- export MEMOS_TOKEN=your-access-token
28
+ claude mcp add --scope user memos -e MEMOS_URL=https://your-memos-instance.com -e MEMOS_TOKEN=your-access-token -- npx -y @chriscurrycc/memos-mcp
28
29
  ```
29
30
 
30
31
  ### Claude Desktop
@@ -36,7 +37,7 @@ Add to your `claude_desktop_config.json`:
36
37
  "mcpServers": {
37
38
  "memos": {
38
39
  "command": "npx",
39
- "args": ["-y", "memos-mcp"],
40
+ "args": ["-y", "@chriscurrycc/memos-mcp"],
40
41
  "env": {
41
42
  "MEMOS_URL": "https://your-memos-instance.com",
42
43
  "MEMOS_TOKEN": "your-access-token"
@@ -48,14 +49,30 @@ Add to your `claude_desktop_config.json`:
48
49
 
49
50
  ### With 1Password (recommended)
50
51
 
51
- Use `op run` to inject the token securely — no plaintext secrets on disk:
52
+ Store your token securely in 1Password — no plaintext secrets on disk.
53
+
54
+ 1. Save the token to 1Password:
55
+
56
+ ```bash
57
+ op item create --category=apiCredential --title="memos-api" token=your-access-token "valid from[date]=2026-01-01" "expires[date]=2026-02-01"
58
+ ```
59
+
60
+ 2. Configure with `op run` to inject the token at runtime:
61
+
62
+ **Claude Code:**
63
+
64
+ ```bash
65
+ claude mcp add --scope user memos -e MEMOS_URL=https://your-memos-instance.com -e MEMOS_TOKEN=op://Personal/memos-api/token -- op run --no-masking -- npx -y @chriscurrycc/memos-mcp
66
+ ```
67
+
68
+ **Claude Desktop:**
52
69
 
53
70
  ```json
54
71
  {
55
72
  "mcpServers": {
56
73
  "memos": {
57
74
  "command": "op",
58
- "args": ["run", "--", "npx", "-y", "memos-mcp"],
75
+ "args": ["run", "--no-masking", "--", "npx", "-y", "@chriscurrycc/memos-mcp"],
59
76
  "env": {
60
77
  "MEMOS_URL": "https://your-memos-instance.com",
61
78
  "MEMOS_TOKEN": "op://Personal/memos-api/token"
@@ -71,71 +88,25 @@ Use `op run` to inject the token securely — no plaintext secrets on disk:
71
88
 
72
89
  | Tool | Description |
73
90
  |------|-------------|
74
- | `list_memos` | List memos with filtering and pagination |
75
- | `get_memo` | Get a single memo by ID |
76
- | `search_memos` | Search memos by keyword |
77
- | `create_memo` | Create a new memo |
78
- | `update_memo` | Update content, visibility, pin, or archive state |
91
+ | `list_memos` | Search and list memos with structured filters (keyword, tags, date range, visibility, pinned, content properties, etc.) |
92
+ | `get_memo` | Get a single memo by numeric ID or UID string |
93
+ | `create_memo` | Create a new memo with markdown content |
94
+ | `update_memo` | Update content, visibility, pin, archive state, with optional `preserveUpdateTime` |
79
95
  | `delete_memo` | Permanently delete a memo |
80
96
 
81
- ### Comments
82
-
83
- | Tool | Description |
84
- |------|-------------|
85
- | `list_memo_comments` | List comments on a memo |
86
- | `create_memo_comment` | Add a comment to a memo |
87
-
88
97
  ### Tags
89
98
 
90
99
  | Tool | Description |
91
100
  |------|-------------|
92
- | `list_pinned_tags` | List all pinned tags |
93
- | `list_tags_with_emoji` | List tags with their emojis |
94
- | `update_tag` | Update a tag's emoji or pinned status |
95
-
96
- ### Resources
97
-
98
- | Tool | Description |
99
- |------|-------------|
100
- | `list_resources` | List all resources (attachments) |
101
- | `get_resource` | Get a resource by ID |
102
- | `delete_resource` | Delete a resource |
103
- | `link_resource_to_memo` | Link resources to a memo |
104
-
105
- ### Relations
106
-
107
- | Tool | Description |
108
- |------|-------------|
109
- | `list_memo_relations` | List memo relations |
110
- | `set_memo_relations` | Set relations (replaces all) |
111
- | `delete_memo_relation` | Remove a specific relation |
112
-
113
- ### Reactions
114
-
115
- | Tool | Description |
116
- |------|-------------|
117
- | `list_reactions` | List reactions on a memo |
118
- | `upsert_reaction` | Add a reaction emoji |
119
- | `delete_reaction` | Remove a reaction |
120
-
121
- ### Review (Spaced Repetition)
122
-
123
- | Tool | Description |
124
- |------|-------------|
125
- | `list_review_memos` | Get memos due for review |
126
- | `get_random_memo` | Get a random memo |
127
- | `list_on_this_day_memos` | Memos created on this day in past years |
128
- | `get_time_travel_memos` | Memos from a random time period |
129
- | `record_review` | Record that memos have been reviewed |
130
- | `get_review_stats` | Get review statistics |
101
+ | `list_tags` | List tags with usage counts, hierarchy support, and pinned/emoji metadata |
102
+ | `update_tag` | Update a tag's pinned status or emoji |
103
+ | `rename_tag` | Rename a tag across all memos |
131
104
 
132
105
  ## Prompts
133
106
 
134
107
  | Prompt | Description |
135
108
  |--------|-------------|
136
109
  | `capture` | Quick-save a thought as a memo |
137
- | `review` | Start a guided review session |
138
- | `daily_digest` | Summarize recent memo activity |
139
110
 
140
111
  ## Resources
141
112
 
package/dist/client.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  export declare class MemosClient {
2
2
  private baseUrl;
3
3
  private token;
4
+ private _currentUser;
4
5
  constructor(baseUrl: string, token: string);
6
+ getCurrentUser(): Promise<string>;
5
7
  private headers;
6
8
  get<T>(path: string, params?: Record<string, string>): Promise<T>;
7
9
  post<T>(path: string, body?: unknown): Promise<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAK1C,OAAO,CAAC,OAAO;IAOT,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAiBjE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAajD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBnF,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAWpD"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAAuB;gBAE/B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAMpC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAOvC,OAAO,CAAC,OAAO;IAOT,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAiBjE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAajD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBnF,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAWpD"}
package/dist/client.js CHANGED
@@ -1,10 +1,19 @@
1
1
  export class MemosClient {
2
2
  baseUrl;
3
3
  token;
4
+ _currentUser = null;
4
5
  constructor(baseUrl, token) {
5
6
  this.baseUrl = baseUrl.replace(/\/+$/, "");
6
7
  this.token = token;
7
8
  }
9
+ // Fetch and cache the current user's name (e.g. "users/1")
10
+ async getCurrentUser() {
11
+ if (this._currentUser)
12
+ return this._currentUser;
13
+ const res = await this.post("/api/v1/auth/status", {});
14
+ this._currentUser = res.name;
15
+ return this._currentUser;
16
+ }
8
17
  headers() {
9
18
  return {
10
19
  Authorization: `Bearer ${this.token}`,
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,eAAO,MAAM,eAAe,GAAI,QAAQ,SAAS,SAoFhD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,eAAO,MAAM,eAAe,GAAI,QAAQ,SAAS,SAiFhD,CAAC"}
@@ -33,12 +33,10 @@ export const registerPrompts = (server) => {
33
33
  content: {
34
34
  type: "text",
35
35
  text: `Start a memo review session:
36
- 1. Call list_review_memos to get memos due for review
37
- 2. If the session is already completed, let me know
38
- 3. Otherwise, present each memo one by one with its content
39
- 4. After presenting all memos, ask if I want to record the review
40
- 5. If yes, call record_review with the memo IDs and source REVIEW_SOURCE_REVIEW
41
- 6. Finally, show the updated review stats using get_review_stats`,
36
+ 1. Call list_memos with random=true and pageSize=5 to get random memos for review
37
+ 2. Present each memo one by one with its content (use get_memo for full details)
38
+ 3. After presenting all memos, ask if I'd like to see more or stop
39
+ 4. Optionally suggest related memos based on tags`,
42
40
  },
43
41
  },
44
42
  ],
@@ -52,15 +50,14 @@ export const registerPrompts = (server) => {
52
50
  content: {
53
51
  type: "text",
54
52
  text: `Create a daily digest of my memos:
55
- 1. Call list_memos with pageSize 50 to get recent memos
56
- 2. Call list_pinned_tags to see my important tags
53
+ 1. Call list_memos with pageSize=50 to get recent memos
54
+ 2. Call list_tags to see my top tags and their usage
57
55
  3. Summarize:
58
56
  - How many memos were created/updated recently
59
57
  - Key themes and topics based on tags
60
58
  - Any pinned memos that might need attention
61
- - Any memos with incomplete tasks (if visible in properties)
62
- 4. Check list_on_this_day_memos for any "on this day" memories
63
- 5. Present everything in a concise daily briefing format`,
59
+ - Any memos with incomplete tasks (use hasIncompleteTasks filter)
60
+ 4. Present everything in a concise daily briefing format`,
64
61
  },
65
62
  },
66
63
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAiB,EAAE,EAAE;IACnD,MAAM,CAAC,MAAM,CACX,SAAS,EACT,gCAAgC,EAChC;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAC9D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC;QACxF,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;KACtG,EACD,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE;QAChC,IAAI,WAAW,GAAG,OAAO,CAAC;QAC1B,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,OAAO,GAAG,IAAI;iBACjB,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;iBAC1B,IAAI,CAAC,GAAG,CAAC,CAAC;YACb,WAAW,GAAG,GAAG,WAAW,OAAO,OAAO,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,oFAAoF,UAAU,kBAAkB,WAAW,EAAE;qBACpI;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,QAAQ,EACR,oCAAoC,EACpC,EAAE,EACF,GAAG,EAAE;QACH,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;;;;;iEAM6C;qBACpD;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,cAAc,EACd,gCAAgC,EAChC,EAAE,EACF,GAAG,EAAE;QACH,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;;;;;;;;yDASqC;qBAC5C;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAiB,EAAE,EAAE;IACnD,MAAM,CAAC,MAAM,CACX,SAAS,EACT,gCAAgC,EAChC;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAC9D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC;QACxF,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;KACtG,EACD,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE;QAChC,IAAI,WAAW,GAAG,OAAO,CAAC;QAC1B,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,OAAO,GAAG,IAAI;iBACjB,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;iBAC1B,IAAI,CAAC,GAAG,CAAC,CAAC;YACb,WAAW,GAAG,GAAG,WAAW,OAAO,OAAO,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,oFAAoF,UAAU,kBAAkB,WAAW,EAAE;qBACpI;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,QAAQ,EACR,oCAAoC,EACpC,EAAE,EACF,GAAG,EAAE;QACH,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;;;kDAI8B;qBACrC;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,cAAc,EACd,gCAAgC,EAChC,EAAE,EACF,GAAG,EAAE;QACH,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;;;;;;;yDAQqC;qBAC5C;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE,eAAO,MAAM,YAAY,iBAoCxB,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,eAAO,MAAM,YAAY,iBAiCxB,CAAC"}
package/dist/server.js CHANGED
@@ -1,14 +1,9 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { MemosClient } from "./client.js";
3
3
  import { registerMemoTools } from "./tools/memos.js";
4
- import { registerCommentTools } from "./tools/comments.js";
5
4
  import { registerTagTools } from "./tools/tags.js";
6
- import { registerResourceTools } from "./tools/resources.js";
7
- import { registerRelationTools } from "./tools/relations.js";
8
- import { registerReactionTools } from "./tools/reactions.js";
9
- import { registerReviewTools } from "./tools/review.js";
10
- import { registerPrompts } from "./prompts/index.js";
11
5
  import { registerResources } from "./resources/index.js";
6
+ const VALID_VISIBILITIES = ["PRIVATE", "PROTECTED", "PUBLIC"];
12
7
  export const createServer = () => {
13
8
  const memosUrl = process.env.MEMOS_URL;
14
9
  const memosToken = process.env.MEMOS_TOKEN;
@@ -20,21 +15,17 @@ export const createServer = () => {
20
15
  console.error("Error: MEMOS_TOKEN environment variable is required");
21
16
  process.exit(1);
22
17
  }
18
+ const rawVisibility = process.env.MEMOS_DEFAULT_VISIBILITY?.toUpperCase();
19
+ const defaultVisibility = rawVisibility && VALID_VISIBILITIES.includes(rawVisibility)
20
+ ? rawVisibility
21
+ : "PRIVATE";
23
22
  const client = new MemosClient(memosUrl, memosToken);
24
23
  const server = new McpServer({
25
24
  name: "memos-mcp",
26
- version: "0.1.0",
25
+ version: "0.2.0",
27
26
  });
28
- // Register all tools
29
- registerMemoTools(server, client);
30
- registerCommentTools(server, client);
27
+ registerMemoTools(server, client, { defaultVisibility });
31
28
  registerTagTools(server, client);
32
- registerResourceTools(server, client);
33
- registerRelationTools(server, client);
34
- registerReactionTools(server, client);
35
- registerReviewTools(server, client);
36
- // Register prompts
37
- registerPrompts(server);
38
29
  // Register resources
39
30
  registerResources(server, client);
40
31
  return server;
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE;IAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;IACvC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAE3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,qBAAqB;IACrB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC,mBAAmB;IACnB,eAAe,CAAC,MAAM,CAAC,CAAC;IAExB,qBAAqB;IACrB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,kBAAkB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAU,CAAC;AAGvE,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE;IAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;IACvC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAE3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,WAAW,EAAE,CAAC;IAC1E,MAAM,iBAAiB,GACrB,aAAa,IAAI,kBAAkB,CAAC,QAAQ,CAAC,aAA2B,CAAC;QACvE,CAAC,CAAE,aAA4B;QAC/B,CAAC,CAAC,SAAS,CAAC;IAEhB,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACzD,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,qBAAqB;IACrB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
@@ -1,4 +1,9 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { MemosClient } from "../client.js";
3
- export declare const registerMemoTools: (server: McpServer, client: MemosClient) => void;
3
+ type Visibility = "PRIVATE" | "PROTECTED" | "PUBLIC";
4
+ interface MemoToolsOptions {
5
+ defaultVisibility: Visibility;
6
+ }
7
+ export declare const registerMemoTools: (server: McpServer, client: MemosClient, options: MemoToolsOptions) => void;
8
+ export {};
4
9
  //# sourceMappingURL=memos.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memos.d.ts","sourceRoot":"","sources":["../../src/tools/memos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,eAAO,MAAM,iBAAiB,GAAI,QAAQ,SAAS,EAAE,QAAQ,WAAW,SAmHvE,CAAC"}
1
+ {"version":3,"file":"memos.d.ts","sourceRoot":"","sources":["../../src/tools/memos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,KAAK,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AA8HrD,UAAU,gBAAgB;IACxB,iBAAiB,EAAE,UAAU,CAAC;CAC/B;AAED,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,SAAS,EACjB,QAAQ,WAAW,EACnB,SAAS,gBAAgB,SA6L1B,CAAC"}
@@ -1,55 +1,209 @@
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
- if (state) {
13
- const stateFilter = `row_status == "${state === "ARCHIVED" ? "ARCHIVED" : "ACTIVE"}"`;
14
- params.filter = filter ? `${filter} && ${stateFilter}` : stateFilter;
15
- }
16
- else if (filter) {
17
- params.filter = filter;
2
+ function parseToUnixTimestamp(isoString, paramName) {
3
+ const date = new Date(isoString);
4
+ if (isNaN(date.getTime())) {
5
+ throw new Error(`Invalid date format for ${paramName}. Use ISO 8601 format (e.g., "2025-01-01" or "2025-01-01T00:00:00Z").`);
6
+ }
7
+ return Math.floor(date.getTime() / 1000);
8
+ }
9
+ function buildCelFilter(opts) {
10
+ const parts = [`creator == "${opts.creator}"`];
11
+ if (opts.query) {
12
+ const escaped = opts.query.replace(/"/g, '\\"');
13
+ parts.push(`content_search == ["${escaped}"]`);
14
+ }
15
+ if (opts.tags?.length) {
16
+ const tagList = opts.tags.map((t) => `"${t.replace(/"/g, '\\"')}"`).join(", ");
17
+ parts.push(`tag_search == [${tagList}]`);
18
+ }
19
+ if (opts.visibility?.length) {
20
+ const visList = opts.visibility.map((v) => `"${v}"`).join(", ");
21
+ parts.push(`visibilities == [${visList}]`);
22
+ }
23
+ if (opts.state) {
24
+ parts.push(`row_status == "${opts.state === "ARCHIVED" ? "ARCHIVED" : "ACTIVE"}"`);
25
+ }
26
+ if (opts.pinned !== undefined) {
27
+ parts.push(`pinned == ${opts.pinned}`);
28
+ }
29
+ if (opts.startDate) {
30
+ parts.push(`display_time_after == ${parseToUnixTimestamp(opts.startDate, "startDate")}`);
31
+ }
32
+ if (opts.endDate) {
33
+ parts.push(`display_time_before == ${parseToUnixTimestamp(opts.endDate, "endDate")}`);
34
+ }
35
+ if (opts.hasLink)
36
+ parts.push(`has_link == true`);
37
+ if (opts.hasTaskList)
38
+ parts.push(`has_task_list == true`);
39
+ if (opts.hasCode)
40
+ parts.push(`has_code == true`);
41
+ if (opts.hasIncompleteTasks)
42
+ parts.push(`has_incomplete_tasks == true`);
43
+ if (opts.random)
44
+ parts.push(`random == true`);
45
+ return parts.join(" && ");
46
+ }
47
+ async function resolveToNumericId(client, id) {
48
+ if (/^\d+$/.test(id)) {
49
+ return parseInt(id, 10);
50
+ }
51
+ const memo = await client.get(`/api/v1/memos:by-uid/${id}`);
52
+ const match = memo.name.match(/^memos\/(\d+)$/);
53
+ if (!match)
54
+ throw new Error(`Unexpected memo name format: ${memo.name}`);
55
+ return parseInt(match[1], 10);
56
+ }
57
+ const SNIPPET_MAX_LENGTH = 200;
58
+ function compactProperty(property) {
59
+ if (!property)
60
+ return undefined;
61
+ const truthy = {};
62
+ for (const [k, v] of Object.entries(property)) {
63
+ if (v)
64
+ truthy[k] = v;
65
+ }
66
+ return Object.keys(truthy).length > 0 ? truthy : undefined;
67
+ }
68
+ function summarizeMemo(memo) {
69
+ const content = memo.content || "";
70
+ const snippet = content.length > SNIPPET_MAX_LENGTH
71
+ ? content.slice(0, SNIPPET_MAX_LENGTH) + "..."
72
+ : content;
73
+ const name = memo.name;
74
+ const id = name?.match(/^memos\/(\d+)$/)?.[1];
75
+ const summary = {
76
+ id: id ? Number(id) : undefined,
77
+ uid: memo.uid,
78
+ displayTime: memo.displayTime,
79
+ snippet,
80
+ tags: memo.tags,
81
+ visibility: memo.visibility,
82
+ };
83
+ if (memo.pinned)
84
+ summary.pinned = true;
85
+ const property = compactProperty(memo.property);
86
+ if (property)
87
+ summary.property = property;
88
+ return summary;
89
+ }
90
+ function cleanMemo(memo) {
91
+ const { name, nodes, snippet, creator, ...rest } = memo;
92
+ // Add clean numeric id
93
+ const id = name?.match(/^memos\/(\d+)$/)?.[1];
94
+ if (id)
95
+ rest.id = Number(id);
96
+ // Remove empty arrays
97
+ for (const key of ["resources", "relations", "reactions"]) {
98
+ if (Array.isArray(rest[key]) && rest[key].length === 0) {
99
+ delete rest[key];
18
100
  }
101
+ }
102
+ return rest;
103
+ }
104
+ export const registerMemoTools = (server, client, options) => {
105
+ const visibilityEnum = z.enum(["PRIVATE", "PROTECTED", "PUBLIC"]);
106
+ // 1. list_memos
107
+ server.tool("list_memos", "Search and list memos. All filters are optional and combined with AND logic.", {
108
+ query: z.string().optional().describe("Keyword search in memo content"),
109
+ tags: z.array(z.string()).optional().describe("Filter by tags, e.g. [\"project\", \"todo\"]"),
110
+ visibility: z
111
+ .array(visibilityEnum)
112
+ .optional()
113
+ .describe("Filter by visibility levels"),
114
+ state: z
115
+ .enum(["NORMAL", "ARCHIVED"])
116
+ .optional()
117
+ .describe("Filter by memo state"),
118
+ pinned: z.boolean().optional().describe("Filter by pinned status"),
119
+ startDate: z
120
+ .string()
121
+ .optional()
122
+ .describe("Return memos after this date (ISO 8601, e.g. \"2025-01-01\")"),
123
+ endDate: z
124
+ .string()
125
+ .optional()
126
+ .describe("Return memos before this date (ISO 8601, e.g. \"2025-03-01\")"),
127
+ hasLink: z.boolean().optional().describe("Filter to memos containing links"),
128
+ hasTaskList: z.boolean().optional().describe("Filter to memos containing task lists"),
129
+ hasCode: z.boolean().optional().describe("Filter to memos containing code blocks"),
130
+ hasIncompleteTasks: z
131
+ .boolean()
132
+ .optional()
133
+ .describe("Filter to memos with incomplete tasks"),
134
+ random: z.boolean().optional().describe("Return results in random order"),
135
+ pageSize: z
136
+ .number()
137
+ .int()
138
+ .min(1)
139
+ .max(100)
140
+ .default(20)
141
+ .describe("Number of memos per page"),
142
+ pageToken: z.string().optional().describe("Token for fetching the next page"),
143
+ }, async (args) => {
144
+ const currentUser = await client.getCurrentUser();
145
+ const filter = buildCelFilter({ creator: currentUser, ...args });
146
+ const params = {
147
+ pageSize: String(args.pageSize),
148
+ filter,
149
+ };
150
+ if (args.pageToken)
151
+ params.pageToken = args.pageToken;
19
152
  const result = await client.get("/api/v1/memos", params);
20
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
153
+ const summaries = (result.memos || []).map((m) => summarizeMemo(m));
154
+ const output = { memos: summaries };
155
+ if (result.nextPageToken)
156
+ output.nextPageToken = result.nextPageToken;
157
+ return { content: [{ type: "text", text: JSON.stringify(output, null, 2) }] };
21
158
  });
22
- server.tool("get_memo", "Get a single memo by ID", {
23
- id: z.number().int().describe("Memo ID"),
159
+ // 2. get_memo
160
+ server.tool("get_memo", "Get a single memo by its numeric ID or UID string (the ID from the memo URL).", {
161
+ id: z
162
+ .string()
163
+ .min(1)
164
+ .describe("Memo identifier. Numeric ID (e.g. \"42\") or UID string (e.g. \"AjF4AQJayxvDj2mrWzFWuP\")"),
24
165
  }, async ({ id }) => {
25
- const memo = await client.get(`/api/v1/memos/${id}`);
26
- return { content: [{ type: "text", text: JSON.stringify(memo, null, 2) }] };
27
- });
28
- server.tool("search_memos", "Search memos by keyword in content", {
29
- query: z.string().min(1).describe("Search keyword"),
30
- pageSize: z.number().int().min(1).max(100).default(20).describe("Number of results"),
31
- }, async ({ query, pageSize }) => {
32
- const filter = `content.contains("${query.replace(/"/g, '\\"')}")`;
33
- const result = await client.get("/api/v1/memos", {
34
- pageSize: String(pageSize),
35
- filter,
36
- });
37
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
166
+ const path = /^\d+$/.test(id)
167
+ ? `/api/v1/memos/${id}`
168
+ : `/api/v1/memos:by-uid/${id}`;
169
+ const memo = await client.get(path);
170
+ const cleaned = cleanMemo(memo);
171
+ return { content: [{ type: "text", text: JSON.stringify(cleaned, null, 2) }] };
38
172
  });
39
- server.tool("create_memo", "Create a new memo", {
40
- content: z.string().min(1).describe("Memo content in markdown"),
41
- visibility: z.enum(["PRIVATE", "PROTECTED", "PUBLIC"]).default("PRIVATE").describe("Memo visibility"),
173
+ // 3. create_memo
174
+ server.tool("create_memo", "Create a new memo with markdown content.", {
175
+ content: z.string().min(1).describe("Memo content in markdown. Tags can be included with #tagname syntax"),
176
+ visibility: visibilityEnum
177
+ .optional()
178
+ .describe("Memo visibility. Omit to use the configured default"),
42
179
  }, async ({ content, visibility }) => {
43
- const memo = await client.post("/api/v1/memos", { content, visibility });
44
- return { content: [{ type: "text", text: JSON.stringify(memo, null, 2) }] };
180
+ const memo = await client.post("/api/v1/memos", {
181
+ content,
182
+ visibility: visibility ?? options.defaultVisibility,
183
+ });
184
+ const id = memo.name?.match(/^memos\/(\d+)$/)?.[1];
185
+ const result = { id: id ? Number(id) : undefined, uid: memo.uid, visibility: memo.visibility };
186
+ return { content: [{ type: "text", text: JSON.stringify(result) }] };
45
187
  });
46
- server.tool("update_memo", "Update an existing memo", {
47
- id: z.number().int().describe("Memo ID"),
48
- content: z.string().optional().describe("New content"),
49
- visibility: z.enum(["PRIVATE", "PROTECTED", "PUBLIC"]).optional().describe("New visibility"),
188
+ // 4. update_memo
189
+ server.tool("update_memo", "Update an existing memo. Only the fields you provide will be modified.", {
190
+ id: z
191
+ .string()
192
+ .min(1)
193
+ .describe("Memo identifier. Numeric ID or UID string"),
194
+ content: z.string().optional().describe("New memo content in markdown"),
195
+ visibility: visibilityEnum.optional().describe("New visibility level"),
50
196
  pinned: z.boolean().optional().describe("Pin or unpin the memo"),
51
- state: z.enum(["NORMAL", "ARCHIVED"]).optional().describe("Archive or restore the memo"),
52
- }, async ({ id, content, visibility, pinned, state }) => {
197
+ state: z
198
+ .enum(["NORMAL", "ARCHIVED"])
199
+ .optional()
200
+ .describe("Set to ARCHIVED to archive, NORMAL to restore"),
201
+ preserveUpdateTime: z
202
+ .boolean()
203
+ .optional()
204
+ .describe("When true, the memo's update time will not change. Use for formatting or style-only edits"),
205
+ }, async ({ id, content, visibility, pinned, state, preserveUpdateTime }) => {
206
+ const numericId = await resolveToNumericId(client, id);
53
207
  const body = {};
54
208
  const updateMaskPaths = [];
55
209
  if (content !== undefined) {
@@ -68,15 +222,33 @@ export const registerMemoTools = (server, client) => {
68
222
  body.rowStatus = state === "ARCHIVED" ? "ARCHIVED" : "ACTIVE";
69
223
  updateMaskPaths.push("row_status");
70
224
  }
71
- const memo = await client.patch(`/api/v1/memos/${id}`, body, {
225
+ if (updateMaskPaths.length === 0) {
226
+ return {
227
+ content: [
228
+ {
229
+ type: "text",
230
+ text: "No fields to update. Provide at least one of: content, visibility, pinned, state.",
231
+ },
232
+ ],
233
+ };
234
+ }
235
+ const params = {
72
236
  updateMask: updateMaskPaths.join(","),
73
- });
74
- return { content: [{ type: "text", text: JSON.stringify(memo, null, 2) }] };
237
+ };
238
+ if (preserveUpdateTime)
239
+ params.preserveUpdateTime = "true";
240
+ await client.patch(`/api/v1/memos/${numericId}`, body, params);
241
+ return { content: [{ type: "text", text: `Memo ${id} updated.` }] };
75
242
  });
76
- server.tool("delete_memo", "Permanently delete a memo", {
77
- id: z.number().int().describe("Memo ID to delete"),
243
+ // 5. delete_memo
244
+ server.tool("delete_memo", "Permanently delete a memo. This action cannot be undone.", {
245
+ id: z
246
+ .string()
247
+ .min(1)
248
+ .describe("Memo identifier. Numeric ID or UID string"),
78
249
  }, async ({ id }) => {
79
- await client.delete(`/api/v1/memos/${id}`);
250
+ const numericId = await resolveToNumericId(client, id);
251
+ await client.delete(`/api/v1/memos/${numericId}`);
80
252
  return { content: [{ type: "text", text: `Memo ${id} deleted.` }] };
81
253
  });
82
254
  };
@@ -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":"tags.d.ts","sourceRoot":"","sources":["../../src/tools/tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,eAAO,MAAM,gBAAgB,GAAI,QAAQ,SAAS,EAAE,QAAQ,WAAW,SAgDtE,CAAC"}
1
+ {"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../src/tools/tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAyD3C,eAAO,MAAM,gBAAgB,GAAI,QAAQ,SAAS,EAAE,QAAQ,WAAW,SA+HtE,CAAC"}
@@ -1,16 +1,111 @@
1
1
  import { z } from "zod";
2
- export const registerTagTools = (server, client) => {
3
- server.tool("list_pinned_tags", "List all pinned tags", {}, async () => {
4
- const result = await client.get("/api/v1/tags:pinned");
5
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
2
+ function collectTags(memos, parent, recursive) {
3
+ const tagCounts = new Map();
4
+ for (const memo of memos) {
5
+ for (const tag of memo.tags ?? []) {
6
+ if (parent) {
7
+ const prefix = parent + "/";
8
+ if (!tag.startsWith(prefix))
9
+ continue;
10
+ if (recursive) {
11
+ tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1);
12
+ }
13
+ else {
14
+ const child = prefix + tag.slice(prefix.length).split("/")[0];
15
+ tagCounts.set(child, (tagCounts.get(child) || 0) + 1);
16
+ }
17
+ }
18
+ else if (recursive) {
19
+ tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1);
20
+ }
21
+ else {
22
+ const topLevel = tag.split("/")[0];
23
+ tagCounts.set(topLevel, (tagCounts.get(topLevel) || 0) + 1);
24
+ }
25
+ }
26
+ }
27
+ return tagCounts;
28
+ }
29
+ function buildAllTagsSet(memos) {
30
+ const allTags = new Set();
31
+ for (const memo of memos) {
32
+ for (const tag of memo.tags ?? []) {
33
+ allTags.add(tag);
34
+ }
35
+ }
36
+ return allTags;
37
+ }
38
+ async function fetchAllMemoMetadata(client) {
39
+ const currentUser = await client.getCurrentUser();
40
+ const filter = `creator == "${currentUser}"`;
41
+ const result = await client.get("/api/v1/memos", {
42
+ pageSize: "1000000",
43
+ filter,
44
+ view: "MEMO_VIEW_METADATA_ONLY",
6
45
  });
7
- server.tool("list_tags_with_emoji", "List all tags with their associated emojis", {}, async () => {
8
- const result = await client.get("/api/v1/tags:emoji");
9
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
46
+ return result.memos || [];
47
+ }
48
+ export const registerTagTools = (server, client) => {
49
+ server.tool("list_tags", [
50
+ "List tags with usage counts. Returns {name, count, hasChildren, pinned, emoji} for each tag.",
51
+ "- No args: top-level tags only.",
52
+ "- recursive=true: every tag (flat list, good for recommending tags).",
53
+ "- parent=\"x\": direct children of tag \"x\".",
54
+ "- parent=\"x\" + recursive=true: all descendants under \"x\".",
55
+ "- pinnedOnly=true: only user-pinned tags.",
56
+ "Tags use \"/\" for hierarchy (e.g. \"project/work/backend\").",
57
+ ].join(" "), {
58
+ parent: z
59
+ .string()
60
+ .optional()
61
+ .describe("Parent tag to scope the listing (e.g. \"project\" or \"project/work\"). Omit to start from root"),
62
+ recursive: z
63
+ .boolean()
64
+ .optional()
65
+ .describe("When true, return all tags/descendants instead of only direct children"),
66
+ pinnedOnly: z
67
+ .boolean()
68
+ .optional()
69
+ .describe("When true, only return user-pinned tags"),
70
+ }, async ({ parent, recursive, pinnedOnly }) => {
71
+ const [memos, pinnedResult] = await Promise.all([
72
+ fetchAllMemoMetadata(client),
73
+ client.get("/api/v1/tags:pinned"),
74
+ ]);
75
+ const tagCounts = collectTags(memos, parent, recursive);
76
+ const allTags = buildAllTagsSet(memos);
77
+ const pinnedMap = new Map();
78
+ for (const t of pinnedResult.tags ?? []) {
79
+ pinnedMap.set(t.tagName, t);
80
+ }
81
+ const results = Array.from(tagCounts.entries())
82
+ .map(([name, count]) => {
83
+ const pinData = pinnedMap.get(name);
84
+ const entry = { name, count };
85
+ if ([...allTags].some((t) => t.startsWith(name + "/")))
86
+ entry.hasChildren = true;
87
+ if (pinData) {
88
+ entry.pinned = true;
89
+ if (pinData.emoji)
90
+ entry.emoji = pinData.emoji;
91
+ }
92
+ return entry;
93
+ })
94
+ .filter((t) => !pinnedOnly || t.pinned)
95
+ .sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));
96
+ if (results.length === 0) {
97
+ const msg = pinnedOnly
98
+ ? "No pinned tags found."
99
+ : parent
100
+ ? `No child tags found under "${parent}".`
101
+ : "No tags found.";
102
+ return { content: [{ type: "text", text: msg }] };
103
+ }
104
+ return { content: [{ type: "text", text: JSON.stringify(results, null, 2) }] };
10
105
  });
11
- server.tool("update_tag", "Update a tag's emoji or pinned status", {
106
+ server.tool("update_tag", "Update a tag's pinned status or emoji. Pinned tags are highlighted in the UI for quick access.", {
12
107
  tagName: z.string().min(1).describe("Tag name (without #)"),
13
- emoji: z.string().optional().describe("Emoji to associate with the tag"),
108
+ emoji: z.string().optional().describe("Emoji to associate with the tag (e.g. \"📅\"). Pass empty string to remove"),
14
109
  pinned: z.boolean().optional().describe("Pin or unpin the tag"),
15
110
  }, async ({ tagName, emoji, pinned }) => {
16
111
  const body = {};
@@ -23,10 +118,36 @@ export const registerTagTools = (server, client) => {
23
118
  body.pinned = pinned;
24
119
  updateMaskPaths.push("pinned");
25
120
  }
26
- const tag = await client.patch(`/api/v1/tags/${tagName}`, body, {
121
+ await client.patch(`/api/v1/tags/${tagName}`, body, {
27
122
  updateMask: updateMaskPaths.join(","),
28
123
  });
29
- return { content: [{ type: "text", text: JSON.stringify(tag, null, 2) }] };
124
+ const parts = [];
125
+ if (emoji !== undefined)
126
+ parts.push(emoji ? `emoji set to ${emoji}` : "emoji removed");
127
+ if (pinned !== undefined)
128
+ parts.push(pinned ? "pinned" : "unpinned");
129
+ return {
130
+ content: [{ type: "text", text: `Tag "#${tagName}" updated: ${parts.join(", ")}.` }],
131
+ };
132
+ });
133
+ server.tool("rename_tag", "Rename a tag across ALL memos. This is a destructive operation that modifies memo content globally — use with caution.", {
134
+ oldTag: z.string().min(1).describe("Current tag name (without #)"),
135
+ newTag: z.string().min(1).describe("New tag name (without #)"),
136
+ }, { destructiveHint: true }, async ({ oldTag, newTag }) => {
137
+ // parent = "memos/-" means rename across all memos
138
+ await client.patch(`/api/v1/memos/-/tags:rename`, {
139
+ parent: "memos/-",
140
+ oldTag,
141
+ newTag,
142
+ });
143
+ return {
144
+ content: [
145
+ {
146
+ type: "text",
147
+ text: `Tag "#${oldTag}" has been renamed to "#${newTag}" across all memos.`,
148
+ },
149
+ ],
150
+ };
30
151
  });
31
152
  };
32
153
  //# sourceMappingURL=tags.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/tools/tags.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAiB,EAAE,MAAmB,EAAE,EAAE;IACzE,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,sBAAsB,EACtB,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAkB,qBAAqB,CAAC,CAAC;QACxE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,4CAA4C,EAC5C,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAkB,oBAAoB,CAAC,CAAC;QACvE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,uCAAuC,EACvC;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QAC3D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QACxE,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KAChE,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;QACnC,MAAM,IAAI,GAA4B,EAAE,CAAC;QACzC,MAAM,eAAe,GAAa,EAAE,CAAC;QAErC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAM,gBAAgB,OAAO,EAAE,EAAE,IAAI,EAAE;YACnE,UAAU,EAAE,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;SACtC,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACtF,CAAC,CACF,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/tools/tags.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,SAAS,WAAW,CAClB,KAAa,EACb,MAAe,EACf,SAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;YAClC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC;gBAC5B,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;oBAAE,SAAS;gBACtC,IAAI,SAAS,EAAE,CAAC;oBACd,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACpD,CAAC;qBAAM,CAAC;oBACN,MAAM,KAAK,GAAG,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC9D,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC;iBAAM,IAAI,SAAS,EAAE,CAAC;gBACrB,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,MAAmB;IACrD,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,CAAC;IAClD,MAAM,MAAM,GAAG,eAAe,WAAW,GAAG,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAC7B,eAAe,EACf;QACE,QAAQ,EAAE,SAAS;QACnB,MAAM;QACN,IAAI,EAAE,yBAAyB;KAChC,CACF,CAAC;IACF,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAiB,EAAE,MAAmB,EAAE,EAAE;IACzE,MAAM,CAAC,IAAI,CACT,WAAW,EACX;QACE,8FAA8F;QAC9F,iCAAiC;QACjC,sEAAsE;QACtE,+CAA+C;QAC/C,+DAA+D;QAC/D,2CAA2C;QAC3C,+DAA+D;KAChE,CAAC,IAAI,CAAC,GAAG,CAAC,EACX;QACE,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,iGAAiG,CAClG;QACH,SAAS,EAAE,CAAC;aACT,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,wEAAwE,CAAC;QACrF,UAAU,EAAE,CAAC;aACV,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,yCAAyC,CAAC;KACvD,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE;QAC1C,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC9C,oBAAoB,CAAC,MAAM,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAkB,qBAAqB,CAAC;SACnD,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAEvC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAe,CAAC;QACzC,KAAK,MAAM,CAAC,IAAI,YAAY,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;YACxC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;aAC5C,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;YACrB,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,KAAK,GAA4B,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;YACvD,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;gBAAE,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YACjF,IAAI,OAAO,EAAE,CAAC;gBACZ,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;gBACpB,IAAI,OAAO,CAAC,KAAK;oBAAE,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;YACjD,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,MAAM,CAAC;aACtC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAE,CAAC,CAAC,KAAgB,GAAI,CAAC,CAAC,KAAgB,IAAK,CAAC,CAAC,IAAe,CAAC,aAAa,CAAC,CAAC,CAAC,IAAc,CAAC,CAAC,CAAC;QAEnH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,UAAU;gBACpB,CAAC,CAAC,uBAAuB;gBACzB,CAAC,CAAC,MAAM;oBACN,CAAC,CAAC,8BAA8B,MAAM,IAAI;oBAC1C,CAAC,CAAC,gBAAgB,CAAC;YACvB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QAC7D,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC1F,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,gGAAgG,EAChG;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QAC3D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4EAA4E,CAAC;QACnH,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KAChE,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;QACnC,MAAM,IAAI,GAA4B,EAAE,CAAC;QACzC,MAAM,eAAe,GAAa,EAAE,CAAC;QAErC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QAED,MAAM,MAAM,CAAC,KAAK,CAAM,gBAAgB,OAAO,EAAE,EAAE,IAAI,EAAE;YACvD,UAAU,EAAE,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;SACtC,CAAC,CAAC;QACH,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,KAAK,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QACvF,IAAI,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACrE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,SAAS,OAAO,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;SAC9F,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,wHAAwH,EACxH;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAClE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC;KAC/D,EACD,EAAE,eAAe,EAAE,IAAI,EAAE,EACzB,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;QAC3B,mDAAmD;QACnD,MAAM,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE;YAChD,MAAM,EAAE,SAAS;YACjB,MAAM;YACN,MAAM;SACP,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,SAAS,MAAM,2BAA2B,MAAM,qBAAqB;iBAC5E;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chriscurrycc/memos-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Model Context Protocol server for Memos - a self-hosted note-taking service",
5
5
  "type": "module",
6
6
  "bin": {