context-mcp-server 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.
Files changed (58) hide show
  1. package/README.md +464 -0
  2. package/codegraph/__init__.py +0 -0
  3. package/codegraph/__main__.py +24 -0
  4. package/codegraph/__pycache__/__init__.cpython-313.pyc +0 -0
  5. package/codegraph/__pycache__/__main__.cpython-313.pyc +0 -0
  6. package/codegraph/__pycache__/cache.cpython-313.pyc +0 -0
  7. package/codegraph/__pycache__/config.cpython-313.pyc +0 -0
  8. package/codegraph/__pycache__/report.cpython-313.pyc +0 -0
  9. package/codegraph/__pycache__/scanner.cpython-313.pyc +0 -0
  10. package/codegraph/__pycache__/server.cpython-313.pyc +0 -0
  11. package/codegraph/cache.py +137 -0
  12. package/codegraph/config.py +31 -0
  13. package/codegraph/extractors/__init__.py +0 -0
  14. package/codegraph/extractors/__pycache__/__init__.cpython-313.pyc +0 -0
  15. package/codegraph/extractors/__pycache__/ast_extractor.cpython-313.pyc +0 -0
  16. package/codegraph/extractors/__pycache__/audio_extractor.cpython-313.pyc +0 -0
  17. package/codegraph/extractors/__pycache__/doc_extractor.cpython-313.pyc +0 -0
  18. package/codegraph/extractors/__pycache__/image_extractor.cpython-313.pyc +0 -0
  19. package/codegraph/extractors/ast_extractor.py +222 -0
  20. package/codegraph/extractors/audio_extractor.py +8 -0
  21. package/codegraph/extractors/doc_extractor.py +34 -0
  22. package/codegraph/extractors/image_extractor.py +26 -0
  23. package/codegraph/graph/__init__.py +0 -0
  24. package/codegraph/graph/__pycache__/__init__.cpython-313.pyc +0 -0
  25. package/codegraph/graph/__pycache__/builder.cpython-313.pyc +0 -0
  26. package/codegraph/graph/__pycache__/clustering.cpython-313.pyc +0 -0
  27. package/codegraph/graph/__pycache__/query.cpython-313.pyc +0 -0
  28. package/codegraph/graph/builder.py +145 -0
  29. package/codegraph/graph/clustering.py +40 -0
  30. package/codegraph/graph/query.py +283 -0
  31. package/codegraph/report.py +115 -0
  32. package/codegraph/scanner.py +92 -0
  33. package/codegraph/server.py +514 -0
  34. package/package.json +62 -0
  35. package/src/cli.js +1010 -0
  36. package/src/config.js +89 -0
  37. package/src/db.js +786 -0
  38. package/src/guard.js +20 -0
  39. package/src/hooks/autoContext.js +17 -0
  40. package/src/hooks/autoLink.js +7 -0
  41. package/src/http.js +765 -0
  42. package/src/index.js +47 -0
  43. package/src/search.js +50 -0
  44. package/src/server.js +80 -0
  45. package/src/summarizer.js +124 -0
  46. package/src/templates/AGENTS.md +76 -0
  47. package/src/templates/CLAUDE.md +94 -0
  48. package/src/templates/GEMINI.md +76 -0
  49. package/src/templates/cursor-rules.mdc +41 -0
  50. package/src/templates/windsurf-rules.md +35 -0
  51. package/src/tools/codegraph.js +215 -0
  52. package/src/tools/context.js +188 -0
  53. package/src/tools/discussion.js +123 -0
  54. package/src/tools/errorCheck.js +65 -0
  55. package/src/tools/fileTools.js +185 -0
  56. package/src/tools/gitTools.js +259 -0
  57. package/src/tools/search.js +55 -0
  58. package/src/vector.js +153 -0
