@ekkos/mcp-server 2.0.3 → 2.0.4

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.
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Offline Write Queue for ekkOS MCP Server
3
+ *
4
+ * When the cloud gateway is unreachable, queues write operations
5
+ * (Forge, Track, Outcome, Directive) to a local JSONL file.
6
+ * Flushes the queue when connectivity is restored.
7
+ */
8
+ import { appendFileSync, readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { homedir } from 'os';
11
+ const CACHE_DIR = join(homedir(), '.ekkos', 'cache');
12
+ const QUEUE_FILE = join(CACHE_DIR, 'pending-writes.jsonl');
13
+ // Tools that perform writes and should be queued when offline
14
+ const WRITE_TOOLS = new Set([
15
+ 'ekkOS_Forge',
16
+ 'ekkOS_Track',
17
+ 'ekkOS_Outcome',
18
+ 'ekkOS_Directive',
19
+ 'ekkOS_UpdateDirective',
20
+ 'ekkOS_DeleteDirective',
21
+ 'ekkOS_Capture',
22
+ 'ekkOS_StoreSecret',
23
+ 'ekkOS_RotateSecret',
24
+ 'ekkOS_DeleteSecret',
25
+ ]);
26
+ /**
27
+ * Check if a tool is a write operation that can be queued
28
+ */
29
+ export function isWriteTool(toolName) {
30
+ return WRITE_TOOLS.has(toolName);
31
+ }
32
+ /**
33
+ * Queue a write operation for later execution
34
+ */
35
+ export function queueWrite(toolName, args) {
36
+ try {
37
+ if (!existsSync(CACHE_DIR)) {
38
+ mkdirSync(CACHE_DIR, { recursive: true });
39
+ }
40
+ const entry = {
41
+ timestamp: new Date().toISOString(),
42
+ toolName,
43
+ arguments: args,
44
+ };
45
+ appendFileSync(QUEUE_FILE, JSON.stringify(entry) + '\n');
46
+ console.error(`[ekkOS:offline] Queued ${toolName} for later sync`);
47
+ }
48
+ catch (err) {
49
+ console.error('[ekkOS:offline] Failed to queue write:', err);
50
+ }
51
+ }
52
+ /**
53
+ * Flush all pending writes to the cloud gateway
54
+ * Returns the number of successfully flushed writes
55
+ */
56
+ export async function flushQueue(callGateway) {
57
+ if (!existsSync(QUEUE_FILE))
58
+ return 0;
59
+ let lines;
60
+ try {
61
+ const raw = readFileSync(QUEUE_FILE, 'utf-8').trim();
62
+ if (!raw)
63
+ return 0;
64
+ lines = raw.split('\n');
65
+ }
66
+ catch {
67
+ return 0;
68
+ }
69
+ let flushed = 0;
70
+ const failed = [];
71
+ for (const line of lines) {
72
+ try {
73
+ const entry = JSON.parse(line);
74
+ await callGateway('tools/call', 'tools/call', {
75
+ name: entry.toolName,
76
+ arguments: entry.arguments,
77
+ });
78
+ flushed++;
79
+ }
80
+ catch {
81
+ // Keep failed writes for next flush attempt
82
+ failed.push(line);
83
+ }
84
+ }
85
+ // Rewrite queue with only failed writes
86
+ try {
87
+ if (failed.length > 0) {
88
+ writeFileSync(QUEUE_FILE, failed.join('\n') + '\n');
89
+ }
90
+ else {
91
+ writeFileSync(QUEUE_FILE, '');
92
+ }
93
+ }
94
+ catch {
95
+ // Best effort cleanup
96
+ }
97
+ if (flushed > 0) {
98
+ console.error(`[ekkOS:offline] Flushed ${flushed} queued writes (${failed.length} remaining)`);
99
+ }
100
+ return flushed;
101
+ }
102
+ /**
103
+ * Get count of pending writes
104
+ */
105
+ export function getPendingCount() {
106
+ try {
107
+ if (!existsSync(QUEUE_FILE))
108
+ return 0;
109
+ const raw = readFileSync(QUEUE_FILE, 'utf-8').trim();
110
+ if (!raw)
111
+ return 0;
112
+ return raw.split('\n').length;
113
+ }
114
+ catch {
115
+ return 0;
116
+ }
117
+ }
118
+ //# sourceMappingURL=offline-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-queue.js","sourceRoot":"","sources":["../src/offline-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ ---
2
+ system_id: packages-ekkos-mcp-server
3
+ domain: packages
4
+ status: active
5
+ last_compiled_at: 2026-03-17T00:54:14.311-04:00
6
+ compiled_timezone: America/Toronto
7
+ activity_status: active
8
+ days_since_last_change: 15
9
+ content_hash: dd7d874972bb04417852038485edca703142b4cb1c8e477abd26d7a8aa69f788
10
+ invalidation_fingerprint: 60d856ec21bd71e6ac9cc693cdbdea5717a152588e2fc22b153f6cad9f6a0f1b
11
+ recompile_reason: "1 local file change"
12
+ source_event_ids: []
13
+ source_event_count: 1
14
+ evidence_window_start: 2026-03-17T00:54:11.658-04:00
15
+ evidence_window_end: 2026-03-17T00:54:11.658-04:00
16
+ confidence: medium
17
+ redactions: 0
18
+ compiled_by: ekkOS Local Compiler
19
+ compiler_model: local-mechanical-v1
20
+ compiler_template_version: local-mechanical-v4
21
+ ---
22
+
23
+ <!-- EKKOS_AUTOGENERATED_START dd7d874972bb04417852038485edca703142b4cb1c8e477abd26d7a8aa69f788 -->
24
+
25
+ # packages/ekkos-mcp-server
26
+
27
+ Stdio-to-SSE bridge for [ekkOS](https://ekkos.dev) Memory substrate. Enables AI tools like Claude Code and Cursor to access your persistent memory via the Model Context Protocol (MCP).
28
+
29
+ ## Architecture
30
+ - **Runtime**: JSON, TS, MD
31
+ - **Entry points**: `index.ts`
32
+ - **Key dependencies**: `@modelcontextprotocol/sdk`, `@sentry/node`, `@types/better-sqlite3`, `@types/node`, `typescript`
33
+ - **Size**: 7 files across 1 directories (json (3), ts (3), md (1))
34
+
35
+ ## Key Modules
36
+ - `src/` — 3 .ts files
37
+
38
+ ## Environment Variables
39
+ - `EKKOS_API_KEY`
40
+ - `EKKOS_DEBUG`
41
+ - `EKKOS_MCP_URL`
42
+ - `EKKOS_USER_ID`
43
+ - `NODE_ENV`
44
+ - `SENTRY_DSN`
45
+
46
+ ## Change Log
47
+ - **Mar 1**: feat(synk): rebrand Happy Coder fork → ekkOS Synk — files: package-lock.json, package.json, index.ts, local-cache.ts, offline-queue.ts +12 more | - Rename packages: happy-wire → @ekkos/wire, happy-cli → @ekkos/remote, happy-agent → @ekkos/agent, happy-server → @ekko
48
+
49
+ ## Active Work
50
+ These 1 file(s) changed since last compile:
51
+
52
+ - `ekkos-mcp-server/package.json`
53
+
54
+ ## System Info
55
+ - **Path**: `packages/ekkos-mcp-server` · **ID**: `packages-ekkos-mcp-server` · **Domain**: `packages`
56
+ - **Status**: active (15d since last commit) · **Compiled**: Today, 12:54 AM
57
+ - **Trigger**: 1 local file change
58
+
59
+ <!-- EKKOS_AUTOGENERATED_END -->
60
+
61
+ ---
62
+ *Generated directly from the local workspace to keep CLI context aligned with on-disk code.*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ekkos/mcp-server",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "description": "ekkOS Memory MCP Server - stdio bridge to cloud memory substrate",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,7 +32,11 @@
32
32
  "@modelcontextprotocol/sdk": "^1.0.4",
33
33
  "@sentry/node": "^10.31.0"
34
34
  },
35
+ "optionalDependencies": {
36
+ "better-sqlite3": "^9.4.3"
37
+ },
35
38
  "devDependencies": {
39
+ "@types/better-sqlite3": "^7.6.8",
36
40
  "@types/node": "^20.11.5",
37
41
  "typescript": "^5.3.3"
38
42
  },