hanzo-mcp 0.6.12__py3-none-any.whl → 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of hanzo-mcp might be problematic. Click here for more details.

Files changed (117) hide show
  1. hanzo_mcp/__init__.py +2 -2
  2. hanzo_mcp/analytics/__init__.py +5 -0
  3. hanzo_mcp/analytics/posthog_analytics.py +364 -0
  4. hanzo_mcp/cli.py +5 -5
  5. hanzo_mcp/cli_enhanced.py +7 -7
  6. hanzo_mcp/cli_plugin.py +91 -0
  7. hanzo_mcp/config/__init__.py +1 -1
  8. hanzo_mcp/config/settings.py +70 -7
  9. hanzo_mcp/config/tool_config.py +20 -6
  10. hanzo_mcp/dev_server.py +3 -3
  11. hanzo_mcp/prompts/project_system.py +1 -1
  12. hanzo_mcp/server.py +40 -3
  13. hanzo_mcp/server_enhanced.py +69 -0
  14. hanzo_mcp/tools/__init__.py +140 -31
  15. hanzo_mcp/tools/agent/__init__.py +85 -4
  16. hanzo_mcp/tools/agent/agent_tool.py +104 -6
  17. hanzo_mcp/tools/agent/agent_tool_v2.py +459 -0
  18. hanzo_mcp/tools/agent/clarification_protocol.py +220 -0
  19. hanzo_mcp/tools/agent/clarification_tool.py +68 -0
  20. hanzo_mcp/tools/agent/claude_cli_tool.py +125 -0
  21. hanzo_mcp/tools/agent/claude_desktop_auth.py +508 -0
  22. hanzo_mcp/tools/agent/cli_agent_base.py +191 -0
  23. hanzo_mcp/tools/agent/code_auth.py +436 -0
  24. hanzo_mcp/tools/agent/code_auth_tool.py +194 -0
  25. hanzo_mcp/tools/agent/codex_cli_tool.py +123 -0
  26. hanzo_mcp/tools/agent/critic_tool.py +376 -0
  27. hanzo_mcp/tools/agent/gemini_cli_tool.py +128 -0
  28. hanzo_mcp/tools/agent/grok_cli_tool.py +128 -0
  29. hanzo_mcp/tools/agent/iching_tool.py +380 -0
  30. hanzo_mcp/tools/agent/network_tool.py +273 -0
  31. hanzo_mcp/tools/agent/prompt.py +62 -20
  32. hanzo_mcp/tools/agent/review_tool.py +433 -0
  33. hanzo_mcp/tools/agent/swarm_tool.py +535 -0
  34. hanzo_mcp/tools/agent/swarm_tool_v2.py +594 -0
  35. hanzo_mcp/tools/common/__init__.py +15 -1
  36. hanzo_mcp/tools/common/base.py +5 -4
  37. hanzo_mcp/tools/common/batch_tool.py +103 -11
  38. hanzo_mcp/tools/common/config_tool.py +2 -2
  39. hanzo_mcp/tools/common/context.py +2 -2
  40. hanzo_mcp/tools/common/context_fix.py +26 -0
  41. hanzo_mcp/tools/common/critic_tool.py +196 -0
  42. hanzo_mcp/tools/common/decorators.py +208 -0
  43. hanzo_mcp/tools/common/enhanced_base.py +106 -0
  44. hanzo_mcp/tools/common/fastmcp_pagination.py +369 -0
  45. hanzo_mcp/tools/common/forgiving_edit.py +243 -0
  46. hanzo_mcp/tools/common/mode.py +116 -0
  47. hanzo_mcp/tools/common/mode_loader.py +105 -0
  48. hanzo_mcp/tools/common/paginated_base.py +230 -0
  49. hanzo_mcp/tools/common/paginated_response.py +307 -0
  50. hanzo_mcp/tools/common/pagination.py +226 -0
  51. hanzo_mcp/tools/common/permissions.py +1 -1
  52. hanzo_mcp/tools/common/personality.py +936 -0
  53. hanzo_mcp/tools/common/plugin_loader.py +287 -0
  54. hanzo_mcp/tools/common/stats.py +4 -4
  55. hanzo_mcp/tools/common/tool_list.py +4 -1
  56. hanzo_mcp/tools/common/truncate.py +101 -0
  57. hanzo_mcp/tools/common/validation.py +1 -1
  58. hanzo_mcp/tools/config/__init__.py +3 -1
  59. hanzo_mcp/tools/config/config_tool.py +1 -1
  60. hanzo_mcp/tools/config/mode_tool.py +209 -0
  61. hanzo_mcp/tools/database/__init__.py +1 -1
  62. hanzo_mcp/tools/editor/__init__.py +1 -1
  63. hanzo_mcp/tools/filesystem/__init__.py +48 -14
  64. hanzo_mcp/tools/filesystem/ast_multi_edit.py +562 -0
  65. hanzo_mcp/tools/filesystem/batch_search.py +3 -3
  66. hanzo_mcp/tools/filesystem/diff.py +2 -2
  67. hanzo_mcp/tools/filesystem/directory_tree_paginated.py +338 -0
  68. hanzo_mcp/tools/filesystem/rules_tool.py +235 -0
  69. hanzo_mcp/tools/filesystem/{unified_search.py → search_tool.py} +12 -12
  70. hanzo_mcp/tools/filesystem/{symbols_unified.py → symbols_tool.py} +104 -5
  71. hanzo_mcp/tools/filesystem/watch.py +3 -2
  72. hanzo_mcp/tools/jupyter/__init__.py +2 -2
  73. hanzo_mcp/tools/jupyter/jupyter.py +1 -1
  74. hanzo_mcp/tools/llm/__init__.py +3 -3
  75. hanzo_mcp/tools/llm/llm_tool.py +648 -143
  76. hanzo_mcp/tools/lsp/__init__.py +5 -0
  77. hanzo_mcp/tools/lsp/lsp_tool.py +512 -0
  78. hanzo_mcp/tools/mcp/__init__.py +2 -2
  79. hanzo_mcp/tools/mcp/{mcp_unified.py → mcp_tool.py} +3 -3
  80. hanzo_mcp/tools/memory/__init__.py +76 -0
  81. hanzo_mcp/tools/memory/knowledge_tools.py +518 -0
  82. hanzo_mcp/tools/memory/memory_tools.py +456 -0
  83. hanzo_mcp/tools/search/__init__.py +6 -0
  84. hanzo_mcp/tools/search/find_tool.py +581 -0
  85. hanzo_mcp/tools/search/unified_search.py +953 -0
  86. hanzo_mcp/tools/shell/__init__.py +11 -6
  87. hanzo_mcp/tools/shell/auto_background.py +203 -0
  88. hanzo_mcp/tools/shell/base_process.py +57 -29
  89. hanzo_mcp/tools/shell/bash_session_executor.py +1 -1
  90. hanzo_mcp/tools/shell/{bash_unified.py → bash_tool.py} +18 -34
  91. hanzo_mcp/tools/shell/command_executor.py +2 -2
  92. hanzo_mcp/tools/shell/{npx_unified.py → npx_tool.py} +16 -33
  93. hanzo_mcp/tools/shell/open.py +2 -2
  94. hanzo_mcp/tools/shell/{process_unified.py → process_tool.py} +1 -1
  95. hanzo_mcp/tools/shell/run_command_windows.py +1 -1
  96. hanzo_mcp/tools/shell/streaming_command.py +594 -0
  97. hanzo_mcp/tools/shell/uvx.py +47 -2
  98. hanzo_mcp/tools/shell/uvx_background.py +47 -2
  99. hanzo_mcp/tools/shell/{uvx_unified.py → uvx_tool.py} +16 -33
  100. hanzo_mcp/tools/todo/__init__.py +14 -19
  101. hanzo_mcp/tools/todo/todo.py +22 -1
  102. hanzo_mcp/tools/vector/__init__.py +1 -1
  103. hanzo_mcp/tools/vector/infinity_store.py +2 -2
  104. hanzo_mcp/tools/vector/project_manager.py +1 -1
  105. hanzo_mcp/types.py +23 -0
  106. hanzo_mcp-0.7.0.dist-info/METADATA +516 -0
  107. hanzo_mcp-0.7.0.dist-info/RECORD +180 -0
  108. {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.7.0.dist-info}/entry_points.txt +1 -0
  109. hanzo_mcp/tools/common/palette.py +0 -344
  110. hanzo_mcp/tools/common/palette_loader.py +0 -108
  111. hanzo_mcp/tools/config/palette_tool.py +0 -179
  112. hanzo_mcp/tools/llm/llm_unified.py +0 -851
  113. hanzo_mcp-0.6.12.dist-info/METADATA +0 -339
  114. hanzo_mcp-0.6.12.dist-info/RECORD +0 -135
  115. hanzo_mcp-0.6.12.dist-info/licenses/LICENSE +0 -21
  116. {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.7.0.dist-info}/WHEEL +0 -0
  117. {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.7.0.dist-info}/top_level.txt +0 -0
