memory-journal-mcp 4.4.2 → 5.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/.github/workflows/codeql.yml +1 -6
- package/.github/workflows/docker-publish.yml +15 -49
- package/.github/workflows/lint-and-test.yml +1 -1
- package/.github/workflows/secrets-scanning.yml +4 -3
- package/.github/workflows/security-update.yml +3 -3
- package/CHANGELOG.md +213 -0
- package/CONTRIBUTING.md +132 -97
- package/DOCKER_README.md +184 -235
- package/Dockerfile +27 -24
- package/README.md +218 -190
- package/SECURITY.md +27 -35
- package/dist/cli.js +16 -1
- package/dist/cli.js.map +1 -1
- package/dist/constants/ServerInstructions.d.ts +5 -1
- package/dist/constants/ServerInstructions.d.ts.map +1 -1
- package/dist/constants/ServerInstructions.js +133 -73
- package/dist/constants/ServerInstructions.js.map +1 -1
- package/dist/constants/icons.d.ts +2 -2
- package/dist/constants/icons.d.ts.map +1 -1
- package/dist/constants/icons.js +7 -6
- package/dist/constants/icons.js.map +1 -1
- package/dist/database/SqliteAdapter.d.ts +37 -24
- package/dist/database/SqliteAdapter.d.ts.map +1 -1
- package/dist/database/SqliteAdapter.js +319 -157
- package/dist/database/SqliteAdapter.js.map +1 -1
- package/dist/database/schema.d.ts +45 -0
- package/dist/database/schema.d.ts.map +1 -0
- package/dist/database/schema.js +92 -0
- package/dist/database/schema.js.map +1 -0
- package/dist/filtering/ToolFilter.d.ts +1 -1
- package/dist/filtering/ToolFilter.d.ts.map +1 -1
- package/dist/filtering/ToolFilter.js +13 -2
- package/dist/filtering/ToolFilter.js.map +1 -1
- package/dist/github/GitHubIntegration.d.ts.map +1 -1
- package/dist/github/GitHubIntegration.js +1 -3
- package/dist/github/GitHubIntegration.js.map +1 -1
- package/dist/handlers/prompts/github.d.ts +12 -0
- package/dist/handlers/prompts/github.d.ts.map +1 -0
- package/dist/handlers/prompts/github.js +178 -0
- package/dist/handlers/prompts/github.js.map +1 -0
- package/dist/handlers/prompts/index.d.ts +23 -2
- package/dist/handlers/prompts/index.d.ts.map +1 -1
- package/dist/handlers/prompts/index.js +7 -432
- package/dist/handlers/prompts/index.js.map +1 -1
- package/dist/handlers/prompts/workflow.d.ts +12 -0
- package/dist/handlers/prompts/workflow.d.ts.map +1 -0
- package/dist/handlers/prompts/workflow.js +277 -0
- package/dist/handlers/prompts/workflow.js.map +1 -0
- package/dist/handlers/resources/core.d.ts +11 -0
- package/dist/handlers/resources/core.d.ts.map +1 -0
- package/dist/handlers/resources/core.js +433 -0
- package/dist/handlers/resources/core.js.map +1 -0
- package/dist/handlers/resources/github.d.ts +11 -0
- package/dist/handlers/resources/github.d.ts.map +1 -0
- package/dist/handlers/resources/github.js +314 -0
- package/dist/handlers/resources/github.js.map +1 -0
- package/dist/handlers/resources/graph.d.ts +11 -0
- package/dist/handlers/resources/graph.d.ts.map +1 -0
- package/dist/handlers/resources/graph.js +204 -0
- package/dist/handlers/resources/graph.js.map +1 -0
- package/dist/handlers/resources/index.d.ts +5 -20
- package/dist/handlers/resources/index.d.ts.map +1 -1
- package/dist/handlers/resources/index.js +16 -1278
- package/dist/handlers/resources/index.js.map +1 -1
- package/dist/handlers/resources/shared.d.ts +60 -0
- package/dist/handlers/resources/shared.d.ts.map +1 -0
- package/dist/handlers/resources/shared.js +49 -0
- package/dist/handlers/resources/shared.js.map +1 -0
- package/dist/handlers/resources/team.d.ts +13 -0
- package/dist/handlers/resources/team.d.ts.map +1 -0
- package/dist/handlers/resources/team.js +119 -0
- package/dist/handlers/resources/team.js.map +1 -0
- package/dist/handlers/resources/templates.d.ts +13 -0
- package/dist/handlers/resources/templates.d.ts.map +1 -0
- package/dist/handlers/resources/templates.js +310 -0
- package/dist/handlers/resources/templates.js.map +1 -0
- package/dist/handlers/tools/admin.d.ts +8 -0
- package/dist/handlers/tools/admin.d.ts.map +1 -0
- package/dist/handlers/tools/admin.js +270 -0
- package/dist/handlers/tools/admin.js.map +1 -0
- package/dist/handlers/tools/analytics.d.ts +8 -0
- package/dist/handlers/tools/analytics.d.ts.map +1 -0
- package/dist/handlers/tools/analytics.js +256 -0
- package/dist/handlers/tools/analytics.js.map +1 -0
- package/dist/handlers/tools/backup.d.ts +8 -0
- package/dist/handlers/tools/backup.d.ts.map +1 -0
- package/dist/handlers/tools/backup.js +224 -0
- package/dist/handlers/tools/backup.js.map +1 -0
- package/dist/handlers/tools/core.d.ts +9 -0
- package/dist/handlers/tools/core.d.ts.map +1 -0
- package/dist/handlers/tools/core.js +326 -0
- package/dist/handlers/tools/core.js.map +1 -0
- package/dist/handlers/tools/export.d.ts +8 -0
- package/dist/handlers/tools/export.d.ts.map +1 -0
- package/dist/handlers/tools/export.js +89 -0
- package/dist/handlers/tools/export.js.map +1 -0
- package/dist/handlers/tools/github/helpers.d.ts +34 -0
- package/dist/handlers/tools/github/helpers.d.ts.map +1 -0
- package/dist/handlers/tools/github/helpers.js +52 -0
- package/dist/handlers/tools/github/helpers.js.map +1 -0
- package/dist/handlers/tools/github/insights-tools.d.ts +8 -0
- package/dist/handlers/tools/github/insights-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/insights-tools.js +104 -0
- package/dist/handlers/tools/github/insights-tools.js.map +1 -0
- package/dist/handlers/tools/github/issue-tools.d.ts +8 -0
- package/dist/handlers/tools/github/issue-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/issue-tools.js +359 -0
- package/dist/handlers/tools/github/issue-tools.js.map +1 -0
- package/dist/handlers/tools/github/kanban-tools.d.ts +8 -0
- package/dist/handlers/tools/github/kanban-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/kanban-tools.js +108 -0
- package/dist/handlers/tools/github/kanban-tools.js.map +1 -0
- package/dist/handlers/tools/github/milestone-tools.d.ts +9 -0
- package/dist/handlers/tools/github/milestone-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/milestone-tools.js +302 -0
- package/dist/handlers/tools/github/milestone-tools.js.map +1 -0
- package/dist/handlers/tools/github/mutation-tools.d.ts +12 -0
- package/dist/handlers/tools/github/mutation-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/mutation-tools.js +15 -0
- package/dist/handlers/tools/github/mutation-tools.js.map +1 -0
- package/dist/handlers/tools/github/read-tools.d.ts +8 -0
- package/dist/handlers/tools/github/read-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/read-tools.js +260 -0
- package/dist/handlers/tools/github/read-tools.js.map +1 -0
- package/dist/handlers/tools/github/schemas.d.ts +467 -0
- package/dist/handlers/tools/github/schemas.d.ts.map +1 -0
- package/dist/handlers/tools/github/schemas.js +335 -0
- package/dist/handlers/tools/github/schemas.js.map +1 -0
- package/dist/handlers/tools/github.d.ts +14 -0
- package/dist/handlers/tools/github.d.ts.map +1 -0
- package/dist/handlers/tools/github.js +28 -0
- package/dist/handlers/tools/github.js.map +1 -0
- package/dist/handlers/tools/index.d.ts +15 -20
- package/dist/handlers/tools/index.d.ts.map +1 -1
- package/dist/handlers/tools/index.js +117 -2909
- package/dist/handlers/tools/index.js.map +1 -1
- package/dist/handlers/tools/relationships.d.ts +8 -0
- package/dist/handlers/tools/relationships.d.ts.map +1 -0
- package/dist/handlers/tools/relationships.js +308 -0
- package/dist/handlers/tools/relationships.js.map +1 -0
- package/dist/handlers/tools/schemas.d.ts +108 -0
- package/dist/handlers/tools/schemas.d.ts.map +1 -0
- package/dist/handlers/tools/schemas.js +122 -0
- package/dist/handlers/tools/schemas.js.map +1 -0
- package/dist/handlers/tools/search.d.ts +8 -0
- package/dist/handlers/tools/search.d.ts.map +1 -0
- package/dist/handlers/tools/search.js +282 -0
- package/dist/handlers/tools/search.js.map +1 -0
- package/dist/handlers/tools/team.d.ts +11 -0
- package/dist/handlers/tools/team.d.ts.map +1 -0
- package/dist/handlers/tools/team.js +239 -0
- package/dist/handlers/tools/team.js.map +1 -0
- package/dist/server/McpServer.d.ts +4 -0
- package/dist/server/McpServer.d.ts.map +1 -1
- package/dist/server/McpServer.js +48 -297
- package/dist/server/McpServer.js.map +1 -1
- package/dist/server/Scheduler.d.ts +91 -0
- package/dist/server/Scheduler.d.ts.map +1 -0
- package/dist/server/Scheduler.js +201 -0
- package/dist/server/Scheduler.js.map +1 -0
- package/dist/transports/http.d.ts +66 -0
- package/dist/transports/http.d.ts.map +1 -0
- package/dist/transports/http.js +519 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/types/entities.d.ts +101 -0
- package/dist/types/entities.d.ts.map +1 -0
- package/dist/types/entities.js +5 -0
- package/dist/types/entities.js.map +1 -0
- package/dist/types/filtering.d.ts +34 -0
- package/dist/types/filtering.d.ts.map +1 -0
- package/dist/types/filtering.js +5 -0
- package/dist/types/filtering.js.map +1 -0
- package/dist/types/github.d.ts +166 -0
- package/dist/types/github.d.ts.map +1 -0
- package/dist/types/github.js +5 -0
- package/dist/types/github.js.map +1 -0
- package/dist/types/index.d.ts +35 -292
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -2
- package/dist/types/index.js.map +1 -1
- package/dist/utils/error-helpers.d.ts +37 -0
- package/dist/utils/error-helpers.d.ts.map +1 -0
- package/dist/utils/error-helpers.js +47 -0
- package/dist/utils/error-helpers.js.map +1 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +6 -3
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/security-utils.d.ts +0 -21
- package/dist/utils/security-utils.d.ts.map +1 -1
- package/dist/utils/security-utils.js +0 -47
- package/dist/utils/security-utils.js.map +1 -1
- package/dist/vector/VectorSearchManager.d.ts.map +1 -1
- package/dist/vector/VectorSearchManager.js +9 -32
- package/dist/vector/VectorSearchManager.js.map +1 -1
- package/docker-compose.yml +11 -2
- package/hooks/README.md +107 -0
- package/hooks/cursor/hooks.json +10 -0
- package/hooks/cursor/memory-journal.mdc +22 -0
- package/hooks/cursor/session-end.sh +19 -0
- package/hooks/kilo-code/session-end-mode.json +11 -0
- package/hooks/kiro/session-end.md +13 -0
- package/mcp-config-example.json +1 -0
- package/package.json +11 -9
- package/playwright.config.ts +29 -0
- package/releases/v4.5.0.md +116 -0
- package/releases/v5.0.0.md +105 -0
- package/scripts/generate-server-instructions.ts +176 -0
- package/scripts/server-instructions-function-body.ts +77 -0
- package/server.json +3 -3
- package/src/cli.ts +45 -1
- package/src/constants/ServerInstructions.ts +133 -73
- package/src/constants/icons.ts +8 -7
- package/src/constants/server-instructions.md +268 -0
- package/src/database/SqliteAdapter.ts +358 -192
- package/src/database/schema.ts +125 -0
- package/src/filtering/ToolFilter.ts +13 -2
- package/src/github/GitHubIntegration.ts +1 -3
- package/src/handlers/prompts/github.ts +209 -0
- package/src/handlers/prompts/index.ts +10 -499
- package/src/handlers/prompts/workflow.ts +314 -0
- package/src/handlers/resources/core.ts +528 -0
- package/src/handlers/resources/github.ts +358 -0
- package/src/handlers/resources/graph.ts +254 -0
- package/src/handlers/resources/index.ts +23 -1570
- package/src/handlers/resources/shared.ts +103 -0
- package/src/handlers/resources/team.ts +133 -0
- package/src/handlers/resources/templates.ts +374 -0
- package/src/handlers/tools/admin.ts +285 -0
- package/src/handlers/tools/analytics.ts +301 -0
- package/src/handlers/tools/backup.ts +242 -0
- package/src/handlers/tools/core.ts +350 -0
- package/src/handlers/tools/export.ts +115 -0
- package/src/handlers/tools/github/helpers.ts +86 -0
- package/src/handlers/tools/github/insights-tools.ts +119 -0
- package/src/handlers/tools/github/issue-tools.ts +439 -0
- package/src/handlers/tools/github/kanban-tools.ts +134 -0
- package/src/handlers/tools/github/milestone-tools.ts +392 -0
- package/src/handlers/tools/github/mutation-tools.ts +17 -0
- package/src/handlers/tools/github/read-tools.ts +328 -0
- package/src/handlers/tools/github/schemas.ts +369 -0
- package/src/handlers/tools/github.ts +36 -0
- package/src/handlers/tools/index.ts +144 -3325
- package/src/handlers/tools/relationships.ts +358 -0
- package/src/handlers/tools/schemas.ts +132 -0
- package/src/handlers/tools/search.ts +343 -0
- package/src/handlers/tools/team.ts +273 -0
- package/src/server/McpServer.ts +63 -358
- package/src/server/Scheduler.ts +278 -0
- package/src/transports/http.ts +635 -0
- package/src/types/entities.ts +145 -0
- package/src/types/filtering.ts +54 -0
- package/src/types/github.ts +180 -0
- package/src/types/index.ts +67 -375
- package/src/utils/error-helpers.ts +52 -0
- package/src/utils/logger.ts +6 -3
- package/src/utils/security-utils.ts +0 -52
- package/src/vector/VectorSearchManager.ts +9 -33
- package/tests/constants/icons.test.ts +1 -2
- package/tests/constants/server-instructions.test.ts +30 -4
- package/tests/database/sqlite-adapter.test.ts +91 -7
- package/tests/e2e/auth.spec.ts +154 -0
- package/tests/e2e/health.spec.ts +63 -0
- package/tests/e2e/protocols.spec.ts +134 -0
- package/tests/e2e/resources.spec.ts +103 -0
- package/tests/e2e/scheduler.spec.ts +79 -0
- package/tests/e2e/security.spec.ts +91 -0
- package/tests/e2e/sessions.spec.ts +95 -0
- package/tests/e2e/stateless.spec.ts +121 -0
- package/tests/e2e/tools.spec.ts +111 -0
- package/tests/filtering/tool-filter.test.ts +46 -0
- package/tests/handlers/error-path-coverage.test.ts +324 -0
- package/tests/handlers/github-resource-handlers.test.ts +453 -0
- package/tests/handlers/github-tool-handlers.test.ts +899 -0
- package/tests/handlers/prompt-handler-coverage.test.ts +106 -0
- package/tests/handlers/prompt-handlers.test.ts +40 -0
- package/tests/handlers/resource-handler-coverage.test.ts +181 -0
- package/tests/handlers/resource-handlers.test.ts +33 -9
- package/tests/handlers/search-tool-handlers.test.ts +272 -0
- package/tests/handlers/targeted-gap-closure.test.ts +387 -0
- package/tests/handlers/team-resource-handlers.test.ts +156 -0
- package/tests/handlers/team-tool-handlers.test.ts +301 -0
- package/tests/handlers/tool-handler-coverage.test.ts +469 -0
- package/tests/handlers/tool-handlers.test.ts +2 -2
- package/tests/security/sql-injection.test.ts +3 -54
- package/tests/server/mcp-server.test.ts +503 -8
- package/tests/server/scheduler.test.ts +400 -0
- package/tests/transports/http-transport.test.ts +620 -0
- package/tests/vector/vector-search-manager.test.ts +60 -0
- package/vitest.config.ts +4 -1
- package/.memory-journal-team.db +0 -0
- package/.vscode/settings.json +0 -84
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
testDir: './tests/e2e',
|
|
5
|
+
fullyParallel: false,
|
|
6
|
+
forbidOnly: !!process.env.CI,
|
|
7
|
+
retries: process.env.CI ? 2 : 0,
|
|
8
|
+
workers: 1,
|
|
9
|
+
reporter: 'list',
|
|
10
|
+
use: {
|
|
11
|
+
baseURL: 'http://localhost:3100',
|
|
12
|
+
trace: 'on-first-retry',
|
|
13
|
+
},
|
|
14
|
+
projects: [
|
|
15
|
+
{
|
|
16
|
+
name: 'api',
|
|
17
|
+
use: { ...devices['Desktop Chrome'] },
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
webServer: {
|
|
21
|
+
command:
|
|
22
|
+
'node dist/cli.js --transport http --port 3100 --db ./test-e2e.db --backup-interval 1 --keep-backups 3 --vacuum-interval 2 --rebuild-index-interval 2',
|
|
23
|
+
url: 'http://localhost:3100/health',
|
|
24
|
+
reuseExistingServer: !process.env.CI,
|
|
25
|
+
timeout: 15000,
|
|
26
|
+
stdout: 'pipe',
|
|
27
|
+
stderr: 'pipe',
|
|
28
|
+
},
|
|
29
|
+
})
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# v4.5.0 - Automated Scheduling, Security Hardening & Quality Improvements
|
|
2
|
+
|
|
3
|
+
**Released: March 2, 2026**
|
|
4
|
+
|
|
5
|
+
## Highlights
|
|
6
|
+
|
|
7
|
+
### ⏰ Automated Scheduler (HTTP/SSE Only)
|
|
8
|
+
|
|
9
|
+
New in-process scheduler runs periodic maintenance jobs for long-running HTTP/SSE server processes:
|
|
10
|
+
|
|
11
|
+
- `--backup-interval <minutes>` — Automated database backups with cleanup
|
|
12
|
+
- `--keep-backups <count>` — Max backups to retain (default: 5)
|
|
13
|
+
- `--vacuum-interval <minutes>` — Database optimization (`PRAGMA optimize`)
|
|
14
|
+
- `--rebuild-index-interval <minutes>` — Full vector index rebuild
|
|
15
|
+
|
|
16
|
+
Each job is error-isolated. Status visible via `memory://health`.
|
|
17
|
+
|
|
18
|
+
### 🔒 Security Hardening
|
|
19
|
+
|
|
20
|
+
Comprehensive security improvements across the entire stack:
|
|
21
|
+
|
|
22
|
+
- **HTTP Transport** — Rate limiting (100 req/min), CSP headers, Cache-Control, Referrer-Policy, CORS wildcard warning
|
|
23
|
+
- **Input Validation** — `entry_type` and `significance_type` now constrained to Zod enums; date format validation via regex
|
|
24
|
+
- **Dead Code Wiring** — `sanitizeSearchQuery()` and `assertNoPathTraversal()` now active in code paths
|
|
25
|
+
- **Foreign Keys** — `PRAGMA foreign_keys = ON` enforced at database initialization
|
|
26
|
+
- **Path Traversal** — `exportToFile()` now protected with `assertNoPathTraversal()`
|
|
27
|
+
- **Logger Hardening** — `LOG_LEVEL` validated; `setLevel()` guarded against invalid values
|
|
28
|
+
- **Removed dead code** — SQL injection detection functions that provided false sense of security
|
|
29
|
+
- **CI** — Blocking `npm audit` and TruffleHog steps; Node.js test matrix aligned to `>=24.0.0`
|
|
30
|
+
|
|
31
|
+
### ✅ Test Coverage → 92%
|
|
32
|
+
|
|
33
|
+
Expanded test suite from 549 → 590 tests, raising line coverage from 88.59% → 92.06%:
|
|
34
|
+
|
|
35
|
+
- SIGINT shutdown handlers for all three transport modes
|
|
36
|
+
- Prompt handlers with proper arguments
|
|
37
|
+
- `SqliteAdapter` backup edge cases
|
|
38
|
+
- GitHub integration error paths
|
|
39
|
+
|
|
40
|
+
### 📝 Cursor Rule for Session Management
|
|
41
|
+
|
|
42
|
+
Added `hooks/cursor/memory-journal.mdc` — an `alwaysApply` Cursor rule that instructs agents to read `memory://briefing` at session start and create a retrospective at session end. This is the most reliable mechanism for session behavior in Cursor.
|
|
43
|
+
|
|
44
|
+
## Added
|
|
45
|
+
|
|
46
|
+
- **Automated Scheduler** — `Scheduler.ts` module with CLI flags for backup, vacuum, and index rebuild intervals
|
|
47
|
+
- **Cursor Rule** — `hooks/cursor/memory-journal.mdc` for reliable session management
|
|
48
|
+
- **Cursor `sessionEnd` Hook** — `hooks/cursor/hooks.json` + `session-end.sh` audit script
|
|
49
|
+
|
|
50
|
+
## Improved
|
|
51
|
+
|
|
52
|
+
- **Test Coverage** — 88.59% → 92.06% line coverage (549 → 590 tests)
|
|
53
|
+
- **Database I/O** — Debounced `scheduleSave()` reduces disk writes on rapid mutations
|
|
54
|
+
- **Vector Index Rebuild** — Paginated fetching (200/page) + parallel batch embedding (5 at a time)
|
|
55
|
+
- **Server Startup** — Eliminated duplicate `getTools()` call
|
|
56
|
+
- **GitHub API** — TTL response cache (5 min) with automatic invalidation on mutations
|
|
57
|
+
|
|
58
|
+
## Fixed
|
|
59
|
+
|
|
60
|
+
- **Session Start briefing in Cursor** — Added `user-memory-journal-mcp` server name for Cursor compatibility
|
|
61
|
+
- **`deleteOldBackups` Test Isolation** — Fixed flaky test by cleaning up pre-existing backups
|
|
62
|
+
- **`share_with_team` Not Setting `isPersonal`** — `create_entry` with `share_with_team: true` now correctly sets `isPersonal: false`
|
|
63
|
+
- **Path Traversal Test Assertion** — Updated to assert `PathTraversalError` type
|
|
64
|
+
- **Tool Handler Test Fix** — Updated to use valid `entry_type` enum value
|
|
65
|
+
|
|
66
|
+
## Security
|
|
67
|
+
|
|
68
|
+
- Wire dead-code security utilities (F-001, F-002)
|
|
69
|
+
- HTTP security headers: CSP, Cache-Control, Referrer-Policy (F-003)
|
|
70
|
+
- `PRAGMA foreign_keys = ON` (F-005)
|
|
71
|
+
- CORS wildcard warning (F-006)
|
|
72
|
+
- `entry_type` / `significance_type` enum constraints
|
|
73
|
+
- Date format validation on all date string fields
|
|
74
|
+
- HTTP rate limiting (100 req/min per IP)
|
|
75
|
+
- Remove dead SQL injection detection code
|
|
76
|
+
- `exportToFile()` path traversal protection
|
|
77
|
+
- `getRawDb()` safety documentation
|
|
78
|
+
- Logger `LOG_LEVEL` validation (L1) and `setLevel()` guard (L2)
|
|
79
|
+
- CI `security-scan` Node version alignment (L3)
|
|
80
|
+
|
|
81
|
+
## Changed
|
|
82
|
+
|
|
83
|
+
- `@types/node`: 25.3.2 → 25.3.3 (patch)
|
|
84
|
+
- `globals`: 17.3.0 → 17.4.0 (minor)
|
|
85
|
+
- `minimatch` override: 10.2.3 → 10.2.4 (patch)
|
|
86
|
+
- `tar` override: 7.5.8 → 7.5.9 (patch)
|
|
87
|
+
|
|
88
|
+
## Removed
|
|
89
|
+
|
|
90
|
+
- **Unused `cors` dependency** — CORS handled by custom middleware
|
|
91
|
+
|
|
92
|
+
## CI/CD
|
|
93
|
+
|
|
94
|
+
- Removed Dependabot auto-merge workflow
|
|
95
|
+
- Trivy Action updated to 0.34.0
|
|
96
|
+
- Node.js test matrix aligned: `[24.x, 25.x]`
|
|
97
|
+
- Blocking `npm audit` in CI pipeline
|
|
98
|
+
- Blocking TruffleHog secret scanning
|
|
99
|
+
|
|
100
|
+
## Documentation
|
|
101
|
+
|
|
102
|
+
- Revised `hooks/README.md` with progressive enhancement model
|
|
103
|
+
- Updated Session Management in README.md and DOCKER_README.md
|
|
104
|
+
- SECURITY.md rewrite for TypeScript era
|
|
105
|
+
- Team collaboration in READMEs with wiki links
|
|
106
|
+
- Rate limiting documentation
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# npm
|
|
112
|
+
npm install -g memory-journal-mcp@4.5.0
|
|
113
|
+
|
|
114
|
+
# Docker
|
|
115
|
+
docker pull writenotenow/memory-journal-mcp:v4.5.0
|
|
116
|
+
```
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# v5.0.0 — Major Architecture & Security Release
|
|
2
|
+
|
|
3
|
+
**Release Date:** March 6, 2026
|
|
4
|
+
|
|
5
|
+
This is a major release featuring a complete architectural overhaul, comprehensive security hardening, a new E2E test suite, redesigned team collaboration, and deterministic error handling across all 42 tools.
|
|
6
|
+
|
|
7
|
+
## ✨ Highlights
|
|
8
|
+
|
|
9
|
+
- **Architecture Overhaul** — Tool handler monolith (3,428 lines) split into 12 focused modules. Resource handlers, prompt handlers, types, mutation tools, and HTTP transport all modularized similarly.
|
|
10
|
+
- **Team Collaboration Redesign** — Rebuilt from scratch with separate team database (`TEAM_DB_PATH`), author attribution, cross-DB search, and 3 dedicated tools (`team_create_entry`, `team_get_recent`, `team_search`).
|
|
11
|
+
- **Deterministic Error Handling** — All 42 tool handlers wrapped with `formatHandlerError()` returning structured `{ success: false, error }` responses. Dual-schema validation pattern ensures Zod errors also produce structured responses.
|
|
12
|
+
- **20+ Security Improvements** — Bearer token authentication, HSTS, timing-safe token comparison, shell-free git detection, Docker hardening, CI pipeline action pinning, and more.
|
|
13
|
+
- **Playwright E2E Test Suite** — 8 spec files (47 tests) testing HTTP/SSE transport end-to-end: health, protocols, security headers, auth, sessions, tools, resources, stateless mode, and scheduler.
|
|
14
|
+
- **Dual HTTP Transport** — Streamable HTTP (`/mcp`) + Legacy SSE (`/sse`) running simultaneously in stateful mode.
|
|
15
|
+
|
|
16
|
+
## 🆕 Added
|
|
17
|
+
|
|
18
|
+
- **Playwright E2E Test Suite** — `health.spec.ts`, `protocols.spec.ts`, `security.spec.ts`, `auth.spec.ts`, `sessions.spec.ts`, `tools.spec.ts`, `resources.spec.ts`, `stateless.spec.ts`, `scheduler.spec.ts`
|
|
19
|
+
- **Legacy SSE Transport** — `GET /sse` + `POST /messages?sessionId=<id>` for backward-compatible MCP 2024-11-05 clients (stateful mode only)
|
|
20
|
+
- **Health Endpoint** — `GET /health` returns `{ status: "healthy", timestamp }`
|
|
21
|
+
- **Root Info Endpoint** — `GET /` returns server name, version, endpoints, docs link
|
|
22
|
+
- **404 Handler** — Unknown paths return `{ error: "Not found" }`
|
|
23
|
+
- **`DB_PATH` Environment Variable** — Database path via env block (precedence: CLI `--db` > `DB_PATH` > `./memory_journal.db`)
|
|
24
|
+
- **`--auth-token` CLI Option** — Bearer token authentication for HTTP transport (`MCP_AUTH_TOKEN` env)
|
|
25
|
+
- **`Permissions-Policy` Header** — 6th security header: `camera=(), microphone=(), geolocation=()`
|
|
26
|
+
- **Team Collaboration** — `TEAM_DB_PATH`, `TEAM_AUTHOR`, `share_with_team`, `memory://team/recent`, `memory://team/statistics`
|
|
27
|
+
- Tool count: 39 → 42 · Tool groups: 8 → 9 · Resources: 20 → 22
|
|
28
|
+
|
|
29
|
+
## 🔒 Security
|
|
30
|
+
|
|
31
|
+
- **Trigger Name Validation** — `SAFE_IDENTIFIER_RE` regex in `migrateSchema()` prevents SQL injection via crafted trigger names
|
|
32
|
+
- **Query Limit Caps** — `.max(500)` on all `limit` parameters (10 schemas)
|
|
33
|
+
- **TruffleHog Pinned** — `@main` → `@v3.93.7`
|
|
34
|
+
- **Docker Scout Official Action** — Replaces `curl | sh` installer with `docker/scout-action@v1.18.2`
|
|
35
|
+
- **Gitleaks Blocking** — Removed `continue-on-error: true`; leaks now fail the workflow
|
|
36
|
+
- **Gitleaks Pinned** — `@v2` → `@v2.3.9`
|
|
37
|
+
- **Bearer Token Auth** — Optional `--auth-token` with `MCP_AUTH_TOKEN` env support
|
|
38
|
+
- **SSE Session Timeout** — Legacy SSE sessions expire after 30 min idle
|
|
39
|
+
- **`searchByDateRange` Limit** — `LIMIT 500` prevents unbounded result sets
|
|
40
|
+
- **Docker Production-Only Dependencies** — `npm ci --omit=dev` in production image
|
|
41
|
+
- **CORS `Authorization` Header** — Added for bearer token support
|
|
42
|
+
- **Timing-Safe Auth** — `crypto.timingSafeEqual()` for token comparison
|
|
43
|
+
- **HSTS Header** — Conditional `Strict-Transport-Security` behind reverse proxy
|
|
44
|
+
- **Docker Compose Hardening** — `read_only: true`, `tmpfs`, generic token placeholder, explicit `NODE_ENV`
|
|
45
|
+
- **Shell-Free Git** — `execFileSync('git', [...])` replaces `execSync('git config ...')`
|
|
46
|
+
|
|
47
|
+
## ⚡ Improved
|
|
48
|
+
|
|
49
|
+
- **Batch Tag Fetching** — N+1 elimination: `getRecentEntries(50)` reduced from 51 queries to 2
|
|
50
|
+
- **Batch Tag Linking** — Single `INSERT OR IGNORE` + `SELECT ... WHERE name IN (...)`
|
|
51
|
+
- **Tool Dispatch Cache** — O(1) `Map` lookup instead of rebuilding 42 definitions per call
|
|
52
|
+
- **Conditional JOIN in `searchByDateRange`** — Tag tables only JOINed when tag filter provided
|
|
53
|
+
- **Consolidated `getStatistics` Queries** — 5 sequential `db.exec()` → 3 with `SUM(CASE ...)`
|
|
54
|
+
- **Dual-Schema Validation** — Relaxed schemas for SDK, strict schemas in handlers
|
|
55
|
+
|
|
56
|
+
## 🐛 Fixed
|
|
57
|
+
|
|
58
|
+
- **Entry Type Enum** — Added 6 missing types (`technical_note`, `development_note`, `enhancement`, `milestone`, `system_integration_test`, `test_entry`)
|
|
59
|
+
- **`get_github_milestones` State Filter** — `state: "all"` no longer silently defaults to `"open"`
|
|
60
|
+
- **Legacy Database Migration** — `migrateSchema()` adds missing columns + drops FTS5 triggers
|
|
61
|
+
- **`list_tags` Null Count** — `COALESCE(usage_count, 0)` prevents null validation failures
|
|
62
|
+
- **Output Schema Error Responses** — All schemas now accept `{ success: false, error }` responses
|
|
63
|
+
- **Multi-Session Connect Crash** — Close-before-reconnect pattern for concurrent HTTP sessions
|
|
64
|
+
- **Backup Error Path** — Error responses now pass Zod output validation
|
|
65
|
+
- **`share_with_team` Not Setting `isPersonal`** — Fixed `create_entry` with `share_with_team: true`
|
|
66
|
+
- **Legacy SSE `start()` Redundancy** — Eliminated duplicate `sseTransport.start()` call
|
|
67
|
+
|
|
68
|
+
## 🔄 Changed
|
|
69
|
+
|
|
70
|
+
- **HTTP Transport Modularized** — `McpServer.ts` (813 → ~450 lines) → `src/transports/http.ts`
|
|
71
|
+
- **`ToolDefinition.handler` Return Type** — `Promise<unknown>` → `unknown` (supports sync+async)
|
|
72
|
+
- **Dependency Updates** — `@types/node` 25.3.3→25.3.5, `express-rate-limit` 8.2.1→8.3.0, `sql.js` 1.14.0→1.14.1
|
|
73
|
+
|
|
74
|
+
## 🗑️ Removed
|
|
75
|
+
|
|
76
|
+
- Legacy team collaboration system (rebuilt from scratch)
|
|
77
|
+
- Tool handler monolith `src/handlers/tools/index.ts` (replaced by 12 modules)
|
|
78
|
+
- Unused `cors` and `@types/cors` packages
|
|
79
|
+
- Database files reorganized into `data/` directory
|
|
80
|
+
|
|
81
|
+
## 🔄 CI/CD
|
|
82
|
+
|
|
83
|
+
- **CodeQL Default Setup Disabled** — Custom workflow is now sole scanner
|
|
84
|
+
- **CodeQL `actions` Language** — Added to replace Default Setup coverage
|
|
85
|
+
- **Trivy Action** — 0.34.0 → 0.34.1
|
|
86
|
+
|
|
87
|
+
## 📖 Documentation
|
|
88
|
+
|
|
89
|
+
- Cursor Rule for session management (`hooks/cursor/memory-journal.mdc`)
|
|
90
|
+
- Revised hooks/README.md with progressive enhancement model
|
|
91
|
+
- SECURITY.md rewritten for current architecture
|
|
92
|
+
- Team collaboration documented in READMEs
|
|
93
|
+
- Wiki security page expanded (16-item checklist)
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
**Full Changelog:** [v4.5.0...v5.0.0](https://github.com/neverinfamous/memory-journal-mcp/compare/v4.5.0...v5.0.0)
|
|
98
|
+
|
|
99
|
+
**Install/Update:**
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm install -g memory-journal-mcp@5.0.0
|
|
103
|
+
# or
|
|
104
|
+
docker pull writenotenow/memory-journal-mcp:v5.0.0
|
|
105
|
+
```
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates src/constants/ServerInstructions.ts from src/constants/server-instructions.md
|
|
3
|
+
*
|
|
4
|
+
* Reads the markdown source file, splits it by section delimiters,
|
|
5
|
+
* escapes for template literals, and produces the full TypeScript module
|
|
6
|
+
* with types, constants, and the generateInstructions function.
|
|
7
|
+
*
|
|
8
|
+
* Usage: node scripts/generate-server-instructions.ts
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { readFileSync, writeFileSync } from 'node:fs'
|
|
12
|
+
import { dirname, resolve } from 'node:path'
|
|
13
|
+
import { fileURLToPath } from 'node:url'
|
|
14
|
+
|
|
15
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
16
|
+
const projectRoot = resolve(__dirname, '..')
|
|
17
|
+
|
|
18
|
+
const mdPath = resolve(projectRoot, 'src/constants/server-instructions.md')
|
|
19
|
+
const tsPath = resolve(projectRoot, 'src/constants/ServerInstructions.ts')
|
|
20
|
+
|
|
21
|
+
// Read plain markdown source
|
|
22
|
+
const markdown = readFileSync(mdPath, 'utf-8')
|
|
23
|
+
|
|
24
|
+
// Section names in order
|
|
25
|
+
const SECTION_NAMES = ['ESSENTIAL', 'GITHUB', 'SERVER_ACCESS', 'TOOL_PARAMETER_REFERENCE']
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Parse sections from markdown using <!-- SECTION:NAME --> delimiters
|
|
29
|
+
*/
|
|
30
|
+
function parseSections(content) {
|
|
31
|
+
const sections = {}
|
|
32
|
+
|
|
33
|
+
for (let i = 0; i < SECTION_NAMES.length; i++) {
|
|
34
|
+
const name = SECTION_NAMES[i]
|
|
35
|
+
const startMarker = '<!-- SECTION:' + name + ' -->'
|
|
36
|
+
const startIdx = content.indexOf(startMarker)
|
|
37
|
+
|
|
38
|
+
if (startIdx === -1) {
|
|
39
|
+
throw new Error('Missing section marker: ' + startMarker)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const contentStart = startIdx + startMarker.length
|
|
43
|
+
|
|
44
|
+
// Find next section marker or end of file
|
|
45
|
+
let contentEnd
|
|
46
|
+
if (i + 1 < SECTION_NAMES.length) {
|
|
47
|
+
const nextMarker = '<!-- SECTION:' + SECTION_NAMES[i + 1] + ' -->'
|
|
48
|
+
contentEnd = content.indexOf(nextMarker)
|
|
49
|
+
if (contentEnd === -1) {
|
|
50
|
+
throw new Error('Missing section marker: ' + nextMarker)
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
contentEnd = content.length
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Trim leading/trailing whitespace but preserve internal structure
|
|
57
|
+
sections[name] = content.slice(contentStart, contentEnd).trim()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return sections
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Escape content for use inside a JS/TS template literal
|
|
65
|
+
*/
|
|
66
|
+
function escapeForTemplateLiteral(content) {
|
|
67
|
+
return content.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const sections = parseSections(markdown)
|
|
71
|
+
|
|
72
|
+
// Read the function body template (static TypeScript code after the constants)
|
|
73
|
+
const FUNCTION_BODY = readFileSync(
|
|
74
|
+
resolve(projectRoot, 'scripts/server-instructions-function-body.ts'),
|
|
75
|
+
'utf-8'
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
// Build the TypeScript file using string concatenation to avoid nested escaping
|
|
79
|
+
const lines = []
|
|
80
|
+
|
|
81
|
+
lines.push('/**')
|
|
82
|
+
lines.push(' * Server instructions for Memory Journal MCP.')
|
|
83
|
+
lines.push(' *')
|
|
84
|
+
lines.push(' * ⚠️ AUTO-GENERATED — DO NOT EDIT THIS FILE DIRECTLY')
|
|
85
|
+
lines.push(' * Edit src/constants/server-instructions.md instead,')
|
|
86
|
+
lines.push(' * then run: npm run generate:instructions')
|
|
87
|
+
lines.push(' *')
|
|
88
|
+
lines.push(' * These instructions are automatically sent to MCP clients during initialization,')
|
|
89
|
+
lines.push(' * providing guidance for AI agents on tool usage.')
|
|
90
|
+
lines.push(' *')
|
|
91
|
+
lines.push(' * Optimized for token efficiency with tiered instruction levels.')
|
|
92
|
+
lines.push(' */')
|
|
93
|
+
lines.push('')
|
|
94
|
+
lines.push("import type { ToolGroup } from '../types/index.js'")
|
|
95
|
+
lines.push("import { TOOL_GROUPS } from '../filtering/ToolFilter.js'")
|
|
96
|
+
lines.push('')
|
|
97
|
+
lines.push('/**')
|
|
98
|
+
lines.push(' * Resource definition for instruction generation')
|
|
99
|
+
lines.push(' */')
|
|
100
|
+
lines.push('export interface ResourceDefinition {')
|
|
101
|
+
lines.push(' uri: string')
|
|
102
|
+
lines.push(' name: string')
|
|
103
|
+
lines.push(' description?: string')
|
|
104
|
+
lines.push('}')
|
|
105
|
+
lines.push('')
|
|
106
|
+
lines.push('/**')
|
|
107
|
+
lines.push(' * Prompt definition for instruction generation')
|
|
108
|
+
lines.push(' */')
|
|
109
|
+
lines.push('export interface PromptDefinition {')
|
|
110
|
+
lines.push(' name: string')
|
|
111
|
+
lines.push(' description?: string')
|
|
112
|
+
lines.push('}')
|
|
113
|
+
lines.push('')
|
|
114
|
+
lines.push('/**')
|
|
115
|
+
lines.push(' * Latest entry snapshot for initial briefing')
|
|
116
|
+
lines.push(' */')
|
|
117
|
+
lines.push('export interface LatestEntrySnapshot {')
|
|
118
|
+
lines.push(' id: number')
|
|
119
|
+
lines.push(' timestamp: string')
|
|
120
|
+
lines.push(' entryType: string')
|
|
121
|
+
lines.push(' content: string')
|
|
122
|
+
lines.push('}')
|
|
123
|
+
lines.push('')
|
|
124
|
+
lines.push('/**')
|
|
125
|
+
lines.push(' * Instruction detail level for token efficiency')
|
|
126
|
+
lines.push(' * - essential: ~200 tokens - Core behaviors only (for token-constrained clients)')
|
|
127
|
+
lines.push(' * - standard: ~400 tokens - + GitHub patterns (default)')
|
|
128
|
+
lines.push(' * - full: ~600 tokens - + tool/resource listings')
|
|
129
|
+
lines.push(' */')
|
|
130
|
+
lines.push("export type InstructionLevel = 'essential' | 'standard' | 'full'")
|
|
131
|
+
lines.push('')
|
|
132
|
+
lines.push('/**')
|
|
133
|
+
lines.push(' * Essential behavioral guidance (~200 tokens)')
|
|
134
|
+
lines.push(' * Core patterns every AI agent should follow.')
|
|
135
|
+
lines.push(' */')
|
|
136
|
+
lines.push(
|
|
137
|
+
'const ESSENTIAL_INSTRUCTIONS = `' + escapeForTemplateLiteral(sections.ESSENTIAL) + '\n`'
|
|
138
|
+
)
|
|
139
|
+
lines.push('')
|
|
140
|
+
lines.push('/**')
|
|
141
|
+
lines.push(' * GitHub integration patterns (~150 additional tokens)')
|
|
142
|
+
lines.push(' */')
|
|
143
|
+
lines.push('const GITHUB_INSTRUCTIONS = `\n' + escapeForTemplateLiteral(sections.GITHUB) + '\n`')
|
|
144
|
+
lines.push('')
|
|
145
|
+
lines.push('/**')
|
|
146
|
+
lines.push(' * Server access instructions - critical for AI agents to call tools correctly')
|
|
147
|
+
lines.push(' */')
|
|
148
|
+
lines.push(
|
|
149
|
+
'const SERVER_ACCESS_INSTRUCTIONS = `\n' +
|
|
150
|
+
escapeForTemplateLiteral(sections.SERVER_ACCESS) +
|
|
151
|
+
'\n`'
|
|
152
|
+
)
|
|
153
|
+
lines.push('')
|
|
154
|
+
lines.push('/**')
|
|
155
|
+
lines.push(' * Tool parameter reference - essential for correct tool invocation')
|
|
156
|
+
lines.push(' */')
|
|
157
|
+
lines.push(
|
|
158
|
+
'const TOOL_PARAMETER_REFERENCE = `\n' +
|
|
159
|
+
escapeForTemplateLiteral(sections.TOOL_PARAMETER_REFERENCE) +
|
|
160
|
+
'\n`'
|
|
161
|
+
)
|
|
162
|
+
lines.push('')
|
|
163
|
+
lines.push(FUNCTION_BODY)
|
|
164
|
+
lines.push('')
|
|
165
|
+
|
|
166
|
+
const tsContent = lines.join('\n')
|
|
167
|
+
|
|
168
|
+
writeFileSync(tsPath, tsContent, 'utf-8')
|
|
169
|
+
|
|
170
|
+
process.stderr.write(
|
|
171
|
+
'✅ Generated ServerInstructions.ts (' +
|
|
172
|
+
tsContent.length.toLocaleString() +
|
|
173
|
+
' bytes) from server-instructions.md (' +
|
|
174
|
+
markdown.length.toLocaleString() +
|
|
175
|
+
' bytes)\n'
|
|
176
|
+
)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate dynamic instructions based on enabled tools, resources, prompts, and latest entry
|
|
3
|
+
*
|
|
4
|
+
* @param enabledTools - Set of enabled tool names
|
|
5
|
+
* @param resources - Available resource definitions
|
|
6
|
+
* @param prompts - Available prompt definitions
|
|
7
|
+
* @param latestEntry - Optional latest entry for context snapshot
|
|
8
|
+
* @param level - Instruction detail level (default: 'standard')
|
|
9
|
+
*/
|
|
10
|
+
export function generateInstructions(
|
|
11
|
+
enabledTools: Set<string>,
|
|
12
|
+
_resources: ResourceDefinition[],
|
|
13
|
+
prompts: PromptDefinition[],
|
|
14
|
+
latestEntry?: LatestEntrySnapshot,
|
|
15
|
+
level: InstructionLevel = 'standard'
|
|
16
|
+
): string {
|
|
17
|
+
let instructions = ESSENTIAL_INSTRUCTIONS
|
|
18
|
+
|
|
19
|
+
// Add latest entry snapshot for immediate context (compact format)
|
|
20
|
+
if (latestEntry) {
|
|
21
|
+
const preview = latestEntry.content.slice(0, 120)
|
|
22
|
+
instructions += `\n**Latest**: #${String(latestEntry.id)} (${latestEntry.timestamp}) ${latestEntry.entryType}\n> ${preview}${latestEntry.content.length > 120 ? '...' : ''}\n`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Standard and full levels include GitHub patterns
|
|
26
|
+
if (level === 'standard' || level === 'full') {
|
|
27
|
+
instructions += GITHUB_INSTRUCTIONS
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Full level includes server access instructions and tool parameter reference
|
|
31
|
+
if (level === 'full') {
|
|
32
|
+
instructions += SERVER_ACCESS_INSTRUCTIONS
|
|
33
|
+
instructions += TOOL_PARAMETER_REFERENCE
|
|
34
|
+
|
|
35
|
+
// Add active tools summary
|
|
36
|
+
const activeGroups = getActiveToolGroups(enabledTools)
|
|
37
|
+
if (activeGroups.length > 0) {
|
|
38
|
+
instructions += `\n## Active Tools (${String(enabledTools.size)})\n`
|
|
39
|
+
for (const { group, tools } of activeGroups) {
|
|
40
|
+
instructions += `**${group}**: ${tools.map((t) => `\`${t}\``).join(', ')}\n`
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Add prompts section
|
|
45
|
+
if (prompts.length > 0) {
|
|
46
|
+
instructions += `\n## Prompts (${String(prompts.length)})\n`
|
|
47
|
+
instructions += 'Pre-built templates and guided workflows:\n'
|
|
48
|
+
for (const prompt of prompts) {
|
|
49
|
+
instructions += `- \`${prompt.name}\` - ${prompt.description ?? ''}\n`
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return instructions
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get active tool groups with their enabled tools
|
|
59
|
+
*/
|
|
60
|
+
function getActiveToolGroups(enabledTools: Set<string>): { group: ToolGroup; tools: string[] }[] {
|
|
61
|
+
const activeGroups: { group: ToolGroup; tools: string[] }[] = []
|
|
62
|
+
|
|
63
|
+
for (const [group, allTools] of Object.entries(TOOL_GROUPS) as [ToolGroup, string[]][]) {
|
|
64
|
+
const enabledInGroup = allTools.filter((tool) => enabledTools.has(tool))
|
|
65
|
+
if (enabledInGroup.length > 0) {
|
|
66
|
+
activeGroups.push({ group, tools: enabledInGroup })
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return activeGroups
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Static instructions for backward compatibility
|
|
75
|
+
* @deprecated Use generateInstructions() instead for dynamic content
|
|
76
|
+
*/
|
|
77
|
+
export const SERVER_INSTRUCTIONS = ESSENTIAL_INSTRUCTIONS + GITHUB_INSTRUCTIONS
|
package/server.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"name": "io.github.neverinfamous/memory-journal-mcp",
|
|
4
4
|
"title": "Memory Journal MCP",
|
|
5
5
|
"description": "MCP server– Project memory system with GitHub-aware context, knowledge graphs, and CI/PR timelines",
|
|
6
|
-
"version": "4.
|
|
6
|
+
"version": "4.5.0",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "oci",
|
|
10
|
-
"identifier": "docker.io/writenotenow/memory-journal-mcp:v4.
|
|
11
|
-
"version": "4.
|
|
10
|
+
"identifier": "docker.io/writenotenow/memory-journal-mcp:v4.5.0",
|
|
11
|
+
"version": "4.5.0",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
}
|
package/src/cli.ts
CHANGED
|
@@ -17,12 +17,41 @@ program
|
|
|
17
17
|
.option('--port <number>', 'HTTP port (for http transport)', '3000')
|
|
18
18
|
.option('--server-host <host>', 'Server bind host for HTTP transport (default: localhost)')
|
|
19
19
|
.option('--stateless', 'Use stateless HTTP mode (no session management)')
|
|
20
|
-
.option(
|
|
20
|
+
.option(
|
|
21
|
+
'--db <path>',
|
|
22
|
+
'Database path (env: DB_PATH)',
|
|
23
|
+
process.env['DB_PATH'] ?? './memory_journal.db'
|
|
24
|
+
)
|
|
25
|
+
.option(
|
|
26
|
+
'--team-db <path>',
|
|
27
|
+
'Team database path (env: TEAM_DB_PATH)',
|
|
28
|
+
process.env['TEAM_DB_PATH'] ?? undefined
|
|
29
|
+
)
|
|
21
30
|
.option('--tool-filter <filter>', 'Tool filter string (e.g., "starter", "core,search")')
|
|
22
31
|
.option('--default-project <number>', 'Default GitHub Project number')
|
|
23
32
|
.option('--auto-rebuild-index', 'Rebuild vector index on server startup')
|
|
24
33
|
.option('--cors-origin <origin>', 'CORS allowed origin for HTTP transport (default: *)')
|
|
34
|
+
.option(
|
|
35
|
+
'--auth-token <token>',
|
|
36
|
+
'Bearer token for HTTP transport authentication (env: MCP_AUTH_TOKEN)'
|
|
37
|
+
)
|
|
25
38
|
.option('--log-level <level>', 'Log level: debug, info, warning, error', 'info')
|
|
39
|
+
.option(
|
|
40
|
+
'--backup-interval <minutes>',
|
|
41
|
+
'Automated backup interval in minutes, HTTP only (0 = disabled)',
|
|
42
|
+
'0'
|
|
43
|
+
)
|
|
44
|
+
.option('--keep-backups <count>', 'Max backups to retain during automated cleanup', '5')
|
|
45
|
+
.option(
|
|
46
|
+
'--vacuum-interval <minutes>',
|
|
47
|
+
'Database optimize interval in minutes, HTTP only (0 = disabled)',
|
|
48
|
+
'0'
|
|
49
|
+
)
|
|
50
|
+
.option(
|
|
51
|
+
'--rebuild-index-interval <minutes>',
|
|
52
|
+
'Vector index rebuild interval in minutes, HTTP only (0 = disabled)',
|
|
53
|
+
'0'
|
|
54
|
+
)
|
|
26
55
|
.action(
|
|
27
56
|
async (options: {
|
|
28
57
|
transport: string
|
|
@@ -30,11 +59,17 @@ program
|
|
|
30
59
|
serverHost?: string
|
|
31
60
|
stateless?: boolean
|
|
32
61
|
db: string
|
|
62
|
+
teamDb?: string
|
|
33
63
|
toolFilter?: string
|
|
34
64
|
defaultProject: string
|
|
35
65
|
autoRebuildIndex?: boolean
|
|
36
66
|
corsOrigin?: string
|
|
67
|
+
authToken?: string
|
|
37
68
|
logLevel: string
|
|
69
|
+
backupInterval: string
|
|
70
|
+
keepBackups: string
|
|
71
|
+
vacuumInterval: string
|
|
72
|
+
rebuildIndexInterval: string
|
|
38
73
|
}) => {
|
|
39
74
|
// Set log level
|
|
40
75
|
logger.setLevel(options.logLevel as 'debug' | 'info' | 'warning' | 'error')
|
|
@@ -48,6 +83,7 @@ program
|
|
|
48
83
|
transport: options.transport,
|
|
49
84
|
stateless: options.stateless ?? false,
|
|
50
85
|
db: options.db,
|
|
86
|
+
...(options.teamDb ? { teamDb: options.teamDb } : {}),
|
|
51
87
|
...(host ? { host } : {}),
|
|
52
88
|
})
|
|
53
89
|
|
|
@@ -58,6 +94,7 @@ program
|
|
|
58
94
|
host,
|
|
59
95
|
statelessHttp: options.stateless === true,
|
|
60
96
|
dbPath: options.db,
|
|
97
|
+
teamDbPath: options.teamDb,
|
|
61
98
|
toolFilter: options.toolFilter,
|
|
62
99
|
defaultProjectNumber: options.defaultProject
|
|
63
100
|
? parseInt(options.defaultProject, 10)
|
|
@@ -67,6 +104,13 @@ program
|
|
|
67
104
|
autoRebuildIndex:
|
|
68
105
|
options.autoRebuildIndex ?? process.env['AUTO_REBUILD_INDEX'] === 'true',
|
|
69
106
|
corsOrigin: options.corsOrigin,
|
|
107
|
+
authToken: options.authToken,
|
|
108
|
+
scheduler: {
|
|
109
|
+
backupIntervalMinutes: parseInt(options.backupInterval, 10),
|
|
110
|
+
keepBackups: parseInt(options.keepBackups, 10),
|
|
111
|
+
vacuumIntervalMinutes: parseInt(options.vacuumInterval, 10),
|
|
112
|
+
rebuildIndexIntervalMinutes: parseInt(options.rebuildIndexInterval, 10),
|
|
113
|
+
},
|
|
70
114
|
})
|
|
71
115
|
} catch (error) {
|
|
72
116
|
logger.error('Failed to start server', {
|