memax-cli 0.1.0-alpha.8 → 0.1.0

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.
Files changed (197) hide show
  1. package/assets/skills/memax-memory/SKILL.md +173 -0
  2. package/dist/commands/agent-configs.d.ts +41 -0
  3. package/dist/commands/agent-configs.d.ts.map +1 -0
  4. package/dist/commands/agent-configs.js +1290 -0
  5. package/dist/commands/agent-configs.js.map +1 -0
  6. package/dist/commands/agent-configs.test.d.ts +2 -0
  7. package/dist/commands/agent-configs.test.d.ts.map +1 -0
  8. package/dist/commands/agent-configs.test.js +122 -0
  9. package/dist/commands/agent-configs.test.js.map +1 -0
  10. package/dist/commands/agent-sessions.d.ts +74 -0
  11. package/dist/commands/agent-sessions.d.ts.map +1 -0
  12. package/dist/commands/agent-sessions.js +1513 -0
  13. package/dist/commands/agent-sessions.js.map +1 -0
  14. package/dist/commands/agent-sessions.test.d.ts +2 -0
  15. package/dist/commands/agent-sessions.test.d.ts.map +1 -0
  16. package/dist/commands/agent-sessions.test.js +255 -0
  17. package/dist/commands/agent-sessions.test.js.map +1 -0
  18. package/dist/commands/agents.d.ts +3 -0
  19. package/dist/commands/agents.d.ts.map +1 -0
  20. package/dist/commands/agents.js +36 -0
  21. package/dist/commands/agents.js.map +1 -0
  22. package/dist/commands/ask.d.ts +15 -0
  23. package/dist/commands/ask.d.ts.map +1 -0
  24. package/dist/commands/ask.js +483 -0
  25. package/dist/commands/ask.js.map +1 -0
  26. package/dist/commands/auth.d.ts +7 -0
  27. package/dist/commands/auth.d.ts.map +1 -1
  28. package/dist/commands/auth.js +103 -8
  29. package/dist/commands/auth.js.map +1 -1
  30. package/dist/commands/capture.d.ts +19 -0
  31. package/dist/commands/capture.d.ts.map +1 -0
  32. package/dist/commands/capture.js +69 -0
  33. package/dist/commands/capture.js.map +1 -0
  34. package/dist/commands/config.d.ts +2 -0
  35. package/dist/commands/config.d.ts.map +1 -1
  36. package/dist/commands/config.js +13 -0
  37. package/dist/commands/config.js.map +1 -1
  38. package/dist/commands/delete.d.ts +2 -0
  39. package/dist/commands/delete.d.ts.map +1 -1
  40. package/dist/commands/delete.js +15 -18
  41. package/dist/commands/delete.js.map +1 -1
  42. package/dist/commands/dreams.d.ts +22 -0
  43. package/dist/commands/dreams.d.ts.map +1 -0
  44. package/dist/commands/dreams.js +251 -0
  45. package/dist/commands/dreams.js.map +1 -0
  46. package/dist/commands/dreams.test.d.ts +2 -0
  47. package/dist/commands/dreams.test.d.ts.map +1 -0
  48. package/dist/commands/dreams.test.js +39 -0
  49. package/dist/commands/dreams.test.js.map +1 -0
  50. package/dist/commands/hook.d.ts +2 -0
  51. package/dist/commands/hook.d.ts.map +1 -1
  52. package/dist/commands/hook.js +25 -103
  53. package/dist/commands/hook.js.map +1 -1
  54. package/dist/commands/hub.d.ts +37 -0
  55. package/dist/commands/hub.d.ts.map +1 -0
  56. package/dist/commands/hub.js +347 -0
  57. package/dist/commands/hub.js.map +1 -0
  58. package/dist/commands/hub.test.d.ts +2 -0
  59. package/dist/commands/hub.test.d.ts.map +1 -0
  60. package/dist/commands/hub.test.js +62 -0
  61. package/dist/commands/hub.test.js.map +1 -0
  62. package/dist/commands/import.d.ts +13 -0
  63. package/dist/commands/import.d.ts.map +1 -0
  64. package/dist/commands/import.js +257 -0
  65. package/dist/commands/import.js.map +1 -0
  66. package/dist/commands/import.test.d.ts +2 -0
  67. package/dist/commands/import.test.d.ts.map +1 -0
  68. package/dist/commands/import.test.js +11 -0
  69. package/dist/commands/import.test.js.map +1 -0
  70. package/dist/commands/list.d.ts +9 -2
  71. package/dist/commands/list.d.ts.map +1 -1
  72. package/dist/commands/list.js +118 -9
  73. package/dist/commands/list.js.map +1 -1
  74. package/dist/commands/list.test.d.ts +2 -0
  75. package/dist/commands/list.test.d.ts.map +1 -0
  76. package/dist/commands/list.test.js +20 -0
  77. package/dist/commands/list.test.js.map +1 -0
  78. package/dist/commands/login.d.ts +7 -1
  79. package/dist/commands/login.d.ts.map +1 -1
  80. package/dist/commands/login.js +81 -20
  81. package/dist/commands/login.js.map +1 -1
  82. package/dist/commands/mcp.d.ts.map +1 -1
  83. package/dist/commands/mcp.js +386 -65
  84. package/dist/commands/mcp.js.map +1 -1
  85. package/dist/commands/push.d.ts +6 -1
  86. package/dist/commands/push.d.ts.map +1 -1
  87. package/dist/commands/push.js +42 -8
  88. package/dist/commands/push.js.map +1 -1
  89. package/dist/commands/recall.d.ts +11 -1
  90. package/dist/commands/recall.d.ts.map +1 -1
  91. package/dist/commands/recall.js +228 -41
  92. package/dist/commands/recall.js.map +1 -1
  93. package/dist/commands/recall.test.d.ts +2 -0
  94. package/dist/commands/recall.test.d.ts.map +1 -0
  95. package/dist/commands/recall.test.js +31 -0
  96. package/dist/commands/recall.test.js.map +1 -0
  97. package/dist/commands/setup-hooks.d.ts +13 -0
  98. package/dist/commands/setup-hooks.d.ts.map +1 -0
  99. package/dist/commands/setup-hooks.js +193 -0
  100. package/dist/commands/setup-hooks.js.map +1 -0
  101. package/dist/commands/setup-instructions.d.ts +21 -0
  102. package/dist/commands/setup-instructions.d.ts.map +1 -0
  103. package/dist/commands/setup-instructions.js +172 -0
  104. package/dist/commands/setup-instructions.js.map +1 -0
  105. package/dist/commands/setup-mcp.d.ts +40 -0
  106. package/dist/commands/setup-mcp.d.ts.map +1 -0
  107. package/dist/commands/setup-mcp.js +414 -0
  108. package/dist/commands/setup-mcp.js.map +1 -0
  109. package/dist/commands/setup-types.d.ts +33 -0
  110. package/dist/commands/setup-types.d.ts.map +1 -0
  111. package/dist/commands/setup-types.js +60 -0
  112. package/dist/commands/setup-types.js.map +1 -0
  113. package/dist/commands/setup.d.ts +10 -1
  114. package/dist/commands/setup.d.ts.map +1 -1
  115. package/dist/commands/setup.js +216 -532
  116. package/dist/commands/setup.js.map +1 -1
  117. package/dist/commands/show.d.ts +5 -1
  118. package/dist/commands/show.d.ts.map +1 -1
  119. package/dist/commands/show.js +36 -14
  120. package/dist/commands/show.js.map +1 -1
  121. package/dist/commands/topic.d.ts +32 -0
  122. package/dist/commands/topic.d.ts.map +1 -0
  123. package/dist/commands/topic.js +265 -0
  124. package/dist/commands/topic.js.map +1 -0
  125. package/dist/commands/topic.test.d.ts +2 -0
  126. package/dist/commands/topic.test.d.ts.map +1 -0
  127. package/dist/commands/topic.test.js +114 -0
  128. package/dist/commands/topic.test.js.map +1 -0
  129. package/dist/index.js +35 -144
  130. package/dist/index.js.map +1 -1
  131. package/dist/lib/client.d.ts +10 -0
  132. package/dist/lib/client.d.ts.map +1 -0
  133. package/dist/lib/client.js +104 -0
  134. package/dist/lib/client.js.map +1 -0
  135. package/dist/lib/client.test.d.ts +2 -0
  136. package/dist/lib/client.test.d.ts.map +1 -0
  137. package/dist/lib/client.test.js +44 -0
  138. package/dist/lib/client.test.js.map +1 -0
  139. package/dist/lib/config.d.ts +43 -0
  140. package/dist/lib/config.d.ts.map +1 -1
  141. package/dist/lib/config.js +72 -1
  142. package/dist/lib/config.js.map +1 -1
  143. package/dist/lib/credentials.d.ts +3 -0
  144. package/dist/lib/credentials.d.ts.map +1 -1
  145. package/dist/lib/credentials.js +24 -2
  146. package/dist/lib/credentials.js.map +1 -1
  147. package/dist/lib/hubs.d.ts +7 -0
  148. package/dist/lib/hubs.d.ts.map +1 -0
  149. package/dist/lib/hubs.js +33 -0
  150. package/dist/lib/hubs.js.map +1 -0
  151. package/dist/lib/hubs.test.d.ts +2 -0
  152. package/dist/lib/hubs.test.d.ts.map +1 -0
  153. package/dist/lib/hubs.test.js +58 -0
  154. package/dist/lib/hubs.test.js.map +1 -0
  155. package/dist/lib/project-context.d.ts +56 -0
  156. package/dist/lib/project-context.d.ts.map +1 -0
  157. package/dist/lib/project-context.js +225 -0
  158. package/dist/lib/project-context.js.map +1 -0
  159. package/dist/lib/project-context.test.d.ts +2 -0
  160. package/dist/lib/project-context.test.d.ts.map +1 -0
  161. package/dist/lib/project-context.test.js +75 -0
  162. package/dist/lib/project-context.test.js.map +1 -0
  163. package/dist/lib/prompt.d.ts +7 -0
  164. package/dist/lib/prompt.d.ts.map +1 -0
  165. package/dist/lib/prompt.js +41 -0
  166. package/dist/lib/prompt.js.map +1 -0
  167. package/dist/lib/trash.d.ts +6 -0
  168. package/dist/lib/trash.d.ts.map +1 -0
  169. package/dist/lib/trash.js +28 -0
  170. package/dist/lib/trash.js.map +1 -0
  171. package/package.json +17 -13
  172. package/.vscode/mcp.json +0 -8
  173. package/dist/commands/sync.d.ts +0 -12
  174. package/dist/commands/sync.d.ts.map +0 -1
  175. package/dist/commands/sync.js +0 -414
  176. package/dist/commands/sync.js.map +0 -1
  177. package/dist/lib/api.d.ts +0 -4
  178. package/dist/lib/api.d.ts.map +0 -1
  179. package/dist/lib/api.js +0 -95
  180. package/dist/lib/api.js.map +0 -1
  181. package/src/commands/auth.ts +0 -92
  182. package/src/commands/config.ts +0 -27
  183. package/src/commands/delete.ts +0 -58
  184. package/src/commands/hook.ts +0 -243
  185. package/src/commands/list.ts +0 -38
  186. package/src/commands/login.ts +0 -164
  187. package/src/commands/mcp.ts +0 -405
  188. package/src/commands/push.ts +0 -137
  189. package/src/commands/recall.ts +0 -163
  190. package/src/commands/setup.ts +0 -1075
  191. package/src/commands/show.ts +0 -35
  192. package/src/commands/sync.ts +0 -506
  193. package/src/index.ts +0 -213
  194. package/src/lib/api.ts +0 -110
  195. package/src/lib/config.ts +0 -61
  196. package/src/lib/credentials.ts +0 -42
  197. package/tsconfig.json +0 -9
