@kage-core/kage-graph-mcp 1.1.4 → 1.1.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
@@ -38,6 +38,7 @@ kage recall "how do I run tests" --project /path/to/repo
38
38
  kage recall "how do I run tests" --project /path/to/repo --explain --json
39
39
  kage quality --project /path/to/repo
40
40
  kage benchmark --project /path/to/repo
41
+ kage benchmark --project /path/to/repo --compare --task "how do I run tests"
41
42
  kage viewer --project /path/to/repo
42
43
  kage daemon start --project /path/to/repo
43
44
  kage observe --project /path/to/repo --event '{"type":"command_result","session_id":"s1","command":"npm test","exit_code":0}'
@@ -125,6 +126,12 @@ and parser coverage, code graph counts, evidence coverage, approved vs pending
125
126
  memory, validation status, estimated tokens saved per recall, duplicate
126
127
  candidates, average memory quality, and a readiness score.
127
128
 
129
+ Use `kage benchmark --compare --task "<task>" --project <repo>` or
130
+ `kage_benchmark_compare` to compare the same task on the same repo with and
131
+ without Kage. It estimates manual full-file rediscovery tokens/steps, compares
132
+ them to compact Kage recall plus code graph context, and returns evidence plus
133
+ caveats for honest marketing proof.
134
+
128
135
  Use `kage refresh --project <repo>` or the `kage_refresh` MCP tool after
129
136
  meaningful file changes. Refresh rebuilds indexes, code graph, memory graph,
130
137
  metrics, and stale-memory metadata. Memory is marked stale when status or
@@ -151,6 +158,11 @@ ranking: text, graph, path/type/tag, freshness, quality, feedback, and a vector
151
158
  placeholder for future local or external embedding providers. Current fallback
152
159
  is deterministic text plus graph retrieval.
153
160
 
161
+ `kage_context` is the primary MCP entrypoint for agents. It validates repo
162
+ memory, recalls relevant packets, and returns code/knowledge graph context in
163
+ one call. Agents should use it at task start instead of loading separate
164
+ `kage_validate`, `kage_recall`, `kage_code_graph`, and `kage_graph` schemas.
165
+
154
166
  `kage daemon start` exposes the optional local REST runtime on
155
167
  `127.0.0.1:3111`:
156
168
 
@@ -196,6 +208,7 @@ confidence, and token-savings metrics connect.
196
208
 
197
209
  Local repo tools:
198
210
 
211
+ - `kage_context`
199
212
  - `kage_recall`
200
213
  - `kage_code_graph`
201
214
  - `kage_metrics`
@@ -204,6 +217,7 @@ Local repo tools:
204
217
  - `kage_pr_check`
205
218
  - `kage_quality`
206
219
  - `kage_benchmark`
220
+ - `kage_benchmark_compare`
207
221
  - `kage_setup_agent`
208
222
  - `kage_graph`
209
223
  - `kage_graph_visual`
@@ -280,14 +294,12 @@ Minimum policy:
280
294
 
281
295
  ```md
282
296
  Before code changes or repo-specific answers:
283
- 1. Call `kage_validate`.
284
- 2. Call `kage_recall` with the user task as the query.
285
- 3. Call `kage_graph` with the user task as the query.
286
- 4. Capture reusable learnings with `kage_learn` or `kage_capture`.
287
- 5. After meaningful file changes, call `kage_refresh`.
288
- 6. Before finishing changed-file tasks, call `kage_propose_from_diff` or `kage_pr_summarize`.
289
- 7. Before merge, call `kage_pr_check`.
290
- 8. Never publish or promote org/global memory automatically.
297
+ 1. Call `kage_context` with `project_dir` and the user task as `query`.
298
+ 2. Capture reusable learnings with `kage_learn` or `kage_capture`.
299
+ 3. After meaningful file changes, call `kage_refresh`.
300
+ 4. Before finishing changed-file tasks, call `kage_propose_from_diff` or `kage_pr_summarize`.
301
+ 5. Before merge, call `kage_pr_check`.
302
+ 6. Never publish or promote org/global memory automatically.
291
303
  ```
292
304
 
293
305
  Run `kage setup verify-agent --agent codex --project <repo>` after setup. The
package/dist/cli.js CHANGED
@@ -31,6 +31,7 @@ Usage:
31
31
  kage metrics --project <dir> [--json]
32
32
  kage quality --project <dir> [--json]
33
33
  kage benchmark --project <dir> [--json]
