mcp-for-memos 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 +334 -0
- package/dist/client.d.ts +15 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +155 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +18 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +27 -0
- package/dist/config.js.map +1 -0
- package/dist/http.d.ts +4 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +342 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/index.d.ts +3 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +68 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/index.d.ts +4 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +52 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +40 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/memos.d.ts +9 -0
- package/dist/tools/memos.d.ts.map +1 -0
- package/dist/tools/memos.js +137 -0
- package/dist/tools/memos.js.map +1 -0
- package/dist/tools/relations.d.ts +4 -0
- package/dist/tools/relations.d.ts.map +1 -0
- package/dist/tools/relations.js +108 -0
- package/dist/tools/relations.js.map +1 -0
- package/dist/tools/resources.d.ts +4 -0
- package/dist/tools/resources.d.ts.map +1 -0
- package/dist/tools/resources.js +90 -0
- package/dist/tools/resources.js.map +1 -0
- package/dist/tools/review.d.ts +4 -0
- package/dist/tools/review.d.ts.map +1 -0
- package/dist/tools/review.js +208 -0
- package/dist/tools/review.js.map +1 -0
- package/dist/tools/tags.d.ts +4 -0
- package/dist/tools/tags.d.ts.map +1 -0
- package/dist/tools/tags.js +164 -0
- package/dist/tools/tags.js.map +1 -0
- package/dist/tools/utils.d.ts +6 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +68 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/types.d.ts +36 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
# memos-mcp
|
|
2
|
+
|
|
3
|
+
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that turns [Memos](https://github.com/usememos/memos) into a **multi-purpose database** for your AI assistants — notes, projects, tasks, agendas, knowledge base, and more.
|
|
4
|
+
|
|
5
|
+
[中文文档](README_zh.md)
|
|
6
|
+
|
|
7
|
+
## What is this?
|
|
8
|
+
|
|
9
|
+
**memos-mcp** is a bridge between AI assistants and your Memos instance. Instead of context windows that forget, your AI has a **persistent memory database** it can query, create, and organize notes in.
|
|
10
|
+
|
|
11
|
+
Think of it as:
|
|
12
|
+
- 📝 **Personal knowledge base** — capture ideas, research, learnings
|
|
13
|
+
- 📋 **Task manager** — to-dos, checklists, project tracking
|
|
14
|
+
- 📅 **Agenda/planner** — schedules, meeting notes, deadlines
|
|
15
|
+
- 🏗️ **Project database** — specs, decisions, retrospectives
|
|
16
|
+
- 🔖 **Bookmark system** — save links, quotes, references
|
|
17
|
+
|
|
18
|
+
Your AI assistant can search by date, filter by tags, create notes on the fly, and query your entire history — all through natural language.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## What can the AI do with this MCP?
|
|
23
|
+
|
|
24
|
+
Once connected, your AI assistant gains **persistent memory**. Here's what it can do:
|
|
25
|
+
|
|
26
|
+
### 📝 Create Notes
|
|
27
|
+
- Save meeting notes, ideas, tasks, or anything
|
|
28
|
+
- Use `#hashtags` for automatic tagging
|
|
29
|
+
- Backdate notes to a specific time
|
|
30
|
+
- Markdown support (bold, lists, code blocks, etc.)
|
|
31
|
+
|
|
32
|
+
### 🔍 Search & Recall
|
|
33
|
+
- "What did I do yesterday?" → searches by date
|
|
34
|
+
- "Show me #project notes" → filters by tag
|
|
35
|
+
- "Find notes about API design" → full-text search
|
|
36
|
+
- "What's on my agenda today?" → today's memos
|
|
37
|
+
- "Notes from last week" → date range search
|
|
38
|
+
- "Show pinned notes" → filter by pin status
|
|
39
|
+
- "Find notes with incomplete tasks" → task filter
|
|
40
|
+
|
|
41
|
+
### ✏️ Update & Organize
|
|
42
|
+
- Edit existing notes
|
|
43
|
+
- Pin important memos
|
|
44
|
+
- Archive old notes
|
|
45
|
+
- Change visibility (private/public)
|
|
46
|
+
|
|
47
|
+
### 🗑️ Clean Up
|
|
48
|
+
- Delete notes you no longer need
|
|
49
|
+
|
|
50
|
+
### 🏷️ Tag Management
|
|
51
|
+
- List all tags with usage counts
|
|
52
|
+
- Browse tag hierarchy (`#work/meeting`, `#project/backend`)
|
|
53
|
+
- Analyze and suggest tag improvements
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Tools (6)
|
|
58
|
+
|
|
59
|
+
| Tool | What it does | Key Features |
|
|
60
|
+
|------|-------------|--------------|
|
|
61
|
+
| `search` | Search memos by date, tags, content, visibility, pinned status | Relative dates (`today`, `yesterday`, `next_monday`), date ranges, week view, full-text search |
|
|
62
|
+
| `get` | Get a single memo's full content | By ID or UID, includes attachments metadata |
|
|
63
|
+
| `create` | Create a memo with markdown and #hashtags | Backdate support, visibility control. **Max 13,000 chars** |
|
|
64
|
+
| `update` | Update memo content, visibility, or pin status | Partial updates (only changed fields), archive/restore |
|
|
65
|
+
| `delete` | Permanently delete a memo | Cannot be undone |
|
|
66
|
+
| `tags` | List all tags with usage counts | Hierarchical: top-level, children, or recursive flat list |
|
|
67
|
+
|
|
68
|
+
### Search Date Examples
|
|
69
|
+
|
|
70
|
+
| You say | The AI calls |
|
|
71
|
+
|---------|-------------|
|
|
72
|
+
| "What did I do yesterday?" | `search(date="yesterday")` |
|
|
73
|
+
| "What's on my agenda today?" | `search(date="today")` |
|
|
74
|
+
| "Notes from last week" | `search(date="last_week", week=true)` |
|
|
75
|
+
| "Show me #project notes" | `search(tags=["project"])` |
|
|
76
|
+
| "Find notes about API design" | `search(query="API design")` |
|
|
77
|
+
| "What happened on June 15?" | `search(date="2025-06-15")` |
|
|
78
|
+
| "March to April overview" | `search(date="2025-03-01", endDate="2025-04-30")` |
|
|
79
|
+
| "Show all my memos" | `search()` |
|
|
80
|
+
| "Find notes with incomplete tasks" | `search(hasIncompleteTasks=true)` |
|
|
81
|
+
| "Show notes with attachments" | `search(hasAttachments=true)` |
|
|
82
|
+
|
|
83
|
+
### Supported Relative Dates
|
|
84
|
+
|
|
85
|
+
`today`, `yesterday`, `tomorrow`, `this_week`, `next_week`, `last_week`, `this_month`, `next_month`, `last_month`, `next_monday`, `last_friday`, `3_days_ago`, `in_7_days`, `2_weeks_ago`, `in_2_weeks`
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Prompts (4)
|
|
90
|
+
|
|
91
|
+
Prompts are pre-built workflows the AI can follow:
|
|
92
|
+
|
|
93
|
+
| Prompt | What it does | Workflow |
|
|
94
|
+
|--------|-------------|----------|
|
|
95
|
+
| `capture` | Quick-save a thought, task, or idea | Asks for content + optional tags, creates memo |
|
|
96
|
+
| `review` | Review memos from a time period | Searches memos, reads each one, summarizes |
|
|
97
|
+
| `on_day` | Check what happened/is planned for a date | Searches by date, presents findings |
|
|
98
|
+
| `tag_overview` | Analyze your tag system | Lists tags, shows hierarchy, suggests cleanup |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## What the AI sees (Model Instructions)
|
|
103
|
+
|
|
104
|
+
When the AI connects to this MCP, it receives these tool descriptions:
|
|
105
|
+
|
|
106
|
+
### `create` tool instructions:
|
|
107
|
+
> "Create a memo with markdown content. Use #hashtags for tags. **CRITICAL LIMIT: Each memo MUST NOT exceed 13,000 characters.** The Memos server enforces a hard limit of ~18K but to avoid errors always stay under 13K. If you need to write more, split into multiple memos with a shared tag (e.g. #project/my-post) and add part numbers."
|
|
108
|
+
|
|
109
|
+
### `search` tool instructions:
|
|
110
|
+
> "Search memos. Unified tool for date-based, tag-based, and content-based search. Date accepts ISO, relative dates ('today', 'yesterday', 'next_monday'), and week mode. Filters: tags, query, visibility, pinned, state, hasIncompleteTasks, hasAttachments. No date = all memos."
|
|
111
|
+
|
|
112
|
+
### `tags` tool instructions:
|
|
113
|
+
> "List tags with usage counts extracted from your memo content. Tags are hashtags like #project or #work/meeting. Results are cached for 60 seconds. No args = top-level tags only. parent='work' = children of 'work'. recursive=true = all tags flat."
|
|
114
|
+
|
|
115
|
+
### `update` tool instructions:
|
|
116
|
+
> "Update memo fields. Only provided fields are changed. CRITICAL: MUST NOT exceed 13,000 chars."
|
|
117
|
+
|
|
118
|
+
### `get` tool instructions:
|
|
119
|
+
> "Get a single memo by ID or UID."
|
|
120
|
+
|
|
121
|
+
### `delete` tool instructions:
|
|
122
|
+
> "Permanently delete a memo. Cannot be undone."
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Setup
|
|
127
|
+
|
|
128
|
+
### Prerequisites
|
|
129
|
+
|
|
130
|
+
- Node.js >= 18
|
|
131
|
+
- A running Memos instance (v0.29+)
|
|
132
|
+
- A Memos access token (Settings → Access Tokens)
|
|
133
|
+
|
|
134
|
+
### Quick Start — Claude Desktop/Code
|
|
135
|
+
|
|
136
|
+
Add to your MCP config (`claude_desktop_config.json` or equivalent):
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"mcpServers": {
|
|
141
|
+
"memos": {
|
|
142
|
+
"command": "npx",
|
|
143
|
+
"args": ["-y", "memos-mcp"],
|
|
144
|
+
"env": {
|
|
145
|
+
"MEMOS_URL": "https://your-memos-instance.com",
|
|
146
|
+
"MEMOS_TOKEN": "your-access-token"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Quick Start — OpenCode
|
|
154
|
+
|
|
155
|
+
Add to `opencode.json`:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
"mcp": {
|
|
159
|
+
"memos": {
|
|
160
|
+
"type": "remote",
|
|
161
|
+
"enabled": true,
|
|
162
|
+
"url": "http://your-server:8444/mcp",
|
|
163
|
+
"headers": {
|
|
164
|
+
"Authorization": "Bearer your-memos-access-token"
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Quick Start — LibreChat
|
|
171
|
+
|
|
172
|
+
Add to `librechat.yaml`:
|
|
173
|
+
|
|
174
|
+
```yaml
|
|
175
|
+
mcpServers:
|
|
176
|
+
memos:
|
|
177
|
+
type: streamable-http
|
|
178
|
+
url: http://your-server:8444/mcp
|
|
179
|
+
headers:
|
|
180
|
+
Authorization: "Bearer your-memos-access-token"
|
|
181
|
+
timeout: 240000
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Running the Server
|
|
187
|
+
|
|
188
|
+
### HTTP Mode (Multi-tenant)
|
|
189
|
+
|
|
190
|
+
For servers that support remote MCP (OpenCode, LibreChat, etc.):
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Start with npx
|
|
194
|
+
MEMOS_URL=https://your-memos-instance.com npx -y memos-mcp --http
|
|
195
|
+
|
|
196
|
+
# Or with custom port
|
|
197
|
+
MEMOS_URL=https://your-memos-instance.com npx -y memos-mcp --http --port 8443
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Each client sends its own Bearer token — no token in the server config.
|
|
201
|
+
|
|
202
|
+
### Stdio Mode (Single user)
|
|
203
|
+
|
|
204
|
+
For Claude Desktop/Code:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
MEMOS_URL=https://your-memos-instance.com MEMOS_TOKEN=your-token npx -y memos-mcp
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Running from Source
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# 1. Clone and install
|
|
214
|
+
git clone https://github.com/CesarGuzmanLopez/memos-mcp.git
|
|
215
|
+
cd memos-mcp
|
|
216
|
+
pnpm install
|
|
217
|
+
|
|
218
|
+
# 2. Build
|
|
219
|
+
pnpm build
|
|
220
|
+
|
|
221
|
+
# 3. Run in stdio mode
|
|
222
|
+
MEMOS_URL=https://your-memos-instance.com MEMOS_TOKEN=your-token node dist/index.js
|
|
223
|
+
|
|
224
|
+
# 4. Or run in HTTP mode
|
|
225
|
+
MEMOS_URL=https://your-memos-instance.com node dist/index.js --http
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Then add to your MCP client config:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"mcpServers": {
|
|
233
|
+
"memos": {
|
|
234
|
+
"command": "node",
|
|
235
|
+
"args": ["/path/to/memos-mcp/dist/index.js"],
|
|
236
|
+
"env": {
|
|
237
|
+
"MEMOS_URL": "https://your-memos-instance.com",
|
|
238
|
+
"MEMOS_TOKEN": "your-access-token"
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Docker
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
docker run -d --name memos-mcp \
|
|
249
|
+
-p 8444:8443 \
|
|
250
|
+
-e MEMOS_URL=https://your-memos-instance.com \
|
|
251
|
+
ghcr.io/cesarguzmanlopez/memos-mcp:latest \
|
|
252
|
+
node dist/index.js --http --port 8443
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Or with Dockerfile:
|
|
256
|
+
|
|
257
|
+
```dockerfile
|
|
258
|
+
FROM node:20-alpine
|
|
259
|
+
WORKDIR /app
|
|
260
|
+
COPY dist/ ./
|
|
261
|
+
RUN npm install --omit=dev @modelcontextprotocol/sdk express zod
|
|
262
|
+
EXPOSE 8443
|
|
263
|
+
ENV MEMOS_URL=https://your-memos-instance.com
|
|
264
|
+
CMD ["node", "dist/index.js", "--http", "--port", "8443"]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Nginx Reverse Proxy (Production)
|
|
268
|
+
|
|
269
|
+
```nginx
|
|
270
|
+
server {
|
|
271
|
+
listen 443 ssl;
|
|
272
|
+
server_name memos-mcp.your-domain.com;
|
|
273
|
+
|
|
274
|
+
location / {
|
|
275
|
+
proxy_pass http://127.0.0.1:8444;
|
|
276
|
+
proxy_http_version 1.1;
|
|
277
|
+
proxy_set_header Host $host;
|
|
278
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
279
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
280
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
281
|
+
proxy_set_header Accept "application/json, text/event-stream";
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Environment Variables
|
|
289
|
+
|
|
290
|
+
| Variable | Required | Description |
|
|
291
|
+
|----------|----------|-------------|
|
|
292
|
+
| `MEMOS_URL` | Yes | Your Memos instance URL |
|
|
293
|
+
| `MEMOS_TOKEN` | Stdio only | Access token for stdio mode |
|
|
294
|
+
| `HTTP_PORT` | No | HTTP server port (default: 3000) |
|
|
295
|
+
| `HTTP_HOST` | No | HTTP server host (default: 127.0.0.1) |
|
|
296
|
+
| `CORS_ORIGIN` | No | Allowed CORS origins (default: *) |
|
|
297
|
+
| `LOG_LEVEL` | No | Log level: debug, info, warn, error (default: info) |
|
|
298
|
+
|
|
299
|
+
## API Endpoints
|
|
300
|
+
|
|
301
|
+
When running in HTTP mode:
|
|
302
|
+
|
|
303
|
+
| Endpoint | Method | Description |
|
|
304
|
+
|----------|--------|-------------|
|
|
305
|
+
| `/health` | GET | Health check with uptime and memory stats |
|
|
306
|
+
| `/mcp` | POST | Streamable HTTP MCP endpoint |
|
|
307
|
+
| `/sse` | GET | SSE connection endpoint |
|
|
308
|
+
| `/sse/messages` | POST | SSE message endpoint |
|
|
309
|
+
|
|
310
|
+
## Memos Compatibility
|
|
311
|
+
|
|
312
|
+
| Memos Version | Compatible | Notes |
|
|
313
|
+
|---------------|------------|-------|
|
|
314
|
+
| **0.29.x** | ✅ Yes | Fully supported. Tested with 0.29.1 |
|
|
315
|
+
| **0.28.x** | ⚠️ Partial | API works but UIDs may not be supported |
|
|
316
|
+
| **0.22.x — 0.27.x** | ❌ No | Uses v1 API but without UID support |
|
|
317
|
+
| **< 0.22** | ❌ No | Old API, not compatible |
|
|
318
|
+
|
|
319
|
+
**Minimum required:** Memos **v0.29+** (uses UID-based identifiers `memos/abc123` instead of numeric IDs)
|
|
320
|
+
|
|
321
|
+
**Tested with:** Memos **0.29.1** (neosmemo/memos:stable Docker image)
|
|
322
|
+
|
|
323
|
+
**API used:** REST v1 (`/api/v1/memos`) with CEL filter expressions for queries
|
|
324
|
+
|
|
325
|
+
## Important Notes
|
|
326
|
+
|
|
327
|
+
- **Content limit:** Each memo has a hard limit of ~18,000 characters (server-side). The MCP enforces a safe limit of **13,000 characters**. For longer content, split into multiple memos with a shared tag.
|
|
328
|
+
- **Multi-tenant:** In HTTP mode, each client sends their own Bearer token. The server uses that token to access Memos as that specific user.
|
|
329
|
+
- **Rate limiting:** 100 requests per minute per IP.
|
|
330
|
+
- **Tags:** Use `#hashtags` in your memo content. The MCP extracts them automatically.
|
|
331
|
+
|
|
332
|
+
## License
|
|
333
|
+
|
|
334
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class MemosClient {
|
|
2
|
+
readonly baseUrl: string;
|
|
3
|
+
private token;
|
|
4
|
+
private _currentUser;
|
|
5
|
+
constructor(baseUrl: string, token: string);
|
|
6
|
+
validateToken(): Promise<boolean>;
|
|
7
|
+
getCurrentUser(): Promise<string>;
|
|
8
|
+
private headers;
|
|
9
|
+
private fetchWithTimeout;
|
|
10
|
+
get<T>(path: string, params?: Record<string, string>): Promise<T>;
|
|
11
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
12
|
+
patch<T>(path: string, body?: unknown, params?: Record<string, string>): Promise<T>;
|
|
13
|
+
delete<T = unknown>(path: string): Promise<T>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAiBA,qBAAa,WAAW;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAAuB;gBAE/B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAMpC,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAUjC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IA0BvC,OAAO,CAAC,OAAO;YAQD,gBAAgB;IAuBxB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBjE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAejD,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;IAuBnF,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAcpD"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// Cache a nivel de módulo para el usuario actual por combinación baseUrl+token
|
|
2
|
+
const userCache = new Map();
|
|
3
|
+
const USER_CACHE_TTL_MS = 300_000; // 5 minutos
|
|
4
|
+
// Sweep periódico del cache de usuarios
|
|
5
|
+
setInterval(() => {
|
|
6
|
+
const now = Date.now();
|
|
7
|
+
for (const [key, entry] of userCache) {
|
|
8
|
+
if (now - entry.timestamp > USER_CACHE_TTL_MS) {
|
|
9
|
+
userCache.delete(key);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}, 60_000); // Cada minuto
|
|
13
|
+
// Timeout para requests a Memos API (configurable via MEMOS_FETCH_TIMEOUT, default 120s)
|
|
14
|
+
const FETCH_TIMEOUT_MS = parseInt(process.env.MEMOS_FETCH_TIMEOUT || "120000", 10);
|
|
15
|
+
export class MemosClient {
|
|
16
|
+
baseUrl;
|
|
17
|
+
token;
|
|
18
|
+
_currentUser = null;
|
|
19
|
+
constructor(baseUrl, token) {
|
|
20
|
+
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
21
|
+
this.token = token;
|
|
22
|
+
}
|
|
23
|
+
// Validate token is working
|
|
24
|
+
async validateToken() {
|
|
25
|
+
try {
|
|
26
|
+
await this.getCurrentUser();
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Obtener usuario actual con cache global
|
|
34
|
+
async getCurrentUser() {
|
|
35
|
+
if (this._currentUser)
|
|
36
|
+
return this._currentUser;
|
|
37
|
+
const cacheKey = `${this.baseUrl}:${this.token}`;
|
|
38
|
+
const cached = userCache.get(cacheKey);
|
|
39
|
+
if (cached && Date.now() - cached.timestamp < USER_CACHE_TTL_MS) {
|
|
40
|
+
this._currentUser = cached.user;
|
|
41
|
+
return this._currentUser;
|
|
42
|
+
}
|
|
43
|
+
const result = await this.get("/api/v1/memos", { pageSize: "1" });
|
|
44
|
+
if (result.memos && result.memos.length > 0) {
|
|
45
|
+
this._currentUser = result.memos[0].creator;
|
|
46
|
+
userCache.set(cacheKey, { user: this._currentUser, timestamp: Date.now() });
|
|
47
|
+
}
|
|
48
|
+
if (!this._currentUser) {
|
|
49
|
+
throw new Error("Could not determine current user. No memos found with this token.");
|
|
50
|
+
}
|
|
51
|
+
return this._currentUser;
|
|
52
|
+
}
|
|
53
|
+
headers() {
|
|
54
|
+
return {
|
|
55
|
+
Authorization: `Bearer ${this.token}`,
|
|
56
|
+
"Content-Type": "application/json",
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// Helper para fetch con timeout
|
|
60
|
+
async fetchWithTimeout(url, options) {
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
63
|
+
try {
|
|
64
|
+
const response = await fetch(url, {
|
|
65
|
+
...options,
|
|
66
|
+
signal: controller.signal,
|
|
67
|
+
});
|
|
68
|
+
return response;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
72
|
+
throw new Error(`Request to ${url} timed out after ${FETCH_TIMEOUT_MS}ms`);
|
|
73
|
+
}
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
clearTimeout(timeout);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async get(path, params) {
|
|
81
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
82
|
+
if (params) {
|
|
83
|
+
for (const [key, value] of Object.entries(params)) {
|
|
84
|
+
if (value !== undefined && value !== "") {
|
|
85
|
+
url.searchParams.set(key, value);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const res = await this.fetchWithTimeout(url.toString(), {
|
|
90
|
+
headers: this.headers(),
|
|
91
|
+
});
|
|
92
|
+
if (!res.ok) {
|
|
93
|
+
const body = await res.text();
|
|
94
|
+
throw new Error(`GET ${path} failed (${res.status}): ${body}`);
|
|
95
|
+
}
|
|
96
|
+
const text = await res.text();
|
|
97
|
+
if (!text)
|
|
98
|
+
return undefined;
|
|
99
|
+
return JSON.parse(text);
|
|
100
|
+
}
|
|
101
|
+
async post(path, body) {
|
|
102
|
+
const res = await this.fetchWithTimeout(`${this.baseUrl}${path}`, {
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: this.headers(),
|
|
105
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
106
|
+
});
|
|
107
|
+
if (!res.ok) {
|
|
108
|
+
const text = await res.text();
|
|
109
|
+
throw new Error(`POST ${path} failed (${res.status}): ${text}`);
|
|
110
|
+
}
|
|
111
|
+
const text = await res.text();
|
|
112
|
+
if (!text)
|
|
113
|
+
return undefined;
|
|
114
|
+
return JSON.parse(text);
|
|
115
|
+
}
|
|
116
|
+
async patch(path, body, params) {
|
|
117
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
118
|
+
if (params) {
|
|
119
|
+
for (const [key, value] of Object.entries(params)) {
|
|
120
|
+
if (value !== undefined && value !== "") {
|
|
121
|
+
url.searchParams.set(key, value);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const res = await this.fetchWithTimeout(url.toString(), {
|
|
126
|
+
method: "PATCH",
|
|
127
|
+
headers: this.headers(),
|
|
128
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
129
|
+
});
|
|
130
|
+
if (!res.ok) {
|
|
131
|
+
const text = await res.text();
|
|
132
|
+
throw new Error(`PATCH ${path} failed (${res.status}): ${text}`);
|
|
133
|
+
}
|
|
134
|
+
const text = await res.text();
|
|
135
|
+
if (!text)
|
|
136
|
+
return undefined;
|
|
137
|
+
return JSON.parse(text);
|
|
138
|
+
}
|
|
139
|
+
async delete(path) {
|
|
140
|
+
const res = await this.fetchWithTimeout(`${this.baseUrl}${path}`, {
|
|
141
|
+
method: "DELETE",
|
|
142
|
+
headers: this.headers(),
|
|
143
|
+
});
|
|
144
|
+
if (!res.ok) {
|
|
145
|
+
const text = await res.text();
|
|
146
|
+
throw new Error(`DELETE ${path} failed (${res.status}): ${text}`);
|
|
147
|
+
}
|
|
148
|
+
// Memos DELETE may return empty body
|
|
149
|
+
const text = await res.text();
|
|
150
|
+
if (!text)
|
|
151
|
+
return undefined;
|
|
152
|
+
return JSON.parse(text);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const EnvSchema: z.ZodObject<{
|
|
3
|
+
MEMOS_URL: z.ZodString;
|
|
4
|
+
HTTP_PORT: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
5
|
+
HTTP_HOST: z.ZodDefault<z.ZodString>;
|
|
6
|
+
CORS_ORIGIN: z.ZodDefault<z.ZodString>;
|
|
7
|
+
LOG_LEVEL: z.ZodDefault<z.ZodEnum<{
|
|
8
|
+
error: "error";
|
|
9
|
+
debug: "debug";
|
|
10
|
+
info: "info";
|
|
11
|
+
warn: "warn";
|
|
12
|
+
}>>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export type Config = z.infer<typeof EnvSchema>;
|
|
15
|
+
export declare function loadConfig(): Config;
|
|
16
|
+
export declare function getCorsOrigins(config: Config): string[];
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,QAAA,MAAM,SAAS;;;;;;;;;;;iBAab,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAG/C,wBAAgB,UAAU,IAAI,MAAM,CASnC;AAGD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvD"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Schema de validación para variables de entorno
|
|
3
|
+
const EnvSchema = z.object({
|
|
4
|
+
// Memos connection (required)
|
|
5
|
+
MEMOS_URL: z.string().url().describe("Memos instance URL"),
|
|
6
|
+
// HTTP server options
|
|
7
|
+
HTTP_PORT: z.coerce.number().int().min(1).max(65535).default(3000).describe("HTTP server port"),
|
|
8
|
+
HTTP_HOST: z.string().default("127.0.0.1").describe("HTTP server host"),
|
|
9
|
+
// Security
|
|
10
|
+
CORS_ORIGIN: z.string().default("*").describe("CORS allowed origins (comma-separated)"),
|
|
11
|
+
// Logging
|
|
12
|
+
LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info").describe("Log level"),
|
|
13
|
+
});
|
|
14
|
+
// Cargar configuración desde variables de entorno
|
|
15
|
+
export function loadConfig() {
|
|
16
|
+
const result = EnvSchema.safeParse(process.env);
|
|
17
|
+
if (!result.success) {
|
|
18
|
+
console.error("Configuration error:", result.error.flatten().fieldErrors);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
return result.data;
|
|
22
|
+
}
|
|
23
|
+
// Obtener orígenes CORS como array
|
|
24
|
+
export function getCorsOrigins(config) {
|
|
25
|
+
return config.CORS_ORIGIN.split(",").map((o) => o.trim());
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,iDAAiD;AACjD,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,8BAA8B;IAC9B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAE1D,sBAAsB;IACtB,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAC/F,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAEvE,WAAW;IACX,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,wCAAwC,CAAC;IAEvF,UAAU;IACV,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;CAC5F,CAAC,CAAC;AAIH,kDAAkD;AAClD,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAEhD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAC5D,CAAC"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Config } from "./config.js";
|
|
2
|
+
export declare function createHttpApp(config: Config): import("express-serve-static-core").Express;
|
|
3
|
+
export declare function startHttpServer(config: Config): import("node:http").Server<typeof import("node:http").IncomingMessage, typeof import("node:http").ServerResponse>;
|
|
4
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAkB,MAAM,aAAa,CAAC;AAgFrD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,+CAgP3C;AAGD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,qHA4C7C"}
|