memory-journal-mcp 4.1.0 → 4.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/.github/workflows/docker-publish.yml +17 -19
- package/.github/workflows/publish-npm.yml +3 -0
- package/DOCKER_README.md +67 -15
- package/README.md +65 -19
- package/dist/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/constants/ServerInstructions.d.ts.map +1 -1
- package/dist/constants/ServerInstructions.js +8 -1
- package/dist/constants/ServerInstructions.js.map +1 -1
- package/dist/database/SqliteAdapter.d.ts +19 -0
- package/dist/database/SqliteAdapter.d.ts.map +1 -1
- package/dist/database/SqliteAdapter.js +89 -0
- package/dist/database/SqliteAdapter.js.map +1 -1
- package/dist/filtering/ToolFilter.d.ts +1 -1
- package/dist/filtering/ToolFilter.d.ts.map +1 -1
- package/dist/filtering/ToolFilter.js +9 -3
- package/dist/filtering/ToolFilter.js.map +1 -1
- package/dist/handlers/resources/index.d.ts.map +1 -1
- package/dist/handlers/resources/index.js +75 -15
- package/dist/handlers/resources/index.js.map +1 -1
- package/dist/handlers/tools/index.d.ts.map +1 -1
- package/dist/handlers/tools/index.js +261 -4
- package/dist/handlers/tools/index.js.map +1 -1
- package/dist/server/McpServer.d.ts +1 -0
- package/dist/server/McpServer.d.ts.map +1 -1
- package/dist/server/McpServer.js +265 -9
- package/dist/server/McpServer.js.map +1 -1
- package/package.json +5 -1
- package/releases/v4.2.0.md +90 -0
- package/server.json +3 -3
- package/src/cli.ts +6 -1
- package/src/constants/ServerInstructions.ts +8 -1
- package/src/database/SqliteAdapter.ts +111 -0
- package/src/filtering/ToolFilter.ts +9 -3
- package/src/handlers/resources/index.ts +99 -15
- package/src/handlers/tools/index.ts +286 -4
- package/src/server/McpServer.ts +330 -10
- package/VERSION +0 -1
|
@@ -30,6 +30,8 @@ jobs:
|
|
|
30
30
|
steps:
|
|
31
31
|
- name: Checkout code
|
|
32
32
|
uses: actions/checkout@v6
|
|
33
|
+
with:
|
|
34
|
+
ref: ${{ github.ref }}
|
|
33
35
|
|
|
34
36
|
- name: Setup Node.js
|
|
35
37
|
uses: actions/setup-node@v6
|
|
@@ -54,8 +56,8 @@ jobs:
|
|
|
54
56
|
security-scan:
|
|
55
57
|
needs: [preflight-check]
|
|
56
58
|
if: |
|
|
57
|
-
always() &&
|
|
58
|
-
(github.event.workflow_run.conclusion == 'success' ||
|
|
59
|
+
always() &&
|
|
60
|
+
(github.event.workflow_run.conclusion == 'success' ||
|
|
59
61
|
(github.event_name == 'push' && needs.preflight-check.result == 'success'))
|
|
60
62
|
runs-on: ubuntu-latest
|
|
61
63
|
permissions:
|
|
@@ -65,6 +67,8 @@ jobs:
|
|
|
65
67
|
steps:
|
|
66
68
|
- name: Checkout repository
|
|
67
69
|
uses: actions/checkout@v6
|
|
70
|
+
with:
|
|
71
|
+
ref: ${{ github.event_name == 'push' && github.ref || github.event.workflow_run.head_sha }}
|
|
68
72
|
|
|
69
73
|
- name: Set up Docker Buildx
|
|
70
74
|
uses: docker/setup-buildx-action@v3
|
|
@@ -102,7 +106,7 @@ jobs:
|
|
|
102
106
|
# This ensures we block on things we CAN fix while allowing unfixable upstream CVEs
|
|
103
107
|
if timeout 480 docker scout cves local-scan:latest --only-fixed --only-severity critical,high > scout_fixable.txt 2>&1; then
|
|
104
108
|
echo "📊 Scan completed"
|
|
105
|
-
|
|
109
|
+
|
|
106
110
|
# Check if any fixable critical/high CVEs were found
|
|
107
111
|
if grep -qE "(CRITICAL|HIGH)" scout_fixable.txt 2>/dev/null; then
|
|
108
112
|
echo "❌ Fixable CRITICAL/HIGH CVEs detected - blocking deploy"
|
|
@@ -158,6 +162,8 @@ jobs:
|
|
|
158
162
|
steps:
|
|
159
163
|
- name: Checkout repository
|
|
160
164
|
uses: actions/checkout@v6
|
|
165
|
+
with:
|
|
166
|
+
ref: ${{ github.event_name == 'push' && github.ref || github.event.workflow_run.head_sha }}
|
|
161
167
|
|
|
162
168
|
- name: Set up Docker Buildx
|
|
163
169
|
uses: docker/setup-buildx-action@v3
|
|
@@ -169,15 +175,10 @@ jobs:
|
|
|
169
175
|
username: ${{ secrets.DOCKER_USERNAME }}
|
|
170
176
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
171
177
|
|
|
172
|
-
- name: Read version from
|
|
178
|
+
- name: Read version from package.json
|
|
173
179
|
id: version
|
|
174
180
|
run: |
|
|
175
|
-
|
|
176
|
-
VERSION=$(head -1 VERSION | tr -d '[:space:]')
|
|
177
|
-
fi
|
|
178
|
-
if [ -z "$VERSION" ]; then
|
|
179
|
-
VERSION=$(grep -oP '"version":\s*"\K[0-9.]+' package.json | head -1)
|
|
180
|
-
fi
|
|
181
|
+
VERSION=$(grep -oP '"version":\s*"\K[0-9.]+' package.json | head -1)
|
|
181
182
|
if [ -z "$VERSION" ]; then
|
|
182
183
|
VERSION="1.0.0"
|
|
183
184
|
fi
|
|
@@ -243,6 +244,8 @@ jobs:
|
|
|
243
244
|
steps:
|
|
244
245
|
- name: Checkout repository
|
|
245
246
|
uses: actions/checkout@v6
|
|
247
|
+
with:
|
|
248
|
+
ref: ${{ github.event_name == 'push' && github.ref || github.event.workflow_run.head_sha }}
|
|
246
249
|
|
|
247
250
|
- name: Download digests
|
|
248
251
|
uses: actions/download-artifact@v7
|
|
@@ -264,12 +267,7 @@ jobs:
|
|
|
264
267
|
- name: Read version
|
|
265
268
|
id: version
|
|
266
269
|
run: |
|
|
267
|
-
|
|
268
|
-
VERSION=$(head -1 VERSION | tr -d '[:space:]')
|
|
269
|
-
fi
|
|
270
|
-
if [ -z "$VERSION" ]; then
|
|
271
|
-
VERSION=$(grep -oP '"version":\s*"\K[0-9.]+' package.json | head -1)
|
|
272
|
-
fi
|
|
270
|
+
VERSION=$(grep -oP '"version":\s*"\K[0-9.]+' package.json | head -1)
|
|
273
271
|
if [ -z "$VERSION" ]; then
|
|
274
272
|
VERSION="1.0.0"
|
|
275
273
|
fi
|
|
@@ -284,8 +282,8 @@ jobs:
|
|
|
284
282
|
latest=false
|
|
285
283
|
tags: |
|
|
286
284
|
type=semver,pattern=v{{version}}
|
|
287
|
-
type=raw,value=v${{ steps.version.outputs.version }},enable=${{ github.ref
|
|
288
|
-
type=raw,value=latest,enable=${{ github.ref
|
|
285
|
+
type=raw,value=v${{ steps.version.outputs.version }},enable=${{ startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_run' && github.event.workflow_run.head_branch == 'main') }}
|
|
286
|
+
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_run' && github.event.workflow_run.head_branch == 'main') }}
|
|
289
287
|
type=sha,prefix=sha-,format=short
|
|
290
288
|
|
|
291
289
|
- name: Create and push manifest
|
|
@@ -309,7 +307,7 @@ jobs:
|
|
|
309
307
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
310
308
|
repository: ${{ env.IMAGE_NAME }}
|
|
311
309
|
readme-filepath: ./DOCKER_README.md
|
|
312
|
-
short-description: '
|
|
310
|
+
short-description: 'AI Project Memory with Triple Search, Knowledge Graphs, GitHub Integration, HTTPS & Tool Filtering.'
|
|
313
311
|
|
|
314
312
|
- name: Deployment Summary
|
|
315
313
|
if: github.ref == 'refs/heads/main'
|
|
@@ -23,6 +23,9 @@ jobs:
|
|
|
23
23
|
steps:
|
|
24
24
|
- name: Checkout code
|
|
25
25
|
uses: actions/checkout@v6
|
|
26
|
+
with:
|
|
27
|
+
# For release events, checkout the tag; for workflow_dispatch, use ref input or default to latest tag
|
|
28
|
+
ref: ${{ github.event.release.tag_name || format('v{0}', github.event.inputs.version) || github.ref }}
|
|
26
29
|
|
|
27
30
|
- name: Setup Node.js
|
|
28
31
|
uses: actions/setup-node@v6
|
package/DOCKER_README.md
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# Memory Journal MCP Server
|
|
2
2
|
|
|
3
|
-
Last Updated January
|
|
3
|
+
Last Updated January 17, 2026
|
|
4
4
|
|
|
5
5
|
[](https://github.com/neverinfamous/memory-journal-mcp)
|
|
6
6
|
[](https://hub.docker.com/r/writenotenow/memory-journal-mcp)
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
8
|
-

|
|
9
8
|

|
|
10
9
|
[](https://www.npmjs.com/package/memory-journal-mcp)
|
|
11
10
|
[](https://github.com/neverinfamous/memory-journal-mcp/blob/main/SECURITY.md)
|
|
@@ -79,7 +78,7 @@ Last Updated January 16, 2026 - v4.0.0
|
|
|
79
78
|
|
|
80
79
|
### 📈 **Current Capabilities**
|
|
81
80
|
|
|
82
|
-
- **
|
|
81
|
+
- **33 MCP tools** - Complete development workflow + backup/restore + Kanban + issue management
|
|
83
82
|
- **15 workflow prompts** - Standups, retrospectives, PR workflows, CI/CD failure analysis, session acknowledgment
|
|
84
83
|
- **18 MCP resources** - 12 static + 6 template (require parameters)
|
|
85
84
|
- **GitHub Integration** - Projects, Issues, Pull Requests, Actions, **Kanban boards**
|
|
@@ -193,6 +192,59 @@ When GitHub tools cannot auto-detect repository information:
|
|
|
193
192
|
|
|
194
193
|
- **Prompts not available**: AntiGravity does not currently support MCP prompts. The 15 workflow prompts are not accessible.
|
|
195
194
|
|
|
195
|
+
### HTTP/SSE Transport (Remote Access)
|
|
196
|
+
|
|
197
|
+
For remote access, web-based clients, or HTTP-compatible MCP hosts:
|
|
198
|
+
|
|
199
|
+
**Stateful Mode (default):**
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
docker run --rm -p 3000:3000 \
|
|
203
|
+
-v ./data:/app/data \
|
|
204
|
+
writenotenow/memory-journal-mcp:latest \
|
|
205
|
+
--transport http --port 3000
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Stateless Mode (serverless):**
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
docker run --rm -p 3000:3000 \
|
|
212
|
+
-v ./data:/app/data \
|
|
213
|
+
writenotenow/memory-journal-mcp:latest \
|
|
214
|
+
--transport http --port 3000 --stateless
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Endpoints:**
|
|
218
|
+
|
|
219
|
+
- `POST /mcp` — JSON-RPC requests (initialize, tools/call, resources/read, etc.)
|
|
220
|
+
- `GET /mcp` — SSE stream for server-to-client notifications (stateful only)
|
|
221
|
+
- `DELETE /mcp` — Session termination (stateful only)
|
|
222
|
+
|
|
223
|
+
**Session Management:** In stateful mode, include the `mcp-session-id` header (returned from initialization) in subsequent requests.
|
|
224
|
+
|
|
225
|
+
| Mode | Progress Notifications | SSE Streaming | Serverless |
|
|
226
|
+
| ------------------------- | ---------------------- | ------------- | ---------- |
|
|
227
|
+
| Stateful (default) | ✅ Yes | ✅ Yes | ⚠️ Complex |
|
|
228
|
+
| Stateless (`--stateless`) | ❌ No | ❌ No | ✅ Native |
|
|
229
|
+
|
|
230
|
+
**Example with curl (stateful):**
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# Initialize session
|
|
234
|
+
curl -X POST http://localhost:3000/mcp \
|
|
235
|
+
-H "Content-Type: application/json" \
|
|
236
|
+
-H "Accept: application/json, text/event-stream" \
|
|
237
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
|
|
238
|
+
# Returns mcp-session-id header
|
|
239
|
+
|
|
240
|
+
# List tools (with session)
|
|
241
|
+
curl -X POST http://localhost:3000/mcp \
|
|
242
|
+
-H "Content-Type: application/json" \
|
|
243
|
+
-H "Accept: application/json, text/event-stream" \
|
|
244
|
+
-H "mcp-session-id: YOUR_SESSION_ID" \
|
|
245
|
+
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
|
|
246
|
+
```
|
|
247
|
+
|
|
196
248
|
---
|
|
197
249
|
|
|
198
250
|
## ⚡ **Install to Cursor IDE**
|
|
@@ -248,18 +300,18 @@ docker pull writenotenow/memory-journal-mcp@sha256:<manifest-digest>
|
|
|
248
300
|
|
|
249
301
|
## ⚡ Core Features
|
|
250
302
|
|
|
251
|
-
### 🛠️
|
|
252
|
-
|
|
253
|
-
| Group | Tools | Description
|
|
254
|
-
| --------------- | ----- |
|
|
255
|
-
| `core` | 6 | Entry CRUD, tags, test
|
|
256
|
-
| `search` | 4 | Text search, date range, semantic, vector stats
|
|
257
|
-
| `analytics` | 2 | Statistics, cross-project insights
|
|
258
|
-
| `relationships` | 2 | Link entries, visualize graphs
|
|
259
|
-
| `export` | 1 | JSON/Markdown export
|
|
260
|
-
| `admin` |
|
|
261
|
-
| `github` | 9 | Issues, PRs, context, Kanban, **issue lifecycle**
|
|
262
|
-
| `backup` |
|
|
303
|
+
### 🛠️ 33 MCP Tools (8 Groups)
|
|
304
|
+
|
|
305
|
+
| Group | Tools | Description |
|
|
306
|
+
| --------------- | ----- | --------------------------------------------------- |
|
|
307
|
+
| `core` | 6 | Entry CRUD, tags, test |
|
|
308
|
+
| `search` | 4 | Text search, date range, semantic, vector stats |
|
|
309
|
+
| `analytics` | 2 | Statistics, cross-project insights |
|
|
310
|
+
| `relationships` | 2 | Link entries, visualize graphs |
|
|
311
|
+
| `export` | 1 | JSON/Markdown export |
|
|
312
|
+
| `admin` | 5 | Update, delete, vector index management, merge tags |
|
|
313
|
+
| `github` | 9 | Issues, PRs, context, Kanban, **issue lifecycle** |
|
|
314
|
+
| `backup` | 4 | Backup, list, restore, cleanup |
|
|
263
315
|
|
|
264
316
|
**[Complete tools documentation →](https://github.com/neverinfamous/memory-journal-mcp/wiki/Tools)**
|
|
265
317
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Memory Journal MCP Server
|
|
2
2
|
|
|
3
|
-
Last Updated January 17, 2026
|
|
3
|
+
Last Updated January 17, 2026
|
|
4
4
|
|
|
5
5
|
<!-- mcp-name: io.github.neverinfamous/memory-journal-mcp -->
|
|
6
6
|
|
|
@@ -8,7 +8,6 @@ Last Updated January 17, 2026 - v4.1.0
|
|
|
8
8
|
[](https://www.npmjs.com/package/memory-journal-mcp)
|
|
9
9
|
[](https://hub.docker.com/r/writenotenow/memory-journal-mcp)
|
|
10
10
|
[](https://opensource.org/licenses/MIT)
|
|
11
|
-

|
|
12
11
|

|
|
13
12
|
[](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.neverinfamous/memory-journal-mcp)
|
|
14
13
|
[](SECURITY.md)
|
|
@@ -74,7 +73,7 @@ flowchart TB
|
|
|
74
73
|
|
|
75
74
|
### 📈 **Current Capabilities**
|
|
76
75
|
|
|
77
|
-
- **
|
|
76
|
+
- **33 MCP tools** - Complete development workflow + backup/restore + Kanban + issue management
|
|
78
77
|
- **15 workflow prompts** - Standups, retrospectives, PR workflows, CI/CD failure analysis, session acknowledgment
|
|
79
78
|
- **18 MCP resources** - 12 static + 6 template (require parameters)
|
|
80
79
|
- **GitHub Integration** - Projects, Issues, Pull Requests, Actions, **Kanban boards**
|
|
@@ -175,6 +174,53 @@ npm run build
|
|
|
175
174
|
}
|
|
176
175
|
```
|
|
177
176
|
|
|
177
|
+
### Option 4: HTTP/SSE Transport (Remote Access)
|
|
178
|
+
|
|
179
|
+
For remote access or web-based clients, run the server in HTTP mode:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
memory-journal-mcp --transport http --port 3000
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Endpoints:**
|
|
186
|
+
|
|
187
|
+
- `POST /mcp` — JSON-RPC requests (initialize, tools/call, etc.)
|
|
188
|
+
- `GET /mcp` — SSE stream for server-to-client notifications
|
|
189
|
+
- `DELETE /mcp` — Session termination
|
|
190
|
+
|
|
191
|
+
**Session Management:** The server uses stateful sessions by default. Include the `mcp-session-id` header (returned from initialization) in subsequent requests.
|
|
192
|
+
|
|
193
|
+
**Example with curl:**
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Initialize session
|
|
197
|
+
curl -X POST http://localhost:3000/mcp \
|
|
198
|
+
-H "Content-Type: application/json" \
|
|
199
|
+
-H "Accept: application/json, text/event-stream" \
|
|
200
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
|
|
201
|
+
# Returns mcp-session-id header
|
|
202
|
+
|
|
203
|
+
# List tools (with session)
|
|
204
|
+
curl -X POST http://localhost:3000/mcp \
|
|
205
|
+
-H "Content-Type: application/json" \
|
|
206
|
+
-H "Accept: application/json, text/event-stream" \
|
|
207
|
+
-H "mcp-session-id: YOUR_SESSION_ID" \
|
|
208
|
+
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### Stateless Mode (Serverless)
|
|
212
|
+
|
|
213
|
+
For serverless deployments (Lambda, Workers, Vercel), use stateless mode:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
memory-journal-mcp --transport http --port 3000 --stateless
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
| Mode | Progress Notifications | SSE Streaming | Serverless |
|
|
220
|
+
| ------------------------- | ---------------------- | ------------- | ---------- |
|
|
221
|
+
| Stateful (default) | ✅ Yes | ✅ Yes | ⚠️ Complex |
|
|
222
|
+
| Stateless (`--stateless`) | ❌ No | ❌ No | ✅ Native |
|
|
223
|
+
|
|
178
224
|
### GitHub Integration Configuration
|
|
179
225
|
|
|
180
226
|
The GitHub tools (`get_github_issues`, `get_github_prs`, etc.) can auto-detect the repository from your git context. However, MCP clients may run the server from a different directory than your project.
|
|
@@ -240,18 +286,18 @@ When GitHub tools cannot auto-detect repository information:
|
|
|
240
286
|
|
|
241
287
|
## 📋 Core Capabilities
|
|
242
288
|
|
|
243
|
-
### 🛠️ **
|
|
289
|
+
### 🛠️ **33 MCP Tools** (8 Groups)
|
|
244
290
|
|
|
245
|
-
| Group | Tools | Description
|
|
246
|
-
| --------------- | ----- |
|
|
247
|
-
| `core` | 6 | Entry CRUD, tags, test
|
|
248
|
-
| `search` | 4 | Text search, date range, semantic, vector stats
|
|
249
|
-
| `analytics` | 2 | Statistics, cross-project insights
|
|
250
|
-
| `relationships` | 2 | Link entries, visualize graphs
|
|
251
|
-
| `export` | 1 | JSON/Markdown export
|
|
252
|
-
| `admin` |
|
|
253
|
-
| `github` | 9 | Issues, PRs, context, Kanban, **issue lifecycle**
|
|
254
|
-
| `backup` |
|
|
291
|
+
| Group | Tools | Description |
|
|
292
|
+
| --------------- | ----- | ------------------------------------------------------- |
|
|
293
|
+
| `core` | 6 | Entry CRUD, tags, test |
|
|
294
|
+
| `search` | 4 | Text search, date range, semantic, vector stats |
|
|
295
|
+
| `analytics` | 2 | Statistics, cross-project insights |
|
|
296
|
+
| `relationships` | 2 | Link entries, visualize graphs |
|
|
297
|
+
| `export` | 1 | JSON/Markdown export |
|
|
298
|
+
| `admin` | 5 | Update, delete, rebuild/add to vector index, merge tags |
|
|
299
|
+
| `github` | 9 | Issues, PRs, context, Kanban, **issue lifecycle** |
|
|
300
|
+
| `backup` | 4 | Backup, list, restore, cleanup |
|
|
255
301
|
|
|
256
302
|
**[Complete tools reference →](https://github.com/neverinfamous/memory-journal-mcp/wiki/Tools)**
|
|
257
303
|
|
|
@@ -272,7 +318,7 @@ When GitHub tools cannot auto-detect repository information:
|
|
|
272
318
|
|
|
273
319
|
**[Complete prompts guide →](https://github.com/neverinfamous/memory-journal-mcp/wiki/Prompts)**
|
|
274
320
|
|
|
275
|
-
### 📡 **
|
|
321
|
+
### 📡 **18 Resources** (12 Static + 6 Template)
|
|
276
322
|
|
|
277
323
|
**Static Resources** (appear in resource lists):
|
|
278
324
|
|
|
@@ -386,7 +432,7 @@ export MEMORY_JOURNAL_MCP_TOOL_FILTER="-analytics,-github"
|
|
|
386
432
|
| -------------- | ------------- | ----- |
|
|
387
433
|
| Starter | `starter` | ~10 |
|
|
388
434
|
| Essential | `essential` | ~6 |
|
|
389
|
-
| Full (default) | `full` |
|
|
435
|
+
| Full (default) | `full` | 33 |
|
|
390
436
|
| Read-only | `readonly` | ~20 |
|
|
391
437
|
|
|
392
438
|
**[Complete tool filtering guide →](https://github.com/neverinfamous/memory-journal-mcp/wiki/Tool-Filtering)**
|
|
@@ -402,8 +448,8 @@ flowchart TB
|
|
|
402
448
|
AI["🤖 AI Agent<br/>(Cursor, Windsurf, Claude)"]
|
|
403
449
|
|
|
404
450
|
subgraph MCP["Memory Journal MCP Server"]
|
|
405
|
-
Tools["🛠️
|
|
406
|
-
Resources["📡
|
|
451
|
+
Tools["🛠️ 33 Tools"]
|
|
452
|
+
Resources["📡 18 Resources"]
|
|
407
453
|
Prompts["💬 15 Prompts"]
|
|
408
454
|
end
|
|
409
455
|
|
|
@@ -431,7 +477,7 @@ flowchart TB
|
|
|
431
477
|
┌─────────────────────────────────────────────────────────────┐
|
|
432
478
|
│ MCP Server Layer (TypeScript) │
|
|
433
479
|
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
|
|
434
|
-
│ │ Tools (
|
|
480
|
+
│ │ Tools (33) │ │ Resources (18) │ │ Prompts (15)│ │
|
|
435
481
|
│ │ with Annotations│ │ with Annotations│ │ │ │
|
|
436
482
|
│ └─────────────────┘ └─────────────────┘ └─────────────┘ │
|
|
437
483
|
├─────────────────────────────────────────────────────────────┤
|
package/dist/cli.js
CHANGED
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
import { Command } from 'commander';
|
|
5
5
|
import { createServer } from './server/McpServer.js';
|
|
6
6
|
import { logger } from './utils/logger.js';
|
|
7
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
7
8
|
const program = new Command();
|
|
8
9
|
program
|
|
9
10
|
.name('memory-journal-mcp')
|
|
10
11
|
.description('Project context management for AI-assisted development')
|
|
11
|
-
.version(
|
|
12
|
+
.version(pkg.version)
|
|
12
13
|
.option('--transport <type>', 'Transport type: stdio or http', 'stdio')
|
|
13
14
|
.option('--port <number>', 'HTTP port (for http transport)', '3000')
|
|
15
|
+
.option('--stateless', 'Use stateless HTTP mode (no session management)')
|
|
14
16
|
.option('--db <path>', 'Database path', './memory_journal.db')
|
|
15
17
|
.option('--tool-filter <filter>', 'Tool filter string (e.g., "starter", "core,search")')
|
|
16
18
|
.option('--default-project <number>', 'Default GitHub Project number')
|
|
@@ -22,12 +24,14 @@ program
|
|
|
22
24
|
logger.info('Starting Memory Journal MCP Server', {
|
|
23
25
|
module: 'CLI',
|
|
24
26
|
transport: options.transport,
|
|
27
|
+
stateless: options.stateless ?? false,
|
|
25
28
|
db: options.db,
|
|
26
29
|
});
|
|
27
30
|
try {
|
|
28
31
|
await createServer({
|
|
29
32
|
transport: options.transport,
|
|
30
33
|
port: parseInt(options.port, 10),
|
|
34
|
+
statelessHttp: options.stateless === true,
|
|
31
35
|
dbPath: options.db,
|
|
32
36
|
toolFilter: options.toolFilter,
|
|
33
37
|
defaultProjectNumber: options.defaultProject
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1C,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAEvD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACF,IAAI,CAAC,oBAAoB,CAAC;KAC1B,WAAW,CAAC,wDAAwD,CAAC;KACrE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;KACpB,MAAM,CAAC,oBAAoB,EAAE,+BAA+B,EAAE,OAAO,CAAC;KACtE,MAAM,CAAC,iBAAiB,EAAE,gCAAgC,EAAE,MAAM,CAAC;KACnE,MAAM,CAAC,aAAa,EAAE,iDAAiD,CAAC;KACxE,MAAM,CAAC,aAAa,EAAE,eAAe,EAAE,qBAAqB,CAAC;KAC7D,MAAM,CAAC,wBAAwB,EAAE,qDAAqD,CAAC;KACvF,MAAM,CAAC,4BAA4B,EAAE,+BAA+B,CAAC;KACrE,MAAM,CAAC,sBAAsB,EAAE,wCAAwC,CAAC;KACxE,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,EAAE,MAAM,CAAC;KAC/E,MAAM,CACH,KAAK,EAAE,OASN,EAAE,EAAE;IACD,gBAAgB;IAChB,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAkD,CAAC,CAAA;IAE3E,MAAM,CAAC,IAAI,CAAC,oCAAoC,EAAE;QAC9C,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK;QACrC,EAAE,EAAE,OAAO,CAAC,EAAE;KACjB,CAAC,CAAA;IAEF,IAAI,CAAC;QACD,MAAM,YAAY,CAAC;YACf,SAAS,EAAE,OAAO,CAAC,SAA6B;YAChD,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAChC,aAAa,EAAE,OAAO,CAAC,SAAS,KAAK,IAAI;YACzC,MAAM,EAAE,OAAO,CAAC,EAAE;YAClB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,oBAAoB,EAAE,OAAO,CAAC,cAAc;gBACxC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;gBACtC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;oBACrC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,EAAE,CAAC;oBACrD,CAAC,CAAC,SAAS;YACjB,gBAAgB,EACZ,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,KAAK,MAAM;SAC/E,CAAC,CAAA;IACN,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE;YACnC,MAAM,EAAE,KAAK;YACb,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC,CAAA;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;AACL,CAAC,CACJ,CAAA;AAEL,OAAO,CAAC,KAAK,EAAE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerInstructions.d.ts","sourceRoot":"","sources":["../../src/constants/ServerInstructions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAClB;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"ServerInstructions.d.ts","sourceRoot":"","sources":["../../src/constants/ServerInstructions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAClB;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAA;AAoLhE;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAChC,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,EACzB,UAAU,EAAE,kBAAkB,EAAE,EAChC,OAAO,EAAE,gBAAgB,EAAE,EAC3B,WAAW,CAAC,EAAE,mBAAmB,EACjC,KAAK,GAAE,gBAA6B,GACrC,MAAM,CAuCR;AAkBD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAA+C,CAAA"}
|
|
@@ -94,7 +94,7 @@ const TOOL_PARAMETER_REFERENCE = `
|
|
|
94
94
|
|------|---------------------|---------------------|
|
|
95
95
|
| \`search_entries\` | \`query\` (string) | \`limit\`, \`entry_type\`, \`tags\` |
|
|
96
96
|
| \`search_by_date_range\` | \`start_date\`, \`end_date\` (YYYY-MM-DD) | \`tags\`, \`entry_type\` |
|
|
97
|
-
| \`semantic_search\` | \`query\` (string) | \`limit\` (default
|
|
97
|
+
| \`semantic_search\` | \`query\` (string) | \`limit\`, \`similarity_threshold\` (default 0.3) |
|
|
98
98
|
| \`get_vector_index_stats\` | none | none |
|
|
99
99
|
|
|
100
100
|
### Relationship Tools
|
|
@@ -161,6 +161,13 @@ Valid values for \`entry_type\` parameter:
|
|
|
161
161
|
|
|
162
162
|
## Field Notes
|
|
163
163
|
- **\`autoContext\`**: Reserved for future automatic context capture. Currently always \`null\`.
|
|
164
|
+
- **\`memory://tags\` vs \`list_tags\`**: Resource includes \`id\`, \`name\`, \`count\`; tool returns only \`name\`, \`count\`.
|
|
165
|
+
- **Tag naming**: Use lowercase with dashes (e.g., \`bug-fix\`, \`phase-2\`). Use \`merge_tags\` to consolidate duplicates (e.g., merge \`phase2\` into \`phase-2\`).
|
|
166
|
+
- **\`merge_tags\` behavior**: Only updates non-deleted entries. Deleted entries retain their original tags.
|
|
167
|
+
- **\`prStatus\` in entries**: Reflects PR state at entry creation time, not current state. Use \`get_github_pr\` for live status.
|
|
168
|
+
- **\`restore_backup\` behavior**: Restores entire database state. Any recent changes (new entries, tag merges via \`merge_tags\`, relationships) are reverted. A pre-restore backup is automatically created for safety.
|
|
169
|
+
- **Semantic search indexing**: Entries are auto-indexed on creation (fire-and-forget). If index count drifts from DB count, use \`rebuild_vector_index\` or enable \`AUTO_REBUILD_INDEX=true\` for automatic reconciliation on server startup.
|
|
170
|
+
- **\`semantic_search\` thresholds**: Default similarity threshold is 0.25. For broader matches, try 0.15-0.2. Higher values (0.4+) return only very close semantic matches.
|
|
164
171
|
|
|
165
172
|
## Key Resources
|
|
166
173
|
| URI | Description |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerInstructions.js","sourceRoot":"","sources":["../../src/constants/ServerInstructions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAqCxD;;;GAGG;AACH,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;CAoB9B,CAAA;AAED;;GAEG;AACH,MAAM,mBAAmB,GAAG;;;;;;;CAO3B,CAAA;AAED;;GAEG;AACH,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;CAyBlC,CAAA;AAED;;GAEG;AACH,MAAM,wBAAwB,GAAG
|
|
1
|
+
{"version":3,"file":"ServerInstructions.js","sourceRoot":"","sources":["../../src/constants/ServerInstructions.ts"],"names":[],"mappings":"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"}
|
|
@@ -107,6 +107,16 @@ export declare class SqliteAdapter {
|
|
|
107
107
|
* List all tags
|
|
108
108
|
*/
|
|
109
109
|
listTags(): Tag[];
|
|
110
|
+
/**
|
|
111
|
+
* Merge one tag into another (consolidate similar tags)
|
|
112
|
+
* @param sourceTag Tag to merge from (will be deleted)
|
|
113
|
+
* @param targetTag Tag to merge into (will be created if not exists)
|
|
114
|
+
* @returns Merge statistics
|
|
115
|
+
*/
|
|
116
|
+
mergeTags(sourceTag: string, targetTag: string): {
|
|
117
|
+
entriesUpdated: number;
|
|
118
|
+
sourceDeleted: boolean;
|
|
119
|
+
};
|
|
110
120
|
/**
|
|
111
121
|
* Link two entries
|
|
112
122
|
*/
|
|
@@ -150,6 +160,15 @@ export declare class SqliteAdapter {
|
|
|
150
160
|
sizeBytes: number;
|
|
151
161
|
createdAt: string;
|
|
152
162
|
}[];
|
|
163
|
+
/**
|
|
164
|
+
* Delete old backups, keeping only the most recent N
|
|
165
|
+
* @param keepCount Number of backups to keep (most recent)
|
|
166
|
+
* @returns Object with deleted filenames and kept count
|
|
167
|
+
*/
|
|
168
|
+
deleteOldBackups(keepCount: number): {
|
|
169
|
+
deleted: string[];
|
|
170
|
+
kept: number;
|
|
171
|
+
};
|
|
153
172
|
/**
|
|
154
173
|
* Restore database from a backup file
|
|
155
174
|
* @param filename Backup filename to restore from
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqliteAdapter.d.ts","sourceRoot":"","sources":["../../src/database/SqliteAdapter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SqliteAdapter.d.ts","sourceRoot":"","sources":["../../src/database/SqliteAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -425,6 +425,66 @@ export class SqliteAdapter {
|
|
|
425
425
|
usageCount: v[2],
|
|
426
426
|
}));
|
|
427
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* Merge one tag into another (consolidate similar tags)
|
|
430
|
+
* @param sourceTag Tag to merge from (will be deleted)
|
|
431
|
+
* @param targetTag Tag to merge into (will be created if not exists)
|
|
432
|
+
* @returns Merge statistics
|
|
433
|
+
*/
|
|
434
|
+
mergeTags(sourceTag, targetTag) {
|
|
435
|
+
const db = this.ensureDb();
|
|
436
|
+
// Get source tag ID
|
|
437
|
+
const sourceResult = db.exec('SELECT id FROM tags WHERE name = ?', [sourceTag]);
|
|
438
|
+
const sourceTagId = sourceResult[0]?.values[0]?.[0];
|
|
439
|
+
if (sourceTagId === undefined) {
|
|
440
|
+
throw new Error(`Source tag not found: ${sourceTag}`);
|
|
441
|
+
}
|
|
442
|
+
// Get or create target tag
|
|
443
|
+
db.run('INSERT OR IGNORE INTO tags (name, usage_count) VALUES (?, 0)', [targetTag]);
|
|
444
|
+
const targetResult = db.exec('SELECT id FROM tags WHERE name = ?', [targetTag]);
|
|
445
|
+
const targetTagId = targetResult[0]?.values[0]?.[0];
|
|
446
|
+
if (targetTagId === undefined) {
|
|
447
|
+
throw new Error(`Failed to get or create target tag: ${targetTag}`);
|
|
448
|
+
}
|
|
449
|
+
// Get entries linked to source tag
|
|
450
|
+
const entriesResult = db.exec('SELECT entry_id FROM entry_tags WHERE tag_id = ?', [
|
|
451
|
+
sourceTagId,
|
|
452
|
+
]);
|
|
453
|
+
const entryIds = entriesResult[0]?.values.map((v) => v[0]) ?? [];
|
|
454
|
+
let entriesUpdated = 0;
|
|
455
|
+
for (const entryId of entryIds) {
|
|
456
|
+
// Check if entry already has target tag
|
|
457
|
+
const existing = db.exec('SELECT 1 FROM entry_tags WHERE entry_id = ? AND tag_id = ?', [
|
|
458
|
+
entryId,
|
|
459
|
+
targetTagId,
|
|
460
|
+
]);
|
|
461
|
+
if (existing[0]?.values.length === 0 || !existing[0]) {
|
|
462
|
+
// Add target tag link
|
|
463
|
+
db.run('INSERT INTO entry_tags (entry_id, tag_id) VALUES (?, ?)', [
|
|
464
|
+
entryId,
|
|
465
|
+
targetTagId,
|
|
466
|
+
]);
|
|
467
|
+
entriesUpdated++;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
// Update target tag usage count
|
|
471
|
+
if (entriesUpdated > 0) {
|
|
472
|
+
db.run('UPDATE tags SET usage_count = usage_count + ? WHERE id = ?', [
|
|
473
|
+
entriesUpdated,
|
|
474
|
+
targetTagId,
|
|
475
|
+
]);
|
|
476
|
+
}
|
|
477
|
+
// Remove source tag links and delete source tag
|
|
478
|
+
db.run('DELETE FROM entry_tags WHERE tag_id = ?', [sourceTagId]);
|
|
479
|
+
db.run('DELETE FROM tags WHERE id = ?', [sourceTagId]);
|
|
480
|
+
this.save();
|
|
481
|
+
logger.info('Tags merged', {
|
|
482
|
+
module: 'SqliteAdapter',
|
|
483
|
+
operation: 'mergeTags',
|
|
484
|
+
context: { sourceTag, targetTag, entriesUpdated },
|
|
485
|
+
});
|
|
486
|
+
return { entriesUpdated, sourceDeleted: true };
|
|
487
|
+
}
|
|
428
488
|
// =========================================================================
|
|
429
489
|
// Relationship Operations
|
|
430
490
|
// =========================================================================
|
|
@@ -605,6 +665,35 @@ export class SqliteAdapter {
|
|
|
605
665
|
backups.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
606
666
|
return backups;
|
|
607
667
|
}
|
|
668
|
+
/**
|
|
669
|
+
* Delete old backups, keeping only the most recent N
|
|
670
|
+
* @param keepCount Number of backups to keep (most recent)
|
|
671
|
+
* @returns Object with deleted filenames and kept count
|
|
672
|
+
*/
|
|
673
|
+
deleteOldBackups(keepCount) {
|
|
674
|
+
const backups = this.listBackups(); // Already sorted newest-first
|
|
675
|
+
if (keepCount < 1) {
|
|
676
|
+
throw new Error('keepCount must be at least 1');
|
|
677
|
+
}
|
|
678
|
+
const toKeep = backups.slice(0, keepCount);
|
|
679
|
+
const toDelete = backups.slice(keepCount);
|
|
680
|
+
const deleted = [];
|
|
681
|
+
for (const backup of toDelete) {
|
|
682
|
+
try {
|
|
683
|
+
fs.unlinkSync(backup.path);
|
|
684
|
+
deleted.push(backup.filename);
|
|
685
|
+
}
|
|
686
|
+
catch {
|
|
687
|
+
// Skip files that can't be deleted
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
logger.info('Old backups cleaned up', {
|
|
691
|
+
module: 'SqliteAdapter',
|
|
692
|
+
operation: 'deleteOldBackups',
|
|
693
|
+
context: { kept: toKeep.length, deleted: deleted.length },
|
|
694
|
+
});
|
|
695
|
+
return { deleted, kept: toKeep.length };
|
|
696
|
+
}
|
|
608
697
|
/**
|
|
609
698
|
* Restore database from a backup file
|
|
610
699
|
* @param filename Backup filename to restore from
|