@@ -21,7 +21,7 @@ from hanzo_mcp.tools.filesystem.base import FilesystemBaseTool
21
21
  Action = Annotated[
22
22
  str,
23
23
  Field(
24
- description="Action: search (default), index, query, list",
24
+ description="Action: search (default), ast, index, query, list",
25
25
  default="search",
26
26
  ),
27
27
  ]
@@ -88,7 +88,7 @@ class SymbolsParams(TypedDict, total=False):
88
88
 
89
89
  @final
90
90
  class SymbolsTool(FilesystemBaseTool):
91
- """Unified tool for code symbol operations using tree-sitter."""
91
+ """Tool for code symbol operations using tree-sitter."""
92
92
 
93
93
  def __init__(self, permission_manager):
94
94
  """Initialize the symbols tool."""
@@ -105,13 +105,16 @@ class SymbolsTool(FilesystemBaseTool):
105
105
  @override
106
106
  def description(self) -> str:
107
107
  """Get the tool description."""
108
- return """Code symbols with tree-sitter. Actions: search (default), index, query, list.
108
+ return """Code symbols search with tree-sitter AST. Actions: search (default), ast, index, query, list.
109
109
 
110
110
  Usage:
111
111
  symbols "function_name"
112
+ symbols --action ast --pattern "TODO" --path ./src
112
113
  symbols --action query --symbol-type function --path ./src
