@stackmemoryai/stackmemory 1.2.4 → 1.2.6

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 CHANGED
@@ -10,14 +10,17 @@ Lossless, project-scoped memory for AI coding tools.
10
10
  StackMemory is a **production-ready memory runtime** for AI coding tools that preserves full project context across sessions:
11
11
 
12
12
  - **Zero-config setup** — `stackmemory init` just works
13
- - **25 MCP tools** for Claude Code integration
14
- - **Full Linear integration** with bidirectional sync
13
+ - **32 MCP tools** for Claude Code integration (context, tasks, Linear, traces, discovery, cord, team)
14
+ - **FTS5 full-text search** with BM25 scoring and hybrid retrieval
15
+ - **Full Linear integration** with bidirectional sync and OAuth/API key support
15
16
  - **Context persistence** that survives `/clear` operations
16
17
  - **Hierarchical frame organization** (nested call stack model)
18
+ - **Multi-wrapper support** — `claude-sm`, `codex-sm`, `opencode-sm` with auto context loading
17
19
  - **Skills system** with `/spec` and `/linear-run` for Claude Code
18
20
  - **Automatic hooks** for task tracking, Linear sync, and spec progress
19
21
  - **Memory monitor daemon** with automatic capture/clear on RAM pressure
20
- - **652 tests passing** with comprehensive coverage
22
+ - **Auto-save service** for periodic context persistence
23
+ - **Comprehensive test coverage** across all core modules
21
24
 
22
25
  Instead of a linear chat log, StackMemory organizes memory as a **call stack** of scoped work (frames), with intelligent LLM-driven retrieval and team collaboration features.
23
26
 
@@ -50,13 +53,14 @@ Tools forget decisions and constraints between sessions. StackMemory makes conte
50
53
 
51
54
  ## Features
52
55
 
53
- - **MCP tools** for Claude Code: 25 tools across context, tasks, Linear, traces, and discovery
56
+ - **MCP tools** for Claude Code: 36 tools across context, tasks, Linear, traces, discovery, cord, and team
57
+ - **FTS5 search**: full-text search with BM25 scoring, hybrid retrieval, and smart thresholds
54
58
  - **Skills**: `/spec` (iterative spec generation), `/linear-run` (task execution via RLM)
55
- - **Hooks**: automatic context save, task tracking, Linear sync, PROMPT_PLAN updates
59
+ - **Hooks**: automatic context save, task tracking, Linear sync, PROMPT_PLAN updates, cord tracing
56
60
  - **Prompt Forge**: watches CLAUDE.md and AGENTS.md for prompt optimization (GEPA)
57
61
  - **Safe branches**: worktree isolation with `--worktree` or `-w`
58
62
  - **Persistent context**: frames, anchors, decisions, retrieval
59
- - **Integrations**: Linear, DiffMem, Browser MCP
63
+ - **Integrations**: Linear (API key + OAuth), DiffMem, Browser MCP, log-mcp (log analysis)
60
64
 
61
65
  ---
62
66
 
@@ -322,6 +322,28 @@ class ClaudeSM {
322
322
  } catch {
323
323
  }
324
324
  }
