@cybermem/mcp 0.16.0 → 0.16.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @cybermem/mcp
2
2
 
3
+ ## 0.16.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Automated patch version bump.
8
+
3
9
  ## 0.16.0
4
10
 
5
11
  ### Minor Changes
package/dist/index.js CHANGED
@@ -91,15 +91,32 @@ async function initialize() {
91
91
  }
92
92
  /**
93
93
  * Derives the client name from the tool execution context.
94
- * Falls back to handshake client name if session is 'stdio'.
94
+ *
95
+ * Priority:
96
+ * 1. STDIO: handshake clientInfo.name (via context.client.version.name)
97
+ * 2. HTTP with X-Client-Name header: the explicit header value
98
+ * 3. HTTP without header: handshake clientInfo.name as fallback
99
+ * 4. Last resort: "unknown"
95
100
  */
96
101
  function getClientName(context) {
97
102
  const ctx = context;
98
103
  const sessionName = ctx.session?.clientName;
99
- if (sessionName === "stdio" && ctx.client?.version?.name) {
100
- return ctx.client.version.name;
104
+ // FastMCP exposes MCP handshake clientInfo at context.client.version
105
+ const handshakeName = ctx.client?.version?.name;
106
+ // STDIO: always use handshake name (the real client identity)
107
+ if (sessionName === "stdio") {
108
+ return sanitizeClientName(handshakeName || "unknown");
101
109
  }
102
- return sessionName || "unknown";
110
+ // HTTP: prefer explicit X-Client-Name header if it's meaningful
111
+ if (sessionName && sessionName !== "unknown") {
112
+ return sanitizeClientName(sessionName);
113
+ }
114
+ // HTTP without header: fall back to handshake name
115
+ return sanitizeClientName(handshakeName || sessionName || "unknown");
116
+ }
117
+ /** Strip control characters and truncate to prevent log injection. */
118
+ function sanitizeClientName(name) {
119
+ return name.replace(/[\x00-\x1f\x7f]/g, "").slice(0, 64);
103
120
  }
104
121
  const server = new fastmcp_1.FastMCP({
105
122
  name: "cybermem",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cybermem/mcp",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "description": "CyberMem MCP Server - AI Memory with openmemory-js SDK",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/src/index.ts CHANGED
@@ -12,8 +12,8 @@ import { z } from "zod";
12
12
  import { all_async, run_async } from "openmemory-js/dist/core/db.js";
13
13
  import { Memory } from "openmemory-js/dist/core/memory.js";
14
14
  import {
15
- reinforce_memory,
16
- update_memory,
15
+ reinforce_memory,
16
+ update_memory,
17
17
  } from "openmemory-js/dist/memory/hsg.js";
18
18
 
19
19
  // --- TYPES ---
@@ -162,15 +162,36 @@ interface ToolContext {
162
162
 
163
163
  /**
164
164
  * Derives the client name from the tool execution context.
165
- * Falls back to handshake client name if session is 'stdio'.
165
+ *
166
+ * Priority:
167
+ * 1. STDIO: handshake clientInfo.name (via context.client.version.name)
168
+ * 2. HTTP with X-Client-Name header: the explicit header value
169
+ * 3. HTTP without header: handshake clientInfo.name as fallback
170
+ * 4. Last resort: "unknown"
166
171
  */
167
172
  function getClientName(context: any): string {
168
173
  const ctx = context as ToolContext;
169
174
  const sessionName = ctx.session?.clientName;
170
- if (sessionName === "stdio" && ctx.client?.version?.name) {
171
- return ctx.client.version.name;
175
+ // FastMCP exposes MCP handshake clientInfo at context.client.version
176
+ const handshakeName = ctx.client?.version?.name;
177
+
178
+ // STDIO: always use handshake name (the real client identity)
179
+ if (sessionName === "stdio") {
180
+ return sanitizeClientName(handshakeName || "unknown");
181
+ }
182
+
183
+ // HTTP: prefer explicit X-Client-Name header if it's meaningful
184
+ if (sessionName && sessionName !== "unknown") {
185
+ return sanitizeClientName(sessionName);
172
186
  }
173
- return sessionName || "unknown";
187
+
188
+ // HTTP without header: fall back to handshake name
189
+ return sanitizeClientName(handshakeName || sessionName || "unknown");
190
+ }
191
+
192
+ /** Strip control characters and truncate to prevent log injection. */
193
+ function sanitizeClientName(name: string): string {
194
+ return name.replace(/[\x00-\x1f\x7f]/g, "").slice(0, 64);
174
195
  }
175
196
 
176
197
  const server = new FastMCP<AuthContext>({