purecontext-mcp 1.1.0 → 1.1.2

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 (45) hide show
  1. package/AGENT_INSTRUCTIONS.md +509 -0
  2. package/AGENT_INSTRUCTIONS_SHORT.md +97 -0
  3. package/CHANGELOG.md +212 -0
  4. package/docs/01-introduction.md +69 -0
  5. package/docs/02-installation.md +267 -0
  6. package/docs/03-quick-start.md +135 -0
  7. package/docs/04-configuration.md +214 -0
  8. package/docs/05-cli-reference.md +130 -0
  9. package/docs/06-tools-reference.md +499 -0
  10. package/docs/07-language-support.md +88 -0
  11. package/docs/08-framework-adapters.md +324 -0
  12. package/docs/09-dependency-graph.md +182 -0
  13. package/docs/10-semantic-search.md +153 -0
  14. package/docs/11-search-quality.md +110 -0
  15. package/docs/12-ai-summarization.md +106 -0
  16. package/docs/13-token-savings.md +110 -0
  17. package/docs/14-transport-modes.md +167 -0
  18. package/docs/15-team-setup.md +251 -0
  19. package/docs/16-docker.md +186 -0
  20. package/docs/17-web-ui.md +157 -0
  21. package/docs/18-git-history.md +157 -0
  22. package/docs/19-cross-repo.md +177 -0
  23. package/docs/20-architecture-analysis.md +228 -0
  24. package/docs/21-ecosystem-tools.md +189 -0
  25. package/docs/22-distribution.md +240 -0
  26. package/docs/23-performance.md +121 -0
  27. package/docs/24-security.md +144 -0
  28. package/docs/25-architecture-overview.md +240 -0
  29. package/docs/26-troubleshooting.md +234 -0
  30. package/docs/27-api-stability.md +114 -0
  31. package/docs/README.md +71 -0
  32. package/guide/README.md +57 -0
  33. package/guide/ai-summaries.md +127 -0
  34. package/guide/code-health.md +190 -0
  35. package/guide/code-history.md +149 -0
  36. package/guide/finding-code.md +157 -0
  37. package/guide/navigating-new-code.md +121 -0
  38. package/guide/safe-changes.md +156 -0
  39. package/guide/team-setup.md +191 -0
  40. package/guide/web-ui.md +154 -0
  41. package/guide/why-purecontext.md +73 -0
  42. package/guide/workflow-onboarding.md +114 -0
  43. package/guide/workflow-pr-review.md +199 -0
  44. package/guide/workflow-refactoring.md +172 -0
  45. package/package.json +9 -2