@@ -1,14 +1,56 @@
1
1
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
3
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
4
- import { apiGet, apiPost, apiDelete } from "../lib/api.js";
5
- function createServer() {
4
+ import { getClient, setClientAgent } from "../lib/client.js";
5
+ import { getActiveHubID } from "../lib/config.js";
6
+ import { findHubMatch, getHubReference, PERSONAL_HUB_ALIAS, } from "../lib/hubs.js";
7
+ const listMemoriesInputSchema = {
8
+ type: "object",
9
+ properties: {
10
+ limit: {
11
+ type: "number",
12
+ description: "Max results to return (default 20, max 50)",
13
+ },
14
+ cursor: {
15
+ type: "string",
16
+ description: "Pagination cursor from previous response (omit for first page)",
17
+ },
18
+ sort: {
19
+ type: "string",
20
+ description: "Sort by: newest (default) or relevant",
21
+ },
22
+ hub_id: {
23
+ type: "string",
24
+ description: 'Optional hub ID, slug, or "personal" to filter results.',
25
+ },
26
+ topic_id: {
27
+ type: "string",
28
+ description: "Optional topic ID (UUID) to filter results.",
29
+ },
30
+ },
31
+ };
32
+ function memoryClassification(memory) {
33
+ return [memory.kind, memory.stability].filter(Boolean).join("/");
34
+ }
35
+ function memberDisplayName(member) {
36
+ return member.user_name || member.user_email || member.user_id;
37
+ }
38
+ async function resolveHubReference(ref) {
39
+ const hubs = await getClient().hubs.list();
40
+ const hubRef = ref ?? getActiveHubID() ?? PERSONAL_HUB_ALIAS;
41
+ const match = findHubMatch(hubs, hubRef);
42
+ if (!match) {
43
+ throw new Error("Hub not found or not accessible. Use memax_hubs to list available hubs.");
44
+ }
45
+ return match.hub.id;
46
+ }
47
+ function createServer(agentId = "") {
6
48
  const server = new Server({ name: "memax", version: "0.0.1" }, { capabilities: { tools: {} } });
7
49
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
8
50
  tools: [
9
51
  {
10
52
  name: "memax_recall",
11
- description: "Search the user's Memax knowledge base with a natural language query. " +
53
+ description: "Search every hub the current token can access with a natural language query. " +
12
54
  "Returns relevant memories ranked by relevance. Use this when you need " +
13
55
  "background information about the project, team processes, or past decisions.",
14
56
  inputSchema: {
@@ -20,11 +62,19 @@ function createServer() {
20
62
  },
21
63
  limit: {
22
64
  type: "number",
23
- description: "Max results to return (default 5)",
65
+ description: "Max results to return (default 10)",
24
66
  },
25
- category: {
67
+ topic_id: {
26
68
  type: "string",
27
- description: "Filter by category prefix (e.g. 'core', 'decisions', 'process')",
69
+ description: "Restrict results to memories in this topic (UUID).",
70
+ },
71
+ hub_id: {
72
+ type: "string",
73
+ description: "Hub ID, slug, or 'personal'. Boosts ranking for this hub.",
74
+ },
75
+ project_context: {
76
+ type: "object",
77
+ description: "Current project context for relevance boosting. Keys: repo (git remote URL), project (short name).",
28
78
  },
29
79
  },
30
80
  required: ["query"],
@@ -33,7 +83,7 @@ function createServer() {
33
83
  {
34
84
  name: "memax_push",
35
85
  description: "Save a piece of knowledge to the user's Memax knowledge base. " +
36
- "Auto-categorized by AI if no category is provided.",
86
+ "Memax classifies it automatically for retrieval.",
37
87
  inputSchema: {
38
88
  type: "object",
39
89
  properties: {
@@ -45,68 +95,135 @@ function createServer() {
45
95
  type: "string",
46
96
  description: "Optional title (auto-generated if omitted)",
47
97
  },
48
- category: {
98
+ hint: {
49
99
  type: "string",
50
- description: "Category (e.g. 'decisions/adr', 'core/architecture'). Auto-detected if omitted.",
100
+ description: "Context hint to help AI process this memory (e.g. 'This is my resume', 'Meeting notes from product review'). Improves classification, summarization, and retrieval.",
51
101
  },
52
102
  tags: {
53
103
  type: "array",
54
104
  items: { type: "string" },
55
105
  description: "Tags for the memory",
56
106
  },
107
+ initiation_type: {
108
+ type: "string",
109
+ description: "How this save was initiated: human_direct, human_requested_agent, agent_proactive, agent_automatic, import, or unknown.",
110
+ },
111
+ project_context: {
112
+ type: "object",
113
+ description: "Project context (auto-detected by CLI). Keys: repo (git remote URL), project (short name), branch.",
114
+ },
115
+ hub_id: {
116
+ type: "string",
117
+ description: "Target hub ID. Required when pushing into a team hub.",
118
+ },
119
+ hub_reason: {
120
+ type: "string",
121
+ description: "Why this belongs in the shared hub. Required when hub_id targets a team hub.",
122
+ },
57
123
  },
58
124
  required: ["content"],
59
125
  },
60
126
  },
61
127
  {
62
128
  name: "memax_get",
63
- description: "Get the full content of a specific note by ID. " +
129
+ description: "Get the full content of a specific memory by ID. " +
64
130
  "Use this after memax_recall to read the complete content of a relevant memory.",
65
131
  inputSchema: {
66
132
  type: "object",
67
133
  properties: {
68
134
  id: {
69
135
  type: "string",
70
- description: "The note ID (from memax_recall or memax_search results)",
136
+ description: "The memory ID (from memax_recall or memax_list results)",
71
137
  },
72
138
  },
73
139
  required: ["id"],
74
140
  },
75
141
  },
76
142
  {
77
- name: "memax_search",
78
- description: "List notes filtered by category or tags. " +
79
- "For browsing and structured lookups, not semantic search. " +
80
- "Use memax_recall for natural language queries instead.",
143
+ name: "memax_list",
144
+ description: "List memories with pagination. Use cursor from the previous response for the next page. Returns total count.",
145
+ inputSchema: listMemoriesInputSchema,
146
+ },
147
+ {
148
+ name: "memax_hubs",
149
+ description: "List hubs the current user can access, including hub IDs, slugs, roles, and memory counts.",
150
+ inputSchema: {
151
+ type: "object",
152
+ properties: {},
153
+ },
154
+ },
155
+ {
156
+ name: "memax_hub_members",
157
+ description: 'List members for a hub. Requires hub_id (hub ID, slug, or "personal").',
81
158
  inputSchema: {
82
159
  type: "object",
83
160
  properties: {
84
- category: {
161
+ hub_id: {
85
162
  type: "string",
86
- description: "Filter by category prefix",
87
- },
88
- limit: {
89
- type: "number",
90
- description: "Max results to return (default 10)",
163
+ description: 'Hub ID, slug, or "personal".',
91
164
  },
92
165
  },
166
+ required: ["hub_id"],
93
167
  },
94
168
  },
95
169
  {
96
170
  name: "memax_forget",
97
- description: "Delete a note from the user's Memax knowledge base by ID. " +
171
+ description: "Delete a memory from the user's Memax knowledge base by ID. " +
98
172
  "Use this to remove outdated, incorrect, or duplicate memories.",
99
173
  inputSchema: {
100
174
  type: "object",
101
175
  properties: {
102
176
  id: {
103
177
  type: "string",
104
- description: "The note ID to delete (from memax_recall or memax_search results)",
178
+ description: "The memory ID to delete (from memax_recall or memax_list results)",
105
179
  },
106
180
  },
107
181
  required: ["id"],
108
182
  },
109
183
  },
184
+ {
185
+ name: "memax_capture",
186
+ description: "Capture key decisions, learnings, and context from this session. " +
187
+ "Call at the end of a significant work session to save what was accomplished " +
188
+ "and what should be remembered. Each fact is extracted and stored as a separate searchable memory.",
189
+ inputSchema: {
190
+ type: "object",
191
+ properties: {
192
+ summary: {
193
+ type: "string",
194
+ description: "Brief summary of what was accomplished in this session",
195
+ },
196
+ decisions: {
197
+ type: "array",
198
+ items: { type: "string" },
199
+ description: "Key decisions made (e.g., 'Chose PostgreSQL over MongoDB')",
200
+ },
201
+ learnings: {
202
+ type: "array",
203
+ items: { type: "string" },
204
+ description: "Things learned (e.g., 'pg_trgm is language-agnostic')",
205
+ },
206
+ },
207
+ required: ["summary"],
208
+ },
209
+ },
210
+ {
211
+ name: "memax_topics",
212
+ description: "Browse the user's knowledge topics. Without topic_id: returns full topic tree with memory counts. With topic_id: returns memories in that topic.",
213
+ inputSchema: {
214
+ type: "object",
215
+ properties: {
216
+ topic_id: {
217
+ type: "string",
218
+ description: "Topic ID to browse. Omit for full tree.",
219
+ },
220
+ hub_id: {
221
+ type: "string",
222
+ description: "Hub ID to scope topics.",
223
+ },
224
+ },
225
+ },
226
+ },
110
227
  ],
111
228
  }));
112
229
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
@@ -115,25 +232,41 @@ function createServer() {
115
232
  case "memax_recall": {
116
233
  const typedArgs = args;
117
234
  try {
118
- const result = await apiPost("/v1/recall", {
119
- query: typedArgs.query,
120
- limit: typedArgs.limit ?? 5,
121
- category: typedArgs.category ?? "",
235
+ let hubId = getActiveHubID() || undefined;
236
+ if (typedArgs.hub_id) {
237
+ try {
238
+ hubId = await resolveHubReference(typedArgs.hub_id);
239
+ }
240
+ catch {
241
+ // Invalid hub ref — fall back to active hub (hub_id is a ranking boost, not a gate)
242
+ }
243
+ }
244
+ const result = await getClient().recall(typedArgs.query, {
245
+ limit: typedArgs.limit ?? 10,
246
+ topicId: typedArgs.topic_id,
122
247
  source: "mcp",
123
- working_dir: process.cwd(),
248
+ workingDir: process.cwd(),
249
+ projectContext: typedArgs.project_context,
250
+ hubId,
124
251
  });
125
- const notes = result.notes ?? [];
126
- if (notes.length === 0) {
252
+ const memories = result.memories ?? [];
253
+ if (memories.length === 0) {
127
254
  return {
128
255
  content: [{ type: "text", text: "No results found." }],
129
256
  };
130
257
  }
131
- const formatted = notes
132
- .map((n, i) => {
133
- const score = (n.relevance_score * 100).toFixed(0);
134
- const heading = n.heading_chain ? ` — ${n.heading_chain}` : "";
135
- return (`[${i + 1}] ${n.title} [${n.category}, ${score}%, ${n.age}] (id: ${n.id})${heading}\n` +
136
- n.chunk_content);
258
+ const formatted = memories
259
+ .map((m, i) => {
260
+ const score = (m.relevance_score * 100).toFixed(0);
261
+ const heading = m.heading_chain ? ` — ${m.heading_chain}` : "";
262
+ const parts = [
263
+ `[${i + 1}] ${m.title} [${memoryClassification(m)}, ${score}%, ${m.age}] (id: ${m.id})${heading}`,
264
+ ];
265
+ if (m.summary) {
266
+ parts.push(`Summary: ${m.summary}`);
267
+ }
268
+ parts.push(`Relevant excerpt:\n${m.chunk_content}`);
269
+ return parts.join("\n");
137
270
  })
138
271
  .join("\n\n");
139
272
  return { content: [{ type: "text", text: formatted }] };
@@ -153,18 +286,22 @@ function createServer() {
153
286
  case "memax_push": {
154
287
  const typedArgs = args;
155
288
  try {
156
- const note = await apiPost("/v1/notes", {
157
- content: typedArgs.content,
289
+ const memory = await getClient().push(typedArgs.content, {
158
290
  title: typedArgs.title ?? "",
159
- category: typedArgs.category ?? "",
291
+ hint: typedArgs.hint ?? "",
160
292
  tags: typedArgs.tags ?? [],
161
293
  source: "mcp",
294
+ sourceAgent: agentId,
295
+ initiationType: typedArgs.initiation_type ?? undefined,
296
+ projectContext: typedArgs.project_context,
297
+ hubId: typedArgs.hub_id,
298
+ hubReason: typedArgs.hub_reason,
162
299
  });
163
300
  return {
164
301
  content: [
165
302
  {
166
303
  type: "text",
167
- text: `Saved: ${note.title} (id: ${note.id})`,
304
+ text: `Saved: ${memory.title} (id: ${memory.id})`,
168
305
  },
169
306
  ],
170
307
  };
@@ -184,21 +321,21 @@ function createServer() {
184
321
  case "memax_get": {
185
322
  const typedArgs = args;
186
323
  try {
187
- const note = await apiGet(`/v1/notes/${typedArgs.id}`);
324
+ const memory = await getClient().memories.get(typedArgs.id);
188
325
  const parts = [
189
- `# ${note.title}`,
190
- `Category: ${note.category} | Source: ${note.source} | Created: ${note.created_at}`,
326
+ `# ${memory.title}`,
327
+ `Classification: ${memoryClassification(memory)} | Source: ${memory.source} | Created: ${memory.created_at}`,
191
328
  ];
192
- if (note.tags?.length > 0) {
193
- parts.push(`Tags: ${note.tags.join(", ")}`);
329
+ if (memory.tags?.length > 0) {
330
+ parts.push(`Tags: ${memory.tags.join(", ")}`);
194
331
  }
195
- if (note.source_path) {
196
- parts.push(`Source: ${note.source_path}`);
332
+ if (memory.source_path) {
333
+ parts.push(`Source: ${memory.source_path}`);
197
334
  }
198
- if (note.summary) {
199
- parts.push(`\n## Summary\n${note.summary}`);
335
+ if (memory.summary) {
336
+ parts.push(`\n## Summary\n${memory.summary}`);
200
337
  }
201
- parts.push(`\n## Content\n${note.content}`);
338
+ parts.push(`\n## Content\n${memory.content}`);
202
339
  return {
203
340
  content: [{ type: "text", text: parts.join("\n") }],
204
341
  };
@@ -215,23 +352,41 @@ function createServer() {
215
352
  };
216
353
  }
217
354
  }
218
- case "memax_search": {
355
+ case "memax_list": {
219
356
  const typedArgs = args;
220
357
  try {
221
- const notes = (await apiGet("/v1/notes")) ?? [];
222
- let filtered = notes;
223
- if (typedArgs.category) {
224
- filtered = notes.filter((n) => n.category.startsWith(typedArgs.category));
358
+ let hubId;
359
+ if (typedArgs.hub_id) {
360
+ hubId = await resolveHubReference(typedArgs.hub_id);
225
361
  }
226
- const limited = filtered.slice(0, typedArgs.limit ?? 10);
227
- if (limited.length === 0) {
362
+ const res = await getClient().memories.list({
363
+ limit: typedArgs.limit ?? 20,
364
+ cursor: typedArgs.cursor,
365
+ sort: typedArgs.sort,
366
+ hubId,
367
+ topicId: typedArgs.topic_id,
368
+ });
369
+ const memories = res.memories ?? [];
370
+ const total = res.total ?? 0;
371
+ const nextCursor = res.next_cursor ?? "";
372
+ const hasMore = res.has_more ?? false;
373
+ if (memories.length === 0) {
228
374
  return {
229
- content: [{ type: "text", text: "No notes found." }],
375
+ content: [
376
+ {
377
+ type: "text",
378
+ text: `No memories found. (${total} total in workspace)`,
379
+ },
380
+ ],
230
381
  };
231
382
  }
232
- const formatted = limited
233
- .map((n) => `- ${n.title} [${n.category}] — ${n.source} (id: ${n.id})`)
383
+ let formatted = memories
384
+ .map((m) => `- ${m.title} [${memoryClassification(m)}] — ${m.source} (id: ${m.id})`)
234
385
  .join("\n");
386
+ formatted += `\n\nShowing ${memories.length} of ${total} total.`;
387
+ if (hasMore) {
388
+ formatted += ` More available — pass cursor: "${nextCursor}" to get next page.`;
389
+ }
235
390
  return { content: [{ type: "text", text: formatted }] };
236
391
  }
237
392
  catch (err) {
@@ -239,7 +394,70 @@ function createServer() {
239
394
  content: [
240
395
  {
241
396
  type: "text",
242
- text: `Search failed: ${err.message}`,
397
+ text: `List failed: ${err.message}`,
398
+ },
399
+ ],
400
+ isError: true,
401
+ };
402
+ }
403
+ }
404
+ case "memax_hubs": {
405
+ try {
406
+ const hubs = await getClient().hubs.list();
407
+ if (hubs.length === 0) {
408
+ return {
409
+ content: [{ type: "text", text: "No hubs found." }],
410
+ };
411
+ }
412
+ const activeHubID = getActiveHubID();
413
+ const text = hubs
414
+ .map(({ hub, role, memory_count }) => {
415
+ const active = hub.id === activeHubID ? " active" : "";
416
+ return `- **${hub.name}** (${hub.hub_type}, ${role}${active}) ref: ${getHubReference(hub)} id: ${hub.id} memories: ${memory_count}`;
417
+ })
418
+ .join("\n");
419
+ return { content: [{ type: "text", text }] };
420
+ }
421
+ catch (err) {
422
+ return {
423
+ content: [
424
+ {
425
+ type: "text",
426
+ text: `Hubs failed: ${err.message}`,
427
+ },
428
+ ],
429
+ isError: true,
430
+ };
431
+ }
432
+ }
433
+ case "memax_hub_members": {
434
+ const typedArgs = args;
435
+ try {
436
+ const hubID = await resolveHubReference(typedArgs.hub_id);
437
+ const result = await getClient().hubs.get(hubID);
438
+ const members = result.members ?? [];
439
+ let text = `## ${result.hub.name} members\n\n`;
440
+ if (members.length === 0) {
441
+ text += "No members found.";
442
+ }
443
+ else {
444
+ text += members
445
+ .map((member) => {
446
+ const email = member.user_email
447
+ ? ` <${member.user_email}>`
448
+ : "";
449
+ return `- **${memberDisplayName(member)}**${email} [${member.role}] joined: ${member.joined_at}`;
450
+ })
451
+ .join("\n");
452
+ }
453
+ return { content: [{ type: "text", text }] };
454
+ }
455
+ catch (err) {
456
+ return {
457
+ content: [
458
+ {
459
+ type: "text",
460
+ text: `Hub members failed: ${err.message}`,
243
461
  },
244
462
  ],
245
463
  isError: true,
@@ -250,12 +468,14 @@ function createServer() {
250
468
  const typedArgs = args;
251
469
  if (!typedArgs.id) {
252
470
  return {
253
- content: [{ type: "text", text: "Note ID is required." }],
471
+ content: [
472
+ { type: "text", text: "Memory ID is required." },
473
+ ],
254
474
  isError: true,
255
475
  };
256
476
  }
257
477
  try {
258
- await apiDelete(`/v1/notes/${typedArgs.id}`);
478
+ await getClient().memories.delete(typedArgs.id);
259
479
  return {
260
480
  content: [
261
481
  {
@@ -277,6 +497,105 @@ function createServer() {
277
497
  };
278
498
  }
279
499
  }
500
+ case "memax_capture": {
501
+ const typedArgs = args;
502
+ if (!typedArgs.summary) {
503
+ return {
504
+ content: [{ type: "text", text: "Summary is required." }],
505
+ isError: true,
506
+ };
507
+ }
508
+ // Build structured content for the extraction pipeline
509
+ let content = `## Session Summary\n${typedArgs.summary}\n`;
510
+ if (typedArgs.decisions?.length) {
511
+ content += `\n## Decisions Made\n${typedArgs.decisions.map((d) => `- ${d}`).join("\n")}\n`;
512
+ }
513
+ if (typedArgs.learnings?.length) {
514
+ content += `\n## Learnings\n${typedArgs.learnings.map((l) => `- ${l}`).join("\n")}\n`;
515
+ }
516
+ try {
517
+ const memory = await getClient().push(content, {
518
+ title: `Session capture — ${new Date().toLocaleDateString()}`,
519
+ contentType: "transcript",
520
+ source: "mcp/capture",
521
+ sourceAgent: agentId,
522
+ initiationType: "agent_automatic",
523
+ });
524
+ return {
525
+ content: [
526
+ {
527
+ type: "text",
528
+ text: `Session captured (id: ${memory.id}). Key facts will be extracted and stored as separate memories.`,
529
+ },
530
+ ],
531
+ };
532
+ }
533
+ catch (err) {
534
+ return {
535
+ content: [
536
+ {
537
+ type: "text",
538
+ text: `Capture failed: ${err.message}`,
539
+ },
540
+ ],
541
+ isError: true,
542
+ };
543
+ }
544
+ }
545
+ case "memax_topics": {
546
+ const typedArgs = args;
547
+ try {
548
+ if (typedArgs.topic_id) {
549
+ // Browse specific topic's memories
550
+ const res = await getClient().topics.listMemories(typedArgs.topic_id);
551
+ const topic = await getClient().topics.get(typedArgs.topic_id);
552
+ const memories = res.memories ?? [];
553
+ let text = `## ${topic.name} (${memories.length} memories)\n\n`;
554
+ for (const [i, m] of memories.entries()) {
555
+ text += `${i + 1}. **${m.title}** [${memoryClassification(m)}] (id: ${m.id})\n`;
556
+ if (m.summary)
557
+ text += ` ${m.summary}\n`;
558
+ }
559
+ if (memories.length === 0)
560
+ text += "No memories in this topic yet.\n";
561
+ return { content: [{ type: "text", text }] };
562
+ }
563
+ // Full topic tree
564
+ const res = await getClient().topics.list(typedArgs.hub_id);
565
+ const topics = res.topics ?? [];
566
+ let text = "## Topics\n\n";
567
+ if (topics.length === 0) {
568
+ text +=
569
+ "No topics yet. Push memories and run a dream cycle to auto-organize.\n";
570
+ }
571
+ else {
572
+ for (const t of topics) {
573
+ const indent = t.parent_id ? " " : "";
574
+ text += `${indent}- **${t.name}** (${t.memory_count} memories) [id: ${t.id}]\n`;
575
+ if (t.description)
576
+ text += `${indent} ${t.description}\n`;
577
+ for (const child of t.children) {
578
+ text += ` - **${child.name}** (${child.memory_count} memories) [id: ${child.id}]\n`;
579
+ }
580
+ }
581
+ }
582
+ if (res.unassigned_count > 0) {
583
+ text += `\nšŸ“„ **Inbox**: ${res.unassigned_count} unassigned memories\n`;
584
+ }
585
+ return { content: [{ type: "text", text }] };
586
+ }
587
+ catch (err) {
588
+ return {
589
+ content: [
590
+ {
591
+ type: "text",
592
+ text: `Topics failed: ${err.message}`,
593
+ },
594
+ ],
595
+ isError: true,
596
+ };
597
+ }
598
+ }
280
599
  default:
281
600
  return {
282
601
  content: [{ type: "text", text: `Unknown tool: ${name}` }],
@@ -286,8 +605,9 @@ function createServer() {
286
605
  });
287
606
  return server;
288
607
  }
289
- async function mcpServeCommand() {
290
- const server = createServer();
608
+ async function mcpServeCommand(options) {
609
+ setClientAgent(options.agent);
610
+ const server = createServer(options.agent ?? "");
291
611
  const transport = new StdioServerTransport();
292
612
  await server.connect(transport);
293
613
  // Keep the process alive — some agent launchers close stdin early
@@ -307,6 +627,7 @@ export function registerMcpCommand(program) {
307
627
  mcp
308
628
  .command("serve")
309
629
  .description("Start MCP server on stdio")
630
+ .option("--agent <name>", "Agent identity (e.g., claude-code, cursor)")
310
631
  .action(mcpServeCommand);
311
632
  }
312
633
  //# sourceMappingURL=mcp.js.map