Skip to content

Commit 04da6b4

Browse files
authored
Merge pull request #683 from FalkorDB/dvirdukhan/mcp-t13-t14-packaging
MCP-T13 + T14: cgraph init-agent + Docker dual-mode
2 parents 6b23cb6 + 2c2e667 commit 04da6b4

10 files changed

Lines changed: 504 additions & 5 deletions

File tree

AGENTS.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,27 @@ cgraph info [--repo <name>] # Repo stats + metadata
154154
```
155155

156156
`--repo` defaults to the current directory name. Claude Code skill in `skills/code-graph/`.
157+
158+
## MCP server (for agents)
159+
160+
`cgraph-mcp` exposes the code graph over MCP stdio. Seven tools:
161+
`index_repo`, `search_code`, `find_symbol`, `get_neighbors`,
162+
`get_file_neighbors`, `impact_analysis`, `find_path`.
163+
164+
Drop the canonical agent guidance into any repo:
165+
166+
```bash
167+
cgraph init-agent # writes CLAUDE.md + .cursorrules
168+
cgraph init-agent --force # overwrite existing files
169+
```
170+
171+
See `api/mcp/templates/claude_mcp_section.md` for the full tool table
172+
and rules of thumb (start with `search_code`/`find_symbol`; use
173+
`get_neighbors` for who/what-calls; run `impact_analysis` before
174+
refactoring).
175+
176+
Environment:
177+
178+
- `CODE_GRAPH_AUTO_INDEX=true` — auto-index CWD on MCP startup.
179+
- `CGRAPH_MODE=mcp` — run `cgraph-mcp` instead of the FastAPI web
180+
server when using the Docker image.

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,48 @@ npx skills add FalkorDB/code-graph
236236

237237
Then ask Claude things like *"what functions call analyze_sources?"* or *"find the dependency chain between parse_config and send_request"* — it will handle the indexing and querying automatically.
238238

239+
### MCP server (`cgraph-mcp`)
240+
241+
For agents that speak the [Model Context Protocol](https://modelcontextprotocol.io)
242+
(Claude Code, Cursor, Cline, …), code-graph ships a stdio MCP server
243+
that exposes the knowledge graph as 7 first-class tools: `index_repo`,
244+
`search_code`, `find_symbol`, `get_neighbors`, `get_file_neighbors`,
245+
`impact_analysis`, and `find_path`.
246+
247+
Quickstart — Claude Code:
248+
249+
```bash
250+
# 1. Install (in any venv with the cgraph package on PATH)
251+
pip install falkordb-code-graph # or: uv pip install falkordb-code-graph
252+
253+
# 2. Register with Claude Code
254+
claude mcp add-json code-graph '{
255+
"command": "cgraph-mcp",
256+
"env": {
257+
"FALKORDB_HOST": "localhost",
258+
"FALKORDB_PORT": "6379",
259+
"CODE_GRAPH_AUTO_INDEX": "true"
260+
}
261+
}'
262+
263+
# 3. Drop agent guidance into your repo
264+
cd /path/to/your/repo
265+
cgraph init-agent # writes CLAUDE.md and .cursorrules
266+
```
267+
268+
Quickstart — Docker Compose:
269+
270+
```bash
271+
docker compose up -d falkordb # start the DB
272+
docker compose --profile mcp run --rm -i code-graph-mcp # attach via stdio
273+
```
274+
275+
The MCP server auto-bootstraps FalkorDB if it's missing on localhost
276+
(via `cgraph ensure-db`). When `CODE_GRAPH_AUTO_INDEX=true` is set,
277+
the current working directory is indexed automatically on start.
278+
279+
**Transport:** Phase 1 is stdio only. HTTP/SSE is deferred.
280+
239281
## Running with Docker
240282

241283
### Using Docker Compose
@@ -246,18 +288,34 @@ docker compose up --build
246288

247289
This starts FalkorDB and the CodeGraph app together. The checked-in compose file sets `CODE_GRAPH_PUBLIC=1` for the app service.
248290

291+
To run the **MCP stdio server** instead of the web app from the same
292+
image, set `CGRAPH_MODE=mcp` and use the `mcp` profile:
293+
294+
```bash
295+
docker compose --profile mcp run --rm -i code-graph-mcp
296+
```
297+
249298
### Using Docker directly
250299

251300
```bash
252301
docker build -t code-graph .
253302

