@evomap/gep-mcp-server 1.0.0 → 1.0.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/package.json +1 -1
- package/src/index.js +10 -4
- package/src/runtime.js +24 -1
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -23,7 +23,7 @@ const HUB_URL = process.env.EVOMAP_HUB_URL || 'https://evomap.ai';
|
|
|
23
23
|
const runtime = new GepRuntime({ assetsDir: ASSETS_DIR, memoryDir: MEMORY_DIR });
|
|
24
24
|
|
|
25
25
|
const server = new Server(
|
|
26
|
-
{ name: 'gep-mcp-server', version: '1.0.
|
|
26
|
+
{ name: 'gep-mcp-server', version: '1.0.1' },
|
|
27
27
|
{ capabilities: { tools: {}, resources: {} } }
|
|
28
28
|
);
|
|
29
29
|
|
|
@@ -208,7 +208,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
208
208
|
params.set('q', args.query.trim().slice(0, 500));
|
|
209
209
|
if (args.type && ['Gene', 'Capsule'].includes(args.type)) params.set('type', args.type);
|
|
210
210
|
if (args.outcome && ['success', 'failed'].includes(args.outcome)) params.set('outcome', args.outcome);
|
|
211
|
-
params.set('limit', String(args.limit || 10));
|
|
211
|
+
params.set('limit', String(Math.min(Math.max(1, parseInt(args.limit, 10) || 10), 50)));
|
|
212
212
|
params.set('include_context', 'true');
|
|
213
213
|
const url = `${HUB_URL}/a2a/assets/semantic-search?${params.toString()}`;
|
|
214
214
|
const res = await fetch(url, { signal: AbortSignal.timeout(15000) });
|
|
@@ -251,8 +251,14 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
251
251
|
const { uri } = request.params;
|
|
252
252
|
switch (uri) {
|
|
253
253
|
case 'gep://spec': {
|
|
254
|
-
const
|
|
255
|
-
|
|
254
|
+
const candidates = [
|
|
255
|
+
resolve(ASSETS_DIR, 'gep-spec-v1.md'),
|
|
256
|
+
resolve(__dirname, '../../gep-protocol/spec/gep-spec-v1.md'),
|
|
257
|
+
];
|
|
258
|
+
const specPath = candidates.find(p => existsSync(p));
|
|
259
|
+
const content = specPath
|
|
260
|
+
? readFileSync(specPath, 'utf8')
|
|
261
|
+
: 'GEP spec not found. Place gep-spec-v1.md in your GEP_ASSETS_DIR or install gep-protocol alongside this package.';
|
|
256
262
|
return { contents: [{ uri, mimeType: 'text/markdown', text: content }] };
|
|
257
263
|
}
|
|
258
264
|
case 'gep://genes':
|
package/src/runtime.js
CHANGED
|
@@ -189,6 +189,11 @@ export class GepRuntime {
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
exportEvolution({ outputPath, agentName }) {
|
|
192
|
+
const resolvedOutput = resolve(outputPath);
|
|
193
|
+
const allowedRoots = [resolve(this.assetsDir), resolve(this.memoryDir, '..')];
|
|
194
|
+
if (!allowedRoots.some(root => resolvedOutput.startsWith(root + '/'))) {
|
|
195
|
+
outputPath = join(this.assetsDir, 'export.gepx');
|
|
196
|
+
}
|
|
192
197
|
const tmpDir = `${outputPath}.tmp`;
|
|
193
198
|
mkdirSync(join(tmpDir, 'genes'), { recursive: true });
|
|
194
199
|
mkdirSync(join(tmpDir, 'capsules'), { recursive: true });
|
|
@@ -216,7 +221,12 @@ export class GepRuntime {
|
|
|
216
221
|
};
|
|
217
222
|
writeFileSync(join(tmpDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
|
|
218
223
|
|
|
219
|
-
|
|
224
|
+
try {
|
|
225
|
+
execFileSync('tar', ['-czf', outputPath, '-C', tmpDir, '.'], { timeout: 30000 });
|
|
226
|
+
} catch (err) {
|
|
227
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
228
|
+
return { ok: false, error: `tar failed: ${err.message}. Ensure tar is available on your system.` };
|
|
229
|
+
}
|
|
220
230
|
rmSync(tmpDir, { recursive: true, force: true });
|
|
221
231
|
|
|
222
232
|
return { ok: true, outputPath, manifest };
|
|
@@ -376,6 +386,19 @@ export class GepRuntime {
|
|
|
376
386
|
_appendToGraph(event) {
|
|
377
387
|
mkdirSync(this.memoryDir, { recursive: true });
|
|
378
388
|
appendFileSync(this.memoryGraphPath, JSON.stringify(event) + '\n', 'utf8');
|
|
389
|
+
this._maybeTruncateGraph();
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
_maybeTruncateGraph() {
|
|
393
|
+
const MAX_ENTRIES = 5000;
|
|
394
|
+
try {
|
|
395
|
+
if (!existsSync(this.memoryGraphPath)) return;
|
|
396
|
+
const raw = readFileSync(this.memoryGraphPath, 'utf8');
|
|
397
|
+
const lines = raw.split('\n').filter(l => l.trim());
|
|
398
|
+
if (lines.length <= MAX_ENTRIES) return;
|
|
399
|
+
const kept = lines.slice(lines.length - MAX_ENTRIES);
|
|
400
|
+
writeFileSync(this.memoryGraphPath, kept.join('\n') + '\n', 'utf8');
|
|
401
|
+
} catch { /* best effort */ }
|
|
379
402
|
}
|
|
380
403
|
|
|
381
404
|
_recordToGraph({ kind, signals, gene, mutation }) {
|