purecontext-mcp 1.5.0 → 1.5.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.
- package/BENCHMARKS.md +153 -0
- package/FULL-INSTALLATION-GUIDE.md +341 -0
- package/README.md +73 -15
- package/USER-GUIDE.md +21 -21
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/02-installation.md +43 -317
- package/docs/07-language-support.md +73 -50
- package/docs/08-framework-adapters.md +7 -2
- package/docs/15-team-setup.md +70 -200
- package/docs/17-web-ui.md +73 -93
- package/docs/README.md +60 -39
- package/package.json +3 -3
- package/user-manual.md +0 -2466
|
@@ -1,26 +1,31 @@
|
|
|
1
|
-
# Language Support
|
|
1
|
+
# Language Support — Reference
|
|
2
2
|
|
|
3
|
+
This is the reference page: the per-language symbol-kind table and grammar notes.
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
For the **user-friendly tour** — category groupings, framework integration notes, "Adding a new language" guide — see [`LANGUAGE-SUPPORT.md`](../LANGUAGE-SUPPORT.md) at the project root.
|
|
5
6
|
|
|
6
7
|
---
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
PureContext supports **34 languages** via tree-sitter WASM grammars plus four regex-based handlers for CSS-family languages. All grammars are bundled in `grammars/` — no separate install needed.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Symbol-kind matrix (tree-sitter handlers)
|
|
14
|
+
|
|
15
|
+
| Language | Extensions | Symbol Kinds | Doc Comments |
|
|
11
16
|
|----------|-----------|--------------|--------------|
|
|
12
17
|
| TypeScript | `.ts`, `.tsx`, `.mts`, `.cts` | function, class, method, const, type, interface, enum | JSDoc `/** */` |
|
|
13
18
|
| JavaScript | `.js`, `.jsx`, `.mjs`, `.cjs` | function, class, method, const | JSDoc `/** */` |
|
|
14
|
-
| Python | `.py` | function, class, method, const |
|
|
19
|
+
| Python | `.py` | function, class, method, const | `"""` docstrings |
|
|
15
20
|
| Go | `.go` | function, method, class (struct), interface, const, type | `//` preceding comments |
|
|
16
21
|
| Rust | `.rs` | function, method, class (struct), enum, interface (trait), const, type | `///` doc comments |
|
|
17
22
|
| Java | `.java` | class, interface, enum, method, const | Javadoc `/** */` |
|
|
18
23
|
| C# | `.cs` | class, interface, enum, struct, record, method, const, property | XML docs `/// <summary>` |
|
|
19
|
-
| PHP | `.php` | function, class, interface, trait, enum, method, const | PHPDoc `/** */` |
|
|
20
|
-
| Ruby | `.rb` | function, class, method, module, const | `#` comments |
|
|
21
|
-
| Kotlin | `.kt`, `.kts` | function, class, interface, enum, method, typealias, object | KDoc `/**` |
|
|
24
|
+
| PHP | `.php` | function, class, interface, trait, enum, method, const, property | PHPDoc `/** */` |
|
|
25
|
+
| Ruby | `.rb` | function, class, method, module, const, property (DSL macros) | `#` comments |
|
|
26
|
+
| Kotlin | `.kt`, `.kts` | function, class, interface, enum, method, typealias, object, property | KDoc `/**` |
|
|
22
27
|
| C | `.c`, `.h` | function, struct, enum, macro, type | `//` and `/* */` |
|
|
23
|
-
| C++ | `.cpp`, `.cxx`, `.cc`, `.hpp`, `.hxx`, `.hh` | All C
|
|
28
|
+
| C++ | `.cpp`, `.cxx`, `.cc`, `.hpp`, `.hxx`, `.hh` | All C kinds + namespace, template, template-class | `///` Doxygen |
|
|
24
29
|
| Lua | `.lua` | function, method, const | `--` comments |
|
|
25
30
|
| Dart | `.dart` | class, mixin, extension, enum, function, method, const, type | `///` doc comments |
|
|
26
31
|
| Swift | `.swift` | class, struct, protocol, actor, extension, method, enum, type | `///` DocC |
|
|
@@ -28,61 +33,79 @@ PureContext supports **34 languages** via tree-sitter WASM grammars. All grammar
|
|
|
28
33
|
| Haskell | `.hs`, `.lhs` | function, data (class), typeclass (interface), instance, type, newtype | Haddock `-- \|` |
|
|
29
34
|
| Scala | `.scala`, `.sc` | class, trait, object, case class, function, method, type, enum | Scaladoc `/** */` |
|
|
30
35
|
| R | `.r`, `.R`, `.Rmd` | function, const, S3/S4/R6 class | Roxygen2 `#'` |
|
|
31
|
-
| Bash | `.sh`, `.bash
|
|
32
|
-
| Perl | `.pl`, `.pm` | function, package |
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
36
|
+
| Bash | `.sh`, `.bash`, extensionless (shebang-detected) | function | — |
|
|
37
|
+
| Perl | `.pl`, `.pm` | function, package | — |
|
|
38
|
+
| Groovy | `.groovy` | function, class, method | — |
|
|
39
|
+
| Erlang | `.erl`, `.hrl` | function (bare name; arity in `frameworkMeta`), module | — |
|
|
40
|
+
| Gleam | `.gleam` | function, type | — |
|
|
41
|
+
| GDScript | `.gd` | function, class, signal | — |
|
|
42
|
+
| Objective-C | `.m`, `.h` (guarded) | function, class, protocol, method (full selector), property, category | — |
|
|
43
|
+
| Fortran | `.f90`, `.f95`, `.for`, `.f`, `.F90` (case-insensitive) | function, subroutine, module | — |
|
|
44
|
+
| Terraform / HCL | `.tf`, `.tfvars`, `.hcl` | variable, output, resource, data, module, provider, locals | — |
|
|
45
|
+
| Nix | `.nix` | function, attribute | — |
|
|
46
|
+
| SQL | `.sql` | table, view, function, procedure | — |
|
|
47
|
+
| Protobuf | `.proto` | message, service, enum, rpc | — |
|
|
48
|
+
| GraphQL | `.graphql`, `.gql` | type, query, mutation, subscription, fragment | — |
|
|
49
|
+
| OpenAPI / YAML | `.yaml`, `.yml` (content-detected) | endpoint, schema | — |
|
|
50
|
+
| XML | `.xml` | element (disambiguated as `tag@module` in multi-module repos) | — |
|
|
51
|
+
| Angular HTML | `.html` (guarded) | component selector, structural directive, control flow, event binding, template ref | — |
|
|
46
52
|
|
|
47
53
|
---
|
|
48
54
|
|
|
49
|
-
##
|
|
55
|
+
## Symbol-kind matrix (regex handlers, no WASM grammar)
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
| Language | Extensions | Symbol Kinds |
|
|
58
|
+
|----------|-----------|--------------|
|
|
59
|
+
| SCSS / SASS | `.scss`, `.sass` | `@mixin` → function, `@function` → function, top-level `$var` → const, `%placeholder` → class, `@keyframes` → type |
|
|
60
|
+
| LESS | `.less` | `.mixin(@params)` → function, top-level `@var` → const, `@keyframes` → type |
|
|
61
|
+
| CSS | `.css` | `--custom-property` → const (opt-in via `indexing.cssVariables: true`) |
|
|
52
62
|
|
|
53
|
-
-
|
|
54
|
-
- **Symbol kind** — function, class, method, route, component, etc.
|
|
55
|
-
- **Byte offsets** (`startByte`, `endByte`) — for precise source retrieval without reading the whole file
|
|
56
|
-
- **Signature** — a one-line declaration (TypeScript shows full type annotations, Python shows type hints if present)
|
|
57
|
-
- **Summary** — sourced from docstring, framework inference, AI, or signature fallback
|
|
58
|
-
- **Import/dependency edges** — for the dependency graph
|
|
63
|
+
CSS-family languages don't have a stable tree-sitter grammar, so PureContext uses targeted regex extraction. Only named, reusable constructs are indexed — plain selectors would flood the index with noise.
|
|
59
64
|
|
|
60
65
|
---
|
|
61
66
|
|
|
62
|
-
##
|
|
67
|
+
## Visibility filtering
|
|
63
68
|
|
|
64
|
-
|
|
69
|
+
| Language | What is excluded |
|
|
70
|
+
|----------|------------------|
|
|
71
|
+
| Go | Unexported identifiers (lowercase first letter) |
|
|
72
|
+
| C | `static` functions (translation-unit internal) |
|
|
73
|
+
| Java | `private` members |
|
|
74
|
+
| C# | `private` members; interface members are implicitly public |
|
|
75
|
+
| PHP | `private` members |
|
|
76
|
+
| Dart | `_`-prefixed identifiers |
|
|
77
|
+
| Rust | Non-`pub` impl methods |
|
|
65
78
|
|
|
66
|
-
|
|
67
|
-
- `*.lock` files, `.env*` files
|
|
68
|
-
- Binary files (detected by null-byte scanning of the first 8 KB)
|
|
69
|
-
- Files > 1 MB (configurable via `maxFileSizeBytes`)
|
|
70
|
-
- Secret files: `*.pem`, `*.key`, `id_rsa`, `credentials.json`, `serviceAccountKey*.json`, etc.
|
|
71
|
-
- Language-specific private symbols:
|
|
72
|
-
- Go: unexported names (lowercase)
|
|
73
|
-
- C: `static` functions (translation-unit internal)
|
|
74
|
-
- Java/C#/PHP: `private` members
|
|
75
|
-
- Dart: `_`-prefixed names
|
|
79
|
+
`get_public_api` and related tools depend on these rules being applied consistently.
|
|
76
80
|
|
|
77
81
|
---
|
|
78
82
|
|
|
79
|
-
##
|
|
83
|
+
## File-system exclusions
|
|
84
|
+
|
|
85
|
+
Applied before any handler runs:
|
|
86
|
+
|
|
87
|
+
- Directories: `node_modules/`, `.git/`, `dist/`, `build/`, `target/`, `.next/`, `.nuxt/`, `.claude/`
|
|
88
|
+
- Lock files (`*.lock`), env files (`.env*`)
|
|
89
|
+
- Binary files (null-byte scan of first 8 KB; no hardcoded extension list)
|
|
90
|
+
- Files larger than 1 MB (override via `indexing.maxFileSizeBytes`)
|
|
91
|
+
- Secret patterns: `*.pem`, `*.key`, `id_rsa`, `credentials.json`, `serviceAccountKey*.json`
|
|
80
92
|
|
|
81
|
-
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Grammar notes and known limitations
|
|
82
96
|
|
|
83
|
-
|
|
84
|
-
- **
|
|
85
|
-
- **
|
|
97
|
+
- **TypeScript JSX** (`.tsx`) uses `tree-sitter-tsx`, a separate grammar from `tree-sitter-typescript`. Both are bundled.
|
|
98
|
+
- **Python stubs** (`.pyi`) are not indexed — only `.py` files.
|
|
99
|
+
- **Objective-C** `.h` files are guarded: parsed as ObjC only if the first 16 KB contain `@interface` or `@protocol`; otherwise treated as C.
|
|
100
|
+
- **Angular HTML** `.html` files are guarded: parsed as Angular templates only if a sibling `.component.ts` exists or the first 4 KB contain Angular markers.
|
|
86
101
|
- **Terraform**: complex `dynamic` blocks may not be fully extracted.
|
|
87
|
-
- **XML**: element extraction uses configurable patterns
|
|
102
|
+
- **XML**: element extraction uses configurable patterns; not every tag is indexed by default. Root-element symbols are stored as `tag@module` in multi-module repos to avoid collisions.
|
|
103
|
+
- **OpenAPI**: schema-name extraction supports hyphens (`[\w-]+`), so GitHub-style schemas like `pull-request` are indexed.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Related reference
|
|
88
108
|
|
|
109
|
+
- [Framework Adapters](08-framework-adapters.md) — adapter layer that adds framework-specific symbols on top of these handlers
|
|
110
|
+
- [Configuration](04-configuration.md) — `indexing.*` flags including `cssVariables`, `maxFileSizeBytes`, `xmlElementPatterns`
|
|
111
|
+
- [Architecture Overview](25-architecture-overview.md) — three-layer design (Core → Handlers → Adapters)
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
# Framework Adapters
|
|
1
|
+
# Framework Adapters — Reference
|
|
2
2
|
|
|
3
|
+
This is the reference page: detection criteria, extracted symbol kinds, and `frameworkMeta` shape for every adapter.
|
|
4
|
+
|
|
5
|
+
For the **user-friendly tour** — how adapters change what you see in search results, with examples and "useful for" notes — see [`FRAMEWORK-ADAPTERS.md`](../FRAMEWORK-ADAPTERS.md) at the project root.
|
|
6
|
+
|
|
7
|
+
---
|
|
3
8
|
|
|
4
9
|
Framework adapters layer domain-specific symbol extraction on top of language handlers. They are auto-detected from project config files.
|
|
5
10
|
|
|
6
|
-
##
|
|
11
|
+
## The `FrameworkAdapter` interface
|
|
7
12
|
|
|
8
13
|
Each adapter implements the `FrameworkAdapter` interface:
|
|
9
14
|
|
package/docs/15-team-setup.md
CHANGED
|
@@ -1,209 +1,56 @@
|
|
|
1
|
-
# Team Setup & Multi-Tenant
|
|
1
|
+
# Team Setup & Multi-Tenant — Reference
|
|
2
2
|
|
|
3
|
+
This is the reference page: API key permissions, rate-limit configuration, admin API endpoints, and the production hardening checklist.
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
For the **user-friendly walkthrough** — why a shared server matters, deployment options, end-to-end setup with examples — see [`TEAM-SETUP.md`](../TEAM-SETUP.md) at the project root.
|
|
5
6
|
|
|
6
7
|
---
|
|
7
8
|
|
|
8
|
-
##
|
|
9
|
+
## Workspace and key model
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
↓ ↓
|
|
16
|
-
Local SQLite index Shared SQLite index(es)
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
**Why a shared server?** Each developer re-indexes the same codebase independently in local mode. A shared server indexes once and serves all team members — consistent results and no redundant work.
|
|
11
|
+
| Concept | Description |
|
|
12
|
+
|---------|-------------|
|
|
13
|
+
| Workspace | The unit of isolation. One team = one workspace. All repos and keys belong to a workspace. |
|
|
14
|
+
| API key | A per-developer credential. Shown once on creation and never displayed again. Stored as a SHA-256 hash. |
|
|
15
|
+
| Admin key | A long-lived secret (`PCTX_ADMIN_KEY`) that authenticates workspace and key management calls. Set via env var only. |
|
|
20
16
|
|
|
21
17
|
---
|
|
22
18
|
|
|
23
|
-
##
|
|
24
|
-
|
|
25
|
-
### Docker (recommended)
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
mkdir -p ./purecontext-data
|
|
29
|
-
|
|
30
|
-
docker run -d \
|
|
31
|
-
--name purecontext \
|
|
32
|
-
-p 3000:3000 \
|
|
33
|
-
-v "$(pwd)/purecontext-data:/data" \
|
|
34
|
-
-e PCTX_ADMIN_KEY="$(openssl rand -hex 32)" \
|
|
35
|
-
--restart unless-stopped \
|
|
36
|
-
purecontext/purecontext-mcp:latest
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Note your `PCTX_ADMIN_KEY` — you need it to manage workspaces and keys.
|
|
40
|
-
|
|
41
|
-
### Docker Compose
|
|
42
|
-
|
|
43
|
-
```yaml
|
|
44
|
-
version: '3.8'
|
|
45
|
-
services:
|
|
46
|
-
purecontext:
|
|
47
|
-
image: purecontext/purecontext-mcp:latest
|
|
48
|
-
ports:
|
|
49
|
-
- "3000:3000"
|
|
50
|
-
volumes:
|
|
51
|
-
- ./data:/data
|
|
52
|
-
environment:
|
|
53
|
-
PCTX_ADMIN_KEY: "change-me-before-deploying"
|
|
54
|
-
restart: unless-stopped
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
docker compose up -d
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### npm (no Docker)
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
npm install -g purecontext-mcp
|
|
65
|
-
PCTX_ADMIN_KEY=your-secret purecontext-mcp --server --host 0.0.0.0 --port 3000
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Verify the server is running
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
curl http://localhost:3000/health
|
|
72
|
-
# {"status":"ok","version":"1.x.x","repoCount":0}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## Step 2 — Create a workspace
|
|
78
|
-
|
|
79
|
-
A workspace is the unit of isolation — one team = one workspace. All repos and API keys belong to a workspace.
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
export ADMIN_KEY="your-pctx-admin-key"
|
|
83
|
-
export SERVER="http://localhost:3000"
|
|
84
|
-
|
|
85
|
-
curl -s -X POST "$SERVER/admin/workspaces" \
|
|
86
|
-
-H "Authorization: Bearer $ADMIN_KEY" \
|
|
87
|
-
-H "Content-Type: application/json" \
|
|
88
|
-
-d '{"name": "my-team", "plan": "team"}' | jq .
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Response:
|
|
92
|
-
|
|
93
|
-
```json
|
|
94
|
-
{"id": "ws_abc123", "name": "my-team", "plan": "team", "created_at": 1714000000}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Save the `id` — you'll use it when creating API keys.
|
|
98
|
-
|
|
99
|
-
---
|
|
100
|
-
|
|
101
|
-
## Step 3 — Create API keys
|
|
102
|
-
|
|
103
|
-
Each developer gets their own API key. Keys are shown once on creation and never again.
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
curl -s -X POST "$SERVER/admin/keys" \
|
|
107
|
-
-H "Authorization: Bearer $ADMIN_KEY" \
|
|
108
|
-
-H "Content-Type: application/json" \
|
|
109
|
-
-d '{
|
|
110
|
-
"label": "alice-macbook",
|
|
111
|
-
"permissions": ["read", "write"],
|
|
112
|
-
"workspace_id": "ws_abc123"
|
|
113
|
-
}' | jq .
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**Response (key shown only once):**
|
|
117
|
-
|
|
118
|
-
```json
|
|
119
|
-
{
|
|
120
|
-
"key": "pctx_00000000_..._1234",
|
|
121
|
-
"label": "alice-macbook",
|
|
122
|
-
"permissions": ["read", "write"],
|
|
123
|
-
"key_hash_prefix": "deadbeef"
|
|
124
|
-
}
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Permission levels
|
|
19
|
+
## Permission levels
|
|
128
20
|
|
|
129
21
|
| Permission | Allowed operations |
|
|
130
|
-
|
|
131
|
-
| `read` | Search symbols, get outlines,
|
|
132
|
-
| `write` | + `index_folder`, `index_repo` |
|
|
22
|
+
|------------|--------------------|
|
|
23
|
+
| `read` | Search symbols, get outlines, fetch source |
|
|
24
|
+
| `write` | + `index_folder`, `index_repo`, `invalidate_cache` |
|
|
133
25
|
| `admin` | + Manage keys and workspaces |
|
|
134
26
|
|
|
135
|
-
For AI agents that only query
|
|
27
|
+
For AI agents that only query, use `read`. For CI pipelines that re-index on push, use `write`. Never issue `admin` to a developer or agent — keep it on the admin key alone.
|
|
136
28
|
|
|
137
29
|
---
|
|
138
30
|
|
|
139
|
-
##
|
|
140
|
-
|
|
141
|
-
Connect Claude Code (step 5) and ask it to index, or call the API directly:
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
curl -s -X POST "$SERVER/mcp/sse" \
|
|
145
|
-
-H "Authorization: Bearer pctx_yourwritekey" \
|
|
146
|
-
-H "Content-Type: application/json" \
|
|
147
|
-
-d '{
|
|
148
|
-
"jsonrpc": "2.0",
|
|
149
|
-
"method": "tools/call",
|
|
150
|
-
"params": {"name": "index_folder", "arguments": {"path": "/path/to/repo"}},
|
|
151
|
-
"id": 1
|
|
152
|
-
}'
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
## Step 5 — Connect each developer
|
|
158
|
-
|
|
159
|
-
Each developer runs this once:
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
claude mcp add purecontext-remote \
|
|
163
|
-
--transport http \
|
|
164
|
-
--url https://purecontext.mycompany.com/mcp/sse \
|
|
165
|
-
--header "Authorization: Bearer pctx_yourpersonalkey"
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
After adding, verify in Claude Code:
|
|
169
|
-
|
|
170
|
-
```
|
|
171
|
-
/mcp
|
|
172
|
-
# Should show purecontext-remote as connected
|
|
173
|
-
|
|
174
|
-
List my indexed repositories using list_repos
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
## Step 6 — Manage keys over time
|
|
180
|
-
|
|
181
|
-
```bash
|
|
182
|
-
# List all keys (shows label, prefix, permissions — never the raw key)
|
|
183
|
-
curl -s "$SERVER/admin/keys" -H "Authorization: Bearer $ADMIN_KEY" | jq .
|
|
184
|
-
|
|
185
|
-
# Revoke a key (e.g., when someone leaves the team)
|
|
186
|
-
curl -s -X DELETE "$SERVER/admin/keys/deadbeef" \
|
|
187
|
-
-H "Authorization: Bearer $ADMIN_KEY"
|
|
188
|
-
|
|
189
|
-
# Check key usage stats
|
|
190
|
-
curl -s "$SERVER/admin/keys/deadbeef/usage" \
|
|
191
|
-
-H "Authorization: Bearer $ADMIN_KEY" | jq .
|
|
192
|
-
```
|
|
31
|
+
## Rate limiting
|
|
193
32
|
|
|
194
|
-
|
|
33
|
+
HTTP mode uses a token-bucket per API key.
|
|
195
34
|
|
|
196
|
-
|
|
35
|
+
| Field | Default | Description |
|
|
36
|
+
|-------|--------:|-------------|
|
|
37
|
+
| `rateLimit.enabled` | `true` | Disable to allow unbounded usage (single-tenant only) |
|
|
38
|
+
| `rateLimit.maxTokens` | `100` | Bucket capacity per key |
|
|
39
|
+
| `rateLimit.refillRate` | `10` | Tokens added per second |
|
|
40
|
+
| `rateLimit.perToolLimits.<tool>` | varies | Per-tool cost override |
|
|
197
41
|
|
|
198
|
-
|
|
42
|
+
Default per-tool costs:
|
|
199
43
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
44
|
+
| Tool | Cost |
|
|
45
|
+
|------|-----:|
|
|
46
|
+
| `search_symbols`, `search_text`, `search_semantic` | 1 |
|
|
47
|
+
| `get_symbol_source`, `get_file_outline`, `get_context_bundle` | 1 |
|
|
48
|
+
| `index_folder`, `index_repo` | 10 |
|
|
49
|
+
| `health_radar`, `get_debt_report`, `detect_antipatterns` | 5 |
|
|
203
50
|
|
|
204
|
-
When
|
|
51
|
+
When a bucket empties, the server returns `429 Too Many Requests` with a `Retry-After` header.
|
|
205
52
|
|
|
206
|
-
|
|
53
|
+
Example config:
|
|
207
54
|
|
|
208
55
|
```json
|
|
209
56
|
{
|
|
@@ -223,29 +70,52 @@ Configure per-tool costs in `config.json`:
|
|
|
223
70
|
|
|
224
71
|
## Admin API reference
|
|
225
72
|
|
|
226
|
-
All endpoints require `Authorization: Bearer <PCTX_ADMIN_KEY>`.
|
|
73
|
+
All endpoints require `Authorization: Bearer <PCTX_ADMIN_KEY>`. Base URL: the server's bind address (default `http://localhost:3000`).
|
|
227
74
|
|
|
228
75
|
| Endpoint | Method | Description |
|
|
229
76
|
|----------|--------|-------------|
|
|
230
|
-
| `/admin/workspaces` | `POST` | Create workspace |
|
|
231
|
-
| `/admin/workspaces` | `GET` | List workspaces |
|
|
232
|
-
| `/admin/workspaces/:id` | `DELETE` | Delete workspace and all data |
|
|
233
|
-
| `/admin/keys` | `POST` | Create API key |
|
|
234
|
-
| `/admin/keys` | `GET` | List keys |
|
|
235
|
-
| `/admin/keys/:prefix` | `DELETE` | Revoke key |
|
|
236
|
-
| `/admin/keys/:prefix/usage` | `GET` |
|
|
237
|
-
| `/admin/stats` | `GET` | Server-wide statistics |
|
|
77
|
+
| `/admin/workspaces` | `POST` | Create workspace. Body: `{name, plan}`. Returns `{id, name, plan, created_at}`. |
|
|
78
|
+
| `/admin/workspaces` | `GET` | List workspaces. |
|
|
79
|
+
| `/admin/workspaces/:id` | `DELETE` | Delete workspace and all data. |
|
|
80
|
+
| `/admin/keys` | `POST` | Create API key. Body: `{label, permissions[], workspace_id}`. **Raw key returned once.** |
|
|
81
|
+
| `/admin/keys` | `GET` | List keys (label + prefix + permissions; never raw key). |
|
|
82
|
+
| `/admin/keys/:prefix` | `DELETE` | Revoke key by hash prefix. |
|
|
83
|
+
| `/admin/keys/:prefix/usage` | `GET` | Per-key usage counters. |
|
|
84
|
+
| `/admin/stats` | `GET` | Server-wide statistics. |
|
|
85
|
+
| `/health` | `GET` | Public health check (no auth). Returns `{status, version, repoCount}`. |
|
|
238
86
|
|
|
239
87
|
---
|
|
240
88
|
|
|
241
|
-
##
|
|
89
|
+
## Server-mode environment variables
|
|
90
|
+
|
|
91
|
+
| Variable | Required | Description |
|
|
92
|
+
|----------|----------|-------------|
|
|
93
|
+
| `PCTX_ADMIN_KEY` | yes | Admin secret. Minimum 32 hex chars recommended. |
|
|
94
|
+
| `PCTX_DATA_DIR` | no | Override default `/data` (Docker) or `~/.purecontext` (npm). |
|
|
95
|
+
| `PCTX_BIND_HOST` | no | Default `0.0.0.0` in server mode. |
|
|
96
|
+
| `PCTX_BIND_PORT` | no | Default `3000`. |
|
|
97
|
+
| `PCTX_LOG_LEVEL` | no | `debug` / `info` / `warn` / `error`. |
|
|
98
|
+
|
|
99
|
+
CLI flags `--server`, `--host`, `--port` take precedence over env vars.
|
|
100
|
+
|
|
101
|
+
---
|
|
242
102
|
|
|
243
|
-
|
|
103
|
+
## Production hardening checklist
|
|
104
|
+
|
|
105
|
+
- [ ] `PCTX_ADMIN_KEY` is a ≥32-char random secret, set via env var only — never in a committed config file
|
|
244
106
|
- [ ] Server is behind a reverse proxy (nginx, Caddy) with TLS
|
|
245
|
-
- [ ] Port 3000 is not directly exposed to the internet (terminate TLS at the proxy)
|
|
246
|
-
- [ ] `/data` volume
|
|
247
|
-
- [ ] `restart: unless-stopped`
|
|
248
|
-
- [ ] Developers have `read` permission only unless they need to re-index
|
|
107
|
+
- [ ] Port 3000 is not directly exposed to the public internet (terminate TLS at the proxy)
|
|
108
|
+
- [ ] `/data` volume sits on a backed-up disk
|
|
109
|
+
- [ ] `restart: unless-stopped` set in docker-compose
|
|
110
|
+
- [ ] Developers have `read` permission only unless they specifically need to re-index
|
|
249
111
|
- [ ] Admin key is rotated if ever exposed
|
|
112
|
+
- [ ] Rate limiting enabled and tuned for your team size
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Related reference
|
|
250
117
|
|
|
251
|
-
|
|
118
|
+
- [Transport Modes](14-transport-modes.md) — stdio vs HTTP/SSE deep dive
|
|
119
|
+
- [Docker Deployment](16-docker.md) — container image, compose examples, reverse-proxy templates
|
|
120
|
+
- [Security](24-security.md) — threat model, API-key storage, path-traversal protections
|
|
121
|
+
- [Configuration](04-configuration.md) — full `config.json` schema
|