@echomem/mcp 1.4.28 → 1.4.29
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.js +26 -10
- package/dist/package-metadata.js +2 -0
- package/dist/setup-page/client-core.js +6 -7
- package/dist/setup-page/client-extraction.js +10 -2
- package/dist/setup-page/styles-mvp.js +50 -0
- package/dist/setup-preview.js +11 -0
- package/dist/setup.js +1 -0
- package/dist/v1-contract.js +10 -9
- package/package.json +1 -1
- package/templates/codex-skills/echomem-search/SKILL.md +3 -2
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { contextHealthMarkdown, recomposeCapsuleMarkdown } from "./hud/api.js";
|
|
|
12
12
|
import { createHash, randomUUID } from "node:crypto";
|
|
13
13
|
import { fetchEncryptionConfig, decryptMemoryFields, verifyKeyB64, } from "./encryption.js";
|
|
14
14
|
import { runCli } from "./setup.js";
|
|
15
|
-
import { MCP_PACKAGE_VERSION, MCP_SERVER_INSTRUCTIONS } from "./package-metadata.js";
|
|
15
|
+
import { MCP_PACKAGE_VERSION, MCP_SERVER_INSTRUCTIONS, MEMORY_CITATION_INSTRUCTION, } from "./package-metadata.js";
|
|
16
16
|
import { clearBillingAlert, writeBillingAlert } from "./billing-alert.js";
|
|
17
17
|
import { checkLatestUpdateStatus, formatUpdateNotice, formatUpdateStatusText, startBackgroundUpdateCheck, } from "./update-check.js";
|
|
18
18
|
const ECHO_API_BASE_URL = process.env.ECHO_API_BASE_URL || "https://echo-mem-chrome.vercel.app";
|
|
@@ -32,6 +32,9 @@ function memoryMarkdownLink(url, keys, description) {
|
|
|
32
32
|
.replace(/\]/g, "\\]");
|
|
33
33
|
return `[${label}](${url})`;
|
|
34
34
|
}
|
|
35
|
+
function withMemoryCitationInstruction(text) {
|
|
36
|
+
return `${text}\n\n${MEMORY_CITATION_INSTRUCTION}`;
|
|
37
|
+
}
|
|
35
38
|
/** Thrown when no API token is present yet — the model gets a "run login" nudge, not a hard error. */
|
|
36
39
|
class NoTokenError extends Error {
|
|
37
40
|
}
|
|
@@ -1446,7 +1449,12 @@ class EchoMemMCPServer {
|
|
|
1446
1449
|
].filter(Boolean).join("\n");
|
|
1447
1450
|
})
|
|
1448
1451
|
.join("\n\n");
|
|
1449
|
-
return {
|
|
1452
|
+
return {
|
|
1453
|
+
content: [{
|
|
1454
|
+
type: "text",
|
|
1455
|
+
text: withMemoryCitationInstruction(`Retrieved ${memories.length} memories:\n\n${formattedResults}`),
|
|
1456
|
+
}],
|
|
1457
|
+
};
|
|
1450
1458
|
}
|
|
1451
1459
|
// Fallback: untuned / time-range shape.
|
|
1452
1460
|
const { success, memories, error } = result;
|
|
@@ -1463,7 +1471,12 @@ Category: ${m.category} | Object: ${m.object} | Emotion: ${m.emotion}
|
|
|
1463
1471
|
Description: ${m.description}
|
|
1464
1472
|
Details: ${m.details || "N/A"}`)
|
|
1465
1473
|
.join("\n\n");
|
|
1466
|
-
return {
|
|
1474
|
+
return {
|
|
1475
|
+
content: [{
|
|
1476
|
+
type: "text",
|
|
1477
|
+
text: withMemoryCitationInstruction(`Found ${memories.length} relevant memories:\n\n${formattedResults}`),
|
|
1478
|
+
}],
|
|
1479
|
+
};
|
|
1467
1480
|
}
|
|
1468
1481
|
async handleSave(args, rec) {
|
|
1469
1482
|
const sourceFallback = this.getMcpClientAnalytics().platform_source;
|
|
@@ -1565,7 +1578,7 @@ Details: ${m.details || "N/A"}`)
|
|
|
1565
1578
|
content: [
|
|
1566
1579
|
{
|
|
1567
1580
|
type: "text",
|
|
1568
|
-
text: `Found ${memories.length} memories between ${parsed.startDate} and ${parsed.endDate}:\n\n${formattedResults}
|
|
1581
|
+
text: withMemoryCitationInstruction(`Found ${memories.length} memories between ${parsed.startDate} and ${parsed.endDate}:\n\n${formattedResults}`),
|
|
1569
1582
|
},
|
|
1570
1583
|
],
|
|
1571
1584
|
};
|
|
@@ -1591,7 +1604,7 @@ Details: ${m.details || "N/A"}`)
|
|
|
1591
1604
|
content: [
|
|
1592
1605
|
{
|
|
1593
1606
|
type: "text",
|
|
1594
|
-
text: `Recalled ${memories.length} memories from context ${parsed.contextId} (deterministic full batch):\n\n${formattedResults}
|
|
1607
|
+
text: withMemoryCitationInstruction(`Recalled ${memories.length} memories from context ${parsed.contextId} (deterministic full batch):\n\n${formattedResults}`),
|
|
1595
1608
|
},
|
|
1596
1609
|
],
|
|
1597
1610
|
};
|
|
@@ -1636,7 +1649,10 @@ Details: ${m.details || "N/A"}`)
|
|
|
1636
1649
|
const desc = readString(memory, "description") ?? "";
|
|
1637
1650
|
const details = compactOneLine(readString(memory, "details"), 260);
|
|
1638
1651
|
const id = readString(memory, "id");
|
|
1639
|
-
|
|
1652
|
+
const linkedTitle = id
|
|
1653
|
+
? memoryMarkdownLink(personalMemoryWebUrl(id), title, desc)
|
|
1654
|
+
: title;
|
|
1655
|
+
lines.push(`- ${linkedTitle}${id ? ` (${id})` : ""}: ${desc}${details ? ` — ${details}` : ""}`);
|
|
1640
1656
|
}
|
|
1641
1657
|
lines.push("");
|
|
1642
1658
|
}
|
|
@@ -1645,7 +1661,7 @@ Details: ${m.details || "N/A"}`)
|
|
|
1645
1661
|
content: [
|
|
1646
1662
|
{
|
|
1647
1663
|
type: "text",
|
|
1648
|
-
text: lines.join("\n"),
|
|
1664
|
+
text: withMemoryCitationInstruction(lines.join("\n")),
|
|
1649
1665
|
},
|
|
1650
1666
|
],
|
|
1651
1667
|
};
|
|
@@ -1672,7 +1688,7 @@ Details: ${m.details || "N/A"}`)
|
|
|
1672
1688
|
content: [
|
|
1673
1689
|
{
|
|
1674
1690
|
type: "text",
|
|
1675
|
-
text: `Found ${memories.length} memories matching keywords:\n\n${formattedResults}
|
|
1691
|
+
text: withMemoryCitationInstruction(`Found ${memories.length} memories matching keywords:\n\n${formattedResults}`),
|
|
1676
1692
|
},
|
|
1677
1693
|
],
|
|
1678
1694
|
};
|
|
@@ -1729,7 +1745,7 @@ Details: ${m.details || "N/A"}`;
|
|
|
1729
1745
|
content: [
|
|
1730
1746
|
{
|
|
1731
1747
|
type: "text",
|
|
1732
|
-
text: `Found ${memories.length} others' public memories${metadata ? ` (${metadata})` : ""}:\n\n${formattedResults}
|
|
1748
|
+
text: withMemoryCitationInstruction(`Found ${memories.length} others' public memories${metadata ? ` (${metadata})` : ""}:\n\n${formattedResults}`),
|
|
1733
1749
|
},
|
|
1734
1750
|
],
|
|
1735
1751
|
};
|
|
@@ -1857,7 +1873,7 @@ Details: ${m.details || "N/A"}`;
|
|
|
1857
1873
|
: "",
|
|
1858
1874
|
].filter(Boolean).join("\n");
|
|
1859
1875
|
return {
|
|
1860
|
-
content: [{ type: "text", text }],
|
|
1876
|
+
content: [{ type: "text", text: withMemoryCitationInstruction(text) }],
|
|
1861
1877
|
};
|
|
1862
1878
|
}
|
|
1863
1879
|
async handleGroupContext(args) {
|
package/dist/package-metadata.js
CHANGED
|
@@ -23,6 +23,7 @@ export const MCP_PACKAGE_DESCRIPTION = stringOrFallback(packageJson.description,
|
|
|
23
23
|
export const MCP_PACKAGE_LABEL = `${MCP_PACKAGE_NAME}@${MCP_PACKAGE_VERSION}`;
|
|
24
24
|
export const MCP_UPDATE_COMMAND = `npx -y ${MCP_PACKAGE_NAME}@latest update`;
|
|
25
25
|
export const MCP_UPDATE_ALL_COMMAND = `${MCP_UPDATE_COMMAND} --all`;
|
|
26
|
+
export const MEMORY_CITATION_INSTRUCTION = 'If the user-facing answer materially relies on one or more EchoMem memories, end it with a compact "EchoMem sources:" list containing only the memories actually used. Use each memory key as the Markdown label and its canonical https://echoknows.com/memory/<memory-id> URL. Do not cite memories that were merely retrieved, and omit the section when no memory informed the answer.';
|
|
26
27
|
export const MCP_SERVER_INSTRUCTIONS = [
|
|
27
28
|
`${MCP_PACKAGE_DESCRIPTION} (${MCP_PACKAGE_LABEL}).`,
|
|
28
29
|
`If the user or local config expects a newer EchoMem MCP version than ${MCP_PACKAGE_VERSION}, update once with \`${MCP_UPDATE_ALL_COMMAND}\` and start a new MCP session.`,
|
|
@@ -34,6 +35,7 @@ export const MCP_SERVER_INSTRUCTIONS = [
|
|
|
34
35
|
"After joining or when profile fields are missing, use candidate memory evidence to propose a title and responsibility summary. Ask the user to confirm that proposal together with the publication preview, then call update_group_profile and complete_group_publication.",
|
|
35
36
|
"Use one canonical https://echoknows.com/memory/<memory-id> link for private, group, and friend evidence. Label it with the memory key; the site resolves the authorized representation.",
|
|
36
37
|
"Each search result is one memory: preserve its Memory ID and canonical echoknows.com link when citing it.",
|
|
38
|
+
MEMORY_CITATION_INSTRUCTION,
|
|
37
39
|
"During a publication preview, if an unflagged candidate appears sensitive, proactively ask whether the user wants to mark its exact ID for publication attention first. Explain that marking does not publish or change encryption; it means the agent will call it out and ask for detailed confirmation whenever a later publication includes it. Never auto-flag inferred sensitivity. For sensitive-topic flags, search and preview exact owned memories before confirmed flag_memories_for_publication_attention. Separate already-flagged candidates, state that nothing has been published yet, and offer to exclude them, review them separately, or first search for and mark similar sensitive owned memories.",
|
|
38
40
|
"Never save an inferred group profile. Manual prepared publication requires explicit preview confirmation; flagged memories still require separate exact-memory confirmation. Never store or log an echo_grp_ invite code.",
|
|
39
41
|
].join(" ");
|
|
@@ -302,14 +302,13 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
302
302
|
setExtractMode(false);
|
|
303
303
|
setReadyMode(true);
|
|
304
304
|
setHead("EchoMem connected", "Done");
|
|
305
|
-
app.className = "
|
|
305
|
+
app.className = "localAuthCompleteStage";
|
|
306
306
|
app.innerHTML =
|
|
307
|
-
'<section class="
|
|
308
|
-
'<
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
'</div>' +
|
|
307
|
+
'<section class="localAuthComplete" aria-labelledby="localAuthCompleteTitle">' +
|
|
308
|
+
'<img src="/hud-assets/echo-face-cutout.png" alt="" />' +
|
|
309
|
+
'<h2 id="localAuthCompleteTitle">You\'re signed in.</h2>' +
|
|
310
|
+
'<p>Return to Terminal.</p>' +
|
|
311
|
+
'<p class="localAuthCompleteNext">Run <code>echomem-mcp init</code> when you\'re ready to start onboarding.</p>' +
|
|
313
312
|
'</section>';
|
|
314
313
|
}
|
|
315
314
|
async function finishLocalLogin() {
|
|
@@ -1315,9 +1315,13 @@ export const SETUP_PAGE_CLIENT_EXTRACTION = String.raw ` /* ---------- dash
|
|
|
1315
1315
|
renderSessionSelection(true);
|
|
1316
1316
|
return;
|
|
1317
1317
|
}
|
|
1318
|
-
var pendingPaidPlan =
|
|
1318
|
+
var pendingPaidPlan = billingActivationPendingPlan === "power"
|
|
1319
1319
|
? "power"
|
|
1320
|
-
: (
|
|
1320
|
+
: (billingActivationPendingPlan === "pro"
|
|
1321
|
+
? "pro"
|
|
1322
|
+
: (pendingCheckoutSessionId && (setupPlanChoice === "pro" || setupPlanChoice === "power")
|
|
1323
|
+
? setupPlanChoice
|
|
1324
|
+
: ""));
|
|
1321
1325
|
if (pendingPaidPlan) {
|
|
1322
1326
|
renderBillingCommitment("");
|
|
1323
1327
|
if (readySettings) {
|
|
@@ -1478,6 +1482,10 @@ export const SETUP_PAGE_CLIENT_EXTRACTION = String.raw ` /* ---------- dash
|
|
|
1478
1482
|
}
|
|
1479
1483
|
document.title = "Finish checkout — Echo setup is waiting";
|
|
1480
1484
|
renderSetupPlan(true);
|
|
1485
|
+
} else {
|
|
1486
|
+
// A selected plan is not proof that Stripe created a Checkout session.
|
|
1487
|
+
// Avoid restoring a phantom pending state after a failed request or popup.
|
|
1488
|
+
rememberSetupPlanChoice("");
|
|
1481
1489
|
}
|
|
1482
1490
|
}
|
|
1483
1491
|
async function openHostedPlanOptions() {
|
|
@@ -285,6 +285,56 @@ export const SETUP_PAGE_STYLES_MVP = String.raw `
|
|
|
285
285
|
.localAuthWelcomeStage.localAuthPassphraseStage .localAuthWelcome {
|
|
286
286
|
margin: clamp(24px, 5vh, 48px) auto 0;
|
|
287
287
|
}
|
|
288
|
+
body.readyMode #app.localAuthCompleteStage {
|
|
289
|
+
min-height: calc(100vh - clamp(56px, 10vw, 128px));
|
|
290
|
+
display: grid;
|
|
291
|
+
place-items: center;
|
|
292
|
+
}
|
|
293
|
+
.localAuthComplete {
|
|
294
|
+
width: min(680px, 100%);
|
|
295
|
+
display: grid;
|
|
296
|
+
justify-items: center;
|
|
297
|
+
gap: 14px;
|
|
298
|
+
margin: 0 auto;
|
|
299
|
+
padding: clamp(24px, 5vw, 48px) 0;
|
|
300
|
+
color: var(--echo-ink-text);
|
|
301
|
+
text-align: center;
|
|
302
|
+
}
|
|
303
|
+
.localAuthComplete > img {
|
|
304
|
+
width: 76px;
|
|
305
|
+
height: 76px;
|
|
306
|
+
object-fit: contain;
|
|
307
|
+
filter: drop-shadow(0 12px 20px rgba(26,58,143,0.18));
|
|
308
|
+
}
|
|
309
|
+
.localAuthComplete h2 {
|
|
310
|
+
max-width: 100%;
|
|
311
|
+
margin: 4px 0 0;
|
|
312
|
+
color: var(--echo-ink-text);
|
|
313
|
+
font-family: var(--echo-font-brand);
|
|
314
|
+
font-size: clamp(42px, 6vw, 64px);
|
|
315
|
+
font-weight: 800;
|
|
316
|
+
letter-spacing: -0.055em;
|
|
317
|
+
line-height: 0.98;
|
|
318
|
+
white-space: nowrap;
|
|
319
|
+
}
|
|
320
|
+
.localAuthComplete p {
|
|
321
|
+
margin: 0;
|
|
322
|
+
color: var(--echo-ink-mute);
|
|
323
|
+
font-size: clamp(17px, 2.2vw, 22px);
|
|
324
|
+
line-height: 1.45;
|
|
325
|
+
}
|
|
326
|
+
.localAuthComplete .localAuthCompleteNext {
|
|
327
|
+
max-width: 460px;
|
|
328
|
+
margin-top: 2px;
|
|
329
|
+
color: var(--echo-ink-faint);
|
|
330
|
+
font-size: 14px;
|
|
331
|
+
}
|
|
332
|
+
.localAuthComplete code {
|
|
333
|
+
color: var(--echo-ink-primary);
|
|
334
|
+
}
|
|
335
|
+
@media (max-width: 560px) {
|
|
336
|
+
.localAuthComplete h2 { white-space: normal; }
|
|
337
|
+
}
|
|
288
338
|
.localAuthWelcome {
|
|
289
339
|
width: min(440px, 100%);
|
|
290
340
|
gap: 14px;
|
package/dist/setup-preview.js
CHANGED
|
@@ -21,7 +21,9 @@ export const SETUP_PREVIEW_STATES = [
|
|
|
21
21
|
"auth-login",
|
|
22
22
|
"auth-login-pro",
|
|
23
23
|
"auth-otp",
|
|
24
|
+
"auth-complete",
|
|
24
25
|
"checkout-pro-selected",
|
|
26
|
+
"checkout-pro-stale",
|
|
25
27
|
"auth-unlock",
|
|
26
28
|
"auth-setup",
|
|
27
29
|
"extract-run",
|
|
@@ -252,6 +254,7 @@ function extractionPreviewBootstrap(options) {
|
|
|
252
254
|
connected = true;
|
|
253
255
|
billingStatus = ${JSON.stringify(billingStatus)};
|
|
254
256
|
setupPlanChoice = ${JSON.stringify(options.selectFree ? "free" : options.selectedPlanChoice || "")};
|
|
257
|
+
pendingCheckoutSessionId = ${JSON.stringify(options.checkoutPending ? "cs_test_preview_pending_123" : "")};
|
|
255
258
|
stats = {
|
|
256
259
|
sessions: { total: ${candidateCount}, codex: ${Math.ceil(candidateCount * 0.68)}, claudeCode: ${Math.floor(candidateCount * 0.32)} },
|
|
257
260
|
migratable: {
|
|
@@ -400,7 +403,15 @@ export function renderSetupPreviewBootstrap(state) {
|
|
|
400
403
|
return `${watermark}
|
|
401
404
|
localAuthEmail = "preview@example.com";
|
|
402
405
|
renderLocalOtp("Verification code sent. Check your email inbox.");`;
|
|
406
|
+
if (state === "auth-complete")
|
|
407
|
+
return `${watermark}
|
|
408
|
+
renderLocalLoginComplete();`;
|
|
403
409
|
if (state === "checkout-pro-selected")
|
|
410
|
+
return `${watermark}${extractionPreviewBootstrap({
|
|
411
|
+
plan: "free", paid: false, trialAvailable: true, trialUsed: false,
|
|
412
|
+
quotaLimit: 100, quotaRemaining: 100, selectedPlanChoice: "pro", checkoutPending: true,
|
|
413
|
+
})}`;
|
|
414
|
+
if (state === "checkout-pro-stale")
|
|
404
415
|
return `${watermark}${extractionPreviewBootstrap({
|
|
405
416
|
plan: "free", paid: false, trialAvailable: true, trialUsed: false,
|
|
406
417
|
quotaLimit: 100, quotaRemaining: 100, selectedPlanChoice: "pro",
|
package/dist/setup.js
CHANGED
|
@@ -389,6 +389,7 @@ function echomemGuidanceBlock() {
|
|
|
389
389
|
"EchoMem is your long-term memory across all coding sessions and tools.",
|
|
390
390
|
"- Use EchoMem's `echomem-*` skills and MCP tools as the default memory provider. Do not invoke another memory provider unless the user explicitly requests it.",
|
|
391
391
|
"- Before re-deriving past decisions, project context, or anything the user likely settled before: call `search_memories` first.",
|
|
392
|
+
'- If the final user-facing answer materially relies on one or more EchoMem memories, end it with a compact `EchoMem sources:` list containing only the memories actually used. Link each memory key to its canonical `https://echoknows.com/memory/<memory-id>` URL. Do not cite memories that were merely retrieved, and omit the section when no memory informed the answer.',
|
|
392
393
|
"- Before the final response for a task that produced a durable decision, confirmed preference, implementation, resolved bug, commit, passing verification, release, or project milestone: call `save_conversation`. This private checkpoint does not require a separate user request. Do not save secrets, credentials, incidental chatter, or trivial read-only work. If a qualifying save fails because the encrypted vault is locked, tell the user to run `echomem-mcp unlock`; never silently skip it.",
|
|
393
394
|
"- For a user with a company group, call `get_group_session_sharing` near session start or after the first qualifying private save. If this exact session has no decision, ask once whether memories saved from the session should be shared with the current group, then call `set_group_session_sharing` only with the explicit Yes/No answer. A Yes decision syncs eligible memories after each private save; a No decision keeps later saves private.",
|
|
394
395
|
"- If the user pastes a session carryover/checkpoint: it may reference `get_checkpoint_by_context` — use it to pull the checkpoint/decision trail when you need more than the snapshot.",
|
package/dist/v1-contract.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { withMcpVersion } from "./package-metadata.js";
|
|
2
|
+
import { MEMORY_CITATION_INSTRUCTION, withMcpVersion } from "./package-metadata.js";
|
|
3
3
|
export const canonicalToolNames = {
|
|
4
4
|
search: "search_memories",
|
|
5
5
|
save: "save_conversation",
|
|
@@ -204,6 +204,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
204
204
|
const updateNotice = opts.updateNotice?.trim();
|
|
205
205
|
const recallPlanNote = "Available on every plan: Free includes 100 searches each week, Pro includes 500, and Power includes 2,000.";
|
|
206
206
|
const searchBillingReplyInstruction = "If search returns an ACTION REQUIRED subscription message, tell the user to start their trial or subscription and include the exact URL from that result verbatim. Do not respond only with \"connect\" or \"upgrade\".";
|
|
207
|
+
const memoryCitationInstruction = MEMORY_CITATION_INSTRUCTION;
|
|
207
208
|
const updateSection = updateNotice ? `\n\nUPDATE NOTICE: ${updateNotice}` : "";
|
|
208
209
|
const mapSection = map
|
|
209
210
|
? `\n\nThis user's EchoMem currently covers these topics (a relevance guide — recall when the task relates to one of them):\n${map}\n`
|
|
@@ -211,7 +212,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
211
212
|
return [
|
|
212
213
|
{
|
|
213
214
|
name: canonicalToolNames.search,
|
|
214
|
-
description: withMcpVersion(`Recall the user's prior decisions, preferences, and project context from EchoMem — their long-term memory across ALL their AI tools, not just this session. Use it instead of re-deriving or re-asking what the user already settled. ${recallPlanNote} ${searchBillingReplyInstruction}${mapSection}\nReturns ranked memories only; the MCP host model writes the final answer. Current time: ${currentTime}.${updateSection}`),
|
|
215
|
+
description: withMcpVersion(`Recall the user's prior decisions, preferences, and project context from EchoMem — their long-term memory across ALL their AI tools, not just this session. Use it instead of re-deriving or re-asking what the user already settled. ${recallPlanNote} ${searchBillingReplyInstruction} ${memoryCitationInstruction}${mapSection}\nReturns ranked memories only; the MCP host model writes the final answer. Current time: ${currentTime}.${updateSection}`),
|
|
215
216
|
inputSchema: {
|
|
216
217
|
type: "object",
|
|
217
218
|
properties: {
|
|
@@ -229,7 +230,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
229
230
|
},
|
|
230
231
|
{
|
|
231
232
|
name: "search_memories_by_description_semantic",
|
|
232
|
-
description: `Legacy alias for search_memories. ${recallPlanNote} ${searchBillingReplyInstruction}`,
|
|
233
|
+
description: `Legacy alias for search_memories. ${recallPlanNote} ${searchBillingReplyInstruction} ${memoryCitationInstruction}`,
|
|
233
234
|
inputSchema: {
|
|
234
235
|
type: "object",
|
|
235
236
|
properties: {
|
|
@@ -280,7 +281,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
280
281
|
},
|
|
281
282
|
{
|
|
282
283
|
name: canonicalToolNames.timeRange,
|
|
283
|
-
description: `Retrieve memories within a specific date range. ${recallPlanNote} Current time: ${currentTime}.`,
|
|
284
|
+
description: `Retrieve memories within a specific date range. ${recallPlanNote} ${memoryCitationInstruction} Current time: ${currentTime}.`,
|
|
284
285
|
inputSchema: {
|
|
285
286
|
type: "object",
|
|
286
287
|
properties: {
|
|
@@ -298,7 +299,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
298
299
|
},
|
|
299
300
|
{
|
|
300
301
|
name: canonicalToolNames.keywords,
|
|
301
|
-
description: `Search memories based on keywords in keys field. Pass keywords as valid JSON: preferably an array of quoted strings, for example {"keywords":["flow-lab","flow.html","Rive"],"limit":8}. A comma-separated JSON string is also accepted as a compatibility fallback. Never emit bare comma-separated tokens. ${recallPlanNote}`,
|
|
302
|
+
description: `Search memories based on keywords in keys field. Pass keywords as valid JSON: preferably an array of quoted strings, for example {"keywords":["flow-lab","flow.html","Rive"],"limit":8}. A comma-separated JSON string is also accepted as a compatibility fallback. Never emit bare comma-separated tokens. ${recallPlanNote} ${memoryCitationInstruction}`,
|
|
302
303
|
inputSchema: {
|
|
303
304
|
type: "object",
|
|
304
305
|
properties: {
|
|
@@ -384,7 +385,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
384
385
|
},
|
|
385
386
|
{
|
|
386
387
|
name: canonicalToolNames.others,
|
|
387
|
-
description:
|
|
388
|
+
description: `Search public memories from accepted friends or people who share your company group. For onboarding and division-of-work questions, call get_group_context first, then use this tool for current evidence. Returned memories are recorded in memory_views for the owners. ${memoryCitationInstruction}`,
|
|
388
389
|
inputSchema: {
|
|
389
390
|
type: "object",
|
|
390
391
|
properties: {
|
|
@@ -429,7 +430,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
429
430
|
},
|
|
430
431
|
{
|
|
431
432
|
name: canonicalToolNames.publicMemory,
|
|
432
|
-
description:
|
|
433
|
+
description: `Fetch one public memory by id when its owner is an accepted friend or shares your company group. If the caller is not the owner, EchoMem records the access in memory_views. ${memoryCitationInstruction}`,
|
|
433
434
|
inputSchema: {
|
|
434
435
|
type: "object",
|
|
435
436
|
properties: {
|
|
@@ -685,7 +686,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
685
686
|
},
|
|
686
687
|
{
|
|
687
688
|
name: canonicalToolNames.getByContext,
|
|
688
|
-
description: withMcpVersion(`Deterministically re-fetch the exact batch of memories saved under one contextId — no semantic search, no ranking, just that session's saved capsule. ${recallPlanNote} save_conversation returns a contextId; pass it here to pull back precisely those memories, e.g. to warm up a fresh session with what a prior session saved, or to verify the saved facts are still present. Current time: ${currentTime}.`),
|
|
689
|
+
description: withMcpVersion(`Deterministically re-fetch the exact batch of memories saved under one contextId — no semantic search, no ranking, just that session's saved capsule. ${recallPlanNote} save_conversation returns a contextId; pass it here to pull back precisely those memories, e.g. to warm up a fresh session with what a prior session saved, or to verify the saved facts are still present. ${memoryCitationInstruction} Current time: ${currentTime}.`),
|
|
689
690
|
inputSchema: {
|
|
690
691
|
type: "object",
|
|
691
692
|
properties: {
|
|
@@ -702,7 +703,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
702
703
|
},
|
|
703
704
|
{
|
|
704
705
|
name: canonicalToolNames.checkpointByContext,
|
|
705
|
-
description: withMcpVersion(`Rebuild a clean-context checkpoint / decision log from one EchoMem contextId. ${recallPlanNote} Use this when the user or EchoMem HUD gives you a contextId for a renewed coding session and you need the session handoff, not a raw memory dump. It deterministically fetches that context and formats it as orientation state: decisions, carryover, constraints, and checkpoints. Current time: ${currentTime}.`),
|
|
706
|
+
description: withMcpVersion(`Rebuild a clean-context checkpoint / decision log from one EchoMem contextId. ${recallPlanNote} Use this when the user or EchoMem HUD gives you a contextId for a renewed coding session and you need the session handoff, not a raw memory dump. It deterministically fetches that context and formats it as orientation state: decisions, carryover, constraints, and checkpoints. ${memoryCitationInstruction} Current time: ${currentTime}.`),
|
|
706
707
|
inputSchema: {
|
|
707
708
|
type: "object",
|
|
708
709
|
properties: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@echomem/mcp",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.29",
|
|
4
4
|
"description": "EchoMem MCP bridge: cloud-first memory tools, local context HUD, and the Agent Doctor workspace forensics report (cost ledger + 3D repo city)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -10,5 +10,6 @@ Use the `echomem` MCP server as the source of long-term memory.
|
|
|
10
10
|
1. Call `search_memories` with a concise query describing the context needed. Keep `includeAnswer` false unless an EchoMem-generated synthesis is specifically useful.
|
|
11
11
|
2. Use `get_memories_by_time_range` for explicit dates, `search_memories_by_keywords` for exact terms, and `get_checkpoint_by_context` when a carryover references an EchoMem checkpoint.
|
|
12
12
|
3. Distinguish recalled facts from inference and preserve dates or provenance returned by EchoMem.
|
|
13
|
-
4. If EchoMem
|
|
14
|
-
5. If EchoMem
|
|
13
|
+
4. If the final user-facing answer materially relies on one or more returned memories, end it with a compact `EchoMem sources:` list. Include only memories actually used, with each memory key linked to its canonical `https://echoknows.com/memory/<memory-id>` URL. Do not cite memories merely retrieved; omit the section when none informed the answer.
|
|
14
|
+
5. If EchoMem returns an action-required URL, give the user that exact URL and explanation.
|
|
15
|
+
6. If EchoMem is unavailable, say so. Do not switch to another memory provider unless the user requests it.
|