@echomem/mcp 1.4.23 → 1.4.24
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 +40 -4
- package/dist/package-metadata.js +3 -2
- package/dist/setup.js +5 -4
- package/dist/v1-contract.js +24 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4
4
|
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
5
|
import axios from "axios";
|
|
6
6
|
import { ZodError } from "zod";
|
|
7
|
-
import { canonicalToolNames, completeGroupPublicationSchema, createGroupInviteSchema, createGroupSchema, deleteMemorySchema, getByContextSchema, groupContextSchema, joinGroupSchema, keywordsSchema, listFriendsSchema, listToolSpecs, othersSchema, publishBatchToGroupSchema, publishToGroupSchema, prepareGroupPublicationSchema, publicMemorySchema, resolveCanonicalToolName, saveConversationSchema, searchMemoriesSchema, searchUsersSchema, sendFriendRequestSchema, timeRangeSchema, } from "./v1-contract.js";
|
|
7
|
+
import { canonicalToolNames, completeGroupPublicationSchema, createGroupInviteSchema, createGroupSchema, deleteMemorySchema, getByContextSchema, groupContextSchema, joinGroupSchema, keywordsSchema, listFriendsSchema, listToolSpecs, othersSchema, publishBatchToGroupSchema, publishToGroupSchema, prepareGroupPublicationSchema, publicMemorySchema, resolveCanonicalToolName, saveConversationSchema, searchMemoriesSchema, searchUsersSchema, sendFriendRequestSchema, timeRangeSchema, updateGroupProfileSchema, } from "./v1-contract.js";
|
|
8
8
|
import { KeyStore } from "./keystore.js";
|
|
9
9
|
import { EventLogger, hashText } from "./events.js";
|
|
10
10
|
import { buildReportText } from "./report.js";
|
|
@@ -983,6 +983,11 @@ class EchoMemApiClient {
|
|
|
983
983
|
const response = await this.axios.post("/api/extension/social/groups/current/publications/prepare", parsed, { headers: enc.enabled && enc.key ? { "X-Encryption-Key": enc.key } : undefined });
|
|
984
984
|
return response.data;
|
|
985
985
|
}
|
|
986
|
+
async updateGroupProfile(args) {
|
|
987
|
+
const parsed = updateGroupProfileSchema.parse(args ?? {});
|
|
988
|
+
const response = await this.axios.patch("/api/extension/social/groups/current/profile", parsed);
|
|
989
|
+
return response.data;
|
|
990
|
+
}
|
|
986
991
|
async completeGroupPublication(args) {
|
|
987
992
|
const parsed = completeGroupPublicationSchema.parse(args ?? {});
|
|
988
993
|
const enc = await this.encState();
|
|
@@ -1205,6 +1210,8 @@ class EchoMemMCPServer {
|
|
|
1205
1210
|
return await this.handleJoinGroup(request.params.arguments);
|
|
1206
1211
|
case canonicalToolNames.prepareGroupPublication:
|
|
1207
1212
|
return await this.handlePrepareGroupPublication(request.params.arguments);
|
|
1213
|
+
case canonicalToolNames.updateGroupProfile:
|
|
1214
|
+
return await this.handleUpdateGroupProfile(request.params.arguments);
|
|
1208
1215
|
case canonicalToolNames.completeGroupPublication:
|
|
1209
1216
|
return await this.handleCompleteGroupPublication(request.params.arguments);
|
|
1210
1217
|
case canonicalToolNames.publishToGroup:
|
|
@@ -1776,6 +1783,9 @@ Details: ${m.details || "N/A"}`;
|
|
|
1776
1783
|
const participants = Array.isArray(payload?.participants)
|
|
1777
1784
|
? payload.participants.filter(isRecord)
|
|
1778
1785
|
: [];
|
|
1786
|
+
const currentParticipant = isRecord(payload?.currentParticipant)
|
|
1787
|
+
? payload.currentParticipant
|
|
1788
|
+
: null;
|
|
1779
1789
|
const coverage = isRecord(payload?.coverage) ? payload.coverage : {};
|
|
1780
1790
|
if (!group) {
|
|
1781
1791
|
return {
|
|
@@ -1803,6 +1813,10 @@ Details: ${m.details || "N/A"}`;
|
|
|
1803
1813
|
participantText,
|
|
1804
1814
|
"",
|
|
1805
1815
|
"Declared titles and responsibilities are directory facts. Use search_others_memories for current work evidence, and label suggested contribution areas as inference that should be confirmed with the team.",
|
|
1816
|
+
currentParticipant
|
|
1817
|
+
&& (!readString(currentParticipant, "title") || !readString(currentParticipant, "responsibilitySummary"))
|
|
1818
|
+
? "Your group profile is incomplete. Use prepare_group_publication to review your memory evidence, propose the missing fields, and save them only after confirmation with update_group_profile."
|
|
1819
|
+
: "",
|
|
1806
1820
|
].filter(Boolean).join("\n");
|
|
1807
1821
|
return { content: [{ type: "text", text }] };
|
|
1808
1822
|
}
|
|
@@ -1854,8 +1868,8 @@ Details: ${m.details || "N/A"}`;
|
|
|
1854
1868
|
content: [{
|
|
1855
1869
|
type: "text",
|
|
1856
1870
|
text: payload?.alreadyMember
|
|
1857
|
-
? `You are already a member of ${payload?.group?.name ?? "this group"}. No memories were published.`
|
|
1858
|
-
: `Joined ${payload?.group?.name ?? "the company group"}. No memories were published.
|
|
1871
|
+
? `You are already a member of ${payload?.group?.name ?? "this group"}. No memories were published. Use prepare_group_publication to review memories and propose any missing title or responsibility fields.`
|
|
1872
|
+
: `Joined ${payload?.group?.name ?? "the company group"}. No memories were published. Next use prepare_group_publication to review candidates, infer a proposed title and responsibility summary, and ask the user to confirm that profile together with the publication preview.`,
|
|
1859
1873
|
}],
|
|
1860
1874
|
};
|
|
1861
1875
|
}
|
|
@@ -1863,6 +1877,9 @@ Details: ${m.details || "N/A"}`;
|
|
|
1863
1877
|
const parsed = prepareGroupPublicationSchema.parse(args ?? {});
|
|
1864
1878
|
const payload = await this.client.prepareGroupPublication(parsed);
|
|
1865
1879
|
const candidates = Array.isArray(payload?.candidates) ? payload.candidates : [];
|
|
1880
|
+
const participantProfile = isRecord(payload?.participantProfile)
|
|
1881
|
+
? payload.participantProfile
|
|
1882
|
+
: {};
|
|
1866
1883
|
const formatted = candidates.map((candidate, index) => [
|
|
1867
1884
|
`[${index + 1}] Memory ID: ${readString(candidate, "memoryId") ?? "unknown"}`,
|
|
1868
1885
|
`Created: ${readString(candidate, "createdAt") ?? "unknown"}`,
|
|
@@ -1879,10 +1896,29 @@ Details: ${m.details || "N/A"}`;
|
|
|
1879
1896
|
`Prepared publication scan ${payload?.scanId} for ${payload?.group?.name ?? "your group"}.`,
|
|
1880
1897
|
`Window: ${payload?.windowStart ?? "context start"} → ${payload?.windowEnd}`,
|
|
1881
1898
|
`Candidates: ${candidates.length}. Nothing has been published.`,
|
|
1899
|
+
`Current title: ${readString(participantProfile, "title") ?? "Not declared"}`,
|
|
1900
|
+
`Current declared responsibility: ${readString(participantProfile, "responsibilitySummary") ?? "Not provided"}`,
|
|
1882
1901
|
"",
|
|
1883
1902
|
formatted,
|
|
1884
1903
|
"",
|
|
1885
|
-
"Select exact memory IDs matching the user's instruction,
|
|
1904
|
+
"Select exact memory IDs matching the user's instruction. From memory evidence, draft a concise title and responsibility summary. Show the profile proposal and memory preview together, then ask for one explicit confirmation. After confirmation, call update_group_profile and complete_group_publication.",
|
|
1905
|
+
].join("\n"),
|
|
1906
|
+
}],
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
async handleUpdateGroupProfile(args) {
|
|
1910
|
+
const parsed = updateGroupProfileSchema.parse(args ?? {});
|
|
1911
|
+
const payload = await this.client.updateGroupProfile(parsed);
|
|
1912
|
+
const participant = isRecord(payload?.participant) ? payload.participant : {};
|
|
1913
|
+
return {
|
|
1914
|
+
content: [{
|
|
1915
|
+
type: "text",
|
|
1916
|
+
text: [
|
|
1917
|
+
"Confirmed company-group profile updated.",
|
|
1918
|
+
`Display name: ${readString(participant, "displayName") ?? parsed.displayName ?? "unchanged"}`,
|
|
1919
|
+
`Title: ${readString(participant, "title") ?? parsed.title}`,
|
|
1920
|
+
`Declared responsibility: ${readString(participant, "responsibilitySummary") ?? parsed.responsibilitySummary}`,
|
|
1921
|
+
"These fields are now declared directory facts visible to group members.",
|
|
1886
1922
|
].join("\n"),
|
|
1887
1923
|
}],
|
|
1888
1924
|
};
|
package/dist/package-metadata.js
CHANGED
|
@@ -28,8 +28,9 @@ export const MCP_SERVER_INSTRUCTIONS = [
|
|
|
28
28
|
`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.`,
|
|
29
29
|
"Use echomem_update_status to check whether npm has a newer bridge; it is cached and non-blocking during normal tool listing.",
|
|
30
30
|
"Do not auto-update on every MCP startup; this bridge is intentionally stable between explicit updates.",
|
|
31
|
-
"For company-group sharing, use get_group_context for orientation; create_memory_group/create_group_invite/join_memory_group for membership; and prepare_group_publication as a no-
|
|
32
|
-
"
|
|
31
|
+
"For company-group sharing, use get_group_context for orientation; create_memory_group/create_group_invite/join_memory_group for membership; and prepare_group_publication as a no-publication preview.",
|
|
32
|
+
"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.",
|
|
33
|
+
"Never save an inferred group profile or complete a group publication without explicit confirmation, and never store or log an echo_grp_ invite code.",
|
|
33
34
|
].join(" ");
|
|
34
35
|
export function withMcpVersion(description) {
|
|
35
36
|
return `${description}\n\nEchoMem MCP bridge: ${MCP_PACKAGE_LABEL}. If this version is stale, update once with \`${MCP_UPDATE_ALL_COMMAND}\` (or add \`--client cursor|windsurf|claude-desktop|claude-code|codex\` for a single client), then start a new MCP session. Do not run updates repeatedly or on every startup.`;
|
package/dist/setup.js
CHANGED
|
@@ -396,10 +396,11 @@ function echomemGuidanceBlock() {
|
|
|
396
396
|
"- Use `get_group_context` when the user asks who is in their company group, what teammates are responsible for, or what work is already covered. Treat declared participant fields as facts and published-memory conclusions as evidence or inference.",
|
|
397
397
|
"- A group publication is separate from a globally public memory: publishing to a group creates a group-scoped snapshot and must not change the encrypted original or its global `is_public` setting.",
|
|
398
398
|
"- If a user asks to create a group, call `create_memory_group`; if they ask for a code to share, call `create_group_invite` and return the secret invite code only to that user. Never save the invite code to memory or include it in logs, analytics, summaries, or unrelated output.",
|
|
399
|
-
"- If a user supplies an `echo_grp_...` code and explicitly asks to join, call `join_memory_group`. Joining never authorizes publishing by itself and must not move a user out of another group.",
|
|
400
|
-
"- For requests such as “prepare my recent work memories,” “upload work from this ticket,” or “publish work since my last sync,” call `prepare_group_publication` first. This is a no-
|
|
401
|
-
"- After preparing, select only exact candidate memory IDs that match the user's stated scope
|
|
402
|
-
"-
|
|
399
|
+
"- If a user supplies an `echo_grp_...` code and explicitly asks to join, call `join_memory_group`. Joining never authorizes publishing by itself and must not move a user out of another group. After joining, continue into the profile-and-publication preview instead of leaving title or responsibility blank.",
|
|
400
|
+
"- For requests such as “prepare my recent work memories,” “upload work from this ticket,” or “publish work since my last sync,” call `prepare_group_publication` first. This is a no-publication preview. For encrypted accounts, tell the user to run `echomem-mcp unlock` locally if the tool reports that the key is required.",
|
|
401
|
+
"- After preparing, select only exact candidate memory IDs that match the user's stated scope and exclude already-published or exact-content duplicates. Use the candidate evidence to draft a concise title and responsibility summary for the current member, but label both as proposals rather than facts.",
|
|
402
|
+
"- Present the proposed title/responsibility and the memory publication preview together and ask for one explicit confirmation. Never save an inferred profile or publish memories before confirmation.",
|
|
403
|
+
"- On confirmation, call `update_group_profile` with the confirmed title, responsibility summary, and `confirmed: true`, then call `complete_group_publication` with the exact `scanId`, selected memory IDs, and `confirmed: true`. If the user edits either proposal, use their wording. An explicit request to join and upload still requires this combined preview and confirmation.",
|
|
403
404
|
"- If the user asks to show, reopen, restart, or bring back the EchoMem HUD (the context-health overlay), run the shell command `echomem-hud app --client auto`.",
|
|
404
405
|
"- If the user wants the HUD to come back after a computer restart, run the shell command `echomem-hud autostart on --client auto`.",
|
|
405
406
|
AGENTS_MD_END,
|
package/dist/v1-contract.js
CHANGED
|
@@ -15,6 +15,7 @@ export const canonicalToolNames = {
|
|
|
15
15
|
createGroupInvite: "create_group_invite",
|
|
16
16
|
joinGroup: "join_memory_group",
|
|
17
17
|
prepareGroupPublication: "prepare_group_publication",
|
|
18
|
+
updateGroupProfile: "update_group_profile",
|
|
18
19
|
completeGroupPublication: "complete_group_publication",
|
|
19
20
|
publishToGroup: "publish_memory_to_group",
|
|
20
21
|
publishBatchToGroup: "publish_memories_to_group",
|
|
@@ -143,6 +144,13 @@ export const prepareGroupPublicationSchema = z.object({
|
|
|
143
144
|
limit: z.number().int().min(1).max(50).optional(),
|
|
144
145
|
instruction: z.string().max(500).optional(),
|
|
145
146
|
});
|
|
147
|
+
export const updateGroupProfileSchema = z.object({
|
|
148
|
+
...triggerMetadataSchema,
|
|
149
|
+
displayName: z.string().min(1).max(120).optional(),
|
|
150
|
+
title: z.string().min(1).max(160),
|
|
151
|
+
responsibilitySummary: z.string().min(1).max(1000),
|
|
152
|
+
confirmed: z.literal(true),
|
|
153
|
+
});
|
|
146
154
|
export const completeGroupPublicationSchema = z.object({
|
|
147
155
|
...triggerMetadataSchema,
|
|
148
156
|
scanId: z.string().min(1),
|
|
@@ -460,7 +468,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
460
468
|
},
|
|
461
469
|
{
|
|
462
470
|
name: canonicalToolNames.joinGroup,
|
|
463
|
-
description: "Join a company memory group using an invite code after the user explicitly asks to join. Joining never publishes memories
|
|
471
|
+
description: "Join a company memory group using an invite code after the user explicitly asks to join. Joining never publishes memories. Next call prepare_group_publication, infer a proposed title and responsibility summary from the user's own candidate memories, and ask the user to confirm the profile together with the publication preview.",
|
|
464
472
|
inputSchema: {
|
|
465
473
|
type: "object",
|
|
466
474
|
properties: {
|
|
@@ -474,7 +482,7 @@ export function listToolSpecs(opts = {}) {
|
|
|
474
482
|
},
|
|
475
483
|
{
|
|
476
484
|
name: canonicalToolNames.prepareGroupPublication,
|
|
477
|
-
description: "Prepare a no-
|
|
485
|
+
description: "Prepare a no-publication preview of up to 50 owned memories for group publication. For encrypted accounts the local bridge must be unlocked. The host agent selects exact work-related memory ids, drafts a concise title and responsibility summary from memory evidence, and asks the user to confirm both the profile and publication selection together. This tool never publishes.",
|
|
478
486
|
inputSchema: {
|
|
479
487
|
type: "object",
|
|
480
488
|
properties: {
|
|
@@ -488,6 +496,20 @@ export function listToolSpecs(opts = {}) {
|
|
|
488
496
|
},
|
|
489
497
|
},
|
|
490
498
|
},
|
|
499
|
+
{
|
|
500
|
+
name: canonicalToolNames.updateGroupProfile,
|
|
501
|
+
description: "Save the current member's declared group title and responsibility summary only after the user explicitly confirms the agent's proposal. These become directory facts visible to group members; never save an unconfirmed inference.",
|
|
502
|
+
inputSchema: {
|
|
503
|
+
type: "object",
|
|
504
|
+
properties: {
|
|
505
|
+
displayName: { type: "string" },
|
|
506
|
+
title: { type: "string" },
|
|
507
|
+
responsibilitySummary: { type: "string" },
|
|
508
|
+
confirmed: { type: "boolean", const: true },
|
|
509
|
+
},
|
|
510
|
+
required: ["title", "responsibilitySummary", "confirmed"],
|
|
511
|
+
},
|
|
512
|
+
},
|
|
491
513
|
{
|
|
492
514
|
name: canonicalToolNames.completeGroupPublication,
|
|
493
515
|
description: "Publish only the exact memory ids from a prepared scan after the user explicitly confirms the preview. confirmed must be true. Completing an empty selection safely advances the scan cursor without publishing.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@echomem/mcp",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.24",
|
|
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",
|