34
+ kage benchmark --project <dir> --compare --task <task> [--json]
34
35
  kage code-graph --project <dir> [--json]
35
36
  kage code-graph "<query>" --project <dir> [--json]
36
37
  kage graph --project <dir> [--json]
@@ -533,6 +534,46 @@ async function main() {
533
534
  return;
534
535
  }
535
536
  if (command === "benchmark") {
537
+ if (args.includes("--compare")) {
538
+ const result = (0, kernel_js_1.benchmarkTaskComparison)(projectArg(args), takeArg(args, "--task") ?? firstPositional(args) ?? "how do I run tests");
539
+ if (args.includes("--json")) {
540
+ console.log(JSON.stringify(result, null, 2));
541
+ return;
542
+ }
543
+ console.log(`Kage A/B Benchmark: ${result.project_dir}`);
544
+ console.log(`Task: ${result.task}`);
545
+ console.log("");
546
+ console.log("Without Kage:");
547
+ console.log(` Files examined: ${result.baseline_without_kage.files_examined}`);
548
+ console.log(` Full-file tokens: ${result.baseline_without_kage.full_file_tokens}`);
549
+ console.log(` Steps: ${result.baseline_without_kage.steps}`);
550
+ console.log(` Estimated time: ${result.baseline_without_kage.estimated_time_seconds}s`);
551
+ console.log("");
552
+ console.log("With Kage:");
553
+ console.log(` Memory packets: ${result.with_kage.memory_packets_used}`);
554
+ console.log(` Code facts: ${result.with_kage.code_files_returned + result.with_kage.code_symbols_returned + result.with_kage.code_routes_returned + result.with_kage.code_tests_returned}`);
555
+ console.log(` Context tokens: ${result.with_kage.context_tokens}`);
556
+ console.log(` Steps: ${result.with_kage.steps}`);
557
+ console.log(` Estimated time: ${result.with_kage.estimated_time_seconds}s`);
558
+ console.log("");
559
+ console.log("Delta:");
560
+ console.log(` Estimated tokens saved: ${result.delta.estimated_tokens_saved}`);
561
+ console.log(` Context reduction: ${result.delta.context_reduction_percent}%`);
562
+ console.log(` Rediscovery steps saved: ${result.delta.rediscovery_steps_saved}`);
563
+ console.log(` Estimated time saved: ${result.delta.estimated_time_saved_seconds}s`);
564
+ console.log(` Full-file reads avoided: ${result.delta.full_file_reads_avoided}`);
565
+ console.log(` Recall hit: ${result.delta.recall_hit ? "yes" : "no"}`);
566
+ console.log(` Code graph hit: ${result.delta.code_graph_hit ? "yes" : "no"}`);
567
+ console.log("");
568
+ console.log("Baseline files:");
569
+ for (const file of result.evidence.baseline_files.slice(0, 8))
570
+ console.log(` - ${file.path} (${file.tokens} tokens): ${file.why}`);
571
+ console.log("");
572
+ console.log("Kage memory:");
573
+ for (const packet of result.evidence.kage_memory.slice(0, 5))
574
+ console.log(` - ${packet.title} (${packet.type}, score ${packet.score})`);
575
+ return;
576
+ }
536
577
  const result = (0, kernel_js_1.benchmarkProject)(projectArg(args));
537
578
  if (args.includes("--json")) {
538
579
  console.log(JSON.stringify(result, null, 2));
package/dist/index.js CHANGED
@@ -54,9 +54,25 @@ function arrayArg(value) {
54
54
  return value.split(",").map((item) => item.trim()).filter(Boolean);
55
55
  return [];
56
56
  }
57
- const server = new index_js_1.Server({ name: "kage-graph", version: "1.1.0" }, { capabilities: { tools: {} } });
57
+ const server = new index_js_1.Server({ name: "kage-graph", version: "1.1.6" }, { capabilities: { tools: {} } });
58
58
  function listTools() {
59
59
  return [
60
+ {
61
+ // Combined entry-point tool: validate + recall + code_graph + graph in one call.
62
+ // Agents should load this schema first (one ToolSearch) instead of loading four
63
+ // separate deferred schemas. Cuts session start from 4 schema loads to 1.
64
+ name: "kage_context",
65
+ description: "Primary kage entry point. Validates memory health, recalls relevant packets, and queries both the code graph and knowledge graph — all in one call. Call this at the start of every task instead of calling kage_validate, kage_recall, kage_code_graph, and kage_graph separately.",
66
+ inputSchema: {
67
+ type: "object",
68
+ properties: {
69
+ project_dir: { type: "string", description: "Absolute path to the project root" },
70
+ query: { type: "string", description: "The task or question — used for both memory recall and code graph search" },
71
+ limit: { type: "number", description: "Max memory packets to return (default 5)" },
72
+ },
73
+ required: ["project_dir", "query"],
74
+ },
75
+ },
60
76
  {
61
77
  name: "kage_search",
62
78
  description: "Search the kage community knowledge graph for gotchas, patterns, configs, and architectural decisions across auth, database, payments, deployment, frontend, testing, and more. Returns node summaries ranked by relevance.",
@@ -209,6 +225,18 @@ function listTools() {
209
225
  required: ["project_dir"],
210
226
  },
211
227
  },
228
+ {
229
+ name: "kage_benchmark_compare",
230
+ description: "Compare the same task on the same repo with and without Kage. Reports estimated baseline discovery tokens/steps versus Kage recall/code-graph context, with evidence and caveats.",
231
+ inputSchema: {
232
+ type: "object",
233
+ properties: {
234
+ project_dir: { type: "string" },
235
+ task: { type: "string" },
236
+ },
237
+ required: ["project_dir", "task"],
238
+ },
239
+ },
212
240
  {
213
241
  name: "kage_setup_agent",
214
242
  description: "Generate MCP/setup instructions for Codex, Claude Code, Cursor, Windsurf, Gemini CLI, OpenCode, Cline, Goose, Roo Code, Kilo Code, Claude Desktop, Aider, or generic MCP.",
@@ -596,6 +624,28 @@ async function callTool(name, args) {
596
624
  content: [{ type: "text", text: content }],
597
625
  };
598
626
  }
627
+ if (name === "kage_context") {
628
+ const projectDir = String(args?.project_dir ?? "");
629
+ const query = String(args?.query ?? "");
630
+ const limit = Number(args?.limit ?? 5);
631
+ // validate
632
+ const validation = (0, kernel_js_1.validateProject)(projectDir);
633
+ const validationText = validation.ok
634
+ ? "Memory healthy."
635
+ : `Warnings: ${validation.warnings.join("; ")}`;
636
+ // recall (memory + code graph + knowledge graph combined)
637
+ const recallResult = (0, kernel_js_1.recall)(projectDir, query, limit, false);
638
+ // graph facts on top of recall
639
+ const graphResult = (0, kernel_js_1.queryGraph)(projectDir, query, 5);
640
+ const sections = [
641
+ recallResult.context_block,
642
+ graphResult.context_block ? `\n## Graph Facts\n${graphResult.context_block}` : "",
643
+ `\n_${validationText}_`,
644
+ ].filter(Boolean).join("");
645
+ return {
646
+ content: [{ type: "text", text: sections }],
647
+ };
648
+ }
599
649
  if (name === "kage_recall") {
600
650
  const result = (0, kernel_js_1.recall)(String(args?.project_dir ?? ""), String(args?.query ?? ""), Number(args?.limit ?? 5), Boolean(args?.explain));
601
651
  return {
@@ -661,6 +711,12 @@ async function callTool(name, args) {
661
711
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
662
712
  };
663
713
  }
714
+ if (name === "kage_benchmark_compare") {
715
+ const result = (0, kernel_js_1.benchmarkTaskComparison)(String(args?.project_dir ?? ""), String(args?.task ?? ""));
716
+ return {
717
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
718
+ };
719
+ }
664
720
  if (name === "kage_setup_agent") {
665
721
  const result = (0, kernel_js_1.setupAgent)(String(args?.agent ?? ""), String(args?.project_dir ?? ""), { write: Boolean(args?.write) });
666
722
  return {
package/dist/kernel.js CHANGED
@@ -75,6 +75,7 @@ exports.graphMermaid = graphMermaid;
75
75
  exports.kageMetrics = kageMetrics;
76
76
  exports.qualityReport = qualityReport;
77
77
  exports.benchmarkProject = benchmarkProject;
78
+ exports.benchmarkTaskComparison = benchmarkTaskComparison;
78
79
  exports.learn = learn;
79
80
  exports.capture = capture;
80
81
  exports.createPublicCandidate = createPublicCandidate;
@@ -150,12 +151,11 @@ This repo uses Kage as an automatic memory harness for coding agents.
150
151
 
151
152
  Before making code changes, answering repo-specific implementation questions, debugging failures, or proposing architecture:
152
153
 
153
- 1. Call \`kage_validate\` for this repo.
154
- 2. Call \`kage_recall\` with the user's task as the query.
155
- 3. Call \`kage_code_graph\` when the task mentions files, APIs, routes, symbols, tests, dependencies, or code flow.
156
- 4. Call \`kage_graph\` with the user's task as the query when the task depends on decisions, bugs, workflows, commands, or conventions.
157
- 5. Use returned memory only when it is relevant, source-backed, and not stale.
158
- 6. Prefer repo memory over public/community memory when they conflict.
154
+ 1. Call \`kage_context\` with \`project_dir\` and the task as \`query\`.
155
+ This validates memory, recalls relevant packets, and queries both the code graph
156
+ and knowledge graph in one call replacing the old four-step validate/recall/code_graph/graph sequence.
157
+ 2. Use returned memory only when it is relevant, source-backed, and not stale.
158
+ 3. Prefer repo memory over public/community memory when they conflict.
159
159
 
160
160
  Do this without waiting for the user to ask. Kage should feel like ambient repo memory, not a manual search command.
161
161
 
@@ -216,17 +216,13 @@ If recalled memory materially helped, call \`kage_feedback\` with \`helpful\`.
216
216
 
217
217
  For normal coding tasks:
218
218
 
219
- 1. \`kage_validate\`
220
- 2. \`kage_recall\`
221
- 3. \`kage_code_graph\` for source flow, routes, symbols, tests, and dependencies
222
- 4. \`kage_graph\` for remembered decisions, bugs, workflows, and conventions
223
- 5. Work on the task
224
- 6. \`kage_learn\` for concrete learnings
225
- 7. \`kage_refresh\` after meaningful file changes
226
- 8. \`kage_pr_summarize\` or \`kage_propose_from_diff\` before the final response to create repo-local change memory
227
- 9. \`kage_pr_check\` before final handoff or merge readiness claims
219
+ 1. \`kage_context\` — validate + recall + code graph + knowledge graph in one call
220
+ 2. Work on the task
221
+ 3. \`kage_learn\` for concrete learnings
222
+ 4. \`kage_refresh\` after meaningful file changes
223
+ 5. \`kage_propose_from_diff\` before the final response to create repo-local change memory
228
224
 
229
- For quick factual questions, \`kage_recall\` alone is enough. For status or demo requests, call \`kage_metrics\`.
225
+ For quick factual questions, \`kage_context\` alone is enough. For status or demo requests, call \`kage_metrics\`.
230
226
  ${AGENTS_POLICY_END}
231
227
  `;
232
228
  const STOPWORDS = new Set([
@@ -579,7 +575,9 @@ function evaluateMemoryQuality(projectDir, packet) {
579
575
  risks,
580
576
  duplicate_candidates: duplicates,
581
577
  stale_reasons: staleReasons,
582
- estimated_tokens_saved: Math.max(40, estimateTokens(packet.body) * 2),
578
+ // Tokens an agent saves by reading this packet instead of the files it references.
579
+ // Approximated as the token size of the files it grounds to (or the packet body if no paths).
580
+ estimated_tokens_saved: Math.max(20, estimateTokens(packet.body)),
583
581
  };
584
582
  }
585
583
  function evaluateMemoryAdmission(projectDir, packet) {
@@ -2905,8 +2903,13 @@ function kageMetrics(projectDir) {
2905
2903
  const duplicatePairs = allPackets.reduce((sum, packet) => sum + duplicateCandidates(projectDir, packet).length, 0);
2906
2904
  const indexedSourceTokens = Math.ceil(sourceFiles.reduce((sum, file) => sum + file.size_bytes, 0) / 4);
2907
2905
  const memoryTokens = allPackets.reduce((sum, packet) => sum + estimateTokens(packetText(packet)), 0);
2906
+ // Estimated size of a typical recall response: structured packet summaries + code graph
2907
+ // slice, capped at ~1 800 tokens. This is what actually reaches the agent per recall call.
2908
2908
  const recallContextTokens = Math.max(250, Math.min(1800, codeGraph.symbols.length * 12 + codeGraph.routes.length * 10 + knowledgeGraph.edges.length * 14 + 180));
2909
- const tokensSaved = Math.max(0, indexedSourceTokens + memoryTokens - recallContextTokens);
2909
+ // Honest saving: tokens an agent would spend reading all source files minus tokens a
2910
+ // targeted recall costs. Only meaningful when an agent would otherwise read everything.
2911
+ // memoryTokens is storage cost, not context sent — excluded from this calculation.
2912
+ const tokensSaved = Math.max(0, indexedSourceTokens - recallContextTokens);
2910
2913
  const readinessScore = Math.max(0, Math.min(100, Math.round(coverage * 0.35 +
2911
2914
  percent(evidenceBackedEdges, knowledgeGraph.edges.length) * 0.25 +
2912
2915
  (approvedPackets > 0 ? 20 : 0) +
@@ -3064,6 +3067,110 @@ function benchmarkProject(projectDir) {
3064
3067
  },
3065
3068
  };
3066
3069
  }
3070
+ function baselineDiscoveryFiles(projectDir, task) {
3071
+ const terms = tokenize(task);
3072
+ const graph = buildCodeGraph(projectDir);
3073
+ const candidatePaths = unique([
3074
+ "README.md",
3075
+ "AGENTS.md",
3076
+ "CLAUDE.md",
3077
+ "package.json",
3078
+ ...graph.files.map((file) => file.path),
3079
+ ]).filter((path) => path && !shouldSkipRepoMemoryPath(path));
3080
+ return candidatePaths
3081
+ .map((path) => {
3082
+ const absolute = (0, node_path_1.join)(projectDir, path);
3083
+ if (!(0, node_fs_1.existsSync)(absolute))
3084
+ return null;
3085
+ const stats = (0, node_fs_1.statSync)(absolute);
3086
+ if (!stats.isFile() || stats.size > 240_000)
3087
+ return null;
3088
+ const text = (0, node_fs_1.readFileSync)(absolute, "utf8");
3089
+ const score = scoreText(terms, `${path}\n${text.slice(0, 8000)}`, [path]);
3090
+ const alwaysUseful = ["README.md", "AGENTS.md", "CLAUDE.md", "package.json"].includes(path);
3091
+ if (score <= 0 && !alwaysUseful)
3092
+ return null;
3093
+ return {
3094
+ path,
3095
+ tokens: Math.max(1, Math.ceil(stats.size / 4)),
3096
+ why: score > 0 ? "task terms matched path or file content" : "standard repo orientation file",
3097
+ score: score + (alwaysUseful ? 1 : 0),
3098
+ };
3099
+ })
3100
+ .filter((entry) => Boolean(entry))
3101
+ .sort((a, b) => b.score - a.score || b.tokens - a.tokens || a.path.localeCompare(b.path))
3102
+ .slice(0, 10);
3103
+ }
3104
+ function benchmarkTaskComparison(projectDir, task) {
3105
+ ensureMemoryDirs(projectDir);
3106
+ const query = task.trim() || "how do I run tests";
3107
+ const baselineFiles = baselineDiscoveryFiles(projectDir, query);
3108
+ const baselineTokens = baselineFiles.reduce((sum, file) => sum + file.tokens, 0);
3109
+ const recallResult = recall(projectDir, query, 5, true);
3110
+ const codeResult = queryCodeGraph(projectDir, query, 10);
3111
+ const kageContext = `${recallResult.context_block}\n\n${codeResult.context_block}`;
3112
+ const kageTokens = estimateTokens(kageContext);
3113
+ const codeFactLines = [
3114
+ ...codeResult.routes.map((route) => `[route] ${route.method} ${route.path} in ${route.file_path}:${route.line}`),
3115
+ ...codeResult.symbols.map((symbol) => `[symbol] ${symbol.kind} ${symbol.name} in ${symbol.path}:${symbol.line}`),
3116
+ ...codeResult.tests.map((test) => `[test] ${test.title} in ${test.test_path}:${test.line}`),
3117
+ ...codeResult.files.slice(0, 5).map((file) => `[file] ${file.path} (${file.kind}, ${file.language}, ${file.parser})`),
3118
+ ];
3119
+ const baselineSteps = Math.max(3, baselineFiles.length + 2);
3120
+ const kageSteps = 3;
3121
+ const tokensSaved = Math.max(0, baselineTokens - kageTokens);
3122
+ const contextReduction = baselineTokens > 0 ? percent(tokensSaved, baselineTokens) : 0;
3123
+ const timeSaved = Math.max(0, baselineSteps * 45 - kageSteps * 12);
3124
+ return {
3125
+ schema_version: 1,
3126
+ project_dir: projectDir,
3127
+ task: query,
3128
+ generated_at: nowIso(),
3129
+ baseline_without_kage: {
3130
+ strategy: "manual_repo_discovery_estimate",
3131
+ files_examined: baselineFiles.length,
3132
+ full_file_tokens: baselineTokens,
3133
+ steps: baselineSteps,
3134
+ estimated_time_seconds: baselineSteps * 45,
3135
+ },
3136
+ with_kage: {
3137
+ strategy: "recall_plus_code_graph",
3138
+ recall_results: recallResult.results.length,
3139
+ memory_packets_used: recallResult.results.length,
3140
+ code_files_returned: codeResult.files.length,
3141
+ code_symbols_returned: codeResult.symbols.length,
3142
+ code_routes_returned: codeResult.routes.length,
3143
+ code_tests_returned: codeResult.tests.length,
3144
+ context_tokens: kageTokens,
3145
+ steps: kageSteps,
3146
+ estimated_time_seconds: kageSteps * 12,
3147
+ },
3148
+ delta: {
3149
+ estimated_tokens_saved: tokensSaved,
3150
+ context_reduction_percent: contextReduction,
3151
+ rediscovery_steps_saved: Math.max(0, baselineSteps - kageSteps),
3152
+ estimated_time_saved_seconds: timeSaved,
3153
+ full_file_reads_avoided: Math.max(0, baselineFiles.length - codeResult.files.length),
3154
+ recall_hit: recallResult.results.length > 0,
3155
+ code_graph_hit: codeFactLines.length > 0,
3156
+ },
3157
+ evidence: {
3158
+ baseline_files: baselineFiles.map(({ path, tokens, why }) => ({ path, tokens, why })),
3159
+ kage_memory: recallResult.results.map((entry) => ({
3160
+ id: entry.packet.id,
3161
+ title: entry.packet.title,
3162
+ type: entry.packet.type,
3163
+ score: entry.score,
3164
+ })),
3165
+ kage_code_facts: codeFactLines.slice(0, 12),
3166
+ },
3167
+ caveats: [
3168
+ "Baseline is a deterministic manual-discovery estimate, not a live human or agent timing trace.",
3169
+ "Token savings estimate full-file reads avoided versus compact Kage recall/code-graph context.",
3170
+ "Use this for relative proof on the same repo/task, not cross-repo absolute claims.",
3171
+ ],
3172
+ };
3173
+ }
3067
3174
  function kageMetricsShallow(projectDir) {
3068
3175
  const codeGraph = buildCodeGraph(projectDir);
3069
3176
  const knowledgeGraph = buildKnowledgeGraph(projectDir);
@@ -3108,7 +3215,7 @@ function kageMetricsShallow(projectDir) {
3108
3215
  estimated_indexed_source_tokens: indexedSourceTokens,
3109
3216
  estimated_memory_tokens: memoryTokens,
3110
3217
  estimated_recall_context_tokens: recallContextTokens,
3111
- estimated_tokens_saved_per_recall: Math.max(0, indexedSourceTokens + memoryTokens - recallContextTokens),
3218
+ estimated_tokens_saved_per_recall: Math.max(0, indexedSourceTokens - recallContextTokens),
3112
3219
  },
3113
3220
  harness: {
3114
3221
  policy_installed: (0, node_fs_1.existsSync)((0, node_path_1.join)(projectDir, "AGENTS.md")),
@@ -3423,10 +3530,8 @@ fi
3423
3530
  if [[ -z "$POLICY" ]]; then
3424
3531
  POLICY="This repo uses Kage as an automatic memory harness for coding agents.
3425
3532
  Before making code changes or answering implementation questions:
3426
- 1. Call kage_validate for this repo.
3427
- 2. Call kage_recall with the user task as the query.
3428
- 3. Call kage_code_graph for file, symbol, route, test, or dependency questions.
3429
- 4. Call kage_graph for decisions, bugs, workflows, and conventions.
3533
+ 1. Call kage_context with project_dir and the user task as query.
3534
+ 2. Use returned memory only when it is relevant, source-backed, and not stale.
3430
3535
  When you learn something reusable: kage_learn.
3431
3536
  After meaningful file changes: kage_refresh.
3432
3537
  Before finishing a task that changed files: kage_pr_summarize or kage_propose_from_diff, then kage_pr_check.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kage-core/kage-graph-mcp",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "Local-first repo memory, code graph, and recall MCP server for coding agents",
5
5
  "main": "dist/index.js",
6
6
  "files": [