MCP Integration

lip mcp exposes the LIP daemon as a Model Context Protocol server. Any MCP-compatible client — Claude Code, CKB, Cursor, or a custom agent — gets live, always-current code intelligence without building its own indexing layer.


Tools

ToolDescription
lip_blast_radiusWhich files are affected if this symbol changes
lip_workspace_symbolsSemantic symbol search across the whole repo
lip_definitionGo-to-definition at (file, line, col)
lip_referencesAll call sites for a symbol URI
lip_hoverType signature + docs at a position
lip_document_symbolsAll symbols defined in a file
lip_dead_symbolsSymbols defined but never referenced
lip_annotation_getRead a persistent symbol annotation
lip_annotation_setWrite a persistent symbol annotation
lip_annotation_workspace_listAll annotations matching a key prefix, workspace-wide
lip_similar_symbolsTrigram fuzzy-search across all symbol names and docs
lip_stale_filesMerkle sync probe — which files need re-indexing
lip_load_sliceMount a pre-built dependency slice into the daemon graph
lip_batch_queryExecute multiple queries in one round-trip
lip_embedding_batchCompute and cache file embeddings via HTTP endpoint
lip_nearestTop-K files most similar to a given file (cosine similarity)
lip_nearest_by_textTop-K files most similar to a free-text query
lip_index_statusDaemon health: indexed count, embedding coverage, last update
lip_file_statusPer-file indexing status and embedding age
lip_reindex_filesForce re-index of specific file URIs from disk
lip_similarityPairwise cosine similarity of two stored embeddings
lip_query_expansionExpand a query string into related symbol names
lip_clusterGroup URIs by embedding proximity within a given radius
lip_export_embeddingsReturn raw stored vectors for external pipelines

All tools are backed by the live LIP daemon — results are always current, never a stale snapshot.


Setup

1. Start the daemon

lip daemon --socket /tmp/lip.sock

2. Start the MCP server

lip mcp --socket /tmp/lip.sock

The MCP server speaks JSON-RPC 2.0 over stdio. Keep it running alongside the daemon, or launch it on demand — it connects to the daemon per-request.

3. Add to your MCP client config

Claude Code (~/.claude/mcp.json or project .mcp.json):

{
  "mcpServers": {
    "lip": {
      "command": "lip",
      "args": ["mcp", "--socket", "/tmp/lip.sock"]
    }
  }
}

CKB (.ckb/config.json):

{
  "backends": {
    "lip": {
      "command": "lip",
      "args": ["mcp", "--socket", "/tmp/lip.sock"],
      "tools": ["lip_blast_radius", "lip_workspace_symbols", "lip_references"]
    }
  }
}

Cursor (~/.cursor/mcp.json):

{
  "mcpServers": {
    "lip": {
      "command": "lip",
      "args": ["mcp"]
    }
  }
}

Tool reference

lip_blast_radius

Call before modifying any function, class, or interface to understand the scope of impact.

Input:

{ "symbol_uri": "lip://local/src/auth.rs#AuthService.verifyToken" }

Output:

Blast radius for `AuthService.verifyToken`:
direct dependents:     3
transitive dependents: 12
affected files (12):
  file:///src/middleware/auth_guard.rs
  file:///src/handlers/login.rs
  file:///src/handlers/register.rs
  ...

lip_workspace_symbols

Semantic symbol search — finds by name across the entire workspace, returns kind, location, and confidence.

Input:

{ "query": "verifyToken", "limit": 20 }

lip_definition

Find where a symbol is defined.

Input:

{ "uri": "file:///src/auth.rs", "line": 42, "col": 10 }

line and col are 0-based, UTF-8 byte offsets.


lip_references

Find all call sites for a symbol.

Input:

{ "symbol_uri": "lip://local/src/auth.rs#AuthService.verifyToken", "limit": 50 }

lip_annotation_set / lip_annotation_get

Persistent annotations on symbols — survive daemon restarts, file changes, and re-indexes. Useful for AI agents to leave notes that persist across sessions.

Set:

{
  "symbol_uri": "lip://local/src/payments.rs#processCharge",
  "key":        "agent:note",
  "value":      "Uses deprecated Stripe v1 API. Migration tracked in #472.",
  "author_id":  "agent:claude"
}

Get:

