Skip to content

Knowledge Graph API

Maxim Mironenko edited this page May 22, 2026 · 4 revisions

Knowledge Graph API

All tools are exposed via MCP and called by Claude Code automatically. You don't call these directly — Claude does, guided by the hidden skill descriptions loaded at session start.

Tools (8 total)

kg_read(cwd, id?, level?)

The primary entry point. Two modes:

Mode 1: Full graph read (no id) Initializes a session, loads both user and project graphs, returns all nodes (gist only) and edges, plus health stats. Returns a session_id for subsequent tool calls.

Mode 2: Single node read (with id) Returns a single node's full content (gist + notes + touches). If the node is archived, promotes it to active automatically.

Parameters:

Param Type Required Description
cwd string Yes Project root directory. Initializes session on first call.
id string No Node ID to read in full. Omit for full graph.
level string No Hint: "user" or "project". If omitted, searches both.

When it's called: Start of every session (full graph), and whenever full node content is needed.


kg_search(query, session_id?)

Full-text search across node IDs, gists, notes, and touches in both user and project graphs. Reaches all three tiers — active, archived, and orphaned — and flags orphaned results so they can be promoted via kg_read(cwd, id).

The query is tokenized on whitespace; each term is ranked across nodes by occurrence count and ranks are merged via Reciprocal Rank Fusion (RRF, k=60). Results from the user and project graphs are unified into a single ranking.

Parameters:

Param Type Required Description
query string Yes One or more terms (case-insensitive). Multiple terms are RRF-merged.
session_id string No If provided, scopes the project search to this session's project. Omitting it falls back to a best-effort search across all currently-loaded project graphs.

Returns: Ranked list of records with level, id, gist, notes, archived, orphaned, and score fields — gist + notes, not the full node body. Use kg_read(cwd, id) to load a node's full content (and to promote it if archived/orphaned).

When to use: Before creating nodes (check duplicates), when a problem feels familiar, locating nodes by topic.


kg_put_node(session_id, level, id, gist, notes?, touches?)

Creates or updates a node. If the node exists, fields are merged. If the node was archived, it's automatically unarchived. Saves to disk immediately (write-through).

Parameters:

Param Type Required Description
session_id string Yes From kg_read
level "user" or "project" Yes Storage level
id string Yes Node ID (kebab-case)
gist string Yes Compressed headline — the core insight
notes string[] No Rationale, constraints, "why"
touches string[] No Related file paths or artifacts

Side effects: Triggers auto-compaction check. Broadcasts change to WebSocket clients.

Example:

kg_put_node(
  session_id="abc12345",
  level="project",
  id="api-rate-limiting",
  gist="Redis-backed sliding window; 429 response includes Retry-After header",
  touches=["src/middleware/rate_limit.py"],
  notes=["window size configurable via env var RATE_LIMIT_WINDOW"]
)

kg_put_edge(session_id, level, from, to, rel, notes?)

Creates or updates an edge. from and to can be node IDs or file paths — nodes for those IDs don't need to exist.

Parameters:

Param Type Required Description
session_id string Yes From kg_read
level "user" or "project" Yes Storage level
from string Yes Source node ID or file path
to string Yes Target node ID or file path
rel string Yes Relationship type (kebab-case)
notes string[] No Context about this relationship

Example:

kg_put_edge(
  session_id="abc12345",
  level="project",
  from="auth-module",
  to="src/config.yaml",
  rel="reads-config",
  notes=["JWT secret and token TTL"]
)

kg_delete_node(session_id, id)

Deletes a node and all edges connected to it. Automatically finds which graph (user or project) the node is in.

Returns: Node ID deleted, count of edges removed, and resolved level.


kg_delete_edge(session_id, from, to, rel)

Deletes a specific edge. All three identifiers (from, to, rel) must match exactly. Automatically finds which graph the edge is in.

Returns: {"deleted": true/false, "level": "..."}


kg_sync(session_id)

Gets changes made by other sessions since this session's last sync. Returns diff of nodes and edges modified by other sessions.

Parameters:

Param Type Required Description
session_id string Yes From kg_read

Returns: Diff with user and project sections showing changed nodes/edges.

When to use: After subagents finish, before important decisions, periodically in long sessions (~30 min).


kg_progress(session_id, task_id, state?, level?)

Tracks multi-step task progress across context compaction and session boundaries. Omit state to read current progress; include state to write.

Parameters:

Param Type Required Description
session_id string Yes From kg_read
task_id string Yes e.g. "scout", "extract"
state object No Progress state to persist. Omit to read.
level string No Default: "user"

Example (write):

kg_progress(
  session_id="abc12345",
  task_id="scout",
  state={
    "last_ts": 1706000000,
    "sessions_reviewed": ["abc123"],
    "patterns_found": ["docker-networking"]
  }
)

Example (read):

kg_progress(session_id="abc12345", task_id="scout")

Edge and Node ID Conventions

  • Node IDs: kebab-case, descriptive, include domain hint. Good: auth-token-refresh. Bad: refresh.
  • Edge relationships: kebab-case verbs. Common: depends-on, requires, implements, configures, persists, calls, related-to.
  • Touches/from/to: Can be file paths (src/auth/handler.py) or node IDs — mixing is fine.

Clone this wiki locally