cuemap-mcp 0.1.2 → 0.7.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.
- package/README.md +20 -3
- package/build/index.js +94 -10
- package/package.json +11 -7
- package/cuemap-mcp-0.1.0.tgz +0 -0
- package/cuemap-mcp-0.1.1.tgz +0 -0
- package/cuemap-mcp-0.1.2.tgz +0 -0
- package/src/index.ts +0 -270
- package/tsconfig.json +0 -16
package/README.md
CHANGED
|
@@ -54,19 +54,36 @@ To use this MCP server with your AI assistant, add it to your assistant's MCP co
|
|
|
54
54
|
- `path` (string): Absolute path to the local repository.
|
|
55
55
|
- `projectName` (string, optional): The ID of the project to create. Defaults to the folder name of the path.
|
|
56
56
|
|
|
57
|
+
- **`cuemap_add`**: Stores one natural-language memory in an explicit project. The project is created automatically if it does not exist.
|
|
58
|
+
- `content` (string): Memory content to store.
|
|
59
|
+
- `project` (string): Project ID that will own the memory.
|
|
60
|
+
- `cues` (string[], optional): Explicit cues/tags to associate with the memory.
|
|
61
|
+
- `metadata` (object, optional): JSON metadata to store with the memory.
|
|
62
|
+
- `source_key` (string, optional): Stable source key for deterministic upsert/deduplication.
|
|
63
|
+
- `cuepacks` (string[], optional): CuePack names to apply during deterministic cue extraction.
|
|
64
|
+
- `disable_temporal_chunking` (boolean, optional): Disable temporal chunking for this memory.
|
|
65
|
+
- `async_ingest` (boolean, optional): Process ingestion in the background and return immediately.
|
|
66
|
+
|
|
57
67
|
- **`cuemap_recall`**: Recalls context about a codebase from your CueMap integrated brain. Uses natural language and semantic search to find relevant information.
|
|
58
68
|
- `query` (string): The natural language query to search for.
|
|
59
69
|
- `limit` (number, optional): Maximum results to return (default: 10).
|
|
60
70
|
- `projects` (string[], optional): List of project IDs to scope the search to. Multiple enables cross-project queries.
|
|
61
71
|
- `cues` (string[], optional): Specific cue tags to filter the search.
|
|
72
|
+
- `query_time` (string, optional): Timestamp or natural-language time anchor for v0.7 temporal query intent.
|
|
62
73
|
- `depth` (number, optional): Depth of multi-hop recall expander (default: 1).
|
|
74
|
+
- `expansion_depth` (number, optional): Alias/cue expansion depth (default: 1).
|
|
63
75
|
- `auto_reinforce` (boolean, optional): Automatically reinforce retrieved memories (default: false).
|
|
64
76
|
- `min_intersection` (number, optional): Minimum required cue intersection count (default: 0).
|
|
65
77
|
- `explain` (boolean, optional): Include scoring explanation data in results (default: false).
|
|
66
|
-
- `
|
|
78
|
+
- `trace_timing` (boolean, optional): Include v0.7 timing diagnostics.
|
|
67
79
|
- `disable_salience_bias` (boolean, optional): Disable salience scoring bias.
|
|
68
|
-
- `
|
|
69
|
-
- `
|
|
80
|
+
- `disable_alias_expansion` (boolean, optional): Disable lexicon synonym injection during querying (default: true).
|
|
81
|
+
- `cuepacks` (string[], optional): Cuepack names to apply during query-intent expansion.
|
|
82
|
+
- `parent_fusion` (`off` | `auto` | `force`, optional): Chunk-parent fusion mode.
|
|
83
|
+
- `ordered_reconstruction` (`off` | `auto` | `force`, optional): Ordered session reconstruction mode.
|
|
84
|
+
- `evidence_coverage` (`off` | `auto` | `force`, optional): Multi-evidence coverage mode.
|
|
85
|
+
- `disable_cuebridge_artifacts` (boolean, optional): Disable CueBridge artifact expansion.
|
|
86
|
+
- `cuebridge_gap_limit` (number, optional): Maximum CueBridge gap expansions.
|
|
70
87
|
|
|
71
88
|
## License
|
|
72
89
|
|
package/build/index.js
CHANGED
|
@@ -95,10 +95,8 @@ async function main() {
|
|
|
95
95
|
}, async (args) => {
|
|
96
96
|
try {
|
|
97
97
|
const pName = args.projectName || path_1.default.basename(args.path);
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
const rawList = Array.isArray(_projectsRes) ? _projectsRes : (_projectsRes?.projects || []);
|
|
101
|
-
const projectIds = rawList.map((p) => typeof p === 'string' ? p : p.project_id);
|
|
98
|
+
const projects = await client.listProjects();
|
|
99
|
+
const projectIds = projects.map((p) => typeof p === 'string' ? p : p.project_id);
|
|
102
100
|
if (!projectIds.includes(pName)) {
|
|
103
101
|
await client.createProject(pName);
|
|
104
102
|
}
|
|
@@ -135,26 +133,112 @@ async function main() {
|
|
|
135
133
|
};
|
|
136
134
|
}
|
|
137
135
|
});
|
|
136
|
+
server.registerTool("cuemap_add", {
|
|
137
|
+
description: "Store a natural-language memory in an explicit CueMap project. Creates the project if it does not exist, then applies deterministic cue extraction plus any supplied cues and metadata.",
|
|
138
|
+
inputSchema: zod_1.z.object({
|
|
139
|
+
content: zod_1.z.string().min(1).describe("The natural-language memory content to store."),
|
|
140
|
+
project: zod_1.z.string().min(1).describe("The project ID that will own the memory."),
|
|
141
|
+
cues: zod_1.z.array(zod_1.z.string()).optional().describe("Optional explicit cues/tags to associate with the memory."),
|
|
142
|
+
metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional().describe("Optional JSON metadata to store with the memory."),
|
|
143
|
+
source_key: zod_1.z.string().optional().describe("Optional stable source key for deterministic upsert/deduplication."),
|
|
144
|
+
cuepacks: zod_1.z.array(zod_1.z.string()).optional().describe("Optional CuePack names to apply during deterministic cue extraction."),
|
|
145
|
+
disable_temporal_chunking: zod_1.z.boolean().optional().describe("Disable temporal chunking for this memory. Default is false."),
|
|
146
|
+
async_ingest: zod_1.z.boolean().optional().describe("Process ingestion in the background and return immediately. Default is false."),
|
|
147
|
+
})
|
|
148
|
+
}, async (args) => {
|
|
149
|
+
try {
|
|
150
|
+
const projects = await client.listProjects();
|
|
151
|
+
const projectIds = projects.map((p) => typeof p === "string" ? p : p.project_id);
|
|
152
|
+
if (!projectIds.includes(args.project)) {
|
|
153
|
+
await client.createProject(args.project);
|
|
154
|
+
}
|
|
155
|
+
const projectClient = new cuemap_1.default({ url: CUEMAP_URL, projectId: args.project });
|
|
156
|
+
const memoryId = await projectClient.add(args.content, args.cues || [], args.metadata, args.disable_temporal_chunking || false, {
|
|
157
|
+
sourceKey: args.source_key,
|
|
158
|
+
cuepacks: args.cuepacks,
|
|
159
|
+
asyncIngest: args.async_ingest,
|
|
160
|
+
});
|
|
161
|
+
return {
|
|
162
|
+
content: [{
|
|
163
|
+
type: "text",
|
|
164
|
+
text: `Stored memory ${memoryId} in CueMap project ${args.project}.`,
|
|
165
|
+
}],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
console.error("Error adding CueMap memory", error);
|
|
170
|
+
return {
|
|
171
|
+
content: [{
|
|
172
|
+
type: "text",
|
|
173
|
+
text: `Error executing cuemap_add tool: ${error?.message || "Unknown error"}`,
|
|
174
|
+
}],
|
|
175
|
+
isError: true,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
});
|
|
138
179
|
server.registerTool("cuemap_recall", {
|
|
139
|
-
description: "Recall context about a codebase from a CueMap
|
|
180
|
+
description: "Recall context about a codebase from a CueMap integrated brain. Uses natural language and associative search to find relevant information.",
|
|
140
181
|
inputSchema: zod_1.z.object({
|
|
141
182
|
query: zod_1.z.string().describe("The natural language query to search the codebase memory for."),
|
|
142
183
|
limit: zod_1.z.number().optional().describe("Optional limit on the number of results to return. Default is 10."),
|
|
143
184
|
projects: zod_1.z.array(zod_1.z.string()).optional().describe("Optional list of project IDs to scope the search to. Provide multiple for cross-project recall. If not provided, searches the default project."),
|
|
144
185
|
cues: zod_1.z.array(zod_1.z.string()).optional().describe("Optional list of specific cues/tags to filter the search."),
|
|
186
|
+
query_time: zod_1.z.string().optional().describe("Optional timestamp or natural-language time anchor used by v0.7 temporal query intent."),
|
|
145
187
|
depth: zod_1.z.number().optional().describe("Depth of multi-hop recall. Default is 1."),
|
|
188
|
+
expansion_depth: zod_1.z.number().optional().describe("Alias/cue expansion depth. Default is 1."),
|
|
146
189
|
auto_reinforce: zod_1.z.boolean().optional().describe("Automatically reinforce retrieved memories. Default is false."),
|
|
147
190
|
min_intersection: zod_1.z.number().optional().describe("Minimum intersection count for retrieval. Default is 0."),
|
|
148
191
|
explain: zod_1.z.boolean().optional().describe("Include explain component for debug information in results. Default is false."),
|
|
149
|
-
|
|
192
|
+
trace_timing: zod_1.z.boolean().optional().describe("Include v0.7 timing diagnostics in the response. Default is false."),
|
|
150
193
|
disable_salience_bias: zod_1.z.boolean().optional().describe("Disable salience bias scoring. Default is false."),
|
|
151
|
-
|
|
152
|
-
|
|
194
|
+
disable_alias_expansion: zod_1.z.boolean().optional().describe("Disable alias expansion during querying. Default is true."),
|
|
195
|
+
cuepacks: zod_1.z.array(zod_1.z.string()).optional().describe("Optional cuepack names to apply during query-intent expansion."),
|
|
196
|
+
parent_fusion: zod_1.z.enum(["off", "auto", "force"]).optional().describe("Parent fusion mode for chunk-parent reconstruction. Default is off."),
|
|
197
|
+
parent_fusion_limit: zod_1.z.number().optional().describe("Candidate limit for parent fusion. Default is 80."),
|
|
198
|
+
parent_fusion_min_chunks: zod_1.z.number().optional().describe("Minimum sibling chunks required for parent fusion. Default is 2."),
|
|
199
|
+
ordered_reconstruction: zod_1.z.enum(["off", "auto", "force"]).optional().describe("Ordered session reconstruction mode. Default is off."),
|
|
200
|
+
ordered_reconstruction_limit: zod_1.z.number().optional().describe("Result scan limit for ordered reconstruction. Default is 80."),
|
|
201
|
+
ordered_session_scan_limit: zod_1.z.number().optional().describe("Per-session scan limit for ordered reconstruction. Default is 4096."),
|
|
202
|
+
ordered_max_sessions: zod_1.z.number().optional().describe("Maximum sessions considered for ordered reconstruction. Default is 3."),
|
|
203
|
+
evidence_coverage: zod_1.z.enum(["off", "auto", "force"]).optional().describe("Evidence coverage mode for multi-evidence answers. Default is off."),
|
|
204
|
+
evidence_coverage_limit: zod_1.z.number().optional().describe("Result scan limit for evidence coverage. Default is 100."),
|
|
205
|
+
evidence_coverage_session_scan_limit: zod_1.z.number().optional().describe("Per-session scan limit for evidence coverage. Default is 4096."),
|
|
206
|
+
evidence_coverage_max_sessions: zod_1.z.number().optional().describe("Maximum sessions considered for evidence coverage. Default is 3."),
|
|
207
|
+
disable_cuebridge_artifacts: zod_1.z.boolean().optional().describe("Disable CueBridge artifact expansion. Default is false."),
|
|
208
|
+
cuebridge_gap_limit: zod_1.z.number().optional().describe("Maximum CueBridge gap expansions. Default is 6."),
|
|
153
209
|
}),
|
|
154
210
|
}, async (args) => {
|
|
155
211
|
try {
|
|
156
|
-
const { query, limit = 10, projects, cues, depth = 1, auto_reinforce = false, min_intersection, explain = false,
|
|
157
|
-
const results = await client.recall(
|
|
212
|
+
const { query, limit = 10, projects, cues, query_time, depth = 1, expansion_depth = 1, auto_reinforce = false, min_intersection, explain = false, trace_timing = false, disable_salience_bias = false, disable_alias_expansion = true, cuepacks, parent_fusion = "off", parent_fusion_limit = 80, parent_fusion_min_chunks = 2, ordered_reconstruction = "off", ordered_reconstruction_limit = 80, ordered_session_scan_limit = 4096, ordered_max_sessions = 3, evidence_coverage = "off", evidence_coverage_limit = 100, evidence_coverage_session_scan_limit = 4096, evidence_coverage_max_sessions = 3, disable_cuebridge_artifacts = false, cuebridge_gap_limit = 6 } = args;
|
|
213
|
+
const results = await client.recall({
|
|
214
|
+
query_text: query,
|
|
215
|
+
cues,
|
|
216
|
+
projects,
|
|
217
|
+
limit,
|
|
218
|
+
depth,
|
|
219
|
+
query_time,
|
|
220
|
+
expansion_depth,
|
|
221
|
+
auto_reinforce,
|
|
222
|
+
min_intersection,
|
|
223
|
+
explain,
|
|
224
|
+
trace_timing,
|
|
225
|
+
disable_salience_bias,
|
|
226
|
+
disable_alias_expansion,
|
|
227
|
+
cuepacks,
|
|
228
|
+
parent_fusion,
|
|
229
|
+
parent_fusion_limit,
|
|
230
|
+
parent_fusion_min_chunks,
|
|
231
|
+
ordered_reconstruction,
|
|
232
|
+
ordered_reconstruction_limit,
|
|
233
|
+
ordered_session_scan_limit,
|
|
234
|
+
ordered_max_sessions,
|
|
235
|
+
evidence_coverage,
|
|
236
|
+
evidence_coverage_limit,
|
|
237
|
+
evidence_coverage_session_scan_limit,
|
|
238
|
+
evidence_coverage_max_sessions,
|
|
239
|
+
disable_cuebridge_artifacts,
|
|
240
|
+
cuebridge_gap_limit,
|
|
241
|
+
});
|
|
158
242
|
let items = [];
|
|
159
243
|
if (results.results && Array.isArray(results.results)) {
|
|
160
244
|
if (results.results.length > 0 && results.results[0].project_id) {
|
package/package.json
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cuemap-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "MCP server for CueMap",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"cuemap-mcp": "./build/index.js"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"build",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
9
14
|
"scripts": {
|
|
10
15
|
"build": "tsc",
|
|
11
16
|
"start": "node build/index.js",
|
|
@@ -27,7 +32,7 @@
|
|
|
27
32
|
"type": "commonjs",
|
|
28
33
|
"dependencies": {
|
|
29
34
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
30
|
-
"cuemap": "^0.
|
|
35
|
+
"cuemap": "^0.7.0",
|
|
31
36
|
"zod": "^4.3.6"
|
|
32
37
|
},
|
|
33
38
|
"devDependencies": {
|
|
@@ -35,9 +40,8 @@
|
|
|
35
40
|
"typescript": "^5.9.3"
|
|
36
41
|
},
|
|
37
42
|
"optionalDependencies": {
|
|
38
|
-
"@cuemap-dev/engine-darwin-arm64": "^0.
|
|
39
|
-
"@cuemap-dev/engine-darwin-x64": "^0.
|
|
40
|
-
"@cuemap-dev/engine-linux-x64": "^0.
|
|
41
|
-
"@cuemap-dev/engine-win32-x64": "^0.6.4"
|
|
43
|
+
"@cuemap-dev/engine-darwin-arm64": "^0.7.0",
|
|
44
|
+
"@cuemap-dev/engine-darwin-x64": "^0.7.0",
|
|
45
|
+
"@cuemap-dev/engine-linux-x64": "^0.7.0"
|
|
42
46
|
}
|
|
43
|
-
}
|
|
47
|
+
}
|
package/cuemap-mcp-0.1.0.tgz
DELETED
|
Binary file
|
package/cuemap-mcp-0.1.1.tgz
DELETED
|
Binary file
|
package/cuemap-mcp-0.1.2.tgz
DELETED
|
Binary file
|
package/src/index.ts
DELETED
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
import CueMap from "cuemap";
|
|
7
|
-
import { spawn, ChildProcess } from "child_process";
|
|
8
|
-
import path from "path";
|
|
9
|
-
import os from "os";
|
|
10
|
-
import fs from "fs";
|
|
11
|
-
|
|
12
|
-
let engineProcess: ChildProcess | null = null;
|
|
13
|
-
let CUEMAP_URL = process.env.CUEMAP_URL;
|
|
14
|
-
let client: CueMap;
|
|
15
|
-
|
|
16
|
-
const server = new McpServer({
|
|
17
|
-
name: "cuemap-mcp",
|
|
18
|
-
version: "1.0.0",
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
function getCuemapBinaryPath(): string | null {
|
|
22
|
-
if (process.env.CUEMAP_BIN) return process.env.CUEMAP_BIN;
|
|
23
|
-
|
|
24
|
-
// Check optional dependencies dynamically
|
|
25
|
-
try {
|
|
26
|
-
const platform = os.platform();
|
|
27
|
-
const arch = os.arch();
|
|
28
|
-
const pkgName = `@cuemap-dev/engine-${platform}-${arch}`;
|
|
29
|
-
const resolved = require.resolve(`${pkgName}/package.json`);
|
|
30
|
-
const binPath = path.join(path.dirname(resolved), "bin", "cuemap");
|
|
31
|
-
if (fs.existsSync(binPath)) return binPath;
|
|
32
|
-
} catch (e) {
|
|
33
|
-
// Ignored
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Fallback: Check locally built binary (for development)
|
|
37
|
-
const localPath = path.resolve(__dirname, "../../rust_engine/target/release/cuemap");
|
|
38
|
-
if (fs.existsSync(localPath)) return localPath;
|
|
39
|
-
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async function startEngine(): Promise<void> {
|
|
44
|
-
if (CUEMAP_URL) {
|
|
45
|
-
console.error(`Using external CueMap engine at ${CUEMAP_URL}`);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const binPath = getCuemapBinaryPath();
|
|
50
|
-
if (!binPath) {
|
|
51
|
-
console.error("Could not find cuemap binary. Please install the correct optional dependency, set CUEMAP_BIN, or set CUEMAP_URL to an existing instance.");
|
|
52
|
-
console.error("Falling back to expecting 'cuemap' in PATH.");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const execPath = binPath || "cuemap";
|
|
56
|
-
const port = process.env.CUEMAP_PORT || "8080";
|
|
57
|
-
CUEMAP_URL = `http://127.0.0.1:${port}`;
|
|
58
|
-
|
|
59
|
-
const args = ["start", "--port", port];
|
|
60
|
-
if (process.env.CUEMAP_CONFIG_PATH) {
|
|
61
|
-
args.push("--config", process.env.CUEMAP_CONFIG_PATH);
|
|
62
|
-
console.error(`Using custom config at ${process.env.CUEMAP_CONFIG_PATH}`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
console.error(`Starting Embedded CueMap Engine on port ${port}...`);
|
|
66
|
-
engineProcess = spawn(execPath, args, {
|
|
67
|
-
stdio: "ignore",
|
|
68
|
-
env: { ...process.env, CUEMAP_PORT: port }
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
engineProcess.on("error", (err) => {
|
|
72
|
-
console.error("Failed to start embedded engine:", err);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
engineProcess.on("exit", (code) => {
|
|
76
|
-
console.error(`Embedded engine exited with code ${code}`);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
process.on("SIGINT", () => {
|
|
80
|
-
if (engineProcess) engineProcess.kill("SIGINT");
|
|
81
|
-
process.exit(0);
|
|
82
|
-
});
|
|
83
|
-
process.on("SIGTERM", () => {
|
|
84
|
-
if (engineProcess) engineProcess.kill("SIGTERM");
|
|
85
|
-
process.exit(0);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// Wait slightly to ensure startup
|
|
89
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async function main() {
|
|
93
|
-
await startEngine();
|
|
94
|
-
|
|
95
|
-
client = new CueMap({ url: CUEMAP_URL });
|
|
96
|
-
|
|
97
|
-
server.registerTool(
|
|
98
|
-
"cuemap_init",
|
|
99
|
-
{
|
|
100
|
-
description: "Initialize a CueMap project for a given local repository path. This triggers the Self-Learning Agent to ingest the codebase. Call this if the user hasn't set up the project yet or if cuemap_recall returns empty.",
|
|
101
|
-
inputSchema: z.object({
|
|
102
|
-
path: z.string().describe("Absolute path to the local repository."),
|
|
103
|
-
projectName: z.string().optional().describe("The ID of the project to create. Defaults to the folder name of the path.")
|
|
104
|
-
})
|
|
105
|
-
},
|
|
106
|
-
async (args) => {
|
|
107
|
-
try {
|
|
108
|
-
const pName = args.projectName || path.basename(args.path);
|
|
109
|
-
|
|
110
|
-
const _projectsRes: any = await client.listProjects();
|
|
111
|
-
// Engine returns {projects: [{project_id: "...", ...}, ...]}
|
|
112
|
-
const rawList = Array.isArray(_projectsRes) ? _projectsRes : (_projectsRes?.projects || []);
|
|
113
|
-
const projectIds = rawList.map((p: any) => typeof p === 'string' ? p : p.project_id);
|
|
114
|
-
if (!projectIds.includes(pName)) {
|
|
115
|
-
await client.createProject(pName);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
await client.setProjectWatchDir(pName, args.path);
|
|
119
|
-
console.error(`Started ingestion for project ${pName} at ${args.path}`);
|
|
120
|
-
|
|
121
|
-
// Polling for job completion
|
|
122
|
-
let isComplete = false;
|
|
123
|
-
let checks = 0;
|
|
124
|
-
while (!isComplete && checks < 60) {
|
|
125
|
-
const status = await client.jobsStatus(pName);
|
|
126
|
-
if (status.phase === "idle") {
|
|
127
|
-
isComplete = true;
|
|
128
|
-
break;
|
|
129
|
-
}
|
|
130
|
-
checks++;
|
|
131
|
-
await new Promise(r => setTimeout(r, 1000));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (isComplete) {
|
|
135
|
-
return {
|
|
136
|
-
content: [{ type: "text" as const, text: `Successfully initialized and ingested project ${pName}. You can now use cuemap_recall.` }]
|
|
137
|
-
};
|
|
138
|
-
} else {
|
|
139
|
-
return {
|
|
140
|
-
content: [{ type: "text" as const, text: `Project ${pName} initialized, but ingestion is still actively running in the background. Partial results may be returned by cuemap_recall.` }]
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
} catch (error: any) {
|
|
144
|
-
console.error("Error initializing CueMap project", error);
|
|
145
|
-
return {
|
|
146
|
-
content: [{ type: "text" as const, text: `Error initializing project: ${error?.message || "Unknown error"}` }],
|
|
147
|
-
isError: true,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
server.registerTool(
|
|
154
|
-
"cuemap_recall",
|
|
155
|
-
{
|
|
156
|
-
description: "Recall context about a codebase from a CueMap integerated brain. Uses natural language and semantic search to find relevant information.",
|
|
157
|
-
inputSchema: z.object({
|
|
158
|
-
query: z.string().describe("The natural language query to search the codebase memory for."),
|
|
159
|
-
limit: z.number().optional().describe("Optional limit on the number of results to return. Default is 10."),
|
|
160
|
-
projects: z.array(z.string()).optional().describe("Optional list of project IDs to scope the search to. Provide multiple for cross-project recall. If not provided, searches the default project."),
|
|
161
|
-
cues: z.array(z.string()).optional().describe("Optional list of specific cues/tags to filter the search."),
|
|
162
|
-
depth: z.number().optional().describe("Depth of multi-hop recall. Default is 1."),
|
|
163
|
-
auto_reinforce: z.boolean().optional().describe("Automatically reinforce retrieved memories. Default is false."),
|
|
164
|
-
min_intersection: z.number().optional().describe("Minimum intersection count for retrieval. Default is 0."),
|
|
165
|
-
explain: z.boolean().optional().describe("Include explain component for debug information in results. Default is false."),
|
|
166
|
-
disable_pattern_completion: z.boolean().optional().describe("Disable pattern completion inference. Default is false."),
|
|
167
|
-
disable_salience_bias: z.boolean().optional().describe("Disable salience bias scoring. Default is false."),
|
|
168
|
-
disable_systems_consolidation: z.boolean().optional().describe("Disable systems consolidation (exclude summaries). Default is false."),
|
|
169
|
-
disable_alias_expansion: z.boolean().optional().describe("Disable alias expansion during querying. Default is false."),
|
|
170
|
-
}),
|
|
171
|
-
},
|
|
172
|
-
async (args) => {
|
|
173
|
-
try {
|
|
174
|
-
const {
|
|
175
|
-
query, limit = 10, projects, cues,
|
|
176
|
-
depth = 1, auto_reinforce = false, min_intersection,
|
|
177
|
-
explain = false, disable_pattern_completion = false,
|
|
178
|
-
disable_salience_bias = false, disable_systems_consolidation = false,
|
|
179
|
-
disable_alias_expansion = false
|
|
180
|
-
} = args;
|
|
181
|
-
|
|
182
|
-
const results = await client.recall(
|
|
183
|
-
query,
|
|
184
|
-
cues,
|
|
185
|
-
projects,
|
|
186
|
-
limit,
|
|
187
|
-
depth,
|
|
188
|
-
auto_reinforce,
|
|
189
|
-
min_intersection,
|
|
190
|
-
explain,
|
|
191
|
-
disable_pattern_completion,
|
|
192
|
-
disable_salience_bias,
|
|
193
|
-
disable_systems_consolidation,
|
|
194
|
-
disable_alias_expansion
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
let items: any[] = [];
|
|
198
|
-
|
|
199
|
-
if (results.results && Array.isArray(results.results)) {
|
|
200
|
-
if (results.results.length > 0 && results.results[0].project_id) {
|
|
201
|
-
results.results.forEach((projectRes: any) => {
|
|
202
|
-
if (projectRes.results && Array.isArray(projectRes.results)) {
|
|
203
|
-
items = items.concat(projectRes.results.map((r: any) => ({ ...r, project_id: projectRes.project_id })));
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
} else {
|
|
207
|
-
items = results.results;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (!items || items.length === 0) {
|
|
212
|
-
return {
|
|
213
|
-
content: [
|
|
214
|
-
{
|
|
215
|
-
type: "text" as const,
|
|
216
|
-
text: "No results found for the query in CueMap.",
|
|
217
|
-
},
|
|
218
|
-
],
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
let formattedText = `CueMap found ${items.length} relevant results:\n\n`;
|
|
223
|
-
items.forEach((r: any, i: number) => {
|
|
224
|
-
const scoreStr = r.score !== undefined ? ` (Score: ${Number(r.score).toFixed(2)})` : '';
|
|
225
|
-
formattedText += `### Result ${i + 1}${scoreStr}\n`;
|
|
226
|
-
const projectId = r.project_id || (projects && projects.length === 1 ? projects[0] : null);
|
|
227
|
-
if (projectId) formattedText += `*Project: ${projectId}*\n`;
|
|
228
|
-
if (r.timestamp) {
|
|
229
|
-
const date = new Date(r.timestamp);
|
|
230
|
-
formattedText += `*Timestamp: ${date.toISOString()}*\n`;
|
|
231
|
-
} else if (r.created_at) {
|
|
232
|
-
const date = new Date(r.created_at * 1000);
|
|
233
|
-
formattedText += `*Timestamp: ${date.toISOString()}*\n`;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
formattedText += `${r.content}\n\n`;
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
return {
|
|
240
|
-
content: [
|
|
241
|
-
{
|
|
242
|
-
type: "text" as const,
|
|
243
|
-
text: formattedText,
|
|
244
|
-
},
|
|
245
|
-
],
|
|
246
|
-
};
|
|
247
|
-
} catch (error: any) {
|
|
248
|
-
console.error("Error calling CueMap engine", error);
|
|
249
|
-
return {
|
|
250
|
-
content: [
|
|
251
|
-
{
|
|
252
|
-
type: "text" as const,
|
|
253
|
-
text: `Error executing cuemap_recall tool: ${error?.message || "Unknown error"}`,
|
|
254
|
-
},
|
|
255
|
-
],
|
|
256
|
-
isError: true,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
const transport = new StdioServerTransport();
|
|
263
|
-
await server.connect(transport);
|
|
264
|
-
console.error("CueMap MCP server running on stdio");
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
main().catch((error) => {
|
|
268
|
-
console.error("Server error:", error);
|
|
269
|
-
process.exit(1);
|
|
270
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "CommonJS",
|
|
5
|
-
"moduleResolution": "Node",
|
|
6
|
-
"rootDir": "./src",
|
|
7
|
-
"outDir": "./build",
|
|
8
|
-
"esModuleInterop": true,
|
|
9
|
-
"strict": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true
|
|
12
|
-
},
|
|
13
|
-
"include": [
|
|
14
|
-
"src/**/*"
|
|
15
|
-
]
|
|
16
|
-
}
|