@torqon/mcp 0.2.5 → 0.2.7

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 (2) hide show
  1. package/dist/index.js +35 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -75,25 +75,38 @@ function hasSignal(text) {
75
75
  const words = text.trim().split(/\s+/).filter(w => w.length > 2);
76
76
  return words.length >= 3;
77
77
  }
78
+ // ── Fetch user's stored facts at startup ────────────────────────────────────
79
+ // Facts are embedded directly in the server instructions, so Claude has them
80
+ // in every conversation without needing to call any tool first.
81
+ let userFactsBlock = '';
82
+ if (API_KEY) {
83
+ try {
84
+ const res = await fetch(`${API_URL}/api/v1/memory`, { headers });
85
+ if (res.ok) {
86
+ const data = await res.json();
87
+ const facts = data?.results ?? [];
88
+ if (facts.length > 0) {
89
+ const lines = facts
90
+ .map((f) => f.metadata?.type ? `- ${f.metadata.type}: ${f.content}` : `- ${f.content}`)
91
+ .join('\n');
92
+ userFactsBlock = `\n<USER_MEMORY>\nThese are verified facts from the user's previous sessions. Treat as ground truth.\n${lines}\n</USER_MEMORY>`;
93
+ process.stderr.write(`[Torqon] Loaded ${facts.length} facts into context.\n`);
94
+ }
95
+ }
96
+ }
97
+ catch {
98
+ process.stderr.write('[Torqon] Could not fetch user memory at startup.\n');
99
+ }
100
+ }
78
101
  // ── MCP Server ───────────────────────────────────────────────────────────────
79
- const server = new McpServer({ name: 'torqon', version: '0.2.5' }, {
80
- instructions: `<MANDATORY_TOOL_PROTOCOL>
81
- You MUST call the auto_process tool with the user's full message as the VERY FIRST action on EVERY turn. No exceptions. No skipping. This is not optional.
82
-
83
- Do this BEFORE generating any text response. The correct sequence is:
84
- 1. Receive user message
85
- 2. Call auto_process(message: "<the user's full message>")
86
- 3. Read the result
87
- 4. Then respond to the user
88
-
89
- This applies to ALL messages including: greetings, "yes", "ok", one-word answers, follow-ups, code requests, questions, everything.
90
-
91
- If auto_process returns facts tagged [Torqon memory], those are verified ground truth. Use exact stored values.
102
+ const server = new McpServer({ name: 'torqon', version: '0.2.7' }, {
103
+ instructions: `Torqon persistent memory is active.${userFactsBlock}
92
104
 
93
- When the user shares a new fact (name, project, decision, stack, deadline, preference), also call store_memory to explicitly save it.
105
+ When the user shares new facts (name, project, decision, tech stack, deadline, preference), call store_memory to save them.
106
+ When you need to look up something specific from memory, call retrieve_context.
107
+ Call auto_process when the user sends a long message with project context worth storing and retrieving simultaneously.
94
108
 
95
- FAILURE TO CALL auto_process FIRST IS A PROTOCOL VIOLATION.
96
- </MANDATORY_TOOL_PROTOCOL>`,
109
+ Session: ${SESSION_ID}`,
97
110
  });
98
111
  // Live memory loader — user runs /torqon_context once at conversation start.
99
112
  // Fetches all stored facts from the API and injects them directly into the prompt.
@@ -162,8 +175,10 @@ server.tool('auto_process', 'CALL THIS FIRST on every user message. Stores new f
162
175
  return { content: [{ type: 'text', text: '[Torqon] No API key configured. Run: npx -y @torqon/mcp@latest add <client> --api-key <your-key>' }] };
163
176
  }
164
177
  // Fire store and retrieve in parallel
178
+ // Store uses the RAW message so the extraction LLM sees everything.
179
+ // Retrieve uses the cleaned message for better embedding matches.
165
180
  const [, retrieve] = await Promise.all([
166
- apiPost('/chat', { conversationId: SESSION_ID, message: cleaned, storeOnly: true }),
181
+ apiPost('/chat', { conversationId: SESSION_ID, message, storeOnly: true }),
167
182
  apiPost('/chat', { conversationId: SESSION_ID, message: cleaned, rawFacts: true }),
168
183
  ]);
169
184
  if (!retrieve.ok) {
@@ -188,16 +203,16 @@ server.tool('auto_process', 'CALL THIS FIRST on every user message. Stores new f
188
203
  server.tool('store_memory', 'Explicitly stores an important fact or decision into Torqon memory. Use for high-value facts after auto_process.', {
189
204
  message: z.string().describe('The fact or decision to store'),
190
205
  }, async ({ message }) => {
191
- const cleaned = cleanMessage(message);
192
206
  if (!API_KEY) {
193
207
  return { content: [{ type: 'text', text: '[Torqon] No API key configured. Run: npx -y @torqon/mcp@latest add <client> --api-key <your-key>' }] };
194
208
  }
195
- if (!hasSignal(cleaned)) {
209
+ if (!hasSignal(cleanMessage(message))) {
196
210
  return {
197
211
  content: [{ type: 'text', text: 'Nothing meaningful to store.' }],
198
212
  };
199
213
  }
200
- const result = await apiPost('/chat', { conversationId: SESSION_ID, message: cleaned, storeOnly: true });
214
+ // Send raw message so the extraction LLM sees full content
215
+ const result = await apiPost('/chat', { conversationId: SESSION_ID, message, storeOnly: true });
201
216
  if (!result.ok) {
202
217
  const msg = result.status === 401
203
218
  ? '[Torqon] Invalid API key. Check your TORQON_API_KEY.'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torqon/mcp",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {