@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.
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +432 -32
- package/dist/index.js.map +1 -1
- package/dist/local-cache.d.ts +90 -0
- package/dist/local-cache.d.ts.map +1 -0
- package/dist/local-cache.js +525 -0
- package/dist/local-cache.js.map +1 -0
- package/dist/offline-queue.d.ts +25 -0
- package/dist/offline-queue.d.ts.map +1 -0
- package/dist/offline-queue.js +118 -0
- package/dist/offline-queue.js.map +1 -0
- package/ekkOS_CONTEXT.md +62 -0
- package/package.json +5 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @ekkos/mcp-server
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Local-first MCP server for ekkOS cloud memory.
|
|
6
|
+
* - Caches patterns + directives locally for <5ms search
|
|
7
|
+
* - Falls back to cloud gateway for full results
|
|
8
|
+
* - Queues writes when offline, flushes on reconnect
|
|
9
|
+
* - Auto-discovers API key from ~/.ekkos/config.json
|
|
7
10
|
*/
|
|
8
11
|
export {};
|
|
9
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG"}
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @ekkos/mcp-server
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Local-first MCP server for ekkOS cloud memory.
|
|
6
|
+
* - Caches patterns + directives locally for <5ms search
|
|
7
|
+
* - Falls back to cloud gateway for full results
|
|
8
|
+
* - Queues writes when offline, flushes on reconnect
|
|
9
|
+
* - Auto-discovers API key from ~/.ekkos/config.json
|
|
7
10
|
*/
|
|
8
11
|
// Sentry must be imported and initialized before other imports
|
|
9
12
|
import * as Sentry from '@sentry/node';
|
|
@@ -19,18 +22,173 @@ if (process.env.SENTRY_DSN) {
|
|
|
19
22
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
20
23
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
21
24
|
import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
import { readFileSync, existsSync, writeFileSync, mkdirSync } from 'fs';
|
|
26
|
+
import { join } from 'path';
|
|
27
|
+
import { homedir } from 'os';
|
|
28
|
+
import { loadCacheFromDisk, warmCache, searchLocal, getDirectives, invalidateCache, isCacheStale, startPeriodicRefresh, getCacheStats, } from './local-cache.js';
|
|
29
|
+
import { isWriteTool, queueWrite, flushQueue, getPendingCount, } from './offline-queue.js';
|
|
30
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
31
|
+
// CONFIGURATION — resolve API key from env, then ~/.ekkos/config.json
|
|
32
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
33
|
+
function resolveApiKey() {
|
|
34
|
+
// Priority 1: Environment variable
|
|
35
|
+
if (process.env.EKKOS_API_KEY) {
|
|
36
|
+
return process.env.EKKOS_API_KEY;
|
|
37
|
+
}
|
|
38
|
+
// Priority 2: ~/.ekkos/config.json (from prior `ekkos init`)
|
|
39
|
+
try {
|
|
40
|
+
const configPath = join(homedir(), '.ekkos', 'config.json');
|
|
41
|
+
if (existsSync(configPath)) {
|
|
42
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
43
|
+
if (config.apiKey) {
|
|
44
|
+
console.error('[ekkOS] Using API key from ~/.ekkos/config.json');
|
|
45
|
+
return config.apiKey;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Config unreadable — fall through to degraded mode
|
|
51
|
+
}
|
|
52
|
+
// No key found — caller will enable degraded mode
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
const EKKOS_API_KEY = resolveApiKey();
|
|
56
|
+
/**
|
|
57
|
+
* Degraded mode: no API key available.
|
|
58
|
+
* Search returns local cache only. Writes are queued to offline queue.
|
|
59
|
+
* All tools still register normally so Claude sees no missing tools.
|
|
60
|
+
*/
|
|
61
|
+
const degradedMode = EKKOS_API_KEY === null;
|
|
24
62
|
const EKKOS_USER_ID = process.env.EKKOS_USER_ID || '';
|
|
25
63
|
const EKKOS_MCP_URL = process.env.EKKOS_MCP_URL || 'https://mcp.ekkos.dev/api/v1/mcp';
|
|
26
64
|
const DEBUG = process.env.EKKOS_DEBUG === 'true';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
65
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
66
|
+
// SESSION METRICS — written to ~/.ekkos/session-metrics.json after each tool call
|
|
67
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
68
|
+
const METRICS_DIR = join(homedir(), '.ekkos');
|
|
69
|
+
const METRICS_FILE = join(METRICS_DIR, 'session-metrics.json');
|
|
70
|
+
// In-process counters — reset each MCP server process lifetime (= one Claude session)
|
|
71
|
+
const sessionMetrics = {
|
|
72
|
+
session_id: `mcp-${Date.now()}`,
|
|
73
|
+
session_name: '',
|
|
74
|
+
turn: 0,
|
|
75
|
+
started_at: new Date().toISOString(),
|
|
76
|
+
updated_at: new Date().toISOString(),
|
|
77
|
+
tool_calls: 0,
|
|
78
|
+
patterns_recalled: 0,
|
|
79
|
+
patterns_forged: 0,
|
|
80
|
+
directives_active: 0,
|
|
81
|
+
cache_backend: 'json',
|
|
82
|
+
cache_patterns: 0,
|
|
83
|
+
tokens_in: 0,
|
|
84
|
+
tokens_out: 0,
|
|
85
|
+
};
|
|
86
|
+
/** Fire-and-forget write of metrics to disk. Never throws. */
|
|
87
|
+
function writeMetrics() {
|
|
88
|
+
try {
|
|
89
|
+
mkdirSync(METRICS_DIR, { recursive: true });
|
|
90
|
+
const stats = getCacheStats();
|
|
91
|
+
sessionMetrics.updated_at = new Date().toISOString();
|
|
92
|
+
sessionMetrics.cache_backend = stats.backend;
|
|
93
|
+
sessionMetrics.cache_patterns = stats.patterns;
|
|
94
|
+
sessionMetrics.directives_active = stats.directives;
|
|
95
|
+
writeFileSync(METRICS_FILE, JSON.stringify(sessionMetrics, null, 2), 'utf-8');
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// best-effort — never block the tool response
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
102
|
+
// CIRCUIT BREAKER — fast-fail when cloud is unreachable
|
|
103
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
104
|
+
let circuitFailures = 0;
|
|
105
|
+
let circuitOpenUntil = 0;
|
|
106
|
+
const CIRCUIT_THRESHOLD = 3; // failures before opening
|
|
107
|
+
const CIRCUIT_RESET_MS = 60_000; // 60s before half-open retry
|
|
108
|
+
const GATEWAY_TIMEOUT_MS = 8_000; // 8s request timeout
|
|
109
|
+
function isCircuitOpen() {
|
|
110
|
+
if (circuitFailures < CIRCUIT_THRESHOLD)
|
|
111
|
+
return false;
|
|
112
|
+
if (Date.now() > circuitOpenUntil) {
|
|
113
|
+
// Half-open: allow one request through
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
function recordSuccess() {
|
|
119
|
+
circuitFailures = 0;
|
|
120
|
+
circuitOpenUntil = 0;
|
|
31
121
|
}
|
|
32
|
-
|
|
122
|
+
function recordFailure() {
|
|
123
|
+
circuitFailures++;
|
|
124
|
+
if (circuitFailures >= CIRCUIT_THRESHOLD) {
|
|
125
|
+
circuitOpenUntil = Date.now() + CIRCUIT_RESET_MS;
|
|
126
|
+
console.error(`[ekkOS:circuit] OPEN — ${circuitFailures} failures, retrying in ${CIRCUIT_RESET_MS / 1000}s`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
130
|
+
// RESULT SLIMMING — strip verbose _ekkos_* metadata from gateway responses
|
|
131
|
+
// These fields (_ekkos_stream_message, _ekkos_context, _ekkos_pattern_contract,
|
|
132
|
+
// _ekkos_acknowledgment_*) are designed for Cursor's sidebar UI. When returned
|
|
133
|
+
// via MCP stdio to CLI clients (Gemini, Claude Code) the model sees them as
|
|
134
|
+
// raw tool output and parrots them back, producing noisy verbose responses.
|
|
135
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
136
|
+
const VERBOSE_EKKOS_KEYS = new Set([
|
|
137
|
+
'_ekkos_stream_message',
|
|
138
|
+
'_ekkos_context',
|
|
139
|
+
'_ekkos_pattern_contract',
|
|
140
|
+
'_ekkos_acknowledgment_required',
|
|
141
|
+
'_ekkos_acknowledgment_instruction',
|
|
142
|
+
'_ekkos_enforcement',
|
|
143
|
+
'_ekkos_session_summary',
|
|
144
|
+
]);
|
|
145
|
+
/**
|
|
146
|
+
* Strip verbose _ekkos_* fields from a gateway result.
|
|
147
|
+
* Keeps compact fields like _ekkos_patterns and _ekkos_auto_retrieved.
|
|
148
|
+
*/
|
|
149
|
+
function slimGatewayResult(data) {
|
|
150
|
+
if (!data || typeof data !== 'object')
|
|
151
|
+
return data;
|
|
152
|
+
// If result has content[].text with JSON, parse → strip → re-serialize
|
|
153
|
+
if (data.result && typeof data.result === 'object') {
|
|
154
|
+
for (const key of VERBOSE_EKKOS_KEYS) {
|
|
155
|
+
delete data.result[key];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Also strip from top-level content array (MCP format)
|
|
159
|
+
if (data.content && Array.isArray(data.content)) {
|
|
160
|
+
for (const part of data.content) {
|
|
161
|
+
if (part.type === 'text' && typeof part.text === 'string') {
|
|
162
|
+
try {
|
|
163
|
+
const parsed = JSON.parse(part.text);
|
|
164
|
+
if (parsed && typeof parsed === 'object') {
|
|
165
|
+
let changed = false;
|
|
166
|
+
for (const key of VERBOSE_EKKOS_KEYS) {
|
|
167
|
+
if (key in parsed) {
|
|
168
|
+
delete parsed[key];
|
|
169
|
+
changed = true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (changed) {
|
|
173
|
+
part.text = JSON.stringify(parsed);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Not JSON — leave as-is
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return data;
|
|
184
|
+
}
|
|
185
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
186
|
+
// GATEWAY CLIENT — HTTP calls to cloud MCP gateway
|
|
187
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
33
188
|
async function callGateway(endpoint, method, params) {
|
|
189
|
+
if (degradedMode) {
|
|
190
|
+
throw new Error('ekkOS running in cache-only mode — no API key');
|
|
191
|
+
}
|
|
34
192
|
const url = `${EKKOS_MCP_URL}/${endpoint}`;
|
|
35
193
|
const headers = {
|
|
36
194
|
'Content-Type': 'application/json',
|
|
@@ -42,24 +200,155 @@ async function callGateway(endpoint, method, params) {
|
|
|
42
200
|
if (DEBUG) {
|
|
43
201
|
console.error(`[ekkOS] → ${method} ${endpoint}`);
|
|
44
202
|
}
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
203
|
+
const controller = new AbortController();
|
|
204
|
+
const timeout = setTimeout(() => controller.abort(), GATEWAY_TIMEOUT_MS);
|
|
205
|
+
try {
|
|
206
|
+
const response = await fetch(url, {
|
|
207
|
+
method: 'POST',
|
|
208
|
+
headers,
|
|
209
|
+
body: JSON.stringify({ method, params: params || {} }),
|
|
210
|
+
signal: controller.signal,
|
|
211
|
+
});
|
|
212
|
+
if (!response.ok) {
|
|
213
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
214
|
+
}
|
|
215
|
+
const data = await response.json();
|
|
216
|
+
if (DEBUG) {
|
|
217
|
+
console.error(`[ekkOS] ← ${method} OK`);
|
|
218
|
+
}
|
|
219
|
+
recordSuccess();
|
|
220
|
+
return slimGatewayResult(data);
|
|
52
221
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
222
|
+
catch (err) {
|
|
223
|
+
recordFailure();
|
|
224
|
+
throw err;
|
|
225
|
+
}
|
|
226
|
+
finally {
|
|
227
|
+
clearTimeout(timeout);
|
|
56
228
|
}
|
|
57
|
-
return data;
|
|
58
229
|
}
|
|
59
|
-
|
|
230
|
+
/**
|
|
231
|
+
* Call gateway with offline fallback.
|
|
232
|
+
* For write tools: queues when offline.
|
|
233
|
+
* For read tools: returns null when offline (caller handles fallback).
|
|
234
|
+
*/
|
|
235
|
+
async function callGatewayWithFallback(endpoint, method, params, toolName) {
|
|
236
|
+
// If circuit is open, don't even try
|
|
237
|
+
if (isCircuitOpen()) {
|
|
238
|
+
if (toolName && isWriteTool(toolName)) {
|
|
239
|
+
queueWrite(toolName, params?.arguments || {});
|
|
240
|
+
return {
|
|
241
|
+
content: [{ type: 'text', text: JSON.stringify({ _offline: true, _queued: true, message: 'Queued for sync when connection restores' }) }],
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return null; // Caller handles fallback
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
const result = await callGateway(endpoint, method, params);
|
|
248
|
+
// Connectivity restored — flush any pending writes in background
|
|
249
|
+
const pendingCount = getPendingCount();
|
|
250
|
+
if (pendingCount > 0) {
|
|
251
|
+
flushQueue(callGateway).catch(() => { });
|
|
252
|
+
}
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
if (toolName && isWriteTool(toolName)) {
|
|
257
|
+
queueWrite(toolName, params?.arguments || {});
|
|
258
|
+
return {
|
|
259
|
+
content: [{ type: 'text', text: JSON.stringify({ _offline: true, _queued: true, message: 'Queued for sync when connection restores' }) }],
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
return null; // Caller handles fallback
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
266
|
+
// LOCAL-FIRST SEARCH — check cache before cloud
|
|
267
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
268
|
+
/**
|
|
269
|
+
* Handle ekkOS_Search with local-first strategy:
|
|
270
|
+
* 1. Search local cache (<5ms)
|
|
271
|
+
* 2. If cache has results, return them immediately
|
|
272
|
+
* 3. Background: also query cloud for freshness
|
|
273
|
+
* 4. If cache miss or stale, fall through to cloud
|
|
274
|
+
*/
|
|
275
|
+
async function handleSearchLocally(args) {
|
|
276
|
+
const query = args.query || '';
|
|
277
|
+
const limit = args.limit || 5;
|
|
278
|
+
const start = Date.now();
|
|
279
|
+
// Try local cache first
|
|
280
|
+
const localPatterns = searchLocal(query, limit);
|
|
281
|
+
const localDirectives = getDirectives();
|
|
282
|
+
const localLatency = Date.now() - start;
|
|
283
|
+
if (localPatterns.length > 0 || localDirectives.length > 0) {
|
|
284
|
+
// Build a response that matches the cloud format
|
|
285
|
+
const localResult = {
|
|
286
|
+
content: [{
|
|
287
|
+
type: 'text',
|
|
288
|
+
text: JSON.stringify({
|
|
289
|
+
patterns: localPatterns.map(p => ({
|
|
290
|
+
id: p.id,
|
|
291
|
+
title: p.title,
|
|
292
|
+
similarity: 0.75, // Approximate — local search doesn't compute embeddings
|
|
293
|
+
success_rate: p.success_rate,
|
|
294
|
+
applied_count: p.applied_count,
|
|
295
|
+
tags: p.tags?.slice(0, 3),
|
|
296
|
+
})),
|
|
297
|
+
directives: localDirectives,
|
|
298
|
+
total: localPatterns.length + localDirectives.length,
|
|
299
|
+
_cache: 'local',
|
|
300
|
+
_cache_latency_ms: localLatency,
|
|
301
|
+
}),
|
|
302
|
+
}],
|
|
303
|
+
_ekkos_status: `[ekkOS_RETRIEVE] ⚡ Local: ${localPatterns.length} patterns, ${localDirectives.length} directives (${localLatency}ms)`,
|
|
304
|
+
};
|
|
305
|
+
// If cache is stale, trigger background refresh (don't block)
|
|
306
|
+
if (isCacheStale()) {
|
|
307
|
+
warmCache(callGateway, EKKOS_USER_ID).catch(() => { });
|
|
308
|
+
}
|
|
309
|
+
// Also query cloud in background to update cache (don't await)
|
|
310
|
+
callGatewayWithFallback('tools/call', 'tools/call', {
|
|
311
|
+
name: 'ekkOS_Search',
|
|
312
|
+
arguments: args,
|
|
313
|
+
}).then(cloudResult => {
|
|
314
|
+
if (cloudResult) {
|
|
315
|
+
// Update cache with fresh cloud results
|
|
316
|
+
warmCache(callGateway, EKKOS_USER_ID).catch(() => { });
|
|
317
|
+
}
|
|
318
|
+
}).catch(() => { });
|
|
319
|
+
return localResult;
|
|
320
|
+
}
|
|
321
|
+
// No local results — fall through to cloud
|
|
322
|
+
const cloudResult = await callGatewayWithFallback('tools/call', 'tools/call', {
|
|
323
|
+
name: 'ekkOS_Search',
|
|
324
|
+
arguments: args,
|
|
325
|
+
}, 'ekkOS_Search');
|
|
326
|
+
if (cloudResult) {
|
|
327
|
+
// Trigger cache update with fresh data
|
|
328
|
+
warmCache(callGateway, EKKOS_USER_ID).catch(() => { });
|
|
329
|
+
return cloudResult;
|
|
330
|
+
}
|
|
331
|
+
// Both local and cloud failed
|
|
332
|
+
return {
|
|
333
|
+
content: [{
|
|
334
|
+
type: 'text',
|
|
335
|
+
text: JSON.stringify({
|
|
336
|
+
patterns: [],
|
|
337
|
+
directives: [],
|
|
338
|
+
total: 0,
|
|
339
|
+
_cache: 'miss',
|
|
340
|
+
_offline: true,
|
|
341
|
+
message: 'No cached patterns and cloud unreachable',
|
|
342
|
+
}),
|
|
343
|
+
}],
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
347
|
+
// MCP SERVER
|
|
348
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
60
349
|
const server = new Server({
|
|
61
350
|
name: 'ekkos-memory',
|
|
62
|
-
version: '1.
|
|
351
|
+
version: '1.1.0',
|
|
63
352
|
}, {
|
|
64
353
|
capabilities: {
|
|
65
354
|
tools: {},
|
|
@@ -67,26 +356,107 @@ const server = new Server({
|
|
|
67
356
|
prompts: {},
|
|
68
357
|
},
|
|
69
358
|
});
|
|
70
|
-
//
|
|
359
|
+
// Cache-invalidating tools — after these succeed, refresh local cache
|
|
360
|
+
const CACHE_INVALIDATING_TOOLS = new Set([
|
|
361
|
+
'ekkOS_Forge',
|
|
362
|
+
'ekkOS_Directive',
|
|
363
|
+
'ekkOS_UpdateDirective',
|
|
364
|
+
'ekkOS_DeleteDirective',
|
|
365
|
+
]);
|
|
366
|
+
// List tools - proxy to gateway (or return cached list in degraded mode)
|
|
71
367
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
368
|
+
if (degradedMode) {
|
|
369
|
+
// In cache-only mode we have no cloud connection to fetch the full tool
|
|
370
|
+
// definition list. Return a minimal stub so Claude can still call tools
|
|
371
|
+
// (handlers below respond gracefully); the real list is fetched once the
|
|
372
|
+
// user runs `ekkos init` and restarts the server.
|
|
373
|
+
return { tools: [] };
|
|
374
|
+
}
|
|
72
375
|
const result = await callGateway('tools/list', 'tools/list');
|
|
73
376
|
return result;
|
|
74
377
|
});
|
|
75
|
-
// Call tool -
|
|
378
|
+
// Call tool - local-first for search, gateway for everything else
|
|
76
379
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
380
|
+
const toolName = request.params.name;
|
|
381
|
+
const toolArgs = request.params.arguments || {};
|
|
382
|
+
// ── Increment global tool-call counter ──────────────────────────────────
|
|
383
|
+
sessionMetrics.tool_calls++;
|
|
384
|
+
// Extract session_name from ekkOS_Search / ekkOS_Forge args if present
|
|
385
|
+
const argsAny = toolArgs;
|
|
386
|
+
if (argsAny.session_name && typeof argsAny.session_name === 'string' && !sessionMetrics.session_name) {
|
|
387
|
+
sessionMetrics.session_name = argsAny.session_name;
|
|
388
|
+
}
|
|
389
|
+
// LOCAL-FIRST: ekkOS_Search uses local cache
|
|
390
|
+
if (toolName === 'ekkOS_Search') {
|
|
391
|
+
const result = await handleSearchLocally(argsAny);
|
|
392
|
+
// Count patterns returned as "recalled" — parse result text if available
|
|
393
|
+
try {
|
|
394
|
+
const text = result?.content?.[0]?.text;
|
|
395
|
+
if (text) {
|
|
396
|
+
const parsed = JSON.parse(text);
|
|
397
|
+
sessionMetrics.patterns_recalled += (parsed.patterns?.length ?? 0);
|
|
398
|
+
// Infer turn from total search calls (each search ≈ one turn)
|
|
399
|
+
sessionMetrics.turn = sessionMetrics.patterns_recalled > 0
|
|
400
|
+
? Math.max(sessionMetrics.turn, Math.ceil(sessionMetrics.tool_calls / 2))
|
|
401
|
+
: sessionMetrics.turn;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
catch { /* ignore parse errors */ }
|
|
405
|
+
writeMetrics();
|
|
406
|
+
return result;
|
|
407
|
+
}
|
|
408
|
+
// WRITE TOOLS: use fallback with offline queue
|
|
409
|
+
if (isWriteTool(toolName)) {
|
|
410
|
+
const result = await callGatewayWithFallback('tools/call', 'tools/call', {
|
|
411
|
+
name: toolName,
|
|
412
|
+
arguments: toolArgs,
|
|
413
|
+
}, toolName);
|
|
414
|
+
// Invalidate cache after successful writes
|
|
415
|
+
if (result && CACHE_INVALIDATING_TOOLS.has(toolName)) {
|
|
416
|
+
invalidateCache();
|
|
417
|
+
warmCache(callGateway, EKKOS_USER_ID).catch(() => { });
|
|
418
|
+
}
|
|
419
|
+
// Track forged patterns
|
|
420
|
+
if (toolName === 'ekkOS_Forge' && result && !result.content?.[0]?.text?.includes('_offline')) {
|
|
421
|
+
sessionMetrics.patterns_forged++;
|
|
422
|
+
}
|
|
423
|
+
writeMetrics();
|
|
424
|
+
return result || {
|
|
425
|
+
content: [{ type: 'text', text: JSON.stringify({ _offline: true, _queued: true }) }],
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
// ALL OTHER TOOLS: proxy to cloud with graceful fallback
|
|
429
|
+
const result = await callGatewayWithFallback('tools/call', 'tools/call', {
|
|
430
|
+
name: toolName,
|
|
431
|
+
arguments: toolArgs,
|
|
432
|
+
}, toolName);
|
|
433
|
+
writeMetrics();
|
|
434
|
+
if (result)
|
|
435
|
+
return result;
|
|
436
|
+
// Offline fallback for read tools
|
|
437
|
+
return {
|
|
438
|
+
content: [{
|
|
439
|
+
type: 'text',
|
|
440
|
+
text: JSON.stringify({
|
|
441
|
+
_offline: true,
|
|
442
|
+
message: `Cloud unreachable — ${toolName} requires connectivity`,
|
|
443
|
+
cache_stats: getCacheStats(),
|
|
444
|
+
}),
|
|
445
|
+
}],
|
|
446
|
+
};
|
|
82
447
|
});
|
|
83
448
|
// List resources - proxy to gateway
|
|
84
449
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
450
|
+
if (degradedMode)
|
|
451
|
+
return { resources: [] };
|
|
85
452
|
const result = await callGateway('resources/list', 'resources/list');
|
|
86
453
|
return result;
|
|
87
454
|
});
|
|
88
455
|
// Read resource - proxy to gateway
|
|
89
456
|
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
457
|
+
if (degradedMode) {
|
|
458
|
+
return { contents: [{ uri: request.params.uri, text: 'ekkOS running in cache-only mode. Run `ekkos init` to connect.' }] };
|
|
459
|
+
}
|
|
90
460
|
const result = await callGateway('resources/read', 'resources/read', {
|
|
91
461
|
uri: request.params.uri,
|
|
92
462
|
});
|
|
@@ -94,11 +464,16 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
94
464
|
});
|
|
95
465
|
// List prompts - proxy to gateway
|
|
96
466
|
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
467
|
+
if (degradedMode)
|
|
468
|
+
return { prompts: [] };
|
|
97
469
|
const result = await callGateway('prompts/list', 'prompts/list');
|
|
98
470
|
return result;
|
|
99
471
|
});
|
|
100
472
|
// Get prompt - proxy to gateway
|
|
101
473
|
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
474
|
+
if (degradedMode) {
|
|
475
|
+
return { description: 'ekkOS cache-only mode', messages: [] };
|
|
476
|
+
}
|
|
102
477
|
const result = await callGateway('prompts/get', 'prompts/get', {
|
|
103
478
|
name: request.params.name,
|
|
104
479
|
arguments: request.params.arguments,
|
|
@@ -117,17 +492,42 @@ process.on('SIGINT', async () => {
|
|
|
117
492
|
await server.close();
|
|
118
493
|
process.exit(0);
|
|
119
494
|
});
|
|
120
|
-
//
|
|
495
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
496
|
+
// STARTUP
|
|
497
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
121
498
|
async function main() {
|
|
499
|
+
// Step 1: Load cache from disk (instant, <1ms)
|
|
500
|
+
const diskCache = loadCacheFromDisk();
|
|
501
|
+
if (diskCache.patterns > 0 || diskCache.directives > 0) {
|
|
502
|
+
console.error(`[ekkOS] Cache loaded: ${diskCache.patterns} patterns, ${diskCache.directives} directives`);
|
|
503
|
+
}
|
|
504
|
+
// Degraded mode: no API key — run cache-only, skip all cloud steps
|
|
505
|
+
if (degradedMode) {
|
|
506
|
+
console.error('[ekkOS] WARNING: ekkOS running in cache-only mode. Run `ekkos init` to connect.');
|
|
507
|
+
const transport = new StdioServerTransport();
|
|
508
|
+
await server.connect(transport);
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
// Step 2: Flush any pending offline writes (background)
|
|
512
|
+
const pendingCount = getPendingCount();
|
|
513
|
+
if (pendingCount > 0) {
|
|
514
|
+
console.error(`[ekkOS] Flushing ${pendingCount} pending offline writes...`);
|
|
515
|
+
flushQueue(callGateway).catch(() => { });
|
|
516
|
+
}
|
|
517
|
+
// Step 3: Start MCP transport
|
|
122
518
|
if (DEBUG) {
|
|
123
|
-
console.error('[ekkOS] Starting
|
|
519
|
+
console.error('[ekkOS] Starting ekkOS Memory MCP Server...');
|
|
124
520
|
console.error(`[ekkOS] Gateway: ${EKKOS_MCP_URL}`);
|
|
125
521
|
console.error(`[ekkOS] User ID: ${EKKOS_USER_ID || '(not set)'}`);
|
|
126
522
|
}
|
|
127
523
|
const transport = new StdioServerTransport();
|
|
128
524
|
await server.connect(transport);
|
|
525
|
+
// Step 4: Warm cache from cloud (non-blocking background task)
|
|
526
|
+
warmCache(callGateway, EKKOS_USER_ID).catch(() => { });
|
|
527
|
+
// Step 5: Start periodic cache refresh (every 5 min)
|
|
528
|
+
startPeriodicRefresh(callGateway, EKKOS_USER_ID);
|
|
129
529
|
if (DEBUG) {
|
|
130
|
-
console.error('[ekkOS] ✓ Ready!
|
|
530
|
+
console.error('[ekkOS] ✓ Ready! Local-first memory with cloud sync.');
|
|
131
531
|
}
|
|
132
532
|
}
|
|
133
533
|
main().catch((error) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,+DAA+D;AAC/D,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAEvC,wDAAwD;AACxD,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;IAC3B,MAAM,CAAC,IAAI,CAAC;QACV,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;QAC3B,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,YAAY;QACjD,gBAAgB,EAAE,GAAG;QACrB,cAAc,EAAE,IAAI;KACrB,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC1B,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,oCAAoC,CAAC;AAE5C,gBAAgB;AAChB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC;AACtD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC;AACtD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,kCAAkC,CAAC;AACtF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,MAAM,CAAC;AAEjD,IAAI,CAAC,aAAa,EAAE,CAAC;IACnB,OAAO,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;IAC/E,OAAO,CAAC,KAAK,CAAC,oFAAoF,CAAC,CAAC;IACpG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,qCAAqC;AACrC,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,MAAc,EAAE,MAAY;IACvE,MAAM,GAAG,GAAG,GAAG,aAAa,IAAI,QAAQ,EAAE,CAAC;IAE3C,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;QAClC,eAAe,EAAE,UAAU,aAAa,EAAE;KAC3C,CAAC;IAEF,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,WAAW,CAAC,GAAG,aAAa,CAAC;IACvC,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,aAAa,MAAM,IAAI,QAAQ,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;KACvD,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEnC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,aAAa,MAAM,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oBAAoB;AACpB,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,EAAE;KACZ;CACF,CACF,CAAC;AAEF,gCAAgC;AAChC,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAC7D,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,+BAA+B;AAC/B,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,YAAY,EAAE;QAC3D,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;QACzB,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS;KACpC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,oCAAoC;AACpC,MAAM,CAAC,iBAAiB,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;IAC9D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,mCAAmC;AACnC,MAAM,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IACpE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,gBAAgB,EAAE,gBAAgB,EAAE;QACnE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG;KACxB,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,kCAAkC;AAClC,MAAM,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;IAC5D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IACjE,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,gCAAgC;AAChC,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IACjE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,aAAa,EAAE,aAAa,EAAE;QAC7D,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;QACzB,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS;KACpC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,iBAAiB;AACjB,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;IACzB,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC9B,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,eAAe;AACf,KAAK,UAAU,IAAI;IACjB,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAC/D,OAAO,CAAC,KAAK,CAAC,oBAAoB,aAAa,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,oBAAoB,aAAa,IAAI,WAAW,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IAC7C,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|