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
@@ -1,12 +1,35 @@
1
- """Agent tools for Hanzo MCP.
1
+ """Agent tools for Hanzo AI.
2
2
 
3
3
  This module provides tools that allow Claude to delegate tasks to sub-agents,
4
4
  enabling concurrent execution of multiple operations and specialized processing.
5
5
  """
6
6
 
7
+ import os
7
8
  from mcp.server import FastMCP
8
9
 
9
- from hanzo_mcp.tools.agent.agent_tool import AgentTool
10
+ # Try to use hanzo-agents SDK versions if available
11
+ USE_HANZO_AGENTS = os.environ.get("USE_HANZO_AGENTS", "true").lower() == "true"
12
+
13
+ try:
14
+ if USE_HANZO_AGENTS:
15
+ from hanzo_mcp.tools.agent.agent_tool_v2 import AgentTool
16
+ from hanzo_mcp.tools.agent.swarm_tool_v2 import SwarmTool
17
+ print("[MCP] Using hanzo-agents SDK for agent and swarm tools")
18
+ else:
19
+ raise ImportError("USE_HANZO_AGENTS=false")
20
+ except ImportError:
21
+ # Fall back to original implementations
22
+ from hanzo_mcp.tools.agent.agent_tool import AgentTool
23
+ from hanzo_mcp.tools.agent.swarm_tool import SwarmTool
24
+ if USE_HANZO_AGENTS:
25
+ print("[MCP] hanzo-agents SDK not available, using original agent implementations")
26
+
27
+ from hanzo_mcp.tools.agent.claude_cli_tool import ClaudeCLITool
28
+ from hanzo_mcp.tools.agent.codex_cli_tool import CodexCLITool
29
+ from hanzo_mcp.tools.agent.gemini_cli_tool import GeminiCLITool
30
+ from hanzo_mcp.tools.agent.grok_cli_tool import GrokCLITool
31
+ from hanzo_mcp.tools.agent.code_auth_tool import CodeAuthTool
32
+ from hanzo_mcp.tools.agent.network_tool import NetworkTool, LocalSwarmTool
10
33
  from hanzo_mcp.tools.common.base import BaseTool, ToolRegistry
11
34
 
12
35
  from hanzo_mcp.tools.common.permissions import PermissionManager
@@ -48,9 +71,67 @@ def register_agent_tools(
48
71
  max_iterations=agent_max_iterations,
49
72
  max_tool_uses=agent_max_tool_uses,
50
73
  )
74
+
75
+ # Create swarm tool
76
+ swarm_tool = SwarmTool(
77
+ permission_manager=permission_manager,
78
+ model=agent_model,
79
+ api_key=agent_api_key,
80
+ base_url=agent_base_url,
81
+ max_tokens=agent_max_tokens,
82
+ agent_max_iterations=agent_max_iterations,
83
+ agent_max_tool_uses=agent_max_tool_uses,
84
+ )
85
+
86
+
87
+ # Create CLI agent tools
88
+ claude_cli_tool = ClaudeCLITool(
89
+ permission_manager=permission_manager,
90
+ model=agent_model, # Can override default Sonnet
91
+ )
92
+
93
+ codex_cli_tool = CodexCLITool(
94
+ permission_manager=permission_manager,
95
+ model=agent_model if agent_model and "gpt" in agent_model else None,
96
+ )
97
+
98
+ gemini_cli_tool = GeminiCLITool(
99
+ permission_manager=permission_manager,
100
+ model=agent_model if agent_model and "gemini" in agent_model else None,
101
+ )
102
+
103
+ grok_cli_tool = GrokCLITool(
104
+ permission_manager=permission_manager,
105
+ model=agent_model if agent_model and "grok" in agent_model else None,
106
+ )
107
+
108
+ # Create auth management tool
109
+ code_auth_tool = CodeAuthTool()
110
+
111
+ # Create network tool
112
+ network_tool = NetworkTool(
113
+ permission_manager=permission_manager,
114
+ default_mode="hybrid" # Prefer local, fallback to cloud
115
+ )
51
116
 
52
- # Register agent tool
117
+ # Register tools
53
118
  ToolRegistry.register_tool(mcp_server, agent_tool)
119
+ ToolRegistry.register_tool(mcp_server, swarm_tool)
120
+ ToolRegistry.register_tool(mcp_server, network_tool)
121
+ ToolRegistry.register_tool(mcp_server, claude_cli_tool)
122
+ ToolRegistry.register_tool(mcp_server, codex_cli_tool)
123
+ ToolRegistry.register_tool(mcp_server, gemini_cli_tool)
124
+ ToolRegistry.register_tool(mcp_server, grok_cli_tool)
125
+ ToolRegistry.register_tool(mcp_server, code_auth_tool)
54
126
 
55
127
  # Return list of registered tools
56
- return [agent_tool]
128
+ return [
129
+ agent_tool,
130
+ swarm_tool,
131
+ network_tool,
132
+ claude_cli_tool,
133
+ codex_cli_tool,
134
+ gemini_cli_tool,
135
+ grok_cli_tool,
136
+ code_auth_tool,
137
+ ]
@@ -1,4 +1,4 @@
1
- """Agent tool implementation for Hanzo MCP.
1
+ """Agent tool implementation for Hanzo AI.
2
2
 
3
3
  This module implements the AgentTool that allows Claude to delegate tasks to sub-agents,
4
4
  enabling concurrent execution of multiple operations and specialized processing.
@@ -30,6 +30,14 @@ from hanzo_mcp.tools.agent.prompt import (
30
30
  from hanzo_mcp.tools.agent.tool_adapter import (
31
31
  convert_tools_to_openai_functions,
32
32
  )
33
+ from hanzo_mcp.tools.agent.clarification_protocol import (
34
+ AgentClarificationMixin,
35
+ ClarificationType,
36
+ )
37
+ from hanzo_mcp.tools.agent.clarification_tool import ClarificationTool
38
+ from hanzo_mcp.tools.agent.critic_tool import CriticTool, CriticProtocol
39
+ from hanzo_mcp.tools.agent.review_tool import ReviewTool, ReviewProtocol
40
+ from hanzo_mcp.tools.agent.iching_tool import IChingTool
33
41
  from hanzo_mcp.tools.common.base import BaseTool
34
42
  from hanzo_mcp.tools.common.batch_tool import BatchTool
35
43
  from hanzo_mcp.tools.common.context import (
@@ -37,7 +45,7 @@ from hanzo_mcp.tools.common.context import (
37
45
  create_tool_context,
38
46
  )
39
47
  from hanzo_mcp.tools.common.permissions import PermissionManager
40
- from hanzo_mcp.tools.filesystem import get_read_only_filesystem_tools
48
+ from hanzo_mcp.tools.filesystem import get_read_only_filesystem_tools, Edit, MultiEdit
41
49
  from hanzo_mcp.tools.jupyter import get_read_only_jupyter_tools
42
50
 
43
51
  Prompt = Annotated[
@@ -60,11 +68,13 @@ class AgentToolParams(TypedDict, total=False):
60
68
 
61
69
 
62
70
  @final
63
- class AgentTool(BaseTool):
71
+ class AgentTool(AgentClarificationMixin, BaseTool):
64
72
  """Tool for delegating tasks to sub-agents.
