Repository navigation
Configuration
Set these before starting the server, or in the systemd service file.
| Variable | Default | Description |
|---|---|---|
KG_ORPHAN_GRACE_DAYS |
see constants.py
|
Days before orphaned archived nodes are permanently deleted |
KG_STORAGE_ROOT |
~/.knowledge-graph |
Root directory for all graph data (centralized storage) |
KG_HTTP_PORT |
8765 |
Server port |
KG_HTTP_HOST |
127.0.0.1 |
Server host binding |
KG_LOG_LEVEL |
INFO |
Logging level (DEBUG, INFO, WARNING, ERROR) |
KG_SAVE_INTERVAL |
30 |
Seconds between background maintenance ticks |
KG_AUTOCOMMIT_INTERVAL |
900 |
Git auto-commit interval for the storage root, in seconds; 0 disables. Acts only when ~/.knowledge-graph is a git repository |
KG_CHORES |
unset |
1 switches maintenance chores on (same as "enabled": true in chores.json); 0 forces them off |
KG_BUDGET_NOTICES |
unset |
0 turns budget notices off (same as "budget_notices": false in chores.json) |
CODEX_HOME |
~/.codex |
Where the Codex runner looks for Codex's session logs (its quota reading). A custom value must be set in the shared server's environment too |
Note: content mutations and promotions trigger immediate saves. The periodic thread also persists read timestamps, maintenance changes and retries after failed saves, as well as compaction, refill and orphan pruning.
Example:
KG_LOG_LEVEL=DEBUG kg restart # with the systemd service, set it in the unit insteadOr set them in your shell profile for persistence:
export KG_AUTOCOMMIT_INTERVAL=3600The graph's size budget is exact rendered characters, not estimated tokens,
and is not configurable: 22,000 per level for compaction, 50,000 for the combined
full-graph render. The estimator measures the rendered strings. These limits
were sized for Claude Code and Codex; arbitrary batches of full-node notes and
other MCP clients do not inherit the same inline guarantee. Preload has a
separate ceiling: 9,500 UTF-16 units in Claude Code, 9,000 bytes in Codex, 10,000 bytes in Antigravity (each client counts in its own unit). A kg_read reply longer than the client
keeps whole (45,000 UTF-16 units in Claude Code, 36,000 bytes in Codex) arrives
in parts: kg_read(session_id, more=true) returns the next. Oversized
full graphs degrade by hiding lowest-scored archived anchors, then
lowest-value edges, with counts and a search pointer.
The 50,000-character figure is a target rather than an absolute cap: active gists are preserved, even if they alone exceed it. The newest nodes (the fresh tier, up to 30% of a level's budget) are never archived, so a level holding unusually long gists can render past the client's inline limit until a maintenance pass tightens them.
-
Storage root (
KG_STORAGE_ROOT) — Override where all graph data is stored. Default is~/.knowledge-graph/. - Orphan grace — How long orphaned nodes are kept before deletion. Longer = more disk usage, shorter = more aggressive cleanup. New nodes are protected by the fresh tier, a share of the budget rather than a number of days (since 0.13.0).
-
Log level — Set to
DEBUGfor troubleshooting,WARNINGfor quiet operation.
| Setting | Value | Why |
|---|---|---|
| Storage layout | <storage-root>/projects/<slug>/graph.json |
Centralized, plain JSON; root is configurable |
| User graph path | <storage-root>/user.json |
Single shared file |
| Sessions path | <storage-root>/sessions.json |
Central session tracking |
| Session TTL | 24 hours | Sessions expire after inactivity |
| Session ID length | 8 hex chars | Short enough for tool args |
| Char budget per level | 22,000 | Compaction threshold — exact rendered characters (see above) |
| Full-graph read target | 50,000 chars | Combined graph render; can overflow when active gists alone exceed it. Full-node batches have a separate size |
| Search output ceiling | 10,000 chars | Hard cap on a kg_search result |
| Compaction target ratio | 0.8 | Archiving compacts down to this fraction of the budget; refill fills back up to the same ceiling |
| Archived budget ratio | 0.30 | Max fraction of the budget that archived anchor lines may occupy before orphaning |
| Archived-edge weight | 0.2 | Connectedness weight of an edge to an archived neighbour (active = 1.0, orphaned = 0) |
| Scoring formula | 0.25×recency + 0.40×connectedness + 0.35×usefulness |
Tie-aware percentile ranks. Connectedness = max(weighted in×0.66 + out×0.33, 0.5×log1p(total neighbours)); archived neighbours weight 0.2. Endorsements decay with a 90-day half-life. |
| Endorsements per session | 5 guidance, 10 hard cap |
kg_useful — endorsement, not traffic; past five the reply says how far over |
| Maintenance credits | 1–3 per node, 15 per pass |
kg_useful(credits=…) in a maintenance session; fades like an endorsement |
| Preload ceiling | 9,500 UTF-16 units (Claude Code), 9,000 bytes (Codex), 10,000 bytes (Antigravity) | Each harness's inline hook limit, in the unit that client counts |
These are defined in server/core/constants.py. You can modify them if you clone/fork the code, but they're not exposed as env vars.
Leave everything at defaults. The system is designed to work well out of the box with small-to-medium graphs.
export KG_ORPHAN_GRACE_DAYS=90 # default 365: orphaned nodes are deleted soonerexport KG_LOG_LEVEL=DEBUG # Verbose loggingChores are configured in ~/.knowledge-graph/chores.json (copy chores/chores.example.json from the plugin). The file is re-read when it changes; no restart needed. Off by default, because chores spend quota.
| Key | Default | Meaning |
|---|---|---|
enabled |
false |
The switch (KG_CHORES=1 does the same) |
runner |
auto |
Which harness runs the agent, and whose quota it spends: auto (Claude Code if installed, else Codex, else Antigravity), claude, codex, antigravity
|
model |
claude-sonnet-5 |
Model for Claude Code runs |
codex_model |
Codex's default | Model for Codex runs |
codex_reasoning_effort |
low (chore), medium (pass) | Effort for Codex runs |
antigravity_model |
the CLI's default | Model for Antigravity runs; its model group picks the quota bucket |
antigravity_effort |
low (chore), medium (pass) | Effort for Antigravity runs |
antigravity_allow_credits |
false |
Allow a run while useG1Credits could spend paid credits |
budget_notices |
true |
Wrap-up notices from the session's own quota gauge |
min_interval_s / graph_cooldown_s / max_per_day
|
2700 / 21600 / 8 | Spacing between chores, per graph, and per day |
debt_floor |
0.12 | A graph below this debt is left alone |
max_5h / max_7d
|
55 / 80 | Quota gates for a chore (percent used) |
gauge_max_age_s |
5400 | A quota reading older than this refuses the run |
timeout_s |
420 | A chore still running after this is killed, with everything it started |
pass_interval_days / pass_max_per_day
|
21 / 1 | When a graph is due a full pass |
pass_max_5h / pass_max_7d / pass_pace_max
|
40 / 70 / 1.0 | Pass gates: a pass also needs the week to be running under its quota pace |
pass_timeout_s |
1500 | Pass time limit |
A configured claude_bin, codex_bin or antigravity_bin pins its runner, even if the path is wrong: that surfaces as "binary missing" instead of silently spending the other subscription.
The plugin's .mcp.json tells the harness (Claude Code or Codex) where the server is:
{
"mcpServers": {
"kg": {
"type": "http",
"url": "http://127.0.0.1:8765/"
}
}
}If you change KG_HTTP_PORT, configure the client endpoint to match using
its local MCP configuration or a development plugin copy. Editing the cached
plugin's bundled file is temporary: plugin updates overwrite it. Also update
the hook endpoint environment and the editor's MCP_SERVER_URL.
The visual editor has its own env vars (separate from the MCP server):
| Variable | Default | Description |
|---|---|---|
EDITOR_PORT |
8766 |
Visual editor web server port |
EDITOR_HOST |
127.0.0.1 |
Host binding |
MCP_SERVER_URL |
http://127.0.0.1:8765 |
Where to find the MCP server |