325
+ getTheoryContent() {
326
+ try {
327
+ let root;
328
+ try {
329
+ root = execSync("git rev-parse --show-toplevel", {
330
+ encoding: "utf-8",
331
+ timeout: 5e3
332
+ }).trim();
333
+ } catch {
334
+ root = process.cwd();
335
+ }
336
+ const theoryPath = path.join(root, "THEORY.MD");
337
+ if (fs.existsSync(theoryPath)) {
338
+ const content = fs.readFileSync(theoryPath, "utf8").trim();
339
+ if (content.length > 0) {
340
+ return content.length > 4e3 ? content.substring(0, 4e3) + "\n\n[...truncated]" : content;
341
+ }
342
+ }
343
+ } catch {
344
+ }
345
+ return null;
346
+ }
325
347
  getHandoffContent() {
326
348
  if (!this.config.contextEnabled) return null;
327
349
  try {
@@ -684,13 +706,20 @@ Session ended (exit ${exitCode ?? 0})`));
684
706
  this.startGEPAWatcher();
685
707
  }
686
708
  let initialInput = "";
687
- const handoffContent = this.getHandoffContent();
688
- if (handoffContent) {
689
- const hasResume = claudeArgs.includes("--continue") || claudeArgs.some((a) => a === "--resume");
690
- if (!hasResume) {
709
+ const hasResume = claudeArgs.includes("--continue") || claudeArgs.some((a) => a === "--resume");
710
+ if (!hasResume) {
711
+ const handoffContent = this.getHandoffContent();
712
+ if (handoffContent) {
691
713
  initialInput = handoffContent;
692
714
  console.log(chalk.gray(" Handoff context ready"));
693
715
  }
716
+ const theoryContent = this.getTheoryContent();
717
+ if (theoryContent) {
718
+ initialInput += (initialInput ? "\n\n---\n\n" : "") + `## Operating Theory (THEORY.MD)
719
+
720
+ ${theoryContent}`;
721
+ console.log(chalk.gray(" Theory context loaded"));
722
+ }
694
723
  }
695
724
  console.log();
696
725
  if (this.config.useSweep) {
@@ -6,7 +6,10 @@ const __dirname = __pathDirname(__filename);
6
6
  import { spawn } from "child_process";
7
7
  import * as path from "path";
8
8
  const codexSmPath = path.join(__dirname, "codex-sm.js");
9
- const args = ["--dangerously-skip-permissions", ...process.argv.slice(2)];
9
+ const args = [
10
+ "--dangerously-bypass-approvals-and-sandbox",
11
+ ...process.argv.slice(2)
12
+ ];
10
13
  const child = spawn("node", [codexSmPath, ...args], {
11
14
  stdio: "inherit",
12
15
  env: process.env
@@ -795,6 +795,89 @@ ${result.data.diffStat}`));
795
795
  process.exit(1);
796
796
  }
797
797
  });