65
73
 
66
74
  The AgentTool allows Claude to create and manage sub-agents for performing
67
75
  specialized tasks concurrently, such as code search, analysis, and more.
76
+
77
+ Agents can request clarification from the main loop up to once per task.
68
78
  """
69
79
 
70
80
  @property
@@ -75,7 +85,7 @@ class AgentTool(BaseTool):
75
85
  Returns:
76
86
  Tool name
77
87
  """
78
- return "dispatch_agent"
88
+ return "agent"
79
89
 
80
90
  @property
81
91
  @override
@@ -88,22 +98,26 @@ class AgentTool(BaseTool):
88
98
  # TODO: Add glob when it is implemented
89
99
  at = [t.name for t in self.available_tools]
90
100
 
91
- return f"""Launch a new agent that has access to the following tools: {at} When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries, use the Agent tool to perform the search for you.
101
+ return f"""Launch a new agent that has access to the following tools: {at}. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries, use the Agent tool to perform the search for you.
92
102
 
93
103
  When to use the Agent tool:
94
104
  - If you are searching for a keyword like \"config\" or \"logger\", or for questions like \"which file does X?\", the Agent tool is strongly recommended
105
+ - When you need to perform edits across multiple files based on search results
106
+ - When you need to delegate complex file modification tasks
95
107
 
96
108
  When NOT to use the Agent tool:
97
109
  - If you want to read a specific file path, use the read or glob tool instead of the Agent tool, to find the match more quickly
98
110
  - If you are searching for a specific class definition like \"class Foo\", use the glob tool instead, to find the match more quickly