{
  "symbol_uri": "lip://local/src/payments.rs#processCharge",
  "key":        "agent:note"
}

Canonical key prefixes:

PrefixMeaning
lip:fragileHandle with care — high blast radius or known instability
lip:do-not-touchFrozen — do not modify without explicit approval
lip:{agent-id}-lockSymbol is claimed by a running agent instance
team:ownerOwning team or person
agent:noteAI agent observations (scoped per agent ID)

lip:agent-lock — worktree collision prevention

When an agent starts working on a symbol it sets a lock annotation so other instances know to skip it:

{
  "symbol_uri": "lip://local/src/payments.rs#processCharge",
  "key":        "lip:nyx-agent-lock",
  "value":      "{\"worktree\":\"/repo-work\",\"pid\":4821,\"started_at_ms\":1744320000000}",
  "author_id":  "agent:nyx"
}

Before claiming a symbol, check for the lock. If the value is non-empty, a peer is already working on it — skip and move on.

After finishing, clear the lock by writing an empty value:

{ "symbol_uri": "...", "key": "lip:nyx-agent-lock", "value": "", "author_id": "agent:nyx" }

The lock key is agent-type-specific (lip:nyx-agent-lock, lip:claude-agent-lock, …) so two different agent types can work on the same symbol without blocking each other.


lip_batch_query

Execute multiple queries in a single round-trip. One socket connection instead of N — critical for planning workflows where you need several facts per symbol.

Input:

{
  "queries": [
    { "type": "query_blast_radius", "symbol_uri": "lip://local/src/auth.rs#AuthService" },
    { "type": "query_references",   "symbol_uri": "lip://local/src/auth.rs#AuthService", "limit": 50 },
    { "type": "annotation_get",     "symbol_uri": "lip://local/src/auth.rs#AuthService", "key": "lip:fragile" },
    { "type": "annotation_get",     "symbol_uri": "lip://local/src/auth.rs#AuthService", "key": "lip:nyx-agent-lock" }
  ]
}

Manifest and Delta are not permitted inside a batch; they return an error for that slot without aborting the rest.


Semantic search tools

These tools require LIP_EMBEDDING_URL to be set. See Embeddings & Semantic Search.

lip_embedding_batch

Compute and cache dense embedding vectors for a list of file URIs. Already-cached embeddings are returned without a network call.

Input:

{
  "uris": [
    "file:///src/auth.rs",
    "file:///src/payments.rs",
    "file:///src/session.rs"
  ]
}

Output:

embedded 3/3 files  model=nomic-embed-text  dims=768

lip_nearest

Find the top_k files most semantically similar to a given file, using pre-computed embedding vectors and cosine similarity.

Input:

{ "uri": "file:///src/auth.rs", "top_k": 5 }

Output:

score=0.9412  file:///src/session.rs
score=0.8871  file:///src/middleware/auth_guard.rs
score=0.8204  file:///src/handlers/login.rs
score=0.7931  file:///src/tokens.rs
score=0.7456  file:///src/crypto.rs

lip_nearest_by_text

Find the top_k files most semantically similar to a free-text query. The daemon embeds the text on the fly and runs cosine search against all stored vectors.

Input:

{ "text": "authentication token validation and session management", "top_k": 5 }

Observability tools

lip_index_status

Report overall daemon health. Useful as a CI pre-flight check.

Input: {} (no arguments)

Output:

indexed=142  pending_embeddings=38  last_updated=1744400123000ms  embedding_model=nomic-embed-text
  • pending_embeddings — files indexed but not yet embedded.
  • last_updated — Unix timestamp (ms) of the most recent file upsert.

lip_file_status

Report the indexing status of a single file.

Input:

{ "uri": "file:///src/auth.rs" }

Output:

file:///src/auth.rs  indexed=true  has_embedding=true  age=42s

age is seconds since the file was last indexed.


v1.6 embedding integration tools

These tools require LIP_EMBEDDING_URL to be set unless otherwise noted.

lip_reindex_files

Force a re-index of specific file URIs from disk. Does not require embeddings — reads each file, detects its language, and updates the symbol graph.

Input:

{ "uris": ["file:///src/auth.rs", "file:///src/session.rs"] }

Use this after out-of-band changes that the daemon’s file watcher didn’t catch (e.g. selective git checkout or CI-generated files). Returns DeltaAck.


lip_similarity