113
114
  symbols --action index --path ./project
114
- symbols --action list --path ./src --symbol-type class"""
115
+ symbols --action list --path ./src --symbol-type class
116
+
117
+ Finds code structures (functions, classes, methods) with full context."""
115
118
 
116
119
  @override
117
120
  async def call(
@@ -129,6 +132,8 @@ symbols --action list --path ./src --symbol-type class"""
129
132
  # Route to appropriate handler
130
133
  if action == "search":
131
134
  return await self._handle_search(params, tool_ctx)
135
+ elif action == "ast" or action == "grep_ast": # Support both for backward compatibility
136
+ return await self._handle_ast(params, tool_ctx)
132
137
  elif action == "index":
133
138
  return await self._handle_index(params, tool_ctx)
134
139
  elif action == "query":
@@ -136,7 +141,7 @@ symbols --action list --path ./src --symbol-type class"""
136
141
  elif action == "list":
137
142
  return await self._handle_list(params, tool_ctx)
138
143
  else:
139
- return f"Error: Unknown action '{action}'. Valid actions: search, index, query, list"
144
+ return f"Error: Unknown action '{action}'. Valid actions: search, ast, index, query, list"
140
145
 
141
146
  async def _handle_search(self, params: Dict[str, Any], tool_ctx) -> str:
142
147
  """Search for pattern in code with AST context."""
@@ -222,6 +227,100 @@ symbols --action list --path ./src --symbol-type class"""
222
227
 
223
228
  return "\n".join(output)
224
229
 
230
+ async def _handle_ast(self, params: Dict[str, Any], tool_ctx) -> str:
231
+ """AST-aware grep - shows code structure context around matches."""
232
+ pattern = params.get("pattern")
233
+ if not pattern:
234
+ return "Error: pattern required for ast action"
235
+
236
+ path = params.get("path", ".")
237
+ ignore_case = params.get("ignore_case", False)
238
+ show_context = params.get("show_context", True)
239
+ limit = params.get("limit", 50)
240
+
241
+ # Validate path
242
+ path_validation = self.validate_path(path)
243
+ if not path_validation.is_valid:
244
+ await tool_ctx.error(f"Invalid path: {path_validation.error_message}")
245
+ return f"Error: Invalid path: {path_validation.error_message}"
246
+
247
+ # Check permissions
248
+ is_allowed, error_message = await self.check_path_allowed(path, tool_ctx)
249
+ if not is_allowed:
250
+ return error_message
251
+
252
+ # Check existence
253
+ is_exists, error_message = await self.check_path_exists(path, tool_ctx)
254
+ if not is_exists:
255
+ return error_message
256
+
257
+ await tool_ctx.info(f"Running AST-aware grep for '{pattern}' in {path}")
258
+
259
+ # Get files to process
260
+ files_to_process = self._get_source_files(path)
261
+ if not files_to_process:
262
+ return f"No source code files found in {path}"
263
+
264
+ # Process files
265
+ results = []
266
+ match_count = 0
267
+
268
+ for file_path in files_to_process:
269
+ if match_count >= limit:
270
+ break
271
+
272
+ try:
273
+ with open(file_path, "r", encoding="utf-8") as f:
274
+ code = f.read()
275
+
276
+ # Create TreeContext for AST parsing
277
+ tc = TreeContext(
278
+ file_path,
279
+ code,
280
+ color=False,
281
+ verbose=False,
282
+ line_number=True,
283
+ )
284
+
285
+ # Find matches with case sensitivity option
286
+ if ignore_case:
287
+ import re
288
+ loi = tc.grep(pattern, ignore_case=True)
289
+ else:
290
+ loi = tc.grep(pattern, ignore_case=False)
291
+
292
+ if loi:
293
+ # Always show AST context for grep_ast
294
+ tc.add_lines_of_interest(loi)
295
+ tc.add_context()
296
+
297
+ # Get the formatted output with structure
298
+ output = tc.format()
299
+
300
+ # Add section separator and file info
301
+ results.append(f"\n{'='*60}")
302
+ results.append(f"File: {file_path}")
303
+ results.append(f"Matches: {len(loi)}")
304
+ results.append(f"{'='*60}\n")
305
+ results.append(output)
306
+
307
+ match_count += len(loi)
308
+
309
+ except Exception as e:
310
+ await tool_ctx.warning(f"Could not parse {file_path}: {str(e)}")
311
+
312
+ if not results:
313
+ return f"No matches found for '{pattern}' in {path}"
314
+
315
+ output = [f"=== AST-aware Grep Results for '{pattern}' ==="]
316
+ output.append(f"Total matches: {match_count} in {len([r for r in results if '===' in str(r)])//4} files\n")
317
+ output.extend(results)
318
+
319
+ if match_count >= limit:
320
+ output.append(f"\n(Results limited to {limit} matches)")
321
+
322
+ return "\n".join(output)
323
+
225
324
  async def _handle_index(self, params: Dict[str, Any], tool_ctx) -> str:
226
325
  """Index symbols in a codebase."""
227
326
  path = params.get("path", ".")
@@ -23,16 +23,17 @@ class WatchTool(BaseTool):
23
23
 
24
24
  @server.tool(name=self.name, description=self.description)
25
25
  async def watch_handler(
26
+ ctx: MCPContext,
26
27
  path: str,
27
28
  pattern: str = "*",
28
29
  interval: int = 1,
29
30
  recursive: bool = True,
30
31
  exclude: str = "",
31
- duration: int = 30,
32
+ duration: int = 30
32
33
  ) -> str:
33
34
  """Handle watch tool calls."""
34
35
  return await self.run(
35
- None,
36
+ ctx,
36
37
  path=path,
37
38
  pattern=pattern,
38
39
  interval=interval,
@@ -1,4 +1,4 @@
1
- """Jupyter notebook tools package for Hanzo MCP.
1
+ """Jupyter notebook tools package for Hanzo AI.
2
2
 
3
3
  This package provides tools for working with Jupyter notebooks (.ipynb files),
4
4
  including reading and editing notebook cells.
@@ -29,7 +29,7 @@ def get_read_only_jupyter_tools(
29
29
  Returns:
30
30
  List of Jupyter notebook tool instances
31
31
  """
32
- return [] # Unified tool handles both read and write
32
+ return [] # Tool handles both read and write
33
33
 
34
34
 
35
35
  def get_jupyter_tools(permission_manager: PermissionManager) -> list[BaseTool]:
@@ -81,7 +81,7 @@ class NotebookParams(TypedDict, total=False):
81
81
 
82
82
  @final
83
83
  class JupyterTool(JupyterBaseTool):
84
- """Unified tool for Jupyter notebook operations."""
84
+ """Tool for Jupyter notebook operations."""
85
85
 
86
86
  @property
87
87
  @override
@@ -1,6 +1,6 @@
1
- """LLM tools for Hanzo MCP."""
1
+ """LLM tools for Hanzo AI."""
2
2
 
3
- from hanzo_mcp.tools.llm.llm_unified import UnifiedLLMTool
3
+ from hanzo_mcp.tools.llm.llm_tool import LLMTool
4
4
 
5
5
  # Legacy imports for backwards compatibility
6
6
  from hanzo_mcp.tools.llm.llm_tool import LLMTool
@@ -17,7 +17,7 @@ from hanzo_mcp.tools.llm.provider_tools import (
17
17
  )
18
18
 
19
19
  __all__ = [
20
- "UnifiedLLMTool",
20
+ "LLMTool",
21
21
  "LLMTool",
22
22
  "ConsensusTool",
23
23
  "LLMManageTool",