99
111
  - If you are searching for code within a specific file or set of 2-3 files, use the read tool instead of the Agent tool, to find the match more quickly
112
+ - Writing code and running bash commands (use other tools for that)
113
+ - Other tasks that are not related to searching for a keyword or file
100
114
 
101
115
  Usage notes:
102
116
  1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
103
117
  2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.
104
118
  3. Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.
105
119
  4. The agent's outputs should generally be trusted
106
- 5.IMPORTANT: The Agent has no awareness of your context, so you must explicitly specify absolute project/file/directory paths and detailed background information about the current task. """
120
+ 5. Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent"""
107
121
 
108
122
  def __init__(
109
123
  self,
@@ -142,9 +156,30 @@ Usage notes:
142
156
  self.available_tools.extend(
143
157
  get_read_only_jupyter_tools(self.permission_manager)
144
158
  )
159
+
160
+ # Always add edit tools - agents should have edit access
161
+ self.available_tools.append(Edit(self.permission_manager))
162
+ self.available_tools.append(MultiEdit(self.permission_manager))
163
+
164
+ # Add clarification tool for agents
165
+ self.available_tools.append(ClarificationTool())
166
+
167
+ # Add critic tool for agents (devil's advocate)
168
+ self.available_tools.append(CriticTool())
169
+
170
+ # Add review tool for agents (balanced review)
171
+ self.available_tools.append(ReviewTool())
172
+
173
+ # Add I Ching tool for creative guidance
174
+ self.available_tools.append(IChingTool())
175
+
145
176
  self.available_tools.append(
146
177
  BatchTool({t.name: t for t in self.available_tools})
147
178
  )
179
+
180
+ # Initialize protocols
181
+ self.critic_protocol = CriticProtocol()
182
+ self.review_protocol = ReviewProtocol()
148
183
 
149
184
  @override
150
185
  async def call(
@@ -445,6 +480,69 @@ AGENT RESPONSES:
445
480
  )
446
481
  if not tool:
447
482
  tool_result = f"Error: Tool '{function_name}' not found"
483
+ # Special handling for clarification requests
484
+ elif function_name == "request_clarification":
485
+ try:
486
+ # Extract clarification parameters
487
+ request_type = function_args.get("type", "ADDITIONAL_INFO")
488
+ question = function_args.get("question", "")
489
+ context = function_args.get("context", {})
490
+ options = function_args.get("options", None)
491
+
492
+ # Convert string type to enum
493
+ clarification_type = ClarificationType[request_type]
494
+
495
+ # Request clarification
496
+ answer = await self.request_clarification(
497
+ request_type=clarification_type,
498
+ question=question,
499
+ context=context,
500
+ options=options
501
+ )
502
+
503
+ tool_result = self.format_clarification_in_output(question, answer)
504
+ except Exception as e:
505
+ tool_result = f"Error processing clarification: {str(e)}"
506
+ # Special handling for critic requests
507
+ elif function_name == "critic":
508
+ try:
509
+ # Extract critic parameters
510
+ review_type = function_args.get("review_type", "GENERAL")
511
+ work_description = function_args.get("work_description", "")
512
+ code_snippets = function_args.get("code_snippets", None)
513
+ file_paths = function_args.get("file_paths", None)
514
+ specific_concerns = function_args.get("specific_concerns", None)
515
+
516
+ # Request critical review
517
+ tool_result = self.critic_protocol.request_review(
518
+ review_type=review_type,
519
+ work_description=work_description,
520
+ code_snippets=code_snippets,
521
+ file_paths=file_paths,
522
+ specific_concerns=specific_concerns
523
+ )
524
+ except Exception as e:
525
+ tool_result = f"Error processing critic review: {str(e)}"
526
+ # Special handling for review requests
527
+ elif function_name == "review":
528
+ try:
529
+ # Extract review parameters
530
+ focus = function_args.get("focus", "GENERAL")
531
+ work_description = function_args.get("work_description", "")
532
+ code_snippets = function_args.get("code_snippets", None)
533
+ file_paths = function_args.get("file_paths", None)
534
+ context = function_args.get("context", None)
535
+
536
+ # Request balanced review
537
+ tool_result = self.review_protocol.request_review(
538
+ focus=focus,
539
+ work_description=work_description,
540
+ code_snippets=code_snippets,
541
+ file_paths=file_paths,
542
+ context=context
543
+ )
544
+ except Exception as e:
545
+ tool_result = f"Error processing review: {str(e)}"
448
546
  else:
449
547
  try:
450
548
  tool_result = await tool.call(