devsh-memory-mcp 0.3.8 → 0.3.9

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.
@@ -184,7 +184,7 @@ function createMemoryMcpServer(config) {
184
184
  tools: [
185
185
  {
186
186
  name: "read_memory",
187
- description: 'Read a memory file. Type can be "knowledge", "tasks", or "mailbox".',
187
+ description: 'Read a memory file. Type can be "knowledge", "tasks", or "mailbox". For tasks, by default only returns open tasks (pending/in_progress) to prevent context bloat.',
188
188
  inputSchema: {
189
189
  type: "object",
190
190
  properties: {
@@ -192,6 +192,14 @@ function createMemoryMcpServer(config) {
192
192
  type: "string",
193
193
  enum: ["knowledge", "tasks", "mailbox"],
194
194
  description: "The type of memory to read"
195
+ },
196
+ includeCompleted: {
197
+ type: "boolean",
198
+ description: "For tasks: include completed tasks (default: false, only open tasks)"
199
+ },
200
+ limit: {
201
+ type: "number",
202
+ description: "For tasks: maximum number of tasks to return (default: 50)"
195
203
  }
196
204
  },
197
205
  required: ["type"]
@@ -235,7 +243,7 @@ function createMemoryMcpServer(config) {
235
243
  },
236
244
  {
237
245
  name: "send_message",
238
- description: 'Send a message to another agent on the same task. Use "*" to broadcast to all agents.',
246
+ description: 'Send a message to another agent on the same task. Use "*" to broadcast to all agents. Aligned with Claude Code SendMessage pattern.',
239
247
  inputSchema: {
240
248
  type: "object",
241
249
  properties: {
@@ -249,8 +257,25 @@ function createMemoryMcpServer(config) {
249
257
  },
250
258
  type: {
251
259
  type: "string",
252
- enum: ["handoff", "request", "status"],
253
- description: "Message type: handoff (work transfer), request (ask to do something), status (progress update)"
260
+ enum: ["handoff", "request", "status", "response"],
261
+ description: "Message type: handoff (work transfer), request (ask to do something), status (progress update), response (reply to a request)"
262
+ },
263
+ correlationId: {
264
+ type: "string",
265
+ description: "Optional correlation ID for request-response tracking. Use to link related messages."
266
+ },
267
+ replyTo: {
268
+ type: "string",
269
+ description: "Optional message ID this is responding to (for response type messages)."
270
+ },
271
+ priority: {
272
+ type: "string",
273
+ enum: ["high", "normal", "low"],
274
+ description: "Message priority (default: normal). High priority messages appear first."
275
+ },
276
+ metadata: {
277
+ type: "object",
278
+ description: "Optional additional context as key-value pairs."
254
279
  }
255
280
  },
256
281
  required: ["to", "message"]
@@ -258,13 +283,22 @@ function createMemoryMcpServer(config) {
258
283
  },
259
284
  {
260
285
  name: "get_my_messages",
261
- description: "Get all messages addressed to this agent (including broadcasts). Returns unread messages first.",
286
+ description: "Get all messages addressed to this agent (including broadcasts). Returns high-priority and unread messages first.",
262
287
  inputSchema: {
263
288
  type: "object",
264
289
  properties: {
265
290
  includeRead: {
266
291
  type: "boolean",
267
292
  description: "Include messages already marked as read (default: false)"
293
+ },
294
+ correlationId: {
295
+ type: "string",
296
+ description: "Filter messages by correlation ID (for tracking request-response chains)"
297
+ },
298
+ type: {
299
+ type: "string",
300
+ enum: ["handoff", "request", "status", "response"],
301
+ description: "Filter messages by type"
268
302
  }
269
303
  }
270
304
  }
@@ -723,12 +757,34 @@ function createMemoryMcpServer(config) {
723
757
  const { name, arguments: args } = request.params;
724
758
  switch (name) {
725
759
  case "read_memory": {
726
- const type = args.type;
760
+ const { type, includeCompleted, limit } = args;
727
761
  let content = null;
728
762
  if (type === "knowledge") {
729
763
  content = readFile(path.join(knowledgeDir, "MEMORY.md"));
730
764
  } else if (type === "tasks") {
731
- content = readFile(tasksPath);
765
+ const tasksFile = readTasks();
766
+ const maxTasks = limit ?? 50;
767
+ const showCompleted = includeCompleted ?? false;
768
+ let filteredTasks = showCompleted ? tasksFile.tasks : tasksFile.tasks.filter((t) => t.status === "pending" || t.status === "in_progress");
769
+ filteredTasks = filteredTasks.sort((a, b) => {
770
+ const aNum = parseInt(a.id.replace(/\D/g, ""), 10) || 0;
771
+ const bNum = parseInt(b.id.replace(/\D/g, ""), 10) || 0;
772
+ return bNum - aNum;
773
+ });
774
+ const truncated = filteredTasks.length > maxTasks;
775
+ filteredTasks = filteredTasks.slice(0, maxTasks);
776
+ const result = {
777
+ version: tasksFile.version,
778
+ tasks: filteredTasks,
779
+ _meta: {
780
+ totalTasks: tasksFile.tasks.length,
781
+ openTasks: tasksFile.tasks.filter((t) => t.status === "pending" || t.status === "in_progress").length,
782
+ returnedTasks: filteredTasks.length,
783
+ truncated,
784
+ includeCompleted: showCompleted
785
+ }
786
+ };
787
+ content = JSON.stringify(result, null, 2);
732
788
  } else if (type === "mailbox") {
733
789
  content = readFile(mailboxPath);
734
790
  }
@@ -759,7 +815,7 @@ function createMemoryMcpServer(config) {
759
815
  return { content: [{ type: "text", text: formatted }] };
760
816
  }
761
817
  case "send_message": {
762
- const { to, message, type } = args;
818
+ const { to, message, type, correlationId, replyTo, priority, metadata } = args;
763
819
  const mailbox = readMailbox();
764
820
  const newMessage = {
765
821
  id: generateMessageId(),
@@ -768,23 +824,47 @@ function createMemoryMcpServer(config) {
768
824
  type: type ?? "request",
769
825
  message,
770
826
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
771
- read: false
827
+ read: false,
828
+ correlationId,
829
+ replyTo,
830
+ priority,
831
+ metadata
772
832
  };
773
833
  mailbox.messages.push(newMessage);
774
834
  writeMailbox(mailbox);
775
- return { content: [{ type: "text", text: `Message sent successfully. ID: ${newMessage.id}` }] };
835
+ const responseText = correlationId ? `Message sent successfully. ID: ${newMessage.id}, correlationId: ${correlationId}` : `Message sent successfully. ID: ${newMessage.id}`;
836
+ return { content: [{ type: "text", text: responseText }] };
776
837
  }
777
838
  case "get_my_messages": {
778
- const includeRead = args.includeRead ?? false;
839
+ const { includeRead, correlationId, type: filterType } = args;
779
840
  const mailbox = readMailbox();
780
- const myMessages = mailbox.messages.filter(
841
+ let myMessages = mailbox.messages.filter(
781
842
  (m) => m.to === agentName || m.to === "*"
782
843
  );
783
- const filtered = includeRead ? myMessages : myMessages.filter((m) => !m.read);
784
- if (filtered.length === 0) {
844
+ if (!includeRead) {
845
+ myMessages = myMessages.filter((m) => !m.read);
846
+ }
847
+ if (correlationId) {
848
+ myMessages = myMessages.filter((m) => m.correlationId === correlationId);
849
+ }
850
+ if (filterType) {
851
+ myMessages = myMessages.filter((m) => m.type === filterType);
852
+ }
853
+ const priorityOrder = { high: 0, normal: 1, low: 2, undefined: 1 };
854
+ myMessages.sort((a, b) => {
855
+ const pa = priorityOrder[a.priority ?? "normal"];
856
+ const pb = priorityOrder[b.priority ?? "normal"];
857
+ if (pa !== pb) return pa - pb;
858
+ return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
859
+ });
860
+ if (myMessages.length === 0) {
785
861
  return { content: [{ type: "text", text: "No messages for you." }] };
786
862
  }
787
- const formatted = filtered.map((m) => `[${m.id}] ${m.type ?? "message"} from ${m.from}: ${m.message}`).join("\n\n");
863
+ const formatted = myMessages.map((m) => {
864
+ const priorityTag = m.priority === "high" ? "[HIGH] " : m.priority === "low" ? "[low] " : "";
865
+ const corrTag = m.correlationId ? ` (corr: ${m.correlationId})` : "";
866
+ return `${priorityTag}[${m.id}] ${m.type ?? "message"} from ${m.from}${corrTag}: ${m.message}`;
867
+ }).join("\n\n");
788
868
  return { content: [{ type: "text", text: formatted }] };
789
869
  }
790
870
  case "mark_read": {
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runServer
4
- } from "./chunk-BKOJ5TNO.js";
4
+ } from "./chunk-4CUOHQV6.js";
5
5
 
6
6
  // src/cli.ts
7
7
  function parseArgs() {
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createMemoryMcpServer,
3
3
  runServer
4
- } from "./chunk-BKOJ5TNO.js";
4
+ } from "./chunk-4CUOHQV6.js";
5
5
  export {
6
6
  createMemoryMcpServer,
7
7
  runServer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devsh-memory-mcp",
3
- "version": "0.3.8",
3
+ "version": "0.3.9",
4
4
  "description": "MCP server for devsh/cmux agent memory - enables Claude Desktop and external clients to access sandbox memory and orchestrate multi-agent workflows",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,6 +11,7 @@
11
11
  "scripts": {
12
12
  "build": "tsup",
13
13
  "dev": "tsup --watch",
14
+ "test": "bun test",
14
15
  "typecheck": "tsc --noEmit",
15
16
  "prepublishOnly": "npm run build"
16
17
  },