Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion codegraph-skill/codegraph/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ Treat duplicate leads and call-compatibility hints as review leads, not proof.
## MCP

If MCP tools are available, prefer them over repeated CLI invocations.
Use MCP `orient`, `search`, `packet_get`, `goto`, `refs`, `deps`, `rdeps`, `path`, `impact`, and `review` first.
Use MCP `orient`, `search`, `packet_get`, `goto`, `refs`, `deps`, `rdeps`, `path`, `impact`, `review`, and `query_sqlite` first.
After edits, check MCP response `freshness`: `refreshed` means Codegraph rebuilt before answering, and `stale` includes a reason plus bounded changed-file metadata before indexed context is trusted.
Run `refresh_index` before `artifact_build` when MCP reports a stale index; artifact writes refuse stale snapshots.
Fall back to CLI when MCP is unavailable.

## Discovery
Expand Down
7 changes: 4 additions & 3 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,11 +263,12 @@ For SQL, prefer handles or schema-qualified names when basenames may be ambiguou
- `mcp serve` exposes navigation, search, impact, review, SQLite query, session refresh, and artifact-build tools.
- MCP uses stdio by default or Streamable HTTP with `--port <number>`.
- Startup is lazy by default; `--warmup` builds the base session cache before serving requests, and `--warmup-symbols` also builds the detailed symbol graph.
- Use `refresh_index` after changing files while a long-running server is active.
- Index-backed responses include `freshness`; small file changes auto-refresh, while stale responses include a reason, total changed-file count, and a bounded changed-file sample.
- Use `refresh_index` to force a rebuild, reset SQLite artifact state, or recover after stale change bursts.
- HTTP serves `/mcp`, validates Host headers, and binds to `127.0.0.1` unless `--host <host>` is passed.
- MCP file and artifact paths are confined to `--root` after realpath resolution.
- MCP tools are read-only by default; `--allow-build` enables artifact output only.
- `query_sqlite` is row- and byte-bounded and rejects synthetic payload functions.
- MCP tools are read-only by default; `--allow-build` enables artifact output only when the MCP index is fresh or auto-refreshed.
- `query_sqlite` is row- and byte-bounded, returns freshness metadata, rejects synthetic payload functions, and refuses stale artifact rows it cannot refresh safely.

See [docs/mcp.md](./mcp.md) for client configuration examples.

Expand Down
12 changes: 8 additions & 4 deletions docs/library-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ console.log(artifact.manifestPath, artifact.artifacts);

The `graph.json` artifact is self-describing (`schemaVersion: 1`, `format: "codegraph.graph-json"`) and uses project-relative file paths and portable symbol handles. `questions.json` uses the same stable handles for follow-up commands. With `force: true`, stale known Codegraph artifact files are removed before the selected outputs are written; unrelated files in the directory are preserved.

`createAgentSession()` keeps one in-process project snapshot warm for repeated orient, search, explain, packet, artifact, and MCP calls. It uses incremental indexing with disk cache by default, auto-enables native workers for large cold builds, and carries forward top-level analysis metadata from the build report. Set `buildOptions.useNativeWorkers` to `false` to opt out. Use `buildCodegraphArtifactWithSession()` when a host already has a session and wants SQLite, graph JSON, report, questions, and manifest outputs from the same snapshot. `createCodegraphMcpHandlers()` exposes the same primitives without starting stdio, which is useful for tests or host applications:
`createAgentSession()` keeps one in-process project snapshot warm for repeated orient, search, explain, packet, artifact, and MCP calls. It uses incremental indexing with disk cache by default, auto-enables native workers for large cold builds, and carries forward top-level analysis metadata from the build report.
Session callers can use `freshness: { policy: "check" | "auto" | "manual" }` plus `checkFreshness()` to detect file edits before reusing a warm snapshot. `check` reports stale state without invalidating, `auto` invalidates for bounded changes, and stale results include `changedFileCount`, `omittedChangedFileCount`, `reason`, and a bounded changed-file sample.
Set `buildOptions.useNativeWorkers` to `false` to opt out. Use `buildCodegraphArtifactWithSession()` when a host already has a session and wants SQLite, graph JSON, report, questions, and manifest outputs from the same snapshot. `createCodegraphMcpHandlers()` exposes the same primitives without starting stdio, which is useful for tests or host applications:

```ts
import { createCodegraphMcpHandlers } from "@lzehrung/codegraph";
Expand All @@ -178,11 +180,13 @@ const orient = await handlers.orient({ includeRoots: ["src"], budget: "small" })
const packet = await handlers.packet_get({ target: orient.focus.find((entry) => entry.file)!.file! });
const refs = await handlers.refs({ handle: search.results[0]!.handle });
const rows = await handlers.query_sqlite({ query: "select path from files", limit: 5 });
console.log(packet.kind, refs.references, rows.rows);
console.log(search.freshness.state);
console.log(packet.kind, refs.references, rows.rows, rows.freshness.state);
```

`serveCodegraphMcp()` starts the stdio server used by `codegraph mcp serve`. MCP is an agent ergonomics and cache layer over the same analysis engine, not a separate indexer. MCP file and artifact paths are confined after realpath resolution. `query_sqlite` is read-only and row- and byte-bounded; `artifact_build` is disabled by default and requires `readOnly: false` or CLI `--allow-build`.
MCP `orient` and `packet_get` calls use the server-configured root; they do not accept per-request root overrides.
`serveCodegraphMcp()` starts the stdio server used by `codegraph mcp serve`. MCP is an agent ergonomics and cache layer over the same analysis engine, not a separate indexer. MCP file and artifact paths are confined after realpath resolution.
`query_sqlite` is read-only and row- and byte-bounded. It returns freshness metadata for fresh artifact reads, refreshes Codegraph-owned SQLite artifacts after small edits when write access is enabled, and rejects stale artifact queries it cannot refresh safely.
`artifact_build` is disabled by default and requires `readOnly: false` or CLI `--allow-build`; it refuses to write outputs from a stale MCP index until `refresh_index` succeeds. MCP `orient` and `packet_get` calls use the server-configured root; they do not accept per-request root overrides.

