basic mcp org

This commit is contained in:
ed
2026-06-07 01:23:40 -04:00
parent 7d76e6392c
commit fd34467b55
+62 -56
View File
@@ -576,6 +576,28 @@ def edit_file(path: str, old_string: str, new_string: str, replace_all: bool = F
except Exception as e: except Exception as e:
return f"ERROR editing '{path}': {e}" return f"ERROR editing '{path}': {e}"
def get_git_diff(path: str, base_rev: str = "HEAD", head_rev: str = "") -> str:
"""
Returns the git diff for a file or directory.
base_rev: The base revision (default: HEAD)
head_rev: The head revision (optional)
"""
p, err = _resolve_and_check(path)
if err:
return err
assert p is not None
cmd = ["git", "diff", base_rev]
if head_rev:
cmd.append(head_rev)
cmd.extend(["--", str(p)])
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True, encoding="utf-8")
return result.stdout if result.stdout else "(no changes)"
except subprocess.CalledProcessError as e:
return f"ERROR running git diff: {e.stderr}"
except Exception as e:
return f"ERROR: {e}"
def _get_symbol_node(tree: ast.AST, name: str) -> Optional[ast.AST]: def _get_symbol_node(tree: ast.AST, name: str) -> Optional[ast.AST]:
"""Helper to find an AST node by name (Class, Function, or Variable). Supports dot notation.""" """Helper to find an AST node by name (Class, Function, or Variable). Supports dot notation."""
parts = name.split(".") parts = name.split(".")
@@ -602,6 +624,8 @@ def _get_symbol_node(tree: ast.AST, name: str) -> Optional[ast.AST]:
current = found current = found
return current return current
#region: Python AST
def py_get_symbol_info(path: str, name: str) -> tuple[str, int] | str: def py_get_symbol_info(path: str, name: str) -> tuple[str, int] | str:
""" """
@@ -806,30 +830,6 @@ def py_set_var_declaration(path: str, name: str, new_declaration: str) -> str:
except Exception as e: except Exception as e:
return f"ERROR updating variable '{name}' in '{path}': {e}" return f"ERROR updating variable '{name}' in '{path}': {e}"
def get_git_diff(path: str, base_rev: str = "HEAD", head_rev: str = "") -> str:
"""
Returns the git diff for a file or directory.
base_rev: The base revision (default: HEAD)
head_rev: The head revision (optional)
"""
p, err = _resolve_and_check(path)
if err:
return err
assert p is not None
cmd = ["git", "diff", base_rev]
if head_rev:
cmd.append(head_rev)
cmd.extend(["--", str(p)])
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True, encoding="utf-8")
return result.stdout if result.stdout else "(no changes)"
except subprocess.CalledProcessError as e:
return f"ERROR running git diff: {e.stderr}"
except Exception as e:
return f"ERROR: {e}"
def py_find_usages(path: str, name: str) -> str: def py_find_usages(path: str, name: str) -> str:
"""Finds exact string matches of a symbol in a given file or directory.""" """Finds exact string matches of a symbol in a given file or directory."""
p, err = _resolve_and_check(path) p, err = _resolve_and_check(path)
@@ -964,38 +964,6 @@ def py_get_docstring(path: str, name: str) -> str:
except Exception as e: except Exception as e:
return f"ERROR getting docstring for '{name}': {e}" return f"ERROR getting docstring for '{name}': {e}"
def get_tree(path: str, max_depth: int = 2) -> str:
"""Returns a directory structure up to a max depth."""
p, err = _resolve_and_check(path)
if err: return err
assert p is not None
if not p.is_dir(): return f"ERROR: not a directory: {path}"
try:
m_depth = max_depth
def _build_tree(dir_path: Path, current_depth: int, prefix: str = "") -> list[str]:
if current_depth > m_depth: return []
lines = []
try:
entries = sorted(dir_path.iterdir(), key=lambda e: (e.is_file(), e.name.lower()))
except PermissionError:
return []
# Filter
entries = [e for e in entries if not e.name.startswith('.') and e.name not in ('__pycache__', 'venv', 'env') and e.name != "history.toml" and not e.name.endswith("_history.toml")]
for i, entry in enumerate(entries):
is_last = (i == len(entries) - 1)
connector = "└── " if is_last else "├── "
lines.append(f"{prefix}{connector}{entry.name}")
if entry.is_dir():
extension = " " if is_last else ""
lines.extend(_build_tree(entry, current_depth + 1, prefix + extension))
return lines
tree_lines = [f"{p.name}/"] + _build_tree(p, 1)
return "\n".join(tree_lines)
except Exception as e:
return f"ERROR generating tree for '{path}': {e}"
# ------------------------------------------------------------------ web tools
def derive_code_path(target: str, max_depth: int = 5) -> str: def derive_code_path(target: str, max_depth: int = 5) -> str:
"""Recursively traces the execution path of a specific function or method.""" """Recursively traces the execution path of a specific function or method."""
from src.file_cache import ASTParser from src.file_cache import ASTParser
@@ -1056,6 +1024,42 @@ def derive_code_path(target: str, max_depth: int = 5) -> str:
trace(symbol_name, found_path, found_code, 0, "") trace(symbol_name, found_path, found_code, 0, "")
return "\n".join(output) return "\n".join(output)
#endregion Python AST
def get_tree(path: str, max_depth: int = 2) -> str:
"""Returns a directory structure up to a max depth."""
p, err = _resolve_and_check(path)
if err: return err
assert p is not None
if not p.is_dir(): return f"ERROR: not a directory: {path}"
try:
m_depth = max_depth
def _build_tree(dir_path: Path, current_depth: int, prefix: str = "") -> list[str]:
if current_depth > m_depth: return []
lines = []
try:
entries = sorted(dir_path.iterdir(), key=lambda e: (e.is_file(), e.name.lower()))
except PermissionError:
return []
# Filter
entries = [e for e in entries if not e.name.startswith('.') and e.name not in ('__pycache__', 'venv', 'env') and e.name != "history.toml" and not e.name.endswith("_history.toml")]
for i, entry in enumerate(entries):
is_last = (i == len(entries) - 1)
connector = "└── " if is_last else "├── "
lines.append(f"{prefix}{connector}{entry.name}")
if entry.is_dir():
extension = " " if is_last else ""
lines.extend(_build_tree(entry, current_depth + 1, prefix + extension))
return lines
tree_lines = [f"{p.name}/"] + _build_tree(p, 1)
return "\n".join(tree_lines)
except Exception as e:
return f"ERROR generating tree for '{path}': {e}"
# ------------------------------------------------------------------ web tools
#region: Web
class _DDGParser(HTMLParser): class _DDGParser(HTMLParser):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
@@ -1162,6 +1166,8 @@ def fetch_url(url: str) -> str:
except Exception as e: except Exception as e:
return f"ERROR fetching URL '{url}': {e}" return f"ERROR fetching URL '{url}': {e}"
#endregion: Web
def get_ui_performance() -> str: def get_ui_performance() -> str:
""" """