package/src/index.js ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ import { createServer } from './server.js';
3
+
4
+ // ── CLI flags ─────────────────────────────────────────────────────────────────
5
+ // --data-dir <path> Override ~/.context-mcp storage directory
6
+ // --help Show usage
7
+
8
+ const args = process.argv.slice(2);
9
+
10
+ if (args.includes('--help') || args.includes('-h')) {
11
+ console.log(`
12
+ context-mcp — Persistent AI memory MCP server (stdio transport)
13
+
14
+ Usage:
15
+ context-mcp [options]
16
+ npx context-mcp-server@latest [options]
17
+
18
+ Options:
19
+ --data-dir <path> Override storage directory (default: ~/.context-mcp)
20
+ Also settable via env: CONTEXT_MCP_DIR=<path>
21
+ --help, -h Show this help
22
+
23
+ Platform setup (stdio):
24
+ Claude Code: claude mcp add context-mcp npx context-mcp-server@latest
25
+ Cursor: add to .cursor/mcp.json
26
+ VS Code: add to .vscode/mcp.json
27
+ Gemini CLI: add to .gemini/settings.json
28
+ Codex CLI: add to .codex/config.toml
29
+ Windsurf: add to global mcp_config.json
30
+
31
+ Examples:
32
+ context-mcp
33
+ context-mcp --data-dir /my/project/.ctx
34
+ CONTEXT_MCP_DIR=/tmp/ctx context-mcp
35
+ `);
36
+ process.exit(0);
37
+ }
38
+
39
+ const dataDirIdx = args.indexOf('--data-dir');
40
+ if (dataDirIdx !== -1 && args[dataDirIdx + 1]) {
41
+ process.env.CONTEXT_MCP_DIR = args[dataDirIdx + 1];
42
+ }
43
+
44
+ const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
45
+ const server = createServer();
46
+ const transport = new StdioServerTransport();
47
+ await server.connect(transport);
package/src/search.js ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * search.js — unified search entry point
3
+ *
4
+ * Single function replaces direct calls to searchContext / vectorSearch / findRelated
5
+ * across index.js, cli.js, and error_check. db.js + vector.js stay as low-level impls.
6
+ */
7
+
8
+ import { getContext, searchContext } from './db.js';
9
+ import { vectorSearch, findRelated } from './vector.js';
10
+
11
+ /**
12
+ * @param {Object} opts
13
+ * @param {string} opts.query - search query (keyword/semantic)
14
+ * @param {string} [opts.mode] - 'keyword' | 'semantic' | 'related' (default: semantic)
15
+ * @param {string} [opts.project] - scope to project
16
+ * @param {number} [opts.limit] - max results (default 10)
17
+ * @param {string} [opts.id] - [related] entry ID
18
+ * @param {boolean} [opts.compact] - return compact previews
19
+ */
20
+ export function search({ query, mode = 'semantic', project, limit = 10, id, compact = false }) {
21
+ switch (mode) {
22
+ case 'keyword': {
23
+ if (!query) throw new Error('query required for keyword search');
24
+ return searchContext({ query, project, limit, compact });
25
+ }
26
+ case 'semantic': {
27
+ if (!query) throw new Error('query required for semantic search');
28
+ const corpus = getContext({ project, limit: 500 });
29
+ return vectorSearch(query, corpus, limit);
30
+ }
31
+ case 'related': {
32
+ if (!id) throw new Error('id required for related search');
33
+ const all = getContext({ limit: 1000 });
34
+ const target = all.find(e => e.id === id || e.id.startsWith(id));
35
+ if (!target) throw new Error(`No entry found with id starting "${id}"`);
36
+ // explicit relations first, semantic enrichment for remainder
37
+ const explicitIds = new Set([
38
+ ...(target.relations || []).map(r => r.id),
39
+ ...(target.relatedBy || []).map(r => r.id),
40
+ ]);
41
+ const explicit = all.filter(e => explicitIds.has(e.id));
42
+ const semantic = explicitIds.size < limit
43
+ ? findRelated(target, all.filter(e => !explicitIds.has(e.id) && e.id !== target.id), limit - explicitIds.size)
44
+ : [];
45
+ return { target, results: [...explicit, ...semantic].slice(0, limit) };
46
+ }
47
+ default:
48
+ throw new Error(`Unknown search mode: ${mode}. Use: keyword, semantic, related`);
49
+ }
50
+ }
package/src/server.js ADDED
@@ -0,0 +1,80 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
3
+
4
+ import { getConfig } from './config.js';
5
+
6
+ import * as contextTool from './tools/context.js';
7
+ import * as searchTool from './tools/search.js';
8
+ import * as discussionTool from './tools/discussion.js';
9
+ import * as errorCheckTool from './tools/errorCheck.js';
10
+ import * as fileTool from './tools/fileTools.js';
11
+ import * as gitTool from './tools/gitTools.js';
12
+ import * as codegraphTool from './tools/codegraph.js';
13
+
14
+ const FILE_TOOL_NAMES = new Set(fileTool.definitions.map(d => d.name));
15
+ const GIT_TOOL_NAMES = new Set(gitTool.definitions.map(d => d.name));
16
+ const CODEGRAPH_TOOL_NAMES = codegraphTool.TOOL_NAMES;
17
+
18
+ export function createServer({ enableFileTools = false, enableGitTools = getConfig().access_git === true } = {}) {
19
+ const state = {
20
+ sessionProject: null,
21
+ discussionId: null,
22
+ };
23
+
24
+ const server = new Server(
25
+ { name: 'context-mcp', version: '1.0.0' },
26
+ { capabilities: { tools: {} } }
27
+ );
28
+
29
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
30
+ const tools = [
31
+ contextTool.definition,
32
+ searchTool.definition,
33
+ discussionTool.definition,
34
+ errorCheckTool.definition,
35
+ ];
36
+ if (enableFileTools) tools.push(...fileTool.definitions);
37
+ if (enableGitTools) tools.push(...gitTool.definitions);
38
+ tools.push(...codegraphTool.definitions);
39
+ return { tools };
40
+ });
41
+
42
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
43
+ const { name, arguments: args = {} } = request.params;
44
+
45
+ if (FILE_TOOL_NAMES.has(name) && !enableFileTools) {
46
+ throw new Error(`Tool "${name}" is only available in online (HTTP) mode.`);
47
+ }
48
+ if (GIT_TOOL_NAMES.has(name) && !enableGitTools) {
49
+ throw new Error(`Tool "${name}" requires ACCESS_GIT=true.`);
50
+ }
51
+
52
+ try {
53
+ let result;
54
+
55
+ if (name === contextTool.definition.name) {
56
+ result = await contextTool.handle(args, state);
57
+ } else if (name === searchTool.definition.name) {
58
+ result = await searchTool.handle(args, state);
59
+ } else if (name === discussionTool.definition.name) {
60
+ result = await discussionTool.handle(args, state);
61
+ } else if (name === errorCheckTool.definition.name) {
62
+ result = await errorCheckTool.handle(args, state);
63
+ } else if (FILE_TOOL_NAMES.has(name)) {
64
+ result = await fileTool.handle(name, args, state);
65
+ } else if (GIT_TOOL_NAMES.has(name)) {
66
+ result = await gitTool.handle(name, args, state);
67
+ } else if (CODEGRAPH_TOOL_NAMES.has(name)) {
68
+ result = codegraphTool.handle(name, args, state);
69
+ } else {
70
+ throw new Error(`Unknown tool: ${name}`);
71
+ }
72
+
73
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
74
+ } catch (err) {
75
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
76
+ }
77
+ });
78
+
79
+ return server;
80
+ }
@@ -0,0 +1,124 @@
1
+ /**
2
+ * summarizer.js — session auto-summarizer
3
+ *
4
+ * Groups recent context entries by project and tag, then produces
5
+ * a structured Markdown summary you can save back as a single entry.
6
+ *
7
+ * Uses extractive summarization (no LLM needed):
8
+ * 1. Score sentences by TF-IDF weight against the session's corpus
9
+ * 2. Pick top N sentences in original order
10
+ * 3. Format as structured Markdown
11
+ */
12
+
13
+ import { vectorSearch } from './vector.js';
14
+
15
+ // ── Sentence scoring ──────────────────────────────────────────────────────────
16
+
17
+ function sentences(text) {
18
+ return String(text || '')
19
+ .replace(/\n+/g, ' ')
20
+ .split(/(?<=[.!?])\s+/)
21
+ .map(s => s.trim())
22
+ .filter(s => s.length > 20);
23
+ }
24
+
25
+ const STOP = new Set([
26
+ 'a','an','the','and','or','but','in','on','at','to','for','of','with',
27
+ 'by','from','is','it','its','as','be','was','are','this','that','i','we',
28
+ ]);
29
+
30
+ function tokens(text) {
31
+ return text.toLowerCase().replace(/[^a-z0-9\s]/g, ' ').split(/\s+/)
32
+ .filter(w => w.length > 2 && !STOP.has(w));
33
+ }
34
+
35
+ function scoreEntry(entry, corpusTokenFreq) {
36
+ const toks = tokens(`${entry.title || ''} ${entry.content || ''}`);
37
+ if (!toks.length) return 0;
38
+ return toks.reduce((s, t) => s + (corpusTokenFreq[t] || 0), 0) / toks.length;
39
+ }
40
+
41
+ function buildFreq(entries) {
42
+ const freq = {};
43
+ for (const e of entries) {
44
+ for (const t of tokens(`${e.title || ''} ${e.content || ''}`)) {
45
+ freq[t] = (freq[t] || 0) + 1;
46
+ }
47
+ }
48
+ return freq;
49
+ }
50
+
51
+ // ── Group by tag ──────────────────────────────────────────────────────────────
52
+
53
+ function groupByTag(entries) {
54
+ const groups = {};
55
+ for (const e of entries) {
56
+ const tags = Array.isArray(e.tags) ? e.tags : [];
57
+ const primaryTag = tags[0] || 'general';
58
+ if (!groups[primaryTag]) groups[primaryTag] = [];
59
+ groups[primaryTag].push(e);
60
+ }
61
+ return groups;
62
+ }
63
+
64
+ // ── Build Markdown summary ────────────────────────────────────────────────────
65
+
66
+ /**
67
+ * Summarize a set of context entries into structured Markdown.
68
+ *
69
+ * @param {Array} entries - context entries to summarize
70
+ * @param {Object} opts
71
+ * @param {string} opts.project
72
+ * @param {string} opts.sessionLabel - e.g. "2025-01-15 morning session"
73
+ * @param {number} opts.topN - top entries per group (default 3)
74
+ * @returns {string} Markdown summary
75
+ */
76
+ export function summarizeEntries(entries, { project = 'global', sessionLabel = '', topN = 3 } = {}) {
77
+ if (!entries.length) return '_No entries to summarize._';
78
+
79
+ const freq = buildFreq(entries);
80
+ const label = sessionLabel || new Date().toISOString().slice(0, 10);
81
+ const groups = groupByTag(entries);
82
+
83
+ const lines = [
84
+ `## Session summary — ${project} · ${label}`,
85
+ '',
86
+ `**${entries.length} context entries** across ${Object.keys(groups).length} topic(s).`,
87
+ '',
88
+ ];
89
+
90
+ for (const [tag, group] of Object.entries(groups)) {
91
+ lines.push(`### ${tag}`);
92
+ // Score and pick top N
93
+ const ranked = group
94
+ .map(e => ({ ...e, _score: scoreEntry(e, freq) }))
95
+ .sort((a, b) => b._score - a._score)
96
+ .slice(0, topN);
97
+
98
+ for (const e of ranked) {
99
+ lines.push(`- **${e.title || e.id.slice(0, 8)}** _(${e.source || 'user'}, ${(e.createdAt || '').slice(0, 10)})_`);
100
+ // Extract most informative sentence
101
+ const sents = sentences(e.content);
102
+ const best = sents.sort((a, b) =>
103
+ tokens(b).reduce((s, t) => s + (freq[t] || 0), 0) -
104
+ tokens(a).reduce((s, t) => s + (freq[t] || 0), 0)
105
+ )[0];
106
+ if (best) lines.push(` ${best.length > 140 ? best.slice(0, 137) + '...' : best}`);
107
+ }
108
+
109
+ if (group.length > topN) {
110
+ lines.push(` _…and ${group.length - topN} more ${tag} entries_`);
111
+ }
112
+ lines.push('');
113
+ }
114
+
115
+ // Key terms
116
+ const topTerms = Object.entries(freq)
117
+ .sort((a, b) => b[1] - a[1])
118
+ .slice(0, 10)
119
+ .map(([t]) => `\`${t}\``);
120
+ lines.push(`**Key terms:** ${topTerms.join(', ')}`);
121
+
122
+ return lines.join('\n');
123
+ }
124
+
@@ -0,0 +1,76 @@
1
+ # Context-MCP — Codex CLI Usage Guide
2
+
3
+ Persistent memory + codebase knowledge graph.
4
+ Every conversation starts with `context.resume`. Every structural question uses `codegraph_query`. Files only read for bugs/logic.
5
+
6
+ ---
7
+
8
+ ## 1. Start of Every Conversation (MANDATORY)
9
+
10
+ Call the `context` MCP tool with `action: "resume"`, `project: "<project-name>"` **before anything else**.
11
+
12
+ Returns:
13
+ - `recentEntries` — decisions, bugs, notes from previous conversations
14
+ - `activeDiscussions` — ongoing topics
15
+ - `codegraph` — `{ built: true/false, nodes, edges, communities }`
16
+
17
+ Then:
18
+ - `codegraph.built: true` → use `codegraph_query` before reading any files
19
+ - `codegraph.built: false` → call `codegraph_build(path)` first, then proceed
20
+
21
+ ---
22
+
23
+ ## 2. During the Conversation
24
+
25
+ | Situation | Action |
26
+ |-----------|--------|
27
+ | Decision made | `context.save` type: `"decision"` |
28
+ | Bug found/fixed | `context.save` type: `"bug"` |
29
+ | Architecture understood | `context.save` type: `"architecture"` |
30
+ | User says "save/remember this" | `context.save` immediately |
31
+ | Feature spans sessions | `discussion.save` status: `"active"` |
32
+ | Need past info | `search` before asking user |
33
+
34
+ Always pass `project`. Auto-compact fires at >50 entries.
35
+
36
+ ---
37
+
38
+ ## 3. CodeGraph Pipeline
39
+
40
+ ### Step 1 — Build (once, free)
41
+ ```
42
+ codegraph_build(path) → AST graph: functions, classes, imports, edges
43
+ ```
44
+
45
+ ### Step 2 — Enrich (one-time per file)
46
+ ```
47
+ codegraph_extract(path) → file content + node list
48
+ codegraph_add_nodes(path, nodes) → semantic descriptions (permanent cache)
49
+ ```
50
+
51
+ ### Step 3 — Query (free, instant)
52
+ ```
53
+ codegraph_query(path, question) → NODE/EDGE subgraph (token_budget default 2000)
54
+ codegraph_explain(path, node) → single node + neighbors
55
+ codegraph_path(path, from, to) → shortest path
56
+ codegraph_nodes(path, type) → list nodes by type
57
+ codegraph_report(path) → full graph analysis
58
+ ```
59
+
60
+ ---
61
+
62
+ ## 4. Graph vs File
63
+
64
+ **Graph** — structural questions: dependencies, callers, imports.
65
+ **File** — bugs, logic, tracing behavior.
66
+
67
+ ---
68
+
69
+ ## 5. Rules
70
+
71
+ 1. **`context.resume` first** — before any tool or response
72
+ 2. **Always pass `project`**
73
+ 3. **`search` before asking** — if user references past work
74
+ 4. **`codegraph_query` before reading files**
75
+ 5. **Read files for bugs/logic only**
76
+ 6. **Enrich once** — descriptions persist forever
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: context-mcp
3
+ description: >
4
+ Guides Claude on using the context-mcp memory + knowledge graph system.
5
+ Trigger at the start of every conversation, when the user mentions a project,
6
+ asks to remember/save something, or says "pick up where we left off".
7
+ ---
8
+
9
+ # Context-MCP — Claude Usage Guide
10
+
11
+ Persistent memory + codebase knowledge graph for Claude.
12
+ Every conversation starts with `context.resume`. Every structural question uses `codegraph_query`. Files only read for bugs/logic.
13
+
14
+ ---
15
+
16
+ ## 1. Start of Every Conversation (MANDATORY)
17
+
18
+ Call `context` tool, `action: "resume"`, `project: "<project-name>"` **before anything else**.
19
+
20
+ Returns:
21
+ - `recentEntries` — decisions, bugs, notes from previous conversations
22
+ - `activeDiscussions` — ongoing topics (auto-linked if exactly one active)
23
+ - `codegraph` — `{ built: true/false, nodes, edges, communities }`
24
+
25
+ Then:
26
+ - `codegraph.built: true` → use `codegraph_query` before reading any files
27
+ - `codegraph.built: false` → call `codegraph_build(path)` first, then proceed
28
+
29
+ ---
30
+
31
+ ## 2. During the Conversation
32
+
33
+ | Situation | Action |
34
+ |-----------|--------|
35
+ | Decision made | `context.save` type: `"decision"` |
36
+ | Bug found/fixed | `context.save` type: `"bug"` |
37
+ | Architecture understood | `context.save` type: `"architecture"` |
38
+ | User says "save/remember this" | `context.save` immediately |
39
+ | Feature spans multiple conversations | `discussion.create` or `discussion.update` |
40
+ | Need past info | `search` before asking user |
41
+
42
+ Always pass `project`. Auto-compact fires at >50 entries — oldest summarized automatically.
43
+
44
+ ---
45
+
46
+ ## 3. CodeGraph Pipeline
47
+
48
+ ### Step 1 — Build (once per project, free)
49
+ ```
50
+ codegraph_build(path)
51
+ → AST: code files → functions, classes, imports, edges
52
+ → Config: .yaml .toml .sql → schema nodes
53
+ → Docs: .md .txt .pdf → pending (no content yet)
54
+ ```
55
+ Saves graph to `~/.context-mcp/graphs.json`. Visible on `context.resume`.
56
+
57
+ ### Step 2 — Enrich (one-time cost per file)
58
+ ```
59
+ codegraph_extract(path)
60
+ → returns changed code files (with existing node list) + doc files (raw text)
61
+
62
+ For each code file: write description for each node listed in existing_nodes
63
+ For each doc file: extract concept nodes + relationships
64
+
65
+ codegraph_add_nodes(path, nodes)
66
+ → stores descriptions in semantic cache (never overwritten by rebuild)
67
+ ```
68
+
69
+ ### Step 3 — Query (free, instant forever)
70
+ ```
71
+ codegraph_query(path, question) → NODE/EDGE subgraph, token_budget param (default 2000)
72
+ codegraph_explain(path, node) → one node: description + depends_on + used_by
73
+ codegraph_path(path, from, to) → shortest path between two concepts
74
+ codegraph_nodes(path, type) → list all nodes of a type
75
+ codegraph_report(path) → god nodes, clusters, surprises
76
+ ```
77
+
78
+ ---
79
+
80
+ ## 4. Graph vs File
81
+
82
+ **Graph** — structural questions: dependencies, callers, imports, paths between concepts.
83
+ **File** — bugs, logic inside a function, tracing unexpected behavior.
84
+
85
+ ---
86
+
87
+ ## 5. Rules
88
+
89
+ 1. **`context.resume` first** — before any tool or response
90
+ 2. **Always pass `project`** — never save to global unless truly cross-project
91
+ 3. **`search` before asking** — if user references past work, find it first
92
+ 4. **`codegraph_query` before reading files** — graph is faster and cheaper
93
+ 5. **Read files for bugs/logic** — graph is structure only, not behavior
94
+ 6. **Enrich once** — run extract → add_nodes once per project; descriptions persist forever
@@ -0,0 +1,76 @@
1
+ # Context-MCP — Gemini CLI Usage Guide
2
+
3
+ Persistent memory + codebase knowledge graph.
4
+ Every conversation starts with `context.resume`. Every structural question uses `codegraph_query`. Files only read for bugs/logic.
5
+
6
+ ---
7
+
8
+ ## 1. Start of Every Conversation (MANDATORY)
9
+
10
+ Call the `context` MCP tool with `action: "resume"`, `project: "<project-name>"` **before anything else**.
11
+
12
+ Returns:
13
+ - `recentEntries` — decisions, bugs, notes from previous conversations
14
+ - `activeDiscussions` — ongoing topics (auto-linked if exactly one active)
15
+ - `codegraph` — `{ built: true/false, nodes, edges, communities }`
16
+
17
+ Then:
18
+ - `codegraph.built: true` → use `codegraph_query` before reading any files
19
+ - `codegraph.built: false` → call `codegraph_build(path)` first, then proceed
20
+
21
+ ---
22
+
23
+ ## 2. During the Conversation
24
+
25
+ | Situation | Action |
26
+ |-----------|--------|
27
+ | Decision made | `context.save` type: `"decision"` |
28
+ | Bug found/fixed | `context.save` type: `"bug"` |
29
+ | Architecture understood | `context.save` type: `"architecture"` |
30
+ | User says "save/remember this" | `context.save` immediately |
31
+ | Feature spans sessions | `discussion.save` then `discussion.update` |
32
+ | Need past info | `search` before asking user |
33
+
34
+ Always pass `project`. Auto-compact fires at >50 entries.
35
+
36
+ ---
37
+
38
+ ## 3. CodeGraph Pipeline
39
+
40
+ ### Step 1 — Build (once, free)
41
+ ```
42
+ codegraph_build(path) → AST graph: functions, classes, imports, edges
43
+ ```
44
+
45
+ ### Step 2 — Enrich (one-time per file)
46
+ ```
47
+ codegraph_extract(path) → file content + node list
48
+ codegraph_add_nodes(path, nodes) → semantic descriptions (permanent cache)
49
+ ```
50
+
51
+ ### Step 3 — Query (free, instant)
52
+ ```
53
+ codegraph_query(path, question) → NODE/EDGE subgraph (token_budget default 2000)
54
+ codegraph_explain(path, node) → single node + neighbors
55
+ codegraph_path(path, from, to) → shortest path
56
+ codegraph_nodes(path, type) → list nodes by type
57
+ codegraph_report(path) → full graph analysis
58
+ ```
59
+
60
+ ---
61
+
62
+ ## 4. Graph vs File
63
+
64
+ **Graph** — structural questions: dependencies, callers, imports.
65
+ **File** — bugs, logic, tracing behavior.
66
+
67
+ ---
68
+
69
+ ## 5. Rules
70
+
71
+ 1. **`context.resume` first** — before any tool or response
72
+ 2. **Always pass `project`** — never save to global unless truly cross-project
73
+ 3. **`search` before asking** — if user references past work, find it first
74
+ 4. **`codegraph_query` before reading files** — graph is faster and cheaper
75
+ 5. **Read files for bugs/logic** — graph is structure only, not behavior
76
+ 6. **Enrich once** — descriptions persist forever
@@ -0,0 +1,41 @@
1
+ ---
2
+ description: Use context-mcp for persistent memory and codebase knowledge graph across all AI sessions.
3
+ globs: ["**/*"]
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Context-MCP — Cursor Usage Guide
8
+
9
+ Persistent memory + codebase knowledge graph for Cursor.
10
+ Every conversation starts with `context.resume`. Every structural question uses `codegraph_query`. Files only read for bugs/logic.
11
+
12
+ ## 1. Start of Every Conversation (MANDATORY)
13
+
14
+ Call `context` tool, `action: "resume"`, `project: "<project-name>"` before anything else.
15
+
16
+ Returns: `recentEntries`, `activeDiscussions`, `codegraph { built, nodes, edges }`.
17
+
18
+ - `codegraph.built: true` → use `codegraph_query` before reading files
19
+ - `codegraph.built: false` → run `codegraph_build(path)` first
20
+
21
+ ## 2. Save Context
22
+
23
+ | Situation | Action |
24
+ |-----------|--------|
25
+ | Decision made | `context.save` type: `"decision"` |
26
+ | Bug found/fixed | `context.save` type: `"bug"` |
27
+ | Architecture understood | `context.save` type: `"architecture"` |
28
+ | Multi-session feature | `discussion.create` |
29
+
30
+ ## 3. CodeGraph
31
+
32
+ Build once: `codegraph_build(path)` — then query forever.
33
+ Use `codegraph_query` for structural questions. Read files for bugs/logic.
34
+
35
+ ## Rules
36
+
37
+ 1. `context.resume` first — every conversation
38
+ 2. Always pass `project`
39
+ 3. `search` before asking the user about past work
40
+ 4. `codegraph_query` before reading files
41
+ 5. Files only for bugs and logic
@@ -0,0 +1,35 @@
1
+ # Context-MCP — Windsurf Usage Guide
2
+
3
+ Persistent memory + codebase knowledge graph for Windsurf.
4
+ Every conversation starts with `context.resume`. Every structural question uses `codegraph_query`. Files only read for bugs/logic.
5
+
6
+ ## 1. Start of Every Conversation (MANDATORY)
7
+
8
+ Call `context` tool, `action: "resume"`, `project: "<project-name>"` before anything else.
9
+
10
+ Returns: `recentEntries`, `activeDiscussions`, `codegraph { built, nodes, edges }`.
11
+
12
+ - `codegraph.built: true` → use `codegraph_query` before reading files
13
+ - `codegraph.built: false` → run `codegraph_build(path)` first
14
+
15
+ ## 2. Save Context
16
+
17
+ | Situation | Action |
18
+ |-----------|--------|
19
+ | Decision made | `context.save` type: `"decision"` |
20
+ | Bug found/fixed | `context.save` type: `"bug"` |
21
+ | Architecture understood | `context.save` type: `"architecture"` |
22
+ | Multi-session feature | `discussion.create` |
23
+
24
+ ## 3. CodeGraph
25
+
26
+ Build once: `codegraph_build(path)` — then query forever.
27
+ Use `codegraph_query` for structural questions. Read files for bugs/logic.
28
+
29
+ ## Rules
30
+
31
+ 1. `context.resume` first — every conversation
32
+ 2. Always pass `project`
33
+ 3. `search` before asking the user about past work
34
+ 4. `codegraph_query` before reading files
35
+ 5. Files only for bugs and logic