cf-memory-mcp 3.12.0 → 3.13.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/bin/cf-memory-mcp.js +81 -0
- package/package.json +1 -1
package/bin/cf-memory-mcp.js
CHANGED
|
@@ -843,6 +843,13 @@ class CFMemoryMCP {
|
|
|
843
843
|
// Send response to stdout
|
|
844
844
|
process.stdout.write(JSON.stringify(response) + '\n');
|
|
845
845
|
|
|
846
|
+
// Safety net: every N tool calls, if there's an active implicit
|
|
847
|
+
// session AND tracked activity, fire a background auto-checkpoint
|
|
848
|
+
// with a synthesized handoff. Catches agents that forget to call
|
|
849
|
+
// end_session before a crash or timeout. Fire-and-forget so it
|
|
850
|
+
// doesn't slow down the real response.
|
|
851
|
+
this.maybeAutoCheckpoint();
|
|
852
|
+
|
|
846
853
|
} catch (error) {
|
|
847
854
|
this.logError('Error handling message:', error);
|
|
848
855
|
_mcpTrace('ERROR', `${error.message} elapsed=${Date.now()-_t0}ms`);
|
|
@@ -2302,11 +2309,85 @@ class CFMemoryMCP {
|
|
|
2302
2309
|
} else if (toolName === 'refresh_files' && Array.isArray(args.file_paths)) {
|
|
2303
2310
|
for (const p of args.file_paths) noteFile(p, 'refresh_files');
|
|
2304
2311
|
}
|
|
2312
|
+
|
|
2313
|
+
// Remember the most recent retrieve_context query so auto-checkpoints
|
|
2314
|
+
// have something concrete to put in the synthesized handoff.goal.
|
|
2315
|
+
if (toolName === 'retrieve_context' && typeof args.query === 'string' && args.query.trim()) {
|
|
2316
|
+
this._lastRetrieveQuery = args.query.trim();
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
// Tool-call counter for auto-checkpoint safety net. Counts all
|
|
2320
|
+
// tool/call messages; auto-checkpoint fires every N calls.
|
|
2321
|
+
this._toolCallCount = (this._toolCallCount || 0) + 1;
|
|
2305
2322
|
} catch (err) {
|
|
2306
2323
|
this.logDebug(`trackToolActivity failed: ${err && err.message}`);
|
|
2307
2324
|
}
|
|
2308
2325
|
}
|
|
2309
2326
|
|
|
2327
|
+
/**
|
|
2328
|
+
* Fire-and-forget auto-checkpoint. Every N tool calls, if there's an
|
|
2329
|
+
* active implicit session AND there's been meaningful activity, send a
|
|
2330
|
+
* background end_session({keep_open:true}) with a synthesized handoff.
|
|
2331
|
+
* This is the safety net for agents that forget (or crash) before
|
|
2332
|
+
* calling end_session manually.
|
|
2333
|
+
*
|
|
2334
|
+
* Behavior:
|
|
2335
|
+
* - Only fires when an implicit session exists (no surprise creation)
|
|
2336
|
+
* - Synthesizes handoff.goal from the last retrieve_context query
|
|
2337
|
+
* - Pulls files_read from activity tracker
|
|
2338
|
+
* - keep_open=true so the user can still finalize properly
|
|
2339
|
+
* - Failures are silent — never blocks the real tool call
|
|
2340
|
+
*/
|
|
2341
|
+
async maybeAutoCheckpoint() {
|
|
2342
|
+
try {
|
|
2343
|
+
const intervalEnv = parseInt(process.env.CF_MEMORY_CHECKPOINT_EVERY || '25', 10);
|
|
2344
|
+
const interval = Number.isFinite(intervalEnv) && intervalEnv > 0 ? intervalEnv : 25;
|
|
2345
|
+
const opt = process.env.CF_MEMORY_AUTO_CHECKPOINT;
|
|
2346
|
+
// Opt-out by env. Default is on. Set to 0/false/off to disable.
|
|
2347
|
+
const enabled = !(opt === '0' || opt === 'false' || opt === 'off');
|
|
2348
|
+
if (!enabled) return;
|
|
2349
|
+
const count = this._toolCallCount || 0;
|
|
2350
|
+
if (count === 0 || count % interval !== 0) return;
|
|
2351
|
+
const cwd = process.env.CF_MEMORY_WATCH_PATH || process.cwd();
|
|
2352
|
+
const sessionId = this._implicitSessionByCwd?.get(cwd);
|
|
2353
|
+
if (!sessionId) return; // no implicit session, nothing to checkpoint
|
|
2354
|
+
// Require at least one tracked file so we don't spam empty handoffs.
|
|
2355
|
+
if (!this._activityFiles || this._activityFiles.size === 0) return;
|
|
2356
|
+
|
|
2357
|
+
// Synthesize handoff.
|
|
2358
|
+
const meta = this.getRepoMetadata();
|
|
2359
|
+
const fake = { params: { name: 'retrieve_context', arguments: {} } };
|
|
2360
|
+
await this.maybeFillProjectId(fake);
|
|
2361
|
+
const handoff = {
|
|
2362
|
+
goal: this._lastRetrieveQuery
|
|
2363
|
+
? `Working on: ${this._lastRetrieveQuery.slice(0, 120)}`
|
|
2364
|
+
: `Auto-checkpoint at ${count} tool calls`,
|
|
2365
|
+
status: 'in_progress',
|
|
2366
|
+
};
|
|
2367
|
+
if (meta.repo_path) handoff.repo_path = meta.repo_path;
|
|
2368
|
+
if (meta.branch) handoff.branch = meta.branch;
|
|
2369
|
+
if (fake.params.arguments.project_id) handoff.project_id = fake.params.arguments.project_id;
|
|
2370
|
+
this.autoFillHandoffFilesRead(handoff);
|
|
2371
|
+
|
|
2372
|
+
// Fire-and-forget — don't block the real response on this.
|
|
2373
|
+
// Awaiting would serialise auto-checkpoint behind the main
|
|
2374
|
+
// request path. Failures are logged at debug only.
|
|
2375
|
+
this.makeRequest({
|
|
2376
|
+
jsonrpc: '2.0',
|
|
2377
|
+
id: `auto-checkpoint-${Date.now()}`,
|
|
2378
|
+
method: 'tools/call',
|
|
2379
|
+
params: { name: 'end_session', arguments: {
|
|
2380
|
+
session_id: sessionId,
|
|
2381
|
+
keep_open: true,
|
|
2382
|
+
handoff,
|
|
2383
|
+
} },
|
|
2384
|
+
}).catch(err => this.logDebug(`auto-checkpoint failed: ${err && err.message}`));
|
|
2385
|
+
_mcpTrace('AUTO_CHECKPOINT', `session=${sessionId} after ${count} calls files=${this._activityFiles.size}`);
|
|
2386
|
+
} catch (err) {
|
|
2387
|
+
this.logDebug(`maybeAutoCheckpoint failed: ${err && err.message}`);
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2310
2391
|
/**
|
|
2311
2392
|
* Record file paths from a retrieve_context response. Called after the
|
|
2312
2393
|
* server responds so we capture what was actually returned (not just
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cf-memory-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.0",
|
|
4
4
|
"description": "Cloudflare-hosted MCP server for code indexing, retrieval, and assistant memory with a direct remote MCP endpoint and local stdio bridge.",
|
|
5
5
|
"main": "bin/cf-memory-mcp.js",
|
|
6
6
|
"bin": {
|