@echomem/mcp 1.4.32 → 1.4.33

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/README.md CHANGED
@@ -10,7 +10,7 @@ This MCP Server bridges local tools and your EchoMem Cloud API entirely via auth
10
10
  - `save_conversation`: Connects to `POST /api/extension/memories/ingest`
11
11
  - `get_memories_by_time_range`: Connects to `POST /api/extension/memories/time-range`
12
12
  - `search_memories_by_keywords`: Connects to `POST /api/extension/memories/keywords`
13
- - `search_others_memories`: Connects to MemoryFeed public search without sending the authenticated Echo user id
13
+ - `search_others_memories`: Connects to MemoryFeed public search without trusting a model-supplied identity; the hosted API resolves the caller from the EchoMem credential and the tool returns that authenticated viewer explicitly
14
14
  - `delete_memory`: Previews one personal memory and returns a confirmation token; only deletes after a second confirmed call
15
15
 
16
16
  No direct access to the `IndexedDB` or local files is required.
package/dist/index.js CHANGED
@@ -1800,6 +1800,22 @@ Details: ${m.details || "N/A"}`)
1800
1800
  const parsed = othersSchema.parse(args ?? {});
1801
1801
  const payload = await this.client.searchOthersMemories(args);
1802
1802
  const memories = payload?.memories ?? [];
1803
+ const authenticatedViewer = isRecord(payload?.authenticatedViewer)
1804
+ ? payload.authenticatedViewer
1805
+ : null;
1806
+ const authenticatedUserId = authenticatedViewer
1807
+ ? readString(authenticatedViewer, "userId")
1808
+ : null;
1809
+ const authenticatedDisplayName = authenticatedViewer
1810
+ ? readString(authenticatedViewer, "displayName")
1811
+ : null;
1812
+ const authenticatedIdentity = authenticatedUserId
1813
+ ? [
1814
+ `Authenticated EchoMem user: ${authenticatedDisplayName ?? "Unknown display name"} (User ID: ${authenticatedUserId}).`,
1815
+ "This identity comes from the EchoMem credential and is authoritative for this tool call.",
1816
+ "EchoMem has already excluded only this authenticated user's own memories. Return every memory below; do not filter again using a Claude account, host profile, git identity, or inferred identity.",
1817
+ ].join("\n")
1818
+ : "EchoMem has already applied credential-based self filtering. Do not filter the returned memories again using a host account, profile, git identity, or inferred identity.";
1803
1819
  if (!memories.length) {
1804
1820
  const scope = parsed.ownerUserId
1805
1821
  ? ` for peer ${parsed.ownerUserId}`
@@ -1814,7 +1830,7 @@ Details: ${m.details || "N/A"}`)
1814
1830
  : "";
1815
1831
  const queryLabel = parsed.query?.trim() ? ` matching the query: ${parsed.query}` : "";
1816
1832
  return {
1817
- content: [{ type: "text", text: `No others' public memories found${scope}${queryLabel}` }],
1833
+ content: [{ type: "text", text: `${authenticatedIdentity}\n\nNo others' public memories found${scope}${queryLabel}` }],
1818
1834
  };
1819
1835
  }
1820
1836
  const metadata = [
@@ -1848,7 +1864,7 @@ Details: ${m.details || "N/A"}`;
1848
1864
  content: [
1849
1865
  {
1850
1866
  type: "text",
1851
- text: withMemoryCitationInstruction(`Found ${memories.length} others' public memories${metadata ? ` (${metadata})` : ""}:\n\n${formattedResults}`),
1867
+ text: withMemoryCitationInstruction(`${authenticatedIdentity}\n\nFound ${memories.length} others' public memories${metadata ? ` (${metadata})` : ""}:\n\n${formattedResults}`),
1852
1868
  },
1853
1869
  ],
1854
1870
  };
@@ -2033,6 +2049,9 @@ Details: ${m.details || "N/A"}`;
2033
2049
  const text = [
2034
2050
  `Company group: ${readString(group, "name") ?? "Unnamed group"}`,
2035
2051
  readString(group, "description") ? `Description: ${readString(group, "description")}` : "",
2052
+ currentParticipant
2053
+ ? `Authenticated EchoMem member: ${readString(currentParticipant, "displayName") ?? "Unknown display name"} (User ID: ${readString(currentParticipant, "userId") ?? "unknown"}). This identity comes from the EchoMem credential and overrides any conflicting host-account, Claude-profile, git, or inferred identity.`
2054
+ : "EchoMem credential identity is authoritative for this tool; do not substitute a host-account, Claude-profile, git, or inferred identity.",
2036
2055
  `Coverage: ${coveredCount} of ${participantCount} participants have published memories (${totalPublished} total).`,
2037
2056
  "",
2038
2057
  participantText,
@@ -407,7 +407,7 @@ export function listToolSpecs(opts = {}) {
407
407
  },
408
408
  {
409
409
  name: canonicalToolNames.others,
410
- 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}${groupMapSection}`,
410
+ description: `Search public memories from accepted friends or people who share your company group. EchoMem identifies the caller from the EchoMem credential and has already excluded only that authenticated user's own memories. Present every returned owner; never filter again using a Claude account, host profile, git identity, or inferred identity. 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}${groupMapSection}`,
411
411
  inputSchema: {
412
412
  type: "object",
413
413
  properties: {
@@ -499,7 +499,7 @@ export function listToolSpecs(opts = {}) {
499
499
  },
500
500
  {
501
501
  name: canonicalToolNames.groupContext,
502
- description: `Get your current company group, its participant directory, declared titles and responsibilities, and published-memory coverage. Use this before answering who works on what or suggesting where a new group member could contribute. Treat declared profile fields as facts and memory-derived work as evidence or inference. Conversation sharing is separate; call get_group_session_sharing instead of inferring it.${groupMapSection}`,
502
+ description: `Get your current company group, its participant directory, declared titles and responsibilities, published-memory coverage, and the current member authenticated by the EchoMem credential. That authenticated EchoMem identity is authoritative over any conflicting Claude account, host profile, git identity, or inference. Use this before answering who works on what or suggesting where a new group member could contribute. Treat declared profile fields as facts and memory-derived work as evidence or inference. Conversation sharing is separate; call get_group_session_sharing instead of inferring it.${groupMapSection}`,
503
503
  inputSchema: {
504
504
  type: "object",
505
505
  properties: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@echomem/mcp",
3
- "version": "1.4.32",
3
+ "version": "1.4.33",
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",