@@ -0,0 +1,110 @@
1
+ # Search Quality & Ranking
2
+
3
+
4
+ Keyword search is backed by SQLite FTS5 with a custom relevance ranker and a camelCase/snake_case query preprocessor.
5
+
6
+ ---
7
+
8
+ ## How keyword search works
9
+
10
+ `search_symbols` and `search_text` use SQLite's **FTS5** (Full-Text Search) virtual table, which provides:
11
+
12
+ - BM25 ranking — frequency-adjusted term weighting
13
+ - Fast full-text matching without table scans
14
+ - Unicode tokenization
15
+
16
+ Before FTS5, keyword search used SQL `LIKE` — which had 0% precision for camelCase names. FTS5 with the preprocessor below fixed this.
17
+
18
+ ---
19
+
20
+ ## Query preprocessor
21
+
22
+ Before a query hits FTS5, it goes through a preprocessor that splits identifiers into component words:
23
+
24
+ | Input query | Preprocessed to |
25
+ |-------------|----------------|
26
+ | `processOrder` | `process order` |
27
+ | `process_order` | `process order` |
28
+ | `HTTPClient` | `http client` |
29
+ | `getUserById` | `get user by id` |
30
+ | `validate-token` | `validate token` |
31
+ | `auth validate` | `auth validate` (already split) |
32
+
33
+ This means `processOrder` and `process_order` are equivalent queries — no need to guess the naming convention.
34
+
35
+ **Phrase search** bypasses splitting. Use quotes for exact matching:
36
+ ```
37
+ "processOrder" → matches only "processOrder" literally
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Relevance ranker
43
+
44
+ Results are scored by a multi-factor ranker that adjusts raw BM25 scores:
45
+
46
+ | Factor | Boost | Example |
47
+ |--------|-------|---------|
48
+ | Exact name match | +3.0 | query `"authenticate"` matches symbol named `authenticate` |
49
+ | Name starts-with | +1.5 | query `"auth"` matches `authenticateUser` |
50
+ | Symbol kind filter match | +0.5 | `kind: "function"` filters and boosts |
51
+ | File path proximity | +0.3 | query restricted to `src/auth/**` |
52
+ | BM25 base | 1.0 | FTS5 BM25 score |
53
+
54
+ The ranker ensures that an exact name hit always ranks above a summary-only hit, even if the summary appears more times in the index.
55
+
56
+ ---
57
+
58
+ ## `search_symbols` vs `search_text`
59
+
60
+ | Tool | Searches | Returns |
61
+ |------|---------|---------|
62
+ | `search_symbols` | Symbol names and summaries | Symbol metadata (no source) |
63
+ | `search_text` | Raw file content (grep-style) | File + line + context snippet |
64
+
65
+ Use `search_symbols` for navigating by identifier. Use `search_text` when you need to find a string that isn't a symbol name — error messages, config values, comments, string literals.
66
+
67
+ ---
68
+
69
+ ## Debug mode
70
+
71
+ Pass `debug: true` to either search tool to get the scoring breakdown in the response:
72
+
73
+ ```json
74
+ {
75
+ "query": "authenticateUser",
76
+ "debug": true
77
+ }
78
+ ```
79
+
80
+ Response includes:
81
+ ```json
82
+ {
83
+ "symbols": [...],
84
+ "_debug": {
85
+ "preprocessedQuery": "authenticate user",
86
+ "ftsMatches": 12,
87
+ "rankedResults": [
88
+ {
89
+ "name": "authenticateUser",
90
+ "bm25": 4.21,
91
+ "nameBoost": 3.0,
92
+ "finalScore": 7.21
93
+ }
94
+ ]
95
+ }
96
+ }
97
+ ```
98
+
99
+ This is useful for diagnosing why a result ranks unexpectedly high or low.
100
+
101
+ ---
102
+
103
+ ## Search tips
104
+
105
+ - **camelCase and snake_case are equivalent** — `processOrder`, `process_order`, and `process order` all return the same results.
106
+ - **Short queries rank better** — `auth` finds more than `authentication function` because shorter terms match more precisely.
107
+ - **Use `kind` filter to narrow** — `kind: "function"` eliminates class/method noise.
108
+ - **Combine with semantic search** — use `mode: "hybrid"` for the best recall when you're not sure of the exact name.
109
+ - **Scope with `filePath`** — `filePath: "src/auth/**"` restricts to a directory.
110
+ - **For exact strings** — use `search_text` with `is_regex: false` when you need to find a literal string in source.
@@ -0,0 +1,106 @@
1
+ # AI Summarization
2
+
3
+
4
+ AI summarization generates one-line descriptions for symbols that have no docstring. Summaries appear in search results and reduce the need to fetch full source.
5
+
6
+ ---
7
+
8
+ ## Summary priority chain
9
+
10
+ For every symbol, PureContext uses the first successful source in this order:
11
+
12
+ 1. **Extracted docstring** — JSDoc `/** */`, Python `"""`, `///`, `@doc`, Haddock, etc. No AI cost.
13
+ 2. **Framework-derived** — for recognized patterns: `"Vue component UserCard"`, `"GET /api/users Nuxt server route"`. No AI cost.
14
+ 3. **AI-generated** (optional) — requires config. Batched API call to the configured provider.
15
+ 4. **Signature fallback** — if AI is disabled or fails: reformatted one-liner from the symbol signature. No AI cost.
16
+
17
+ The result is that well-documented codebases spend almost nothing on AI summarization.
18
+
19
+ ---
20
+
21
+ ## Enabling AI summarization
22
+
23
+ AI summarization is **always disabled by default** and requires two explicit opt-ins:
24
+
25
+ ```json
26
+ {
27
+ "ai": {
28
+ "provider": "anthropic",
29
+ "allowRemoteAI": true,
30
+ "apiKey": "${ANTHROPIC_API_KEY}",
31
+ "model": "claude-haiku-4-5-20251001",
32
+ "batchSize": 50
33
+ }
34
+ }
35
+ ```
36
+
37
+ `allowRemoteAI: true` is a safety gate — without it, no outbound AI API calls are made even if `provider` is set. This prevents accidental API costs during development.
38
+
39
+ ---
40
+
41
+ ## Supported providers
42
+
43
+ | Provider | `ai.provider` value | Recommended model | Notes |
44
+ |----------|---------------------|-------------------|-------|
45
+ | Anthropic | `"anthropic"` | `claude-haiku-4-5-20251001` | Best quality, fast |
46
+ | OpenAI | `"openai"` | `gpt-4o-mini` | Good quality, cost-effective |
47
+ | Google Gemini | `"google"` | `gemini-flash` | Lowest cost per token |
48
+ | OpenAI-compatible | `"openai-compatible"` | any | Ollama, LM Studio, etc. |
49
+ | Disabled | `"none"` | — | Default — no AI calls |
50
+
51
+ ### Using a local Ollama model
52
+
53
+ ```json
54
+ {
55
+ "ai": {
56
+ "provider": "openai-compatible",
57
+ "allowRemoteAI": true,
58
+ "endpoint": "http://localhost:11434",
59
+ "model": "llama3.2",
60
+ "batchSize": 10
61
+ }
62
+ }
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Batch mode
68
+
69
+ Symbols are summarized in batches to minimize API round trips. `ai.batchSize` controls how many symbols are sent per request (default: 50).
70
+
71
+ The batch prompt includes all symbol signatures and asks for one-line summaries for each. Responses are parsed and cached in SQLite — no re-generation on repeated `index_folder` calls for unchanged files.
72
+
73
+ **Cost estimate:** A 1,000-symbol project with no docstrings, using Claude Haiku at ~50 symbols/batch:
74
+ - 20 API calls
75
+ - ~10,000 input tokens + ~2,000 output tokens per call
76
+ - Total: ~$0.01–0.05 depending on provider
77
+
78
+ ---
79
+
80
+ ## Google Gemini Flash
81
+
82
+ Google Gemini Flash offers the lowest cost per token for summarization. Enable it with:
83
+
84
+ ```json
85
+ {
86
+ "ai": {
87
+ "provider": "google",
88
+ "allowRemoteAI": true,
89
+ "apiKey": "${GEMINI_API_KEY}",
90
+ "model": "gemini-flash",
91
+ "batchSize": 100
92
+ }
93
+ }
94
+ ```
95
+
96
+ Gemini Flash supports larger batches than Claude or GPT-4o-mini, reducing the number of API calls.
97
+
98
+ ---
99
+
100
+ ## Cost management tips
101
+
102
+ - **Use the cheapest model** — summaries are short, quality difference between Haiku/Flash/mini and Opus/GPT-4o is negligible.
103
+ - **Only undocumented symbols trigger AI** — a codebase with JSDoc on every function costs almost nothing.
104
+ - **Summaries are cached** — re-indexing unchanged files does not re-summarize.
105
+ - **Set `allowRemoteAI: false` during development** (the default) to avoid accidental charges.
106
+ - **Lower `batchSize` for local models** — local models can handle fewer tokens per call.
@@ -0,0 +1,110 @@
1
+ # Token Savings Tracker
2
+
3
+
4
+ Every retrieval tool call automatically tracks how many tokens were saved compared to reading full files. The tracker is always on — no configuration required.
5
+
6
+ ---
7
+
8
+ ## How savings are calculated
9
+
10
+ ```
11
+ tokens_saved = max(0, (rawFileBytes - responseBytes) / 4)
12
+ ```
13
+
14
+ - `rawFileBytes` — size of the full file(s) that would have been read
15
+ - `responseBytes` — size of the actual response (symbol source or summary)
16
+ - `4 bytes/token` — approximation using the cl100k_base encoding
17
+
18
+ This is a **conservative estimate** — the actual savings are often higher because agents typically need to read multiple files to locate a symbol, while PureContext returns it directly.
19
+
20
+ ---
21
+
22
+ ## Viewing savings
23
+
24
+ ### In every response
25
+
26
+ Savings are included in the `_meta` field of every retrieval tool response:
27
+
28
+ ```json
29
+ {
30
+ "symbol": { "name": "authenticateUser", ... },
31
+ "source": "...",
32
+ "_meta": {
33
+ "timing_ms": 3,
34
+ "tokens_saved": 1842,
35
+ "total_tokens_saved": 45231,
36
+ "cost_avoided": {
37
+ "claude_opus_4": 0.028,
38
+ "claude_sonnet_4": 0.006
39
+ },
40
+ "powered_by": "PureContext MCP"
41
+ }
42
+ }
43
+ ```
44
+
45
+ ### Cumulative stats
46
+
47
+ Use the `get_savings_stats` tool to view totals across the session:
48
+
49
+ ```json
50
+ {}
51
+ ```
52
+
53
+ **Response:**
54
+
55
+ ```json
56
+ {
57
+ "total_tokens_saved": 1234567,
58
+ "equivalent_context_windows": {
59
+ "claude_200k": 6.17,
60
+ "gpt4_128k": 9.64
61
+ },
62
+ "total_cost_avoided": {
63
+ "claude_opus_4": 18.52,
64
+ "claude_sonnet_4": 3.70,
65
+ "claude_haiku_4": 0.99,
66
+ "gpt4o": 3.09,
67
+ "gpt4o_mini": 0.19
68
+ }
69
+ }
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Interpreting results
75
+
76
+ | Savings % | What it means |
77
+ |-----------|--------------|
78
+ | 90–98% | Typical for well-structured codebases — agents retrieving individual symbols |
79
+ | 70–89% | Normal — some larger functions or files being retrieved whole |
80
+ | < 70% | Check agent tool usage — agents may be calling `get_file_content` for full files, or using `get_repo_outline` frequently |
81
+
82
+ **`equivalent_context_windows`** shows how many full context windows worth of tokens were saved — useful for communicating the value to stakeholders.
83
+
84
+ **`total_cost_avoided`** is the dollar equivalent at published API rates for each model. This is an estimate at the time of the release — actual rates may differ.
85
+
86
+ ---
87
+
88
+ ## Persistence
89
+
90
+ Savings persist to `~/.purecontext/_savings.json` across sessions. They accumulate indefinitely.
91
+
92
+ To reset the counter:
93
+
94
+ ```json
95
+ {
96
+ "reset": true
97
+ }
98
+ ```
99
+
100
+ ---
101
+
102
+ ## What does and does not count
103
+
104
+ | Counts toward savings | Does not count |
105
+ |----------------------|---------------|
106
+ | `get_symbol_source` — returns partial file | `list_repos` — no file content |
107
+ | `get_file_outline` — returns symbols, not file | `search_symbols` — no file content |
108
+ | `get_context_bundle` — returns selected symbols | `get_file_tree` — no file content |
109
+ | `get_blast_radius` — returns file list | `index_folder` — write operation |
110
+ | `get_file_content` with line range | `get_file_content` without range (full file) |
@@ -0,0 +1,167 @@
1
+ # Transport Modes
2
+
3
+
4
+ PureContext supports two transport modes: **stdio** (local, default) and **HTTP/SSE** (team/cloud).
5
+
6
+ ## stdio transport (default)
7
+
8
+ The standard transport for Claude Code and other MCP-native clients.
9
+
10
+ ```bash
11
+ purecontext-mcp
12
+ ```
13
+
14
+ Claude Code spawns `purecontext-mcp` as a child process and communicates over stdin/stdout using the JSON-RPC MCP protocol. No network, no authentication required.
15
+
16
+ **Claude Code setup:**
17
+
18
+ ```bash
19
+ # Using npx (recommended)
20
+ claude mcp add purecontext-mcp -- npx purecontext-mcp
21
+
22
+ # Using global install
23
+ claude mcp add purecontext-mcp purecontext-mcp
24
+ ```
25
+
26
+ **Best for:** Individual developers, local development, any situation where security and simplicity matter more than sharing.
27
+
28
+ ## HTTP / SSE transport
29
+
30
+ For browser-based clients, remote development, or multi-client setups.
31
+
32
+ ```bash
33
+ purecontext-mcp --transport http --port 3000
34
+ ```
35
+
36
+ Or via `config.json`:
37
+
38
+ ```json
39
+ {
40
+ "transport": "http",
41
+ "http": {
42
+ "port": 3000,
43
+ "host": "127.0.0.1",
44
+ "corsOrigins": ["http://localhost:*"]
45
+ }
46
+ }
47
+ ```
48
+
49
+ **HTTP endpoints:**
50
+
51
+ | Endpoint | Description |
52
+ |----------|-------------|
53
+ | `GET /health` | Server health check (always public) |
54
+ | `POST /mcp/sse` | MCP Streamable HTTP endpoint |
55
+ | `GET /` | Web UI (served when UI is built) |
56
+ | `GET /admin/*` | Admin API (requires admin key) |
57
+
58
+ **Connect Claude Code to an HTTP server:**
59
+
60
+ ```json
61
+ // ~/.claude/claude_desktop_config.json
62
+ {
63
+ "mcpServers": {
64
+ "purecontext": {
65
+ "transport": "http",
66
+ "url": "http://localhost:3000/mcp/sse"
67
+ }
68
+ }
69
+ }
70
+ ```
71
+
72
+ Or via CLI:
73
+
74
+ ```bash
75
+ claude mcp add purecontext-remote \
76
+ --transport http \
77
+ --url https://purecontext.mycompany.com/mcp/sse \
78
+ --header "Authorization: Bearer pctx_yourkey"
79
+ ```
80
+
81
+ **Best for:** Team deployments, shared index, CI pipelines, Web UI access.
82
+
83
+ ## Both transports simultaneously (development)
84
+
85
+ Run stdio and HTTP at the same time — useful during development to test the HTTP API while still using Claude Code via stdio:
86
+
87
+ ```bash
88
+ purecontext-mcp --transport both
89
+ ```
90
+
91
+ ## Choosing a transport
92
+
93
+ | Scenario | Recommended transport |
94
+ |----------|-----------------------|
95
+ | Solo developer, local project | `stdio` |
96
+ | Team with shared codebase | `http` (server) |
97
+ | CI pipeline | `http` or `stdio` with cached index |
98
+ | Web UI access | `http` |
99
+ | Testing both simultaneously | `both` |
100
+
101
+ ## Authentication in HTTP mode
102
+
103
+ When binding to a non-loopback address, always enable authentication:
104
+
105
+ ```json
106
+ {
107
+ "http": {
108
+ "host": "0.0.0.0",
109
+ "auth": {
110
+ "enabled": true,
111
+ "token": "${PURECONTEXT_API_TOKEN}"
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ If `token` is empty and `enabled` is `true`, a random 32-byte hex token is generated at startup and printed to stderr. Save it immediately — it is not persisted to disk.
118
+
119
+ All MCP requests must include:
120
+
121
+ ```
122
+ Authorization: Bearer <token>
123
+ ```
124
+
125
+ A warning is logged at startup if the server is bound to a non-loopback address with authentication disabled.
126
+
127
+ ## TLS / HTTPS
128
+
129
+ PureContext does not terminate TLS itself. Put it behind a reverse proxy for HTTPS in production.
130
+
131
+ **nginx example:**
132
+
133
+ ```nginx
134
+ server {
135
+ listen 443 ssl;
136
+ server_name purecontext.mycompany.com;
137
+
138
+ ssl_certificate /etc/letsencrypt/live/purecontext.mycompany.com/fullchain.pem;
139
+ ssl_certificate_key /etc/letsencrypt/live/purecontext.mycompany.com/privkey.pem;
140
+
141
+ location / {
142
+ proxy_pass http://localhost:3000;
143
+ proxy_http_version 1.1;
144
+ proxy_set_header Upgrade $http_upgrade;
145
+ proxy_set_header Connection keep-alive;
146
+ proxy_set_header Host $host;
147
+ # Disable buffering for SSE
148
+ proxy_buffering off;
149
+ proxy_cache off;
150
+ proxy_read_timeout 3600s;
151
+ }
152
+ }
153
+ ```
154
+
155
+ **Caddy example:**
156
+
157
+ ```
158
+ purecontext.mycompany.com {
159
+ reverse_proxy localhost:3000 {
160
+ flush_interval -1
161
+ }
162
+ }
163
+ ```
164
+
165
+ ## SSE keepalive
166
+
167
+ The HTTP server sends a `: ping` comment over the SSE stream every 30 seconds to keep connections alive through proxies and load balancers. If your proxy has a shorter idle timeout than 30 seconds, increase it (e.g., `proxy_read_timeout 3600s` in nginx).