303+
# Web mode (default)
254304
docker run -p 5000:5000 \
255305
-e FALKORDB_HOST=host.docker.internal \
256306
-e FALKORDB_PORT=6379 \
257307
-e MODEL_NAME=gemini/gemini-flash-lite-latest \
258308
-e GEMINI_API_KEY=<YOUR_GEMINI_API_KEY> \
259309
-e SECRET_TOKEN=<YOUR_SECRET_TOKEN> \
260310
code-graph
311+
312+
# MCP stdio mode (same image)
313+
docker run --rm -i \
314+
-e CGRAPH_MODE=mcp \
315+
-e FALKORDB_HOST=host.docker.internal \
316+
-e FALKORDB_PORT=6379 \
317+
-e MODEL_NAME=gemini/gemini-flash-lite-latest \
318+
code-graph
261319
```
262320

263321
## Creating a Code Graph

api/cli.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,5 +425,47 @@ def info(
425425
_json_out({"repo": name, "branch": branch, **stats, "metadata": metadata})
426426

427427

428+
# ── init-agent ─────────────────────────────────────────────────────────
429+
430+
431+
_TEMPLATES_DIR = Path(__file__).parent / "mcp" / "templates"
432+
433+
434+
@app.command("init-agent")
435+
def init_agent(
436+
force: bool = typer.Option(
437+
False, "--force", "-f", help="Overwrite existing CLAUDE.md / .cursorrules."
438+
),
439+
) -> None:
440+
"""Drop AI-agent guidance files (CLAUDE.md, .cursorrules) into CWD.
441+
442+
Copies the canonical code-graph MCP guidance bundled with this
443+
package so any repo can announce the tools to Cursor and Claude
444+
Code with one command.
445+
"""
446+
targets = {
447+
"CLAUDE.md": _TEMPLATES_DIR / "claude_mcp_section.md",
448+
".cursorrules": _TEMPLATES_DIR / "cursorrules.template",
449+
}
450+
451+
cwd = Path.cwd()
452+
if not force:
453+
existing = [name for name in targets if (cwd / name).exists()]
454+
if existing:
455+
_json_error(
456+
f"Refusing to overwrite existing files: {', '.join(existing)}. "
457+
"Re-run with --force to clobber."
458+
)
459+
460+
written: List[str] = []
461+
for name, template in targets.items():
462+
dest = cwd / name
463+
dest.write_text(template.read_text(encoding="utf-8"), encoding="utf-8")
464+
written.append(str(dest))
465+
_stderr(f"Wrote {dest}")
466+
467+
_json_out({"status": "ok", "written": written, "force": force})
468+
469+
428470
if __name__ == "__main__":
429471
app()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# code-graph MCP server — agent guidance
2+
3+
This repo is indexed into a FalkorDB **code knowledge graph** exposed
4+
to you over MCP as `code-graph`. Use it instead of grepping when you
5+
need to understand how symbols connect.
6+
7+
## When to call each tool
8+
9+
| Tool | Call this when… | Example |
10+
|---|---|---|
11+
| `index_repo(path_or_url, branch?)` | **First** thing in a new repo; or after large changes outside your edits. Project name is **derived from the folder or repo URL** — read it back from the response. | `index_repo(path_or_url=".")` |
12+
| `search_code(query, project)` | You know part of a symbol name and need its id (hybrid prefix + ranked match). | `search_code(query="processPay", project="myrepo")` |
13+
| `find_symbol(name, project, file?)` | You know the exact symbol name (optionally in a given file) and want its id directly. | `find_symbol(name="processPayment", project="myrepo")` |
14+
| `get_neighbors(symbol_id, project, relation?, direction?)` | "Who calls this?" (`direction="IN"`), "What does this call?" (`direction="OUT"`), or other edges via `relation` (CALLS/IMPORTS/DEFINES). Replaces the old get_callers/get_callees/get_dependencies. | `get_neighbors(symbol_id=42, project="myrepo", direction="IN")` |
15+
| `get_file_neighbors(file, project)` | Symbols a file defines / depends on — "what's in this file and what does it touch?" | `get_file_neighbors(file="api/graph.py", project="myrepo")` |
16+
| `impact_analysis(symbol_id, project, direction, depth)` | **"What breaks if I change this?"** Transitive upstream callers. | `impact_analysis(symbol_id=42, project="myrepo", direction="IN", depth=3)` |
17+
| `find_path(source_id, dest_id, project)` | Show the call chain between two known symbols. | `find_path(source_id=10, dest_id=42, project="myrepo")` |
18+
19+
## Rules of thumb
20+
21+
1. **Start with `search_code` or `find_symbol`** to turn names into ids. Most tools take a `symbol_id`.
22+
2. **Use `get_neighbors` with `direction`** for who-calls / what-calls: `IN` = callers, `OUT` = callees. Pass `relation` for IMPORTS/DEFINES edges.
23+
3. **`impact_analysis` before refactoring.** Even when you think you know
24+
the answer — the transitive closure often surprises you.
25+
4. **`branch` is optional** but pass it when working on a feature branch
26+
so you query the right per-branch index.
27+
5. **Response shape.** Tools that return collections (`search_code`,
28+
`find_symbol`, `get_neighbors`, `get_file_neighbors`, `find_path`,
29+
`impact_analysis`) put the array in `structuredContent.result` per
30+
the MCP spec. The text content is the same JSON for convenience.
31+
`index_repo` returns a single object.
32+
33+
## Environment
34+
35+
- `CODE_GRAPH_AUTO_INDEX=true` — auto-index CWD on first tool call (off by
36+
default; opt-in because indexing big repos takes minutes).
37+
- `FALKORDB_HOST` / `FALKORDB_PORT` — defaults to `localhost:6379`. If
38+
unreachable on localhost, the server runs `cgraph ensure-db` to
39+
spin up the official Docker image.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Cursor rules — code-graph MCP
2+
3+
This project is indexed into a FalkorDB code knowledge graph via the
4+
`code-graph` MCP server. Use it instead of grepping when you need to
5+
understand how symbols connect.
6+
7+
## Tool selection
8+
9+
- Symbol lookup by name: use `code-graph.search_code` (hybrid prefix +
10+
ranked match) or `code-graph.find_symbol` for an exact name — both give
11+
you the numeric id every other tool needs.
12+
- "Who calls X?": `code-graph.get_neighbors` with `direction="IN"`.
13+
- "What does X call?": `code-graph.get_neighbors` with `direction="OUT"`.
14+
- Other edges (IMPORTS / DEFINES): `code-graph.get_neighbors` with the
15+
matching `relation`.
16+
- What a file defines/touches: `code-graph.get_file_neighbors`.
17+
- Refactoring impact ("what breaks if I change X"):
18+
`code-graph.impact_analysis` with `direction="IN"`.
19+
- Call chain between two specific symbols: `code-graph.find_path`.
20+
21+
## Rules
22+
23+
- Always `search_code`/`find_symbol` first to resolve names to ids.
24+
- Use `get_neighbors(direction=...)` for "who/what calls" questions.
25+
- Run `impact_analysis(direction="IN", depth=3)` before any non-trivial
26+
refactor.
27+
- Pass `branch` when on a feature branch.
28+
29+
## First run
30+
31+
If the repo isn't indexed yet, call `index_repo(path=".")` once. After
32+
that, navigate via the structural tools.

docker-compose.yml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,21 @@ services:
2222
- FALKORDB_PORT=6379
2323
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
2424
- SECRET_TOKEN=${SECRET_TOKEN:-}
25-
- CODE_GRAPH_PUBLIC=1
25+
- CODE_GRAPH_PUBLIC=1
26+
27+
# MCP stdio server — opt-in. Bring up with:
28+
# docker compose run --rm -i code-graph-mcp
29+
# then point Claude Code / Cursor at the running container's stdio.
30+
code-graph-mcp:
31+
build: .
32+
depends_on:
33+
- falkordb
34+
profiles: ["mcp"]
35+
stdin_open: true
36+
tty: false
37+
environment:
38+
- CGRAPH_MODE=mcp
39+
- FALKORDB_HOST=falkordb
40+
- FALKORDB_PORT=6379
41+
- MODEL_NAME=${MODEL_NAME:-gemini/gemini-flash-lite-latest}
42+
- CODE_GRAPH_AUTO_INDEX=${CODE_GRAPH_AUTO_INDEX:-}

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ build-backend = "setuptools.build_meta"
4848
[tool.setuptools.packages.find]
4949
where = ["."]
5050

51+
[tool.setuptools.package-data]
52+
"api.mcp" = ["templates/*"]
53+
5154
[dependency-groups]
5255
dev = [
5356
"pytest>=9.0.2",

0 commit comments

Comments
 (0)