798
+ const theoryCmd = skillsCmd.command("theory").description("Maintain a living THEORY.MD at repo root");
799
+ theoryCmd.command("show").description("Display current THEORY.MD content").action(async () => {
800
+ try {
801
+ const { context } = await initializeSkillContext();
802
+ const { TheorySkill } = await import("../../skills/theory-skill.js");
803
+ const skill = new TheorySkill(context);
804
+ const result = skill.show();
805
+ if (result.success) {
806
+ console.log(result.message);
807
+ } else {
808
+ console.log(chalk.red("\u2717"), result.message);
809
+ }
810
+ await context.database.disconnect();
811
+ } catch (error) {
812
+ console.error(chalk.red("Error:"), error.message);
813
+ process.exit(1);
814
+ }
815
+ });
816
+ theoryCmd.command("init <problem>").description("Create THEORY.MD with scaffold sections").action(async (problem) => {
817
+ try {
818
+ const { context } = await initializeSkillContext();
819
+ const { TheorySkill } = await import("../../skills/theory-skill.js");
820
+ const skill = new TheorySkill(context);
821
+ const result = skill.init(problem);
822
+ if (result.success) {
823
+ console.log(chalk.green("\u2713"), result.message);
824
+ } else {
825
+ console.log(chalk.red("\u2717"), result.message);
826
+ }
827
+ await context.database.disconnect();
828
+ } catch (error) {
829
+ console.error(chalk.red("Error:"), error.message);
830
+ process.exit(1);
831
+ }
832
+ });
833
+ theoryCmd.command("update <content>").description("Overwrite THEORY.MD with new content").action(async (content) => {
834
+ try {
835
+ const { context } = await initializeSkillContext();
836
+ const { TheorySkill } = await import("../../skills/theory-skill.js");
837
+ const skill = new TheorySkill(context);
838
+ const result = skill.update(content);
839
+ if (result.success) {
840
+ console.log(chalk.green("\u2713"), result.message);
841
+ if (result.data?.warnings?.length > 0) {
842
+ result.data.warnings.forEach((w) => {
843
+ console.log(chalk.yellow(` \u26A0 ${w}`));
844
+ });
845
+ }
846
+ } else {
847
+ console.log(chalk.red("\u2717"), result.message);
848
+ }
849
+ await context.database.disconnect();
850
+ } catch (error) {
851
+ console.error(chalk.red("Error:"), error.message);
852
+ process.exit(1);
853
+ }
854
+ });
855
+ theoryCmd.command("status").description("Show THEORY.MD metadata").action(async () => {
856
+ try {
857
+ const { context } = await initializeSkillContext();
858
+ const { TheorySkill } = await import("../../skills/theory-skill.js");
859
+ const skill = new TheorySkill(context);
860
+ const result = skill.status();
861
+ if (result.success) {
862
+ console.log(chalk.cyan("THEORY.MD Status:"));
863
+ if (result.data?.exists) {
864
+ console.log(` Lines: ${result.data.lineCount}`);
865
+ console.log(
866
+ ` Sections: ${result.data.sections?.length}/${result.data.totalSections}`
867
+ );
868
+ console.log(` Last modified: ${result.data.lastModified}`);
869
+ } else {
870
+ console.log(chalk.gray(" Not found"));
871
+ }
872
+ } else {
873
+ console.log(chalk.red("\u2717"), result.message);
874
+ }
875
+ await context.database.disconnect();
876
+ } catch (error) {
877
+ console.error(chalk.red("Error:"), error.message);
878
+ process.exit(1);
879
+ }
880
+ });
798
881
  skillsCmd.command("help [skill]").description("Show help for a specific skill").action(async (skill) => {
799
882
  if (skill) {
800
883
  switch (skill) {
@@ -846,6 +929,27 @@ Examples:
846
929
 
847
930
  Apply patches: git apply .stackmemory/patches/<file>.patch
848
931
  Review specs: cd /tmp/sm-spec-* && git log --oneline
932
+ `);
933
+ break;
934
+ case "theory":
935
+ console.log(`
936
+ theory \u2014 Living Operating Theory Document
937
+
938
+ Maintains a THEORY.MD at repo root: a narrative capturing your problem
939
+ thesis, mental model, strategy, discoveries, and open questions.
940
+
941
+ Subcommands:
942
+ show Display current THEORY.MD
943
+ init <problem> Create THEORY.MD with scaffold sections
944
+ update <content> Overwrite THEORY.MD (validates, warns on anti-patterns)
945
+ status Show metadata (lines, sections, last modified)
946
+
947
+ Examples:
948
+ stackmemory skills theory init "Build context-aware memory for AI agents"
949
+ stackmemory skills theory show
950
+ stackmemory skills theory status
951
+
952
+ Based on Theorist by @blader (MIT).
849
953
  `);
850
954
  break;
851
955
  default:
@@ -875,7 +979,10 @@ Review specs: cd /tmp/sm-spec-* && git log --oneline
875
979
  );
876
980
  console.log(" linear-run - Execute Linear tasks via RLM orchestrator");
877
981
  console.log(
878
- " agent - Spawn parallel agents (research, maintain, spec-run)\n"
982
+ " agent - Spawn parallel agents (research, maintain, spec-run)"
983
+ );
984
+ console.log(
985
+ " theory - Maintain a living THEORY.MD (show, init, update, status)\n"
879
986
  );
880
987
  console.log(
881
988
  chalk.yellow(
@@ -13,7 +13,6 @@ import {
13
13
  import { join, extname, relative } from "path";
14
14
  import { spawn } from "child_process";
15
15
  import { loadConfig } from "./config.js";
16
- import { GraphitiHooks } from "./graphiti-hooks.js";
17
16
  import {
18
17
  hookEmitter
19
18
  } from "./events.js";
@@ -143,13 +142,6 @@ function registerBuiltinHandlers() {
143
142
  hookEmitter.registerHandler("file_change", handleFileChange);
144
143
  hookEmitter.registerHandler("suggestion_ready", handleSuggestionReady);
145
144
  hookEmitter.registerHandler("error", handleError);
146
- try {
147
- if (process.env.GRAPHITI_ENDPOINT || process.env.GRAPHITI_ENABLED === "true") {
148
- const graphiti = new GraphitiHooks();
149
- graphiti.register(hookEmitter);
150
- }
151
- } catch {
152
- }
153
145
  hookEmitter.on("*", () => {
154
146
  state.eventsProcessed++;
155
147
  });
@@ -22,7 +22,6 @@ function getOptionalEnv(key) {
22
22
  class LinearWebhookHandler {
23
23
  syncEngine;
24
24
  taskStore;
25
- graphitiBridge;
26
25
  webhookSecret;
27
26
  constructor(webhookSecret) {
28
27
  this.webhookSecret = webhookSecret || process.env["LINEAR_WEBHOOK_SECRET"];
@@ -39,12 +38,6 @@ class LinearWebhookHandler {
39
38
  setTaskStore(taskStore) {
40
39
  this.taskStore = taskStore;
41
40
  }
42
- /**
43
- * Set the Graphiti bridge for knowledge graph sync
44
- */
45
- setGraphitiBridge(bridge) {
46
- this.graphitiBridge = bridge;
47
- }
48
41
  /**
49
42
  * Verify webhook signature
50
43
  */
@@ -111,15 +104,6 @@ class LinearWebhookHandler {
111
104
  default:
112
105
  logger.warn(`Unknown webhook action: ${payload.action}`);
113
106
  }
114
- if (this.graphitiBridge) {
115
- this.graphitiBridge.processWebhook(payload).catch((err) => {
116
- logger.debug("Linear-Graphiti bridge error", {
117
- action: payload.action,
118
- identifier: payload.data.identifier,
119
- error: err instanceof Error ? err.message : String(err)
120
- });
121
- });
122
- }
123
107
  }
124
108
  /**
125
109
  * Handle issue created in Linear
@@ -99,10 +99,6 @@ class MCPHandlerFactory {
99
99
  return this.taskHandlers.handleGetActiveTasks.bind(this.taskHandlers);
100
100
  case "get_task_metrics":
101
101
  return this.taskHandlers.handleGetTaskMetrics.bind(this.taskHandlers);
102
- case "add_task_dependency":
103
- return this.taskHandlers.handleAddTaskDependency.bind(
104
- this.taskHandlers
105
- );
106
102
  // Linear handlers
107
103
  case "linear_sync":
108
104
  return this.linearHandlers.handleLinearSync.bind(this.linearHandlers);
@@ -119,8 +115,6 @@ class MCPHandlerFactory {
119
115
  // Trace handlers
120
116
  case "get_traces":
121
117
  return this.traceHandlers.handleGetTraces.bind(this.traceHandlers);
122
- case "analyze_traces":
123
- return this.traceHandlers.handleAnalyzeTraces.bind(this.traceHandlers);
124
118
  case "start_browser_debug":
125
119
  return this.traceHandlers.handleStartBrowserDebug.bind(
126
120
  this.traceHandlers
@@ -193,7 +187,6 @@ class MCPHandlerFactory {
193
187
  "update_task_status",
194
188
  "get_active_tasks",
195
189
  "get_task_metrics",
196
- "add_task_dependency",
197
190
  // Linear tools
198
191
  "linear_sync",
199
192
  "linear_update_task",
@@ -201,7 +194,6 @@ class MCPHandlerFactory {
201
194
  "linear_status",
202
195
  // Trace tools
203
196
  "get_traces",
204
- "analyze_traces",
205
197
  "start_browser_debug",
206
198
  "take_screenshot",
207
199
  "execute_script",
@@ -11,6 +11,9 @@ class TraceHandlers {
11
11
  * Get traces with optional filtering
12
12
  */
13
13
  async handleGetTraces(args) {
14
+ if (args.analyze) {
15
+ return this.handleAnalyzeTraces(args);
16
+ }
14
17
  try {
15
18
  const {
16
19
  limit = 20,
@@ -31,7 +31,6 @@ import { LLMContextRetrieval } from "../../core/retrieval/index.js";
31
31
  import { DiscoveryHandlers } from "./handlers/discovery-handlers.js";
32
32
  import { DiffMemHandlers } from "./handlers/diffmem-handlers.js";
33
33
  import { GreptileHandlers } from "./handlers/greptile-handlers.js";
34
- import { GraphitiClient } from "../graphiti/client.js";
35
34
  import { fuzzyEdit } from "../../utils/fuzzy-edit.js";
36
35
  import { v4 as uuidv4 } from "uuid";
37
36
  import {
@@ -67,7 +66,6 @@ class LocalStackMemoryMCP {
67
66
  diffMemHandlers;
68
67
  greptileHandlers;
69
68
  providerHandlers = null;
70
- graphitiClient = null;
71
69
  pendingPlans = /* @__PURE__ */ new Map();
72
70
  constructor() {
73
71
  this.projectRoot = this.findProjectRoot();
@@ -142,15 +140,6 @@ class LocalStackMemoryMCP {
142
140
  this.diffMemHandlers = new DiffMemHandlers();
143
141
  this.greptileHandlers = new GreptileHandlers();
144
142
  this.initProviderHandlers();
145
- if (process.env.GRAPHITI_ENDPOINT) {
146
- this.graphitiClient = new GraphitiClient({
147
- endpoint: process.env.GRAPHITI_ENDPOINT,
148
- projectNamespace: process.env.STACKMEMORY_PROJECT_ID || this.projectId
149
- });
150
- logger.info("Graphiti client initialized", {
151
- endpoint: process.env.GRAPHITI_ENDPOINT
152
- });
153
- }
154
143
  this.setupHandlers();
155
144
  this.loadInitialContext();
156
145
  this.loadPendingPlans();
@@ -711,24 +700,6 @@ ${summary}...`, 0.8);
711
700
  properties: {}
712
701
  }
713
702
  },
714
- {
715
- name: "add_task_dependency",
716
- description: "Add dependency relationship between tasks",
717
- inputSchema: {
718
- type: "object",
719
- properties: {
720
- taskId: {
721
- type: "string",
722
- description: "Task that depends on another"
723
- },
724
- dependsOnId: {
725
- type: "string",
726
- description: "Task ID that this depends on"
727
- }
728
- },
729
- required: ["taskId", "dependsOnId"]
730
- }
731
- },
732
703
  {
733
704
  name: "linear_sync",
734
705
  description: "Sync tasks with Linear",
@@ -1087,51 +1058,6 @@ ${summary}...`, 0.8);
1087
1058
  properties: {}
1088
1059
  }
1089
1060
  },
1090
- // Graphiti tools (only active when GRAPHITI_ENDPOINT is set)
1091
- ...this.graphitiClient ? [
1092
- {
1093
- name: "graphiti_status",
1094
- description: "Check Graphiti temporal knowledge graph connection status",
1095
- inputSchema: {
1096
- type: "object",
1097
- properties: {}
1098
- }
1099
- },
1100
- {
1101
- name: "graphiti_query",
1102
- description: "Query the Graphiti temporal knowledge graph for entities, relations, and episodes",
1103
- inputSchema: {
1104
- type: "object",
1105
- properties: {
1106
- query: {
1107
- type: "string",
1108
- description: "Semantic text query"
1109
- },
1110
- entityTypes: {
1111
- type: "array",
1112
- items: { type: "string" },
1113
- description: 'Entity types to filter (e.g., ["Person", "File", "Issue"])'
1114
- },
1115
- validFrom: {
1116
- type: "number",
1117
- description: "Start of time window (epoch ms)"
1118
- },
1119
- validTo: {
1120
- type: "number",
1121
- description: "End of time window (epoch ms)"
1122
- },
1123
- maxHops: {
1124
- type: "number",
1125
- description: "Graph traversal depth (default 2)"
1126
- },
1127
- k: {
1128
- type: "number",
1129
- description: "Top-k results (default 20)"
1130
- }
1131
- }
1132
- }
1133
- }
1134
- ] : [],
1135
1061
  // Greptile tools (only active when GREPTILE_API_KEY is set)
1136
1062
  ...process.env.GREPTILE_API_KEY ? this.greptileHandlers.getToolDefinitions() : [],
1137
1063
  // Provider tools (only active when STACKMEMORY_MULTI_PROVIDER=true)
@@ -1299,9 +1225,6 @@ ${summary}...`, 0.8);
1299
1225
  case "get_task_metrics":
1300
1226
  result = await this.handleGetTaskMetrics(args);
1301
1227
  break;
1302
- case "add_task_dependency":
1303
- result = await this.handleAddTaskDependency(args);
1304
- break;
1305
1228
  case "linear_sync":
1306
1229
  result = await this.handleLinearSync(args);
1307
1230
  break;
@@ -1456,59 +1379,6 @@ ${summary}...`, 0.8);
1456
1379
  );
1457
1380
  }
1458
1381
  break;
1459
- // Graphiti tools
1460
- case "graphiti_status":
1461
- if (!this.graphitiClient) {
1462
- result = {
1463
- content: [
1464
- {
1465
- type: "text",
1466
- text: JSON.stringify({
1467
- connected: false,
1468
- message: "Graphiti integration disabled (GRAPHITI_ENDPOINT not set)"
1469
- })
1470
- }
1471
- ]
1472
- };
1473
- } else {
1474
- const status = await this.graphitiClient.getStatus();
1475
- result = {
1476
- content: [
1477
- { type: "text", text: JSON.stringify(status, null, 2) }
1478
- ]
1479
- };
1480
- }
1481
- break;
1482
- case "graphiti_query":
1483
- if (!this.graphitiClient) {
1484
- result = {
1485
- content: [
1486
- {
1487
- type: "text",
1488
- text: "Graphiti integration disabled (GRAPHITI_ENDPOINT not set)"
1489
- }
1490
- ]
1491
- };
1492
- } else {
1493
- const gCtx = await this.graphitiClient.queryTemporal({
1494
- query: args.query,
1495
- entityTypes: args.entityTypes,
1496
- validFrom: args.validFrom,
1497
- validTo: args.validTo,
1498
- maxHops: args.maxHops,
1499
- k: args.k
1500
- });
1501
- const text = gCtx.chunks.map((c) => c.text).join("\n\n");
1502
- result = {
1503
- content: [
1504
- {
1505
- type: "text",
1506
- text: text || `No results found (${gCtx.totalTokens} tokens searched)`
1507
- }
1508
- ]
1509
- };
1510
- }
1511
- break;
1512
1382
  default:
1513
1383
  throw new Error(`Unknown tool: ${name}`);
1514
1384
  }
@@ -14,7 +14,6 @@ class MCPToolDefinitions {
14
14
  ...this.getTraceTools(),
15
15
  ...this.getDiscoveryTools(),
16
16
  ...this.getEditTools(),
17
- ...this.getGraphitiTools(),
18
17
  ...this.getTeamTools(),
19
18
  ...this.getCordTools()
20
19
  ];
@@ -283,30 +282,6 @@ class MCPToolDefinitions {
283
282
  type: "object",
284
283
  properties: {}
285
284
  }
286
- },
287
- {
288
- name: "add_task_dependency",
289
- description: "Add dependency between tasks",
290
- inputSchema: {
291
- type: "object",
292
- properties: {
293
- task_id: {
294
- type: "string",
295
- description: "Task that depends on another"
296
- },
297
- depends_on: {
298
- type: "string",
299
- description: "Task that must be completed first"
300
- },
301
- dependency_type: {
302
- type: "string",
303
- enum: ["blocks", "related", "subtask"],
304
- default: "blocks",
305
- description: "Type of dependency"
306
- }
307
- },
308
- required: ["task_id", "depends_on"]
309
- }
310
285
  }
311
286
  ];
312
287
  }
@@ -417,7 +392,7 @@ class MCPToolDefinitions {
417
392
  return [
418
393
  {
419
394
  name: "get_traces",
420
- description: "Get execution traces with optional filtering",
395
+ description: "Get execution traces with optional filtering. Set analyze=true to run pattern analysis instead of listing traces.",
421
396
  inputSchema: {
422
397
  type: "object",
423
398
  properties: {
@@ -444,30 +419,21 @@ class MCPToolDefinitions {
444
419
  type: "boolean",
445
420
  default: false,
446
421
  description: "Include full trace context"
447
- }
448
- }
449
- }
450
- },
451
- {
452
- name: "analyze_traces",
453
- description: "Analyze trace patterns for insights",
454
- inputSchema: {
455
- type: "object",
456
- properties: {
422
+ },
423
+ analyze: {
424
+ type: "boolean",
425
+ default: false,
426
+ description: "Run analysis on traces instead of listing them"
427
+ },
457
428
  trace_id: {
458
429
  type: "string",
459
- description: "Specific trace to analyze"
430
+ description: "Specific trace to analyze (requires analyze=true)"
460
431
  },
461
432
  analysis_type: {
462
433
  type: "string",
463
434
  enum: ["performance", "patterns", "errors"],
464
435
  default: "performance",
465
- description: "Type of analysis to perform"
466
- },
467
- include_recommendations: {
468
- type: "boolean",
469
- default: true,
470
- description: "Include optimization recommendations"
436
+ description: "Type of analysis (requires analyze=true)"
471
437
  }
472
438
  }
473
439
  }
@@ -708,55 +674,6 @@ class MCPToolDefinitions {
708
674
  }
709
675
  ];
710
676
  }
711
- /**
712
- * Graphiti knowledge graph tools
713
- */
714
- getGraphitiTools() {
715
- return [
716
- {
717
- name: "graphiti_status",
718
- description: "Check Graphiti temporal knowledge graph connection status",
719
- inputSchema: {
720
- type: "object",
721
- properties: {}
722
- }
723
- },
724
- {
725
- name: "graphiti_query",
726
- description: "Query the Graphiti temporal knowledge graph for entities, relations, and episodes",
727
- inputSchema: {
728
- type: "object",
729
- properties: {
730
- query: {
731
- type: "string",
732
- description: "Semantic text query"
733
- },
734
- entityTypes: {
735
- type: "array",
736
- items: { type: "string" },
737
- description: 'Entity types to filter (e.g., ["Person", "File", "Issue"])'
738
- },
739
- validFrom: {
740
- type: "number",
741
- description: "Start of time window (epoch ms)"
742
- },
743
- validTo: {
744
- type: "number",
745
- description: "End of time window (epoch ms)"
746
- },
747
- maxHops: {
748
- type: "number",
749
- description: "Graph traversal depth (default 2)"
750
- },
751
- k: {
752
- type: "number",
753
- description: "Top-k results (default 20)"
754
- }
755
- }
756
- }
757
- }
758
- ];
759
- }
760
677
  /**
761
678
  * Multi-agent team collaboration tools
762
679
  */
@@ -988,8 +905,6 @@ class MCPToolDefinitions {
988
905
  return this.getDiscoveryTools();
989
906
  case "edit":
990
907
  return this.getEditTools();
991
- case "graphiti":
992
- return this.getGraphitiTools();
993
908
  case "team":
994
909
  return this.getTeamTools();
995
910
  case "cord":