Pairwise cosine similarity of two stored embeddings.

Input:

{ "uri_a": "file:///src/auth.rs", "uri_b": "file:///src/session.rs" }

Output:

score=0.9214

Returns null when either URI has no cached embedding — call lip_embedding_batch first. Accepts both file:// (file embeddings) and lip:// (symbol embeddings) URIs. Safe inside lip_batch_query.


lip_query_expansion

Embed a short query string and return the display names of the nearest symbols — useful before lip_workspace_symbols when the exact symbol name isn’t known.

Input:

{ "query": "token validation", "top_k": 5 }

Output:

verifyToken
validateSession
checkJwt
parseBearer
refreshToken

Requires symbols to have embeddings in the symbol store (populate with lip_embedding_batch using lip:// URIs).


lip_cluster

Group a list of URIs into clusters based on embedding proximity.

Input:

{
  "uris": [
    "file:///src/auth.rs",
    "file:///src/session.rs",
    "file:///src/payments.rs",
    "file:///src/invoices.rs"
  ],
  "radius": 0.85
}

Output:

Group 1: file:///src/auth.rs  file:///src/session.rs
Group 2: file:///src/payments.rs  file:///src/invoices.rs

radius is the cosine-similarity threshold. Two URIs land in the same group when their similarity is ≥ the radius. URIs without a cached embedding are silently excluded.


lip_export_embeddings

Return the raw stored embedding vectors for a list of URIs. Useful for passing to external re-ranking, custom clustering, or visualization tools.

Input:

{ "uris": ["file:///src/auth.rs", "file:///src/session.rs"] }

Output:

{
  "file:///src/auth.rs":    [0.021, -0.044, 0.117, ...],
  "file:///src/session.rs": [0.019, -0.051, 0.109, ...]
}

URIs with no cached embedding are omitted from the result. Safe inside lip_batch_query.


How agents should use LIP

Planning a multi-symbol refactor (use batch):

1. lip_workspace_symbols → collect URIs for all symbols you plan to touch
2. lip_batch_query       → for each URI: blast_radius + references + annotation_get("lip:fragile")
                           + annotation_get("lip:nyx-agent-lock")
                           — 10 symbols = 1 round-trip, not 40
3. lip_annotation_set    → set lip:nyx-agent-lock on each claimed symbol

Before modifying a single symbol:

1. lip_workspace_symbols → find the symbol URI
2. lip_blast_radius       → understand scope of change
3. lip_references         → see all call sites
4. lip_annotation_get     → check for "lip:fragile" or "lip:do-not-touch"

After modifying code (if the change is notable):

lip_annotation_set("agent:note") → leave a note explaining what changed and why
lip_annotation_set("lip:nyx-agent-lock", value="") → release the lock

Finding dead code:

lip_dead_symbols → candidates for safe deletion
lip_blast_radius on each → confirm truly zero dependents

Semantic exploration workflow

# 1. Bootstrap embeddings for the whole workspace (once per session)
lip_embedding_batch(uris=[all_file_uris])

# 2. Find files related to a concept
lip_nearest_by_text("payment processing and fraud detection", top_k=10)

# 3. For each relevant file: check blast radius and ownership
lip_batch_query([
  blast_radius(file_uri),
  annotation_get(file_uri, "team:owner"),
  annotation_get(file_uri, "lip:fragile")
])

# 4. Health check before committing results
lip_index_status()          # confirm coverage
lip_file_status(target_uri) # confirm specific file is indexed and fresh

The CKB → LIP mapping

CKB toolLIP toolNotes
analyzeImpactlip_blast_radiusLIP is always live; CKB needs SCIP refresh
searchSymbolslip_workspace_symbolsLIP uses live Tier 1 index
findReferenceslip_referencesSame semantics
getCallGraphlip_references + CPG edgesLIP CPG via Tier 2
prepareChangelip_blast_radius + lip_annotation_getLIP adds annotation check
batchSearchlip_query_expansion + lip_workspace_symbolsExpand → search replaces compound text scan
explorelip_cluster + lip_nearest_by_textGroup and navigate by semantic proximity
recentlyRelevantlip_similarity + lip_export_embeddingsFeed raw vectors into CKB’s re-ranking tier

With LIP as CKB’s backend, analyzeImpact and prepareChange are always current — no more ckb index needed.