@mmnto/mcp 0.8.0 → 0.9.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/dist/tools/add-lesson.d.ts.map +1 -1
- package/dist/tools/add-lesson.js +2 -1
- package/dist/tools/add-lesson.js.map +1 -1
- package/dist/tools/search-knowledge.d.ts.map +1 -1
- package/dist/tools/search-knowledge.js +8 -3
- package/dist/tools/search-knowledge.js.map +1 -1
- package/dist/xml-format.d.ts +8 -0
- package/dist/xml-format.d.ts.map +1 -0
- package/dist/xml-format.js +12 -0
- package/dist/xml-format.js.map +1 -0
- package/dist/xml-format.test.d.ts +2 -0
- package/dist/xml-format.test.d.ts.map +1 -0
- package/dist/xml-format.test.js +33 -0
- package/dist/xml-format.test.js.map +1 -0
- package/package.json +5 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-lesson.d.ts","sourceRoot":"","sources":["../../src/tools/add-lesson.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"add-lesson.d.ts","sourceRoot":"","sources":["../../src/tools/add-lesson.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwBzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyFzD"}
|
package/dist/tools/add-lesson.js
CHANGED
|
@@ -3,6 +3,7 @@ import * as fs from 'node:fs';
|
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { getContext, reconnectStore } from '../context.js';
|
|
6
|
+
import { formatXmlResponse } from '../xml-format.js';
|
|
6
7
|
/**
|
|
7
8
|
* Detect the correct package-manager command for running `totem sync`.
|
|
8
9
|
*/
|
|
@@ -81,7 +82,7 @@ export function registerAddLesson(server) {
|
|
|
81
82
|
content: [
|
|
82
83
|
{
|
|
83
84
|
type: 'text',
|
|
84
|
-
text: `Lesson saved to ${config.totemDir}/lessons.md. Background re-index triggered — it will be searchable shortly
|
|
85
|
+
text: formatXmlResponse('lesson_added', `Lesson saved to ${config.totemDir}/lessons.md. Background re-index triggered — it will be searchable shortly.`),
|
|
85
86
|
},
|
|
86
87
|
],
|
|
87
88
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-lesson.js","sourceRoot":"","sources":["../../src/tools/add-lesson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"add-lesson.js","sourceRoot":"","sources":["../../src/tools/add-lesson.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-knowledge.d.ts","sourceRoot":"","sources":["../../src/tools/search-knowledge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"search-knowledge.d.ts","sourceRoot":"","sources":["../../src/tools/search-knowledge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA2CzE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkD/D"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ContentTypeSchema } from '@mmnto/totem';
|
|
3
3
|
import { getContext, reconnectStore } from '../context.js';
|
|
4
|
+
import { formatXmlResponse } from '../xml-format.js';
|
|
4
5
|
async function performSearch(query, typeFilter, maxResults) {
|
|
5
6
|
const { store } = await getContext();
|
|
6
7
|
const results = await store.search({
|
|
@@ -9,18 +10,22 @@ async function performSearch(query, typeFilter, maxResults) {
|
|
|
9
10
|
maxResults: maxResults ?? 5,
|
|
10
11
|
});
|
|
11
12
|
if (results.length === 0) {
|
|
12
|
-
return {
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{ type: 'text', text: formatXmlResponse('knowledge', 'No results found.') },
|
|
16
|
+
],
|
|
17
|
+
};
|
|
13
18
|
}
|
|
14
19
|
const formatted = results
|
|
15
20
|
.map((r, i) => `### ${i + 1}. ${r.label} (${r.type})\n` +
|
|
16
21
|
`**File:** ${r.filePath} | **Score:** ${r.score.toFixed(3)}\n\n` +
|
|
17
22
|
`${r.content}`)
|
|
18
23
|
.join('\n\n---\n\n');
|
|
19
|
-
return { content: [{ type: 'text', text: formatted }] };
|
|
24
|
+
return { content: [{ type: 'text', text: formatXmlResponse('knowledge', formatted) }] };
|
|
20
25
|
}
|
|
21
26
|
export function registerSearchKnowledge(server) {
|
|
22
27
|
server.registerTool('search_knowledge', {
|
|
23
|
-
description:
|
|
28
|
+
description: `Search the Totem knowledge index for relevant code, session logs, specs, or lessons. Use this BEFORE writing code, reviewing PRs, or making architectural decisions to retrieve domain constraints, past traps, and established patterns.`,
|
|
24
29
|
inputSchema: {
|
|
25
30
|
query: z.string().describe('The search query'),
|
|
26
31
|
type_filter: z
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-knowledge.js","sourceRoot":"","sources":["../../src/tools/search-knowledge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"search-knowledge.js","sourceRoot":"","sources":["../../src/tools/search-knowledge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps content in XML delimiters with escaped closing tags to prevent
|
|
3
|
+
* indirect prompt injection when MCP tool responses are consumed by LLMs.
|
|
4
|
+
*
|
|
5
|
+
* @see https://github.com/mmnto-ai/totem/issues/149
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatXmlResponse(tag: string, content: string): string;
|
|
8
|
+
//# sourceMappingURL=xml-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-format.d.ts","sourceRoot":"","sources":["../src/xml-format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAOtE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps content in XML delimiters with escaped closing tags to prevent
|
|
3
|
+
* indirect prompt injection when MCP tool responses are consumed by LLMs.
|
|
4
|
+
*
|
|
5
|
+
* @see https://github.com/mmnto-ai/totem/issues/149
|
|
6
|
+
*/
|
|
7
|
+
export function formatXmlResponse(tag, content) {
|
|
8
|
+
const safeTag = tag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
9
|
+
const escaped = content.replace(new RegExp(`</\\s*${safeTag}\\s*>`, 'gi'), (match) => `<\\/${match.slice(2)}`);
|
|
10
|
+
return `<${tag}>\n${escaped}\n</${tag}>`;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=xml-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-format.js","sourceRoot":"","sources":["../src/xml-format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,OAAe;IAC5D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAC7B,IAAI,MAAM,CAAC,SAAS,OAAO,OAAO,EAAE,IAAI,CAAC,EACzC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CACnC,CAAC;IACF,OAAO,IAAI,GAAG,MAAM,OAAO,OAAO,GAAG,GAAG,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-format.test.d.ts","sourceRoot":"","sources":["../src/xml-format.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { formatXmlResponse } from './xml-format.js';
|
|
3
|
+
describe('formatXmlResponse', () => {
|
|
4
|
+
it('wraps content in XML tags', () => {
|
|
5
|
+
const result = formatXmlResponse('knowledge', 'Hello world');
|
|
6
|
+
expect(result).toBe('<knowledge>\nHello world\n</knowledge>');
|
|
7
|
+
});
|
|
8
|
+
it('escapes exact lowercase closing tags in content', () => {
|
|
9
|
+
const result = formatXmlResponse('knowledge', 'payload </knowledge> injection');
|
|
10
|
+
expect(result).toBe('<knowledge>\npayload <\\/knowledge> injection\n</knowledge>');
|
|
11
|
+
});
|
|
12
|
+
it('escapes mixed-case closing tags (case-insensitive)', () => {
|
|
13
|
+
const result = formatXmlResponse('knowledge', 'try </KNOWLEDGE> or </Knowledge>');
|
|
14
|
+
expect(result).toBe('<knowledge>\ntry <\\/KNOWLEDGE> or <\\/Knowledge>\n</knowledge>');
|
|
15
|
+
});
|
|
16
|
+
it('escapes multiple instances of the closing tag', () => {
|
|
17
|
+
const result = formatXmlResponse('knowledge', '</knowledge> and </knowledge>');
|
|
18
|
+
expect(result).toBe('<knowledge>\n<\\/knowledge> and <\\/knowledge>\n</knowledge>');
|
|
19
|
+
});
|
|
20
|
+
it('wraps empty content', () => {
|
|
21
|
+
const result = formatXmlResponse('knowledge', '');
|
|
22
|
+
expect(result).toBe('<knowledge>\n\n</knowledge>');
|
|
23
|
+
});
|
|
24
|
+
it('works with different tag names', () => {
|
|
25
|
+
const result = formatXmlResponse('lesson_added', 'Saved. </lesson_added> test');
|
|
26
|
+
expect(result).toBe('<lesson_added>\nSaved. <\\/lesson_added> test\n</lesson_added>');
|
|
27
|
+
});
|
|
28
|
+
it('escapes closing tags with internal whitespace', () => {
|
|
29
|
+
const result = formatXmlResponse('knowledge', 'try </ knowledge> or </knowledge >');
|
|
30
|
+
expect(result).toBe('<knowledge>\ntry <\\/ knowledge> or <\\/knowledge >\n</knowledge>');
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=xml-format.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-format.test.js","sourceRoot":"","sources":["../src/xml-format.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,EAAE,gCAAgC,CAAC,CAAC;QAChF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,EAAE,kCAAkC,CAAC,CAAC;QAClF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,EAAE,+BAA+B,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,MAAM,GAAG,iBAAiB,CAAC,cAAc,EAAE,6BAA6B,CAAC,CAAC;QAChF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,EAAE,oCAAoC,CAAC,CAAC;QACpF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmnto/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "MCP server for Totem — AI persistent memory and context layer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,11 +18,12 @@
|
|
|
18
18
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
19
19
|
"jiti": "^2.4.0",
|
|
20
20
|
"zod": "^3.24.0",
|
|
21
|
-
"@mmnto/totem": "0.
|
|
21
|
+
"@mmnto/totem": "0.9.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^22.0.0",
|
|
25
|
-
"typescript": "^5.7.0"
|
|
25
|
+
"typescript": "^5.7.0",
|
|
26
|
+
"vitest": "^4.0.18"
|
|
26
27
|
},
|
|
27
28
|
"files": [
|
|
28
29
|
"dist"
|
|
@@ -46,6 +47,6 @@
|
|
|
46
47
|
"dev": "tsc --watch",
|
|
47
48
|
"clean": "rm -rf dist",
|
|
48
49
|
"lint": "eslint src/",
|
|
49
|
-
"test": "
|
|
50
|
+
"test": "vitest run"
|
|
50
51
|
}
|
|
51
52
|
}
|