cf-memory-mcp 3.20.0 → 3.21.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 +127 -0
- package/package.json +1 -1
package/bin/cf-memory-mcp.js
CHANGED
|
@@ -3582,6 +3582,9 @@ Usage:
|
|
|
3582
3582
|
npx cf-memory-mcp Start the MCP server
|
|
3583
3583
|
npx cf-memory-mcp resume Print the prior resume handoff for cwd (markdown)
|
|
3584
3584
|
npx cf-memory-mcp resume <id> Print a specific handoff by session_id prefix
|
|
3585
|
+
npx cf-memory-mcp list List recent handoffs for cwd
|
|
3586
|
+
npx cf-memory-mcp checkpoint Snapshot current state to a fresh handoff (keep session open)
|
|
3587
|
+
npx cf-memory-mcp checkpoint "<goal>" Same, with an explicit goal string
|
|
3585
3588
|
npx cf-memory-mcp --version Show version
|
|
3586
3589
|
npx cf-memory-mcp --help Show this help
|
|
3587
3590
|
npx cf-memory-mcp --diagnose Test connectivity and report issues
|
|
@@ -3657,11 +3660,135 @@ async function runResumeCli() {
|
|
|
3657
3660
|
}
|
|
3658
3661
|
}
|
|
3659
3662
|
|
|
3663
|
+
async function runListCli() {
|
|
3664
|
+
if (!API_KEY) {
|
|
3665
|
+
console.error('Error: CF_MEMORY_API_KEY environment variable is required');
|
|
3666
|
+
process.exit(1);
|
|
3667
|
+
}
|
|
3668
|
+
const server = new CFMemoryMCP();
|
|
3669
|
+
server.logDebug = () => {};
|
|
3670
|
+
server.logError = (...a) => process.stderr.write(a.join(' ') + '\n');
|
|
3671
|
+
try {
|
|
3672
|
+
const meta = server.getRepoMetadata();
|
|
3673
|
+
const args = { resume: true };
|
|
3674
|
+
if (meta.repo_path) args.repo_path = meta.repo_path;
|
|
3675
|
+
if (meta.branch) args.branch = meta.branch;
|
|
3676
|
+
const fake = { params: { name: 'retrieve_context', arguments: {} } };
|
|
3677
|
+
await server.maybeFillProjectId(fake);
|
|
3678
|
+
if (fake.params.arguments.project_id) args.project_id = fake.params.arguments.project_id;
|
|
3679
|
+
|
|
3680
|
+
const response = await server.makeRequest({
|
|
3681
|
+
jsonrpc: '2.0',
|
|
3682
|
+
id: `cli-list-${Date.now()}`,
|
|
3683
|
+
method: 'tools/call',
|
|
3684
|
+
params: { name: 'get_context_bootstrap', arguments: args },
|
|
3685
|
+
});
|
|
3686
|
+
const text = response?.result?.content?.[0]?.text;
|
|
3687
|
+
const payload = JSON.parse(text || '{}');
|
|
3688
|
+
const list = Array.isArray(payload.recent_handoffs) ? payload.recent_handoffs : [];
|
|
3689
|
+
if (list.length === 0) {
|
|
3690
|
+
process.stdout.write((payload.empty_hint || 'No handoffs for this context.') + '\n');
|
|
3691
|
+
process.exit(0);
|
|
3692
|
+
}
|
|
3693
|
+
// Render a compact table to terminal.
|
|
3694
|
+
process.stdout.write(`Recent handoffs for ${meta.repo_path || 'this cwd'}:\n\n`);
|
|
3695
|
+
const fmtAge = (iso) => {
|
|
3696
|
+
if (!iso) return '?';
|
|
3697
|
+
const min = Math.round((Date.now() - new Date(iso).getTime()) / 60000);
|
|
3698
|
+
if (min < 60) return `${min}m`;
|
|
3699
|
+
if (min < 1440) return `${Math.round(min/60)}h`;
|
|
3700
|
+
return `${Math.round(min/1440)}d`;
|
|
3701
|
+
};
|
|
3702
|
+
for (const h of list) {
|
|
3703
|
+
const shortId = (h.session_id || '').slice(0, 8);
|
|
3704
|
+
const age = fmtAge(h.ended_at || h.started_at);
|
|
3705
|
+
const status = (h.status || 'unknown').padEnd(11);
|
|
3706
|
+
const branch = h.branch ? `[${h.branch}] ` : '';
|
|
3707
|
+
const goal = (h.goal || '(no goal)').slice(0, 80);
|
|
3708
|
+
process.stdout.write(` ${shortId} ${status} ${age.padStart(4)} ago ${branch}${goal}\n`);
|
|
3709
|
+
if (h.next_step) process.stdout.write(` next: ${h.next_step.slice(0, 80)}\n`);
|
|
3710
|
+
}
|
|
3711
|
+
process.stdout.write(`\n(Run "npx cf-memory-mcp resume <id>" to see a specific handoff)\n`);
|
|
3712
|
+
process.exit(0);
|
|
3713
|
+
} catch (err) {
|
|
3714
|
+
console.error('list command failed:', err.message);
|
|
3715
|
+
process.exit(1);
|
|
3716
|
+
}
|
|
3717
|
+
}
|
|
3718
|
+
|
|
3719
|
+
async function runCheckpointCli() {
|
|
3720
|
+
if (!API_KEY) {
|
|
3721
|
+
console.error('Error: CF_MEMORY_API_KEY environment variable is required');
|
|
3722
|
+
process.exit(1);
|
|
3723
|
+
}
|
|
3724
|
+
const server = new CFMemoryMCP();
|
|
3725
|
+
server.logDebug = () => {};
|
|
3726
|
+
server.logError = (...a) => process.stderr.write(a.join(' ') + '\n');
|
|
3727
|
+
try {
|
|
3728
|
+
// Optional positional goal argument: `cf-memory-mcp checkpoint "<goal text>"`
|
|
3729
|
+
const goalArg = process.argv.slice(3).join(' ').trim();
|
|
3730
|
+
const meta = server.getRepoMetadata();
|
|
3731
|
+
// Need a session to attach the handoff to. Use or create the
|
|
3732
|
+
// implicit session for this cwd (creates a new one if no implicit).
|
|
3733
|
+
const sessionId = await server.getOrCreateImplicitSession();
|
|
3734
|
+
if (!sessionId) {
|
|
3735
|
+
console.error('Could not create or find an implicit session for this cwd.');
|
|
3736
|
+
process.exit(1);
|
|
3737
|
+
}
|
|
3738
|
+
// Build handoff: if agent provided a goal, use it; otherwise
|
|
3739
|
+
// synthesize from bridge activity (which is likely sparse since
|
|
3740
|
+
// this is a fresh process).
|
|
3741
|
+
const handoff = server.synthesizeMinimalHandoff();
|
|
3742
|
+
if (goalArg) handoff.goal = goalArg;
|
|
3743
|
+
if (meta.repo_path) handoff.repo_path = meta.repo_path;
|
|
3744
|
+
if (meta.branch) handoff.branch = meta.branch;
|
|
3745
|
+
const fake = { params: { name: 'retrieve_context', arguments: {} } };
|
|
3746
|
+
await server.maybeFillProjectId(fake);
|
|
3747
|
+
if (fake.params.arguments.project_id) handoff.project_id = fake.params.arguments.project_id;
|
|
3748
|
+
|
|
3749
|
+
const response = await server.makeRequest({
|
|
3750
|
+
jsonrpc: '2.0',
|
|
3751
|
+
id: `cli-checkpoint-${Date.now()}`,
|
|
3752
|
+
method: 'tools/call',
|
|
3753
|
+
params: { name: 'end_session', arguments: {
|
|
3754
|
+
session_id: sessionId,
|
|
3755
|
+
keep_open: true,
|
|
3756
|
+
handoff,
|
|
3757
|
+
} },
|
|
3758
|
+
});
|
|
3759
|
+
const text = response?.result?.content?.[0]?.text;
|
|
3760
|
+
const payload = JSON.parse(text || '{}');
|
|
3761
|
+
if (payload.handoff_stored) {
|
|
3762
|
+
const shortId = sessionId.slice(0, 8);
|
|
3763
|
+
process.stdout.write(`Checkpoint saved (session ${shortId}).\n`);
|
|
3764
|
+
process.stdout.write(`Goal: ${handoff.goal}\n`);
|
|
3765
|
+
process.stdout.write(`To resume later: npx cf-memory-mcp resume ${shortId}\n`);
|
|
3766
|
+
process.exit(0);
|
|
3767
|
+
}
|
|
3768
|
+
process.stdout.write('Checkpoint did not store a handoff.\n');
|
|
3769
|
+
if (payload.error) process.stdout.write(`Error: ${payload.error}\n`);
|
|
3770
|
+
process.exit(2);
|
|
3771
|
+
} catch (err) {
|
|
3772
|
+
console.error('checkpoint command failed:', err.message);
|
|
3773
|
+
process.exit(1);
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
|
|
3660
3777
|
if (process.argv[2] === 'resume') {
|
|
3661
3778
|
runResumeCli();
|
|
3662
3779
|
return;
|
|
3663
3780
|
}
|
|
3664
3781
|
|
|
3782
|
+
if (process.argv[2] === 'list') {
|
|
3783
|
+
runListCli();
|
|
3784
|
+
return;
|
|
3785
|
+
}
|
|
3786
|
+
|
|
3787
|
+
if (process.argv[2] === 'checkpoint') {
|
|
3788
|
+
runCheckpointCli();
|
|
3789
|
+
return;
|
|
3790
|
+
}
|
|
3791
|
+
|
|
3665
3792
|
if (process.argv.includes('--diagnose')) {
|
|
3666
3793
|
(async () => {
|
|
3667
3794
|
console.log(`CF Memory MCP v${PACKAGE_VERSION} - Diagnostics`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cf-memory-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.21.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": {
|