See [MCP server](./mcp.md) for CLI server setup and client configuration examples.

Expand Down
18 changes: 10 additions & 8 deletions docs/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,22 @@ The server exposes the same bounded primitives as the CLI and library session la
- `refs`: references by handle or file position.
- `deps`, `rdeps`, `path`: dependency navigation.
- `impact`, `review`: git-range risk and review context.
- `query_sqlite`: bounded read-only SQLite artifact query.
- `query_sqlite`: bounded read-only SQLite artifact query with freshness metadata.
- `refresh_index`: invalidate the in-memory session and optionally rebuild the base or symbol snapshot.
- `artifact_build`: artifact creation, available only with write access enabled.

MCP keeps one Codegraph session warm for the configured root. That makes follow-up calls cheaper than separate CLI invocations. Startup is lazy unless `--warmup` or `--warmup-symbols` is passed.
Use `refresh_index` after changing files while the server is running, or when you need a fresh cache-backed snapshot without restarting the MCP process.
Before index-backed tool calls, MCP checks whether discovered files changed since the warm snapshot. Small changes refresh the session automatically, and responses include `freshness.state` as `fresh`, `refreshed`, or `stale`; stale responses also include `changedFileCount`, `omittedChangedFileCount`, and a bounded changed-file sample.
Use `refresh_index` when you need to force a rebuild, reset SQLite artifact state, or refresh after a change burst that exceeds the automatic refresh limits. `query_sqlite` refreshes Codegraph-owned SQLite artifacts after small edits when write access is enabled; otherwise it refuses to serve stale artifact rows. `artifact_build` refuses to write outputs from a stale MCP index; run `refresh_index` first after large change bursts.
Tool schemas are flat JSON objects for broad client compatibility; argument combinations such as `refs` handle-vs-position mode are validated by the server.

## Safety

- File and artifact paths are confined to `--root` after realpath resolution.
- Tool calls do not accept per-request root overrides.
- Tools are read-only by default.
- `artifact_build` requires `--allow-build`.
- `query_sqlite` rejects mutating SQL, recursive queries, and synthetic payload functions.
- `artifact_build` requires `--allow-build` and a fresh or auto-refreshed MCP index.
- `query_sqlite` rejects mutating SQL, recursive queries, synthetic payload functions, and stale artifact queries it cannot refresh safely.
- SQLite responses are row- and byte-bounded.

## Client Configuration Examples
Expand Down Expand Up @@ -195,9 +196,10 @@ When Codegraph MCP tools are available to an agent:
1. Start with `orient`.
2. Use `search` to find anchors.
3. Use `packet_get`, `refs`, `goto`, `deps`, `rdeps`, or `path` for focused follow-up.
4. Use `impact` and `review` for git-range risk analysis.
5. Use `query_sqlite` only for read-only artifact inspection.
6. Use `refresh_index` after changing files while a long-running server is active.
7. Use `artifact_build` only when write access was intentionally enabled.
4. Check `freshness` on MCP responses after edits; `refreshed` means the answer used an updated snapshot, and `stale` includes a reason plus a bounded changed-file sample.
5. Use `impact` and `review` for git-range risk analysis.
6. Use `query_sqlite` only for read-only artifact inspection; rebuild the artifact when it reports stale state.
7. Use `refresh_index` when you need an explicit rebuild.
8. Use `artifact_build` only when write access was intentionally enabled.

Fall back to CLI commands when MCP tools are unavailable.
9 changes: 8 additions & 1 deletion src/agent.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
export { createAgentSession } from "./agent/session.js";
export type { AgentProjectSnapshot, AgentSession, AgentSessionOptions } from "./agent/session.js";
export type {
AgentFreshnessPolicy,
AgentFreshnessResult,
AgentProjectSnapshot,
AgentSession,
AgentSessionFreshnessOptions,
AgentSessionOptions,
} from "./agent/session.js";
export { orientCodegraph } from "./agent/orient.js";
export type {
AgentModuleSummary,
Expand Down
12 changes: 12 additions & 0 deletions src/agent/artifact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,23 @@ export async function buildCodegraphArtifactWithSession(
const artifacts: CodegraphArtifactBuildResult["artifacts"] = {};

if (selected.sqlite) {
if (!snapshot.fileSignatures) {
throw new Error("SQLite artifact freshness signatures are unavailable.");
}
const fileSignatures: Array<{ path: string; size: number; mtimeMs: number }> = [];
for (const file of snapshot.fileGraph.nodes) {
const signature = snapshot.fileSignatures.get(file);
if (!signature) {
throw new Error(`SQLite artifact freshness signature is missing for ${file}.`);
}
fileSignatures.push({ path: signature.file, size: signature.size, mtimeMs: signature.mtimeMs });
}
const outputPath = path.join(outDir, SQLITE_FILE);
await writeGraphSqlite({
fileGraph: snapshot.fileGraph,
symbolGraph: snapshot.symbolGraph,
outputPath,
fileSignatures,
});
Comment thread
Copilot marked this conversation as resolved.
artifacts.sqlite = SQLITE_FILE;
}
Expand Down
Loading