Skip to content

Configuration

Claude edited this page Oct 9, 2026 · 18 revisions

Configuration

Most people change nothing here. The settings that exist are a few environment variables for the server, and chores.json for background upkeep. The memory budgets are fixed by design.

Where environment variables take effect

What reads a variable is the server process, so where to set it depends on what started the server:

  • systemd service (Linux). When kg setup writes ~/.config/systemd/user/kg-memory.service, it copies PATH, CODEX_HOME and every KG_* variable from its own environment into the unit. Later changes to your shell profile don't reach it, and rerunning setup leaves a working unit as it is. To change a variable, edit the unit's Environment= lines, then run systemctl --user daemon-reload && kg restart.
  • Otherwise. A server started by kg start, kg mcp or a session hook inherits that process's environment. Set the variables in your shell profile, then kg restart.

For example, without the service:

export KG_LOG_LEVEL=DEBUG     # in ~/.bashrc or ~/.zshrc
kg restart

Environment variables

Variable Default Description
KG_STORAGE_ROOT ~/.knowledge-graph Root directory for all graph data. One server per storage root: a second one on the same root refuses to start
KG_HTTP_PORT 8765 Server port. The server, kg, the hooks and kg mcp must all see the same value (see below)
KG_HTTP_HOST 127.0.0.1 Bind address. Keep it local; there is no authentication (SECURITY.md)
KG_SAVE_INTERVAL 30 Seconds between background maintenance ticks
KG_AUTOCOMMIT_INTERVAL 900 Seconds between git auto-commits of the storage root; 0 disables. Acts only when the storage root is a git repository
KG_ORPHAN_GRACE_DAYS 365 Days an orphaned node may go unrecalled before it is permanently deleted
KG_CHORES unset 1 switches background upkeep on, 0 forces it off, overriding "enabled" in chores.json
KG_BUDGET_NOTICES unset (on) 0 turns budget notices off (same as "budget_notices": false in chores.json)
KG_LOG_LEVEL INFO Server log level (DEBUG, INFO, WARNING, ERROR)
CODEX_HOME ~/.codex Where Codex keeps its session logs, which the server reads for Codex quota. A custom value must be in the server's environment too
EDITOR_PORT 8766 Visual editor port, read by kg editor

Content changes and promotions are saved immediately. The background tick (KG_SAVE_INTERVAL) persists read timestamps and session state, retries failed saves, and runs compaction, refill and orphan pruning.

A shorter orphan grace keeps the storage smaller: KG_ORPHAN_GRACE_DAYS=90 deletes orphaned nodes after three months instead of a year. Orphaned nodes no longer appear in kg_read, but kg_search still finds them, and reading a connected node can bring them back until the grace period ends.

Changing the port

Change KG_HTTP_PORT only if another program holds 8765. Every client must then see the new value: the server (in the unit, if you use the service), your shell profile (for kg, the hooks and the kg mcp your harnesses launch), and any app that starts without your shell's environment, such as Claude Desktop. A server on another port keeps its PID file and logs in ~/.local/state/knowledge-graph/port-<N>/. kg editor points the editor at whatever port kg sees.

Don't edit the plugin's bundled .mcp.json. It only launches kg mcp, and every plugin update overwrites it.

The size budget is fixed by design

The graph's budget is measured in exact rendered characters, not estimated tokens, and is not configurable: 22,000 per level for compaction, 50,000 for the combined full-graph read. The budget sets how much memory a session gets; how it reaches each client is handled separately:

  • Preload: at most 9,500 UTF-16 units in Claude Code, 9,000 bytes in Codex and 10,000 bytes in Antigravity, each in the unit that client counts.
  • Long reads arrive in parts. A kg_read reply longer than the client keeps whole (45,000 UTF-16 units in Claude Code, 36,000 bytes in Codex) is split; kg_read(session_id, more=true) returns the next part. Only what a delivered part showed counts as seen.
  • Oversized graphs degrade predictably. A full read hides the lowest-scored archived anchors first, then the lowest-value edges, with counts and a search pointer.

The 50,000-character figure is a target, not 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 its target until a maintenance pass tightens them.

Fixed settings

These live in server/core/constants.py. You can change them in a fork, but they are not exposed as settings, and several are part of the budget arithmetic above.

Setting Value Why
Storage layout <storage-root>/projects/<slug>/graph.json Plain JSON; the root is configurable
User graph path <storage-root>/user.json One shared file
Sessions path <storage-root>/sessions.json Central session tracking
Session TTL 24 hours Sessions expire after inactivity
Session ID length 8 hex characters Short enough for tool arguments
Budget per level 22,000 characters Compaction threshold, in exact rendered characters
Full-graph read target 50,000 characters Can be exceeded when active gists alone exceed it
Search output ceiling 10,000 characters Hard cap on a kg_search result
Compaction target ratio 0.8 Archiving compacts down to this share of the budget; refill fills back up to the same ceiling
Fresh tier 30% of the budget The newest nodes that are never archived
Archived budget ratio 0.30 Most of the budget archived anchor lines may take before the lowest-scored become orphaned
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(all incident edges)). Endorsements decay with a 90-day half-life. Recency is the latest write, read or credit
Endorsements per session 5 guidance, 10 hard cap kg_useful is for what helped, not for 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

Maintenance chores

Background upkeep ("chores") is configured in ~/.knowledge-graph/chores.json. It is off by default because it spends your quota. kg setup --only upkeep creates the file from the plugin's chores/chores.example.json with "enabled": true; you can also edit it by hand. The server re-reads the file when it changes, so no restart is needed. Every decision, including each refusal and its reason, is logged in ~/.knowledge-graph/chores.jsonl.

There are two tiers. A chore fixes one kind of debt on one or two nodes (a cluster of up to five when lifting episodes into a lesson). A pass is the full /kg-maintain runbook, due by time since the last pass, and runs only when the week is on course to leave quota unspent.

Key Default Meaning
enabled false The switch (KG_CHORES overrides it)
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 (works whether upkeep is on or off)
min_interval_s / graph_cooldown_s / max_per_day 2700 / 21600 / 8 Spacing between chores overall, 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 shows up as "binary missing" instead of silently spending another subscription's quota.

Chores need a fresh quota reading from their runner. For Claude Code that is the status-line gauge kg setup installs (Installation#session-limits-and-the-status-line-recommended); Codex and Antigravity readings come from their own session logs and /usage. The kg-ops skill has the full detail on runners, permissions and safety rules.

Visual editor

kg editor starts the editor (and the memory server, if it is down) and points it at the server kg uses. The editor reads its own variables:

Variable Default Description
EDITOR_PORT 8766 Editor web server port
EDITOR_HOST 127.0.0.1 Editor bind address
MCP_SERVER_URL http://127.0.0.1:8765 The memory server for REST requests and live updates. kg editor sets it from KG_HTTP_HOST and KG_HTTP_PORT

See Visual Editor.

Clone this wiki locally