feat: add find_path and get_file_signatures MCP tools

- find_path: BFS traversal to trace relationship chains between two files (max N hops)
- get_file_signatures: lightweight context mode returning just function/type names
- db.find_path(): bidirectional BFS with shortest-path tracking
- db.get_all_files(): list all files with docs and staleness
- db.get_file_signatures(): return functions list without full doc payload

Inspired by Octocode's GraphRAG path-finding pattern.
Addresses Mike/Dmitry feedback on usable roll-up summaries.
This commit is contained in:
Jarvis Prime
2026-03-05 04:23:13 +00:00
parent e28e1a61b2
commit 3256e4e7c3
2 changed files with 96 additions and 0 deletions

View File

@@ -143,6 +143,46 @@ def get_stale_docs() -> str:
return "\n".join(lines)
@mcp.tool()
def find_path(source: str, target: str, max_depth: int = 4) -> str:
"""Trace the relationship chain between two files. Shows how file A connects to file B through imports/dependencies. Useful for understanding impact radius and architectural coupling."""
db = _get_db()
paths = db.find_path(source, target, max_depth)
db.close()
if not paths:
return f"No connection found between {source} and {target} within {max_depth} hops."
lines = [f"Connection paths from {source}{target} ({len(paths)} found):\n"]
for i, path in enumerate(paths[:5]): # Cap at 5 paths
chain = "".join(path)
lines.append(f" Path {i+1} ({len(path)-1} hops): {chain}")
if len(paths) > 5:
lines.append(f" ... and {len(paths) - 5} more paths")
return "\n".join(lines)
@mcp.tool()
def get_file_signatures(path: str) -> str:
"""Get just the function/type signatures for a file — lightweight context without full documentation. Useful when you need a quick map of what a file exports."""
db = _get_db()
f = db.get_file_signatures(path)
db.close()
if not f:
return f"File not found: {path}"
import json
try:
funcs = json.loads(f["functions"]) if f["functions"] else []
except (json.JSONDecodeError, TypeError):
funcs = []
staleness = " [STALE]" if f["staleness"] == "stale" else ""
lines = [f"Signatures for {path}{staleness} ({f['language']}):\n"]
if funcs:
for fn in funcs:
lines.append(f"{fn}")
else:
lines.append(" (no functions extracted)")
return "\n".join(lines)
@mcp.tool()
def get_graph_stats() -> str:
"""Get overall knowledge graph statistics — file count, relationship count, staleness."""