@hu14/memos-mcp 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.
- package/README.md +129 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +379 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Memos MCP Server
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server for interacting with [Memos](https://usememos.com/) - a lightweight, open-source memo hub.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Complete Memo Management**: Create, read, update, and delete memos
|
|
8
|
+
- **Tag Support**: List, create, and manage tags
|
|
9
|
+
- **Flexible Filtering**: Filter memos by creator, tags, visibility, and more
|
|
10
|
+
- **Pagination**: Efficiently handle large memo collections
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g memos-mcp
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or run directly with npx:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx memos-mcp
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Configuration
|
|
25
|
+
|
|
26
|
+
### Environment Variables
|
|
27
|
+
|
|
28
|
+
| Variable | Required | Description |
|
|
29
|
+
|----------|----------|-------------|
|
|
30
|
+
| `MEMOS_API_URL` | No | Your Memos instance URL (default: `http://localhost:5230`) |
|
|
31
|
+
| `MEMOS_API_TOKEN` | Yes | Your Memos API access token |
|
|
32
|
+
|
|
33
|
+
### Getting an API Token
|
|
34
|
+
|
|
35
|
+
1. Log in to your Memos instance
|
|
36
|
+
2. Go to **Settings** → **Access Tokens**
|
|
37
|
+
3. Create a new token with appropriate permissions
|
|
38
|
+
|
|
39
|
+
### Claude Code Configuration
|
|
40
|
+
|
|
41
|
+
Add to your `~/.claude.json`:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"mcpServers": {
|
|
46
|
+
"memos": {
|
|
47
|
+
"command": "npx",
|
|
48
|
+
"args": ["-y", "memos-mcp"],
|
|
49
|
+
"env": {
|
|
50
|
+
"MEMOS_API_URL": "https://your-memos-instance.com",
|
|
51
|
+
"MEMOS_API_TOKEN": "your-api-token"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or for local development:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"mcpServers": {
|
|
63
|
+
"memos": {
|
|
64
|
+
"command": "node",
|
|
65
|
+
"args": ["/path/to/memos-mcp/dist/index.js"],
|
|
66
|
+
"env": {
|
|
67
|
+
"MEMOS_API_URL": "http://localhost:5230",
|
|
68
|
+
"MEMOS_API_TOKEN": "your-api-token"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Available Tools
|
|
76
|
+
|
|
77
|
+
### Memos
|
|
78
|
+
|
|
79
|
+
- **`list_memos`** - List all memos with optional filtering and pagination
|
|
80
|
+
- `filter`: Filter expression (e.g., `creator == "users/1"`, `tag == "ideas"`)
|
|
81
|
+
- `limit`: Maximum number of memos to return (default: 10)
|
|
82
|
+
- `offset`: Number of memos to skip for pagination
|
|
83
|
+
- `sort`: Sort order (e.g., `create_time desc`, `update_time`)
|
|
84
|
+
|
|
85
|
+
- **`get_memo`** - Get a single memo by ID
|
|
86
|
+
- `name`: Memo name/ID (e.g., `memos/123`)
|
|
87
|
+
|
|
88
|
+
- **`create_memo`** - Create a new memo
|
|
89
|
+
- `content`: Memo content (supports Markdown)
|
|
90
|
+
- `visibility`: Visibility level (`PRIVATE`, `PROTECTED`, `PUBLIC`)
|
|
91
|
+
- `tags`: Array of tags to attach
|
|
92
|
+
|
|
93
|
+
- **`update_memo`** - Update an existing memo
|
|
94
|
+
- `name`: Memo name/ID
|
|
95
|
+
- `content`: New content
|
|
96
|
+
- `visibility`: New visibility
|
|
97
|
+
- `tags`: New tags (replaces existing)
|
|
98
|
+
|
|
99
|
+
- **`delete_memo`** - Delete a memo permanently
|
|
100
|
+
- `name`: Memo name/ID to delete
|
|
101
|
+
|
|
102
|
+
### Tags
|
|
103
|
+
|
|
104
|
+
- **`list_tags`** - List all tags
|
|
105
|
+
- `creator`: Filter by creator
|
|
106
|
+
- `limit`: Maximum number of tags
|
|
107
|
+
|
|
108
|
+
- **`create_tag`** - Create a new tag
|
|
109
|
+
- `name`: Tag name (without # prefix)
|
|
110
|
+
|
|
111
|
+
- **`delete_tag`** - Delete a tag
|
|
112
|
+
- `name`: Tag name (e.g., `tags/ideas`)
|
|
113
|
+
|
|
114
|
+
## Development
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Install dependencies
|
|
118
|
+
npm install
|
|
119
|
+
|
|
120
|
+
# Build
|
|
121
|
+
npm run build
|
|
122
|
+
|
|
123
|
+
# Run locally
|
|
124
|
+
MEMOS_API_URL=http://localhost:5230 MEMOS_API_TOKEN=xxx npm run dev
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
MIT
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
7
|
+
// Environment configuration
|
|
8
|
+
const MEMOS_API_URL = process.env.MEMOS_API_URL || "http://localhost:5230";
|
|
9
|
+
const MEMOS_API_TOKEN = process.env.MEMOS_API_TOKEN;
|
|
10
|
+
if (!MEMOS_API_TOKEN) {
|
|
11
|
+
console.error("Error: MEMOS_API_TOKEN environment variable is required");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
// API client
|
|
15
|
+
async function memosApi(path, options = {}) {
|
|
16
|
+
const url = `${MEMOS_API_URL}${path}`;
|
|
17
|
+
const headers = {
|
|
18
|
+
"Authorization": `Bearer ${MEMOS_API_TOKEN}`,
|
|
19
|
+
"Content-Type": "application/json",
|
|
20
|
+
...options.headers,
|
|
21
|
+
};
|
|
22
|
+
const response = await fetch(url, { ...options, headers });
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
const errorText = await response.text();
|
|
25
|
+
throw new Error(`API Error ${response.status}: ${errorText}`);
|
|
26
|
+
}
|
|
27
|
+
if (response.status === 204) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return response.json();
|
|
31
|
+
}
|
|
32
|
+
// Tool definitions
|
|
33
|
+
const TOOLS = [
|
|
34
|
+
{
|
|
35
|
+
name: "list_memos",
|
|
36
|
+
description: "List all memos with optional filtering and pagination",
|
|
37
|
+
inputSchema: {
|
|
38
|
+
type: "object",
|
|
39
|
+
properties: {
|
|
40
|
+
filter: {
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "Filter expression (e.g., 'creator == \"users/1\"', 'tag == \"ideas\"')",
|
|
43
|
+
},
|
|
44
|
+
limit: {
|
|
45
|
+
type: "number",
|
|
46
|
+
description: "Maximum number of memos to return (default: 10)",
|
|
47
|
+
default: 10,
|
|
48
|
+
},
|
|
49
|
+
offset: {
|
|
50
|
+
type: "number",
|
|
51
|
+
description: "Number of memos to skip for pagination",
|
|
52
|
+
default: 0,
|
|
53
|
+
},
|
|
54
|
+
sort: {
|
|
55
|
+
type: "string",
|
|
56
|
+
description: "Sort order (e.g., 'create_time desc', 'update_time')",
|
|
57
|
+
default: "create_time desc",
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: "get_memo",
|
|
64
|
+
description: "Get a single memo by ID",
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: "object",
|
|
67
|
+
properties: {
|
|
68
|
+
name: {
|
|
69
|
+
type: "string",
|
|
70
|
+
description: "Memo name/ID (e.g., 'memos/123')",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
required: ["name"],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: "create_memo",
|
|
78
|
+
description: "Create a new memo",
|
|
79
|
+
inputSchema: {
|
|
80
|
+
type: "object",
|
|
81
|
+
properties: {
|
|
82
|
+
content: {
|
|
83
|
+
type: "string",
|
|
84
|
+
description: "Memo content (supports Markdown)",
|
|
85
|
+
},
|
|
86
|
+
visibility: {
|
|
87
|
+
type: "string",
|
|
88
|
+
description: "Memo visibility: PRIVATE, PROTECTED, or PUBLIC",
|
|
89
|
+
enum: ["PRIVATE", "PROTECTED", "PUBLIC"],
|
|
90
|
+
default: "PRIVATE",
|
|
91
|
+
},
|
|
92
|
+
tags: {
|
|
93
|
+
type: "array",
|
|
94
|
+
items: { type: "string" },
|
|
95
|
+
description: "Tags to attach to the memo",
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
required: ["content"],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "update_memo",
|
|
103
|
+
description: "Update an existing memo",
|
|
104
|
+
inputSchema: {
|
|
105
|
+
type: "object",
|
|
106
|
+
properties: {
|
|
107
|
+
name: {
|
|
108
|
+
type: "string",
|
|
109
|
+
description: "Memo name/ID (e.g., 'memos/123')",
|
|
110
|
+
},
|
|
111
|
+
content: {
|
|
112
|
+
type: "string",
|
|
113
|
+
description: "New memo content",
|
|
114
|
+
},
|
|
115
|
+
visibility: {
|
|
116
|
+
type: "string",
|
|
117
|
+
description: "New visibility: PRIVATE, PROTECTED, or PUBLIC",
|
|
118
|
+
enum: ["PRIVATE", "PROTECTED", "PUBLIC"],
|
|
119
|
+
},
|
|
120
|
+
tags: {
|
|
121
|
+
type: "array",
|
|
122
|
+
items: { type: "string" },
|
|
123
|
+
description: "New tags to replace existing ones",
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
required: ["name"],
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "delete_memo",
|
|
131
|
+
description: "Delete a memo permanently",
|
|
132
|
+
inputSchema: {
|
|
133
|
+
type: "object",
|
|
134
|
+
properties: {
|
|
135
|
+
name: {
|
|
136
|
+
type: "string",
|
|
137
|
+
description: "Memo name/ID to delete (e.g., 'memos/123')",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
required: ["name"],
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "list_tags",
|
|
145
|
+
description: "List all tags with optional filtering",
|
|
146
|
+
inputSchema: {
|
|
147
|
+
type: "object",
|
|
148
|
+
properties: {
|
|
149
|
+
creator: {
|
|
150
|
+
type: "string",
|
|
151
|
+
description: "Filter by creator (e.g., 'users/1')",
|
|
152
|
+
},
|
|
153
|
+
limit: {
|
|
154
|
+
type: "number",
|
|
155
|
+
description: "Maximum number of tags to return",
|
|
156
|
+
default: 100,
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: "create_tag",
|
|
163
|
+
description: "Create a new tag",
|
|
164
|
+
inputSchema: {
|
|
165
|
+
type: "object",
|
|
166
|
+
properties: {
|
|
167
|
+
name: {
|
|
168
|
+
type: "string",
|
|
169
|
+
description: "Tag name (without # prefix)",
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
required: ["name"],
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: "delete_tag",
|
|
177
|
+
description: "Delete a tag",
|
|
178
|
+
inputSchema: {
|
|
179
|
+
type: "object",
|
|
180
|
+
properties: {
|
|
181
|
+
name: {
|
|
182
|
+
type: "string",
|
|
183
|
+
description: "Tag name to delete (e.g., 'tags/ideas')",
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
required: ["name"],
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
];
|
|
190
|
+
// Tool handlers
|
|
191
|
+
async function handleListMemos(args) {
|
|
192
|
+
const params = new URLSearchParams();
|
|
193
|
+
if (args.filter)
|
|
194
|
+
params.append("filter", args.filter);
|
|
195
|
+
if (args.limit)
|
|
196
|
+
params.append("pageSize", args.limit.toString());
|
|
197
|
+
if (args.offset)
|
|
198
|
+
params.append("offset", args.offset.toString());
|
|
199
|
+
if (args.sort)
|
|
200
|
+
params.append("orderBy", args.sort);
|
|
201
|
+
const result = await memosApi(`/api/v1/memos?${params.toString()}`);
|
|
202
|
+
return {
|
|
203
|
+
content: [
|
|
204
|
+
{
|
|
205
|
+
type: "text",
|
|
206
|
+
text: JSON.stringify(result, null, 2),
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
async function handleGetMemo(args) {
|
|
212
|
+
const result = await memosApi(`/api/v1/${args.name}`);
|
|
213
|
+
return {
|
|
214
|
+
content: [
|
|
215
|
+
{
|
|
216
|
+
type: "text",
|
|
217
|
+
text: JSON.stringify(result, null, 2),
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
async function handleCreateMemo(args) {
|
|
223
|
+
const body = {
|
|
224
|
+
content: args.content,
|
|
225
|
+
visibility: args.visibility || "PRIVATE",
|
|
226
|
+
tags: args.tags || [],
|
|
227
|
+
};
|
|
228
|
+
const result = await memosApi("/api/v1/memos", {
|
|
229
|
+
method: "POST",
|
|
230
|
+
body: JSON.stringify(body),
|
|
231
|
+
});
|
|
232
|
+
return {
|
|
233
|
+
content: [
|
|
234
|
+
{
|
|
235
|
+
type: "text",
|
|
236
|
+
text: `Memo created successfully:\n${JSON.stringify(result, null, 2)}`,
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
async function handleUpdateMemo(args) {
|
|
242
|
+
const body = {};
|
|
243
|
+
if (args.content !== undefined)
|
|
244
|
+
body.content = args.content;
|
|
245
|
+
if (args.visibility !== undefined)
|
|
246
|
+
body.visibility = args.visibility;
|
|
247
|
+
if (args.tags !== undefined)
|
|
248
|
+
body.tags = args.tags;
|
|
249
|
+
const result = await memosApi(`/api/v1/${args.name}`, {
|
|
250
|
+
method: "PATCH",
|
|
251
|
+
body: JSON.stringify(body),
|
|
252
|
+
});
|
|
253
|
+
return {
|
|
254
|
+
content: [
|
|
255
|
+
{
|
|
256
|
+
type: "text",
|
|
257
|
+
text: `Memo updated successfully:\n${JSON.stringify(result, null, 2)}`,
|
|
258
|
+
},
|
|
259
|
+
],
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
async function handleDeleteMemo(args) {
|
|
263
|
+
await memosApi(`/api/v1/${args.name}`, {
|
|
264
|
+
method: "DELETE",
|
|
265
|
+
});
|
|
266
|
+
return {
|
|
267
|
+
content: [
|
|
268
|
+
{
|
|
269
|
+
type: "text",
|
|
270
|
+
text: `Memo ${args.name} deleted successfully.`,
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
async function handleListTags(args) {
|
|
276
|
+
const params = new URLSearchParams();
|
|
277
|
+
if (args.creator)
|
|
278
|
+
params.append("filter", `creator == "${args.creator}"`);
|
|
279
|
+
if (args.limit)
|
|
280
|
+
params.append("pageSize", args.limit.toString());
|
|
281
|
+
const result = await memosApi(`/api/v1/tags?${params.toString()}`);
|
|
282
|
+
return {
|
|
283
|
+
content: [
|
|
284
|
+
{
|
|
285
|
+
type: "text",
|
|
286
|
+
text: JSON.stringify(result, null, 2),
|
|
287
|
+
},
|
|
288
|
+
],
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
async function handleCreateTag(args) {
|
|
292
|
+
const body = {
|
|
293
|
+
name: args.name,
|
|
294
|
+
};
|
|
295
|
+
const result = await memosApi("/api/v1/tags", {
|
|
296
|
+
method: "POST",
|
|
297
|
+
body: JSON.stringify(body),
|
|
298
|
+
});
|
|
299
|
+
return {
|
|
300
|
+
content: [
|
|
301
|
+
{
|
|
302
|
+
type: "text",
|
|
303
|
+
text: `Tag created successfully:\n${JSON.stringify(result, null, 2)}`,
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
async function handleDeleteTag(args) {
|
|
309
|
+
await memosApi(`/api/v1/${args.name}`, {
|
|
310
|
+
method: "DELETE",
|
|
311
|
+
});
|
|
312
|
+
return {
|
|
313
|
+
content: [
|
|
314
|
+
{
|
|
315
|
+
type: "text",
|
|
316
|
+
text: `Tag ${args.name} deleted successfully.`,
|
|
317
|
+
},
|
|
318
|
+
],
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
// Main server
|
|
322
|
+
const server = new index_js_1.Server({
|
|
323
|
+
name: "memos-mcp",
|
|
324
|
+
version: "1.0.0",
|
|
325
|
+
}, {
|
|
326
|
+
capabilities: {
|
|
327
|
+
tools: {},
|
|
328
|
+
},
|
|
329
|
+
});
|
|
330
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
331
|
+
return { tools: TOOLS };
|
|
332
|
+
});
|
|
333
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
334
|
+
const { name, arguments: args } = request.params;
|
|
335
|
+
try {
|
|
336
|
+
switch (name) {
|
|
337
|
+
case "list_memos":
|
|
338
|
+
return await handleListMemos(args);
|
|
339
|
+
case "get_memo":
|
|
340
|
+
return await handleGetMemo(args);
|
|
341
|
+
case "create_memo":
|
|
342
|
+
return await handleCreateMemo(args);
|
|
343
|
+
case "update_memo":
|
|
344
|
+
return await handleUpdateMemo(args);
|
|
345
|
+
case "delete_memo":
|
|
346
|
+
return await handleDeleteMemo(args);
|
|
347
|
+
case "list_tags":
|
|
348
|
+
return await handleListTags(args);
|
|
349
|
+
case "create_tag":
|
|
350
|
+
return await handleCreateTag(args);
|
|
351
|
+
case "delete_tag":
|
|
352
|
+
return await handleDeleteTag(args);
|
|
353
|
+
default:
|
|
354
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
359
|
+
return {
|
|
360
|
+
content: [
|
|
361
|
+
{
|
|
362
|
+
type: "text",
|
|
363
|
+
text: `Error: ${errorMessage}`,
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
isError: true,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
// Start server
|
|
371
|
+
async function main() {
|
|
372
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
373
|
+
await server.connect(transport);
|
|
374
|
+
console.error("Memos MCP server running on stdio");
|
|
375
|
+
}
|
|
376
|
+
main().catch((error) => {
|
|
377
|
+
console.error("Fatal error:", error);
|
|
378
|
+
process.exit(1);
|
|
379
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hu14/memos-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for Memos - A lightweight, open-source memo hub",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"memos-mcp": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"start": "node dist/index.js",
|
|
17
|
+
"dev": "npm run build && npm run start"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"memos",
|
|
22
|
+
"model-context-protocol"
|
|
23
|
+
],
|
|
24
|
+
"author": "",
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
31
|
+
"zod": "^4.3.6"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^25.5.2",
|
|
35
|
+
"typescript": "^6.0.2"
|
|
36
|
+
}
|
|
37
|
+
}
|