context-mcp-server 1.0.2 → 1.0.4
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 +12 -16
- package/codegraph/__pycache__/config.cpython-313.pyc +0 -0
- package/codegraph/__pycache__/scanner.cpython-313.pyc +0 -0
- package/codegraph/__pycache__/server.cpython-313.pyc +0 -0
- package/codegraph/config.py +139 -22
- package/codegraph/extractors/__pycache__/ast_extractor.cpython-313.pyc +0 -0
- package/codegraph/extractors/__pycache__/build_extractor.cpython-313.pyc +0 -0
- package/codegraph/extractors/ast_extractor.py +392 -176
- package/codegraph/extractors/build_extractor.py +68 -0
- package/codegraph/scanner.py +5 -21
- package/codegraph/server.py +32 -229
- package/package.json +3 -1
- package/pyproject.toml +69 -0
- package/src/cli.js +2 -2
- package/src/templates/AGENTS.md +8 -15
- package/src/templates/CLAUDE.md +15 -27
- package/src/templates/GEMINI.md +7 -14
- package/uv.lock +1295 -0
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ Persistent memory and codebase knowledge graph for AI coding assistants — deli
|
|
|
4
4
|
|
|
5
5
|
One shared context store. Works across Claude Code, Cursor, Gemini CLI, Codex, Windsurf, VS Code Copilot, Claude.ai, and ChatGPT. Save context from one AI, pick it up in another. Your memory follows the project, not the tool.
|
|
6
6
|
|
|
7
|
+
**6 AI platforms** · **6 IDEs** · **16 programming languages** (Python, JS, TS, Go, Rust, Java, Kotlin, C, C++, C#, Ruby, PHP, Swift, Lua, and more) · tree-sitter AST parsing with regex fallback
|
|
8
|
+
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
## The Problem
|
|
@@ -25,9 +27,6 @@ You fix a bug with Claude Code, then open Cursor and it knows nothing about it.
|
|
|
25
27
|
**3. Structural understanding costs too many tokens.**
|
|
26
28
|
Reading 20 files to answer "what calls this function?" is wasteful. context-mcp builds a knowledge graph of your codebase once, then answers structural questions in ~500 tokens instead of ~50,000.
|
|
27
29
|
|
|
28
|
-
**4. Repeated enrichment is expensive.**
|
|
29
|
-
AI-written descriptions of your code nodes are computed once and stored permanently. They survive file changes, rebuilds, and new conversations — never paid for twice.
|
|
30
|
-
|
|
31
30
|
---
|
|
32
31
|
|
|
33
32
|
## Installation
|
|
@@ -373,11 +372,9 @@ Available to web clients (Claude.ai, ChatGPT) only — local AI clients use thei
|
|
|
373
372
|
All file and git operations are sandboxed to the registered project root. Enable git tools with `--access-git` or `access_git: true` in config.
|
|
374
373
|
|
|
375
374
|
### CodeGraph
|
|
376
|
-
- `codegraph_build` — AST scan: functions, classes, imports, edges. Runs locally, no API cost.
|
|
377
|
-
- `
|
|
378
|
-
- `
|
|
379
|
-
- `codegraph_query` — natural language structural question → NODE/EDGE subgraph with `token_budget` control
|
|
380
|
-
- `codegraph_explain` — single node: description, dependencies, usages
|
|
375
|
+
- `codegraph_build` — AST scan using tree-sitter: functions, classes, imports, edges. Runs locally, no API cost.
|
|
376
|
+
- `codegraph_query` — fetch any details about the codebase using natural language: find functions, classes, files, dependencies, callers
|
|
377
|
+
- `codegraph_explain` — single node: type, file location, all direct connections (depends_on, used_by)
|
|
381
378
|
- `codegraph_path` — shortest path between two concepts
|
|
382
379
|
- `codegraph_nodes` — list all nodes of a given type
|
|
383
380
|
- `codegraph_report` — full graph analysis: god nodes, clusters, surprising connections
|
|
@@ -436,15 +433,14 @@ context-mcp/
|
|
|
436
433
|
│ ├── gitTools.js Git integration (HTTP mode, sandboxed to project root)
|
|
437
434
|
│ └── errorCheck.js Error checking tool
|
|
438
435
|
├── codegraph/ Python package — AST extraction + graph queries
|
|
439
|
-
│ ├── server.py
|
|
440
|
-
│ ├── scanner.py File walker + classifier
|
|
441
|
-
│ ├──
|
|
436
|
+
│ ├── server.py MCP server — tool definitions + dispatch
|
|
437
|
+
│ ├── scanner.py File walker + classifier (SKIP/BUILD/CODE/CONFIG/DOC/MEDIA)
|
|
438
|
+
│ ├── config.py File type taxonomy
|
|
439
|
+
│ ├── cache.py AST cache (hash-based, incremental)
|
|
442
440
|
│ ├── report.py Graph report generator
|
|
443
441
|
│ ├── extractors/
|
|
444
|
-
│ │ ├── ast_extractor.py
|
|
445
|
-
│ │
|
|
446
|
-
│ │ ├── image_extractor.py
|
|
447
|
-
│ │ └── audio_extractor.py
|
|
442
|
+
│ │ ├── ast_extractor.py Tree-sitter AST (16 languages) + regex fallback
|
|
443
|
+
│ │ └── build_extractor.py Single-node extraction for build files
|
|
448
444
|
│ └── graph/
|
|
449
445
|
│ ├── builder.py NetworkX graph construction
|
|
450
446
|
│ ├── query.py Natural language → subgraph traversal
|
|
@@ -453,7 +449,7 @@ context-mcp/
|
|
|
453
449
|
├── contexts.json
|
|
454
450
|
├── discussions.json
|
|
455
451
|
├── projects.json Project registry — includes rootPath per project
|
|
456
|
-
├── graphs.json
|
|
452
|
+
├── graphs.json Knowledge graph (nodes, edges, communities)
|
|
457
453
|
└── contextconfig.json OAuth config + server settings
|
|
458
454
|
```
|
|
459
455
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/codegraph/config.py
CHANGED
|
@@ -1,31 +1,148 @@
|
|
|
1
1
|
"""
|
|
2
|
-
config.py — codegraph settings.
|
|
2
|
+
config.py — codegraph file type taxonomy and settings.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
from pathlib import Path
|
|
6
6
|
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
".
|
|
11
|
-
"
|
|
7
|
+
# ── Skip entirely — pure noise, never extract ─────────────────────────────────
|
|
8
|
+
SKIP_FILENAMES = {
|
|
9
|
+
"package-lock.json", "yarn.lock", "pnpm-lock.yaml",
|
|
10
|
+
"poetry.lock", "Cargo.lock", "Pipfile.lock",
|
|
11
|
+
"composer.lock", "Gemfile.lock", "uv.lock",
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
SKIP_EXTENSIONS = {
|
|
15
|
+
".min.js", ".min.css",
|
|
16
|
+
".map",
|
|
17
|
+
".lock",
|
|
18
|
+
".pyc", ".pyo", ".pyd",
|
|
19
|
+
".class", ".jar",
|
|
20
|
+
".o", ".a", ".so", ".dylib",
|
|
21
|
+
".wasm",
|
|
22
|
+
".exe", ".dll",
|
|
23
|
+
".zip", ".tar", ".gz", ".bz2",
|
|
24
|
+
".db", ".sqlite", ".sqlite3",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
SKIP_DIRS = {
|
|
28
|
+
"node_modules", ".git", ".hg", "__pycache__",
|
|
29
|
+
"dist", "build", ".next", ".nuxt", ".svelte-kit",
|
|
30
|
+
".venv", "venv", "env", ".env",
|
|
31
|
+
"vendor", "target",
|
|
32
|
+
".mypy_cache", ".ruff_cache", ".pytest_cache",
|
|
33
|
+
"coverage", ".nyc_output",
|
|
34
|
+
"codegraph-cache",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# ── Code — tree-sitter AST extraction ────────────────────────────────────────
|
|
15
38
|
CODE_EXTENSIONS = {
|
|
16
|
-
".py", ".
|
|
17
|
-
".
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
39
|
+
".py", ".pyw",
|
|
40
|
+
".js", ".mjs", ".cjs", ".jsx",
|
|
41
|
+
".ts", ".mts", ".cts", ".tsx",
|
|
42
|
+
".go",
|
|
43
|
+
".rs",
|
|
44
|
+
".java", ".kt", ".scala", ".groovy",
|
|
45
|
+
".c", ".h", ".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx",
|
|
46
|
+
".cs",
|
|
47
|
+
".rb", ".rake",
|
|
48
|
+
".php",
|
|
49
|
+
".swift",
|
|
50
|
+
".lua", ".luau",
|
|
51
|
+
".zig",
|
|
52
|
+
".ex", ".exs",
|
|
53
|
+
".dart",
|
|
54
|
+
".vue", ".svelte", ".astro",
|
|
55
|
+
".sh", ".bash", ".zsh", ".fish",
|
|
56
|
+
".ps1", ".psm1",
|
|
57
|
+
".r", ".R",
|
|
58
|
+
".jl",
|
|
59
|
+
".f", ".f90", ".f95", ".f03", ".f08",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# ── SQL — tree-sitter-sql extraction ─────────────────────────────────────────
|
|
63
|
+
SQL_EXTENSIONS = {".sql"}
|
|
64
|
+
|
|
65
|
+
# ── Build/config — single file node + key field extraction ───────────────────
|
|
66
|
+
BUILD_EXTENSIONS = {
|
|
67
|
+
".toml",
|
|
68
|
+
".gradle",
|
|
69
|
+
}
|
|
70
|
+
BUILD_FILENAMES = {
|
|
71
|
+
"package.json", "package.yaml",
|
|
72
|
+
"Makefile", "makefile", "GNUmakefile",
|
|
73
|
+
"CMakeLists.txt",
|
|
74
|
+
"Dockerfile",
|
|
75
|
+
"docker-compose.yml", "docker-compose.yaml",
|
|
76
|
+
"docker-compose.override.yml",
|
|
77
|
+
"requirements.txt", "requirements-dev.txt",
|
|
78
|
+
"Pipfile",
|
|
79
|
+
"go.mod",
|
|
80
|
+
"pom.xml",
|
|
81
|
+
"build.xml",
|
|
82
|
+
".env.example", ".env.template",
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# ── Config — label-only node ──────────────────────────────────────────────────
|
|
86
|
+
CONFIG_EXTENSIONS = {
|
|
87
|
+
".yml", ".yaml",
|
|
88
|
+
".json",
|
|
89
|
+
".ini", ".cfg", ".conf",
|
|
90
|
+
".env",
|
|
91
|
+
".properties",
|
|
92
|
+
".xml",
|
|
93
|
+
".plist",
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# ── Docs — LLM semantic extraction ───────────────────────────────────────────
|
|
97
|
+
DOC_EXTENSIONS = {
|
|
98
|
+
".md", ".mdx", ".markdown",
|
|
99
|
+
".txt", ".rst", ".adoc",
|
|
100
|
+
".tex", ".latex",
|
|
101
|
+
".ipynb",
|
|
102
|
+
".org",
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# ── PDF — LLM semantic extraction ────────────────────────────────────────────
|
|
106
|
+
PDF_EXTENSIONS = {".pdf"}
|
|
107
|
+
|
|
108
|
+
# ── Media — label-only node ───────────────────────────────────────────────────
|
|
109
|
+
IMAGE_EXTENSIONS = {
|
|
110
|
+
".png", ".jpg", ".jpeg", ".gif", ".webp",
|
|
111
|
+
".svg", ".ico", ".bmp", ".tiff", ".avif",
|
|
112
|
+
}
|
|
113
|
+
AUDIO_EXTENSIONS = {".mp3", ".wav", ".ogg", ".flac", ".aac", ".m4a"}
|
|
114
|
+
VIDEO_EXTENSIONS = {".mp4", ".mov", ".avi", ".mkv", ".webm", ".m4v"}
|
|
115
|
+
|
|
116
|
+
# ── Size limits ───────────────────────────────────────────────────────────────
|
|
28
117
|
MAX_FILE_BYTES = 500_000
|
|
118
|
+
DOC_MAX_CHARS = 8_000
|
|
119
|
+
|
|
120
|
+
# Keep for backward compat — scanner imports this
|
|
121
|
+
DEFAULT_IGNORE = SKIP_DIRS
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def classify_file(path: str) -> str:
|
|
125
|
+
p = Path(path)
|
|
126
|
+
name = p.name
|
|
127
|
+
ext = p.suffix.lower()
|
|
128
|
+
stem = p.stem.lower()
|
|
129
|
+
|
|
130
|
+
if name in SKIP_FILENAMES: return "skip"
|
|
131
|
+
if ext in SKIP_EXTENSIONS: return "skip"
|
|
132
|
+
if stem.endswith(".min"): return "skip"
|
|
133
|
+
|
|
134
|
+
if name in BUILD_FILENAMES: return "build"
|
|
135
|
+
if ext in BUILD_EXTENSIONS: return "build"
|
|
136
|
+
|
|
137
|
+
if ext in CODE_EXTENSIONS: return "code"
|
|
138
|
+
if ext in SQL_EXTENSIONS: return "sql"
|
|
139
|
+
|
|
140
|
+
if ext in CONFIG_EXTENSIONS: return "config"
|
|
141
|
+
|
|
142
|
+
if ext in DOC_EXTENSIONS: return "doc"
|
|
143
|
+
if ext in PDF_EXTENSIONS: return "pdf"
|
|
144
|
+
if ext in IMAGE_EXTENSIONS: return "image"
|
|
145
|
+
if ext in AUDIO_EXTENSIONS: return "audio"
|
|
146
|
+
if ext in VIDEO_EXTENSIONS: return "video"
|
|
29
147
|
|
|
30
|
-
|
|
31
|
-
DOC_MAX_CHARS = 8_000
|
|
148
|
+
return "unknown"
|
|
Binary file
|
|
Binary file
|