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:
@@ -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."""
|
||||
|
||||
Reference in New Issue
Block a user