hanzo-mcp 0.5.1__py3-none-any.whl → 0.6.1__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 (118) hide show
  1. hanzo_mcp/__init__.py +1 -1
  2. hanzo_mcp/cli.py +32 -0
  3. hanzo_mcp/dev_server.py +246 -0
  4. hanzo_mcp/prompts/__init__.py +1 -1
  5. hanzo_mcp/prompts/project_system.py +43 -7
  6. hanzo_mcp/server.py +5 -1
  7. hanzo_mcp/tools/__init__.py +168 -6
  8. hanzo_mcp/tools/agent/__init__.py +1 -1
  9. hanzo_mcp/tools/agent/agent.py +401 -0
  10. hanzo_mcp/tools/agent/agent_tool.py +3 -4
  11. hanzo_mcp/tools/common/__init__.py +1 -1
  12. hanzo_mcp/tools/common/base.py +9 -4
  13. hanzo_mcp/tools/common/batch_tool.py +3 -5
  14. hanzo_mcp/tools/common/config_tool.py +1 -1
  15. hanzo_mcp/tools/common/context.py +1 -1
  16. hanzo_mcp/tools/common/palette.py +344 -0
  17. hanzo_mcp/tools/common/palette_loader.py +108 -0
  18. hanzo_mcp/tools/common/stats.py +261 -0
  19. hanzo_mcp/tools/common/thinking_tool.py +3 -5
  20. hanzo_mcp/tools/common/tool_disable.py +144 -0
  21. hanzo_mcp/tools/common/tool_enable.py +182 -0
  22. hanzo_mcp/tools/common/tool_list.py +260 -0
  23. hanzo_mcp/tools/config/__init__.py +10 -0
  24. hanzo_mcp/tools/config/config_tool.py +212 -0
  25. hanzo_mcp/tools/config/index_config.py +176 -0
  26. hanzo_mcp/tools/config/palette_tool.py +166 -0
  27. hanzo_mcp/tools/database/__init__.py +71 -0
  28. hanzo_mcp/tools/database/database_manager.py +246 -0
  29. hanzo_mcp/tools/database/graph.py +482 -0
  30. hanzo_mcp/tools/database/graph_add.py +257 -0
  31. hanzo_mcp/tools/database/graph_query.py +536 -0
  32. hanzo_mcp/tools/database/graph_remove.py +267 -0
  33. hanzo_mcp/tools/database/graph_search.py +348 -0
  34. hanzo_mcp/tools/database/graph_stats.py +345 -0
  35. hanzo_mcp/tools/database/sql.py +411 -0
  36. hanzo_mcp/tools/database/sql_query.py +229 -0
  37. hanzo_mcp/tools/database/sql_search.py +296 -0
  38. hanzo_mcp/tools/database/sql_stats.py +254 -0
  39. hanzo_mcp/tools/editor/__init__.py +11 -0
  40. hanzo_mcp/tools/editor/neovim_command.py +272 -0
  41. hanzo_mcp/tools/editor/neovim_edit.py +290 -0
  42. hanzo_mcp/tools/editor/neovim_session.py +356 -0
  43. hanzo_mcp/tools/filesystem/__init__.py +52 -13
  44. hanzo_mcp/tools/filesystem/base.py +1 -1
  45. hanzo_mcp/tools/filesystem/batch_search.py +812 -0
  46. hanzo_mcp/tools/filesystem/content_replace.py +3 -5
  47. hanzo_mcp/tools/filesystem/diff.py +193 -0
  48. hanzo_mcp/tools/filesystem/directory_tree.py +3 -5
  49. hanzo_mcp/tools/filesystem/edit.py +3 -5
  50. hanzo_mcp/tools/filesystem/find.py +443 -0
  51. hanzo_mcp/tools/filesystem/find_files.py +348 -0
  52. hanzo_mcp/tools/filesystem/git_search.py +505 -0
  53. hanzo_mcp/tools/filesystem/grep.py +2 -2
  54. hanzo_mcp/tools/filesystem/multi_edit.py +3 -5
  55. hanzo_mcp/tools/filesystem/read.py +17 -5
  56. hanzo_mcp/tools/filesystem/{grep_ast_tool.py → symbols.py} +17 -27
  57. hanzo_mcp/tools/filesystem/symbols_unified.py +376 -0
  58. hanzo_mcp/tools/filesystem/tree.py +268 -0
  59. hanzo_mcp/tools/filesystem/unified_search.py +465 -443
  60. hanzo_mcp/tools/filesystem/unix_aliases.py +99 -0
  61. hanzo_mcp/tools/filesystem/watch.py +174 -0
  62. hanzo_mcp/tools/filesystem/write.py +3 -5
  63. hanzo_mcp/tools/jupyter/__init__.py +9 -12
  64. hanzo_mcp/tools/jupyter/base.py +1 -1
  65. hanzo_mcp/tools/jupyter/jupyter.py +326 -0
  66. hanzo_mcp/tools/jupyter/notebook_edit.py +3 -4
  67. hanzo_mcp/tools/jupyter/notebook_read.py +3 -5
  68. hanzo_mcp/tools/llm/__init__.py +31 -0
  69. hanzo_mcp/tools/llm/consensus_tool.py +351 -0
  70. hanzo_mcp/tools/llm/llm_manage.py +413 -0
  71. hanzo_mcp/tools/llm/llm_tool.py +346 -0
  72. hanzo_mcp/tools/llm/llm_unified.py +851 -0
  73. hanzo_mcp/tools/llm/provider_tools.py +412 -0
  74. hanzo_mcp/tools/mcp/__init__.py +15 -0
  75. hanzo_mcp/tools/mcp/mcp_add.py +263 -0
  76. hanzo_mcp/tools/mcp/mcp_remove.py +127 -0
  77. hanzo_mcp/tools/mcp/mcp_stats.py +165 -0
  78. hanzo_mcp/tools/mcp/mcp_unified.py +503 -0
  79. hanzo_mcp/tools/shell/__init__.py +21 -23
  80. hanzo_mcp/tools/shell/base.py +1 -1
  81. hanzo_mcp/tools/shell/base_process.py +303 -0
  82. hanzo_mcp/tools/shell/bash_unified.py +134 -0
  83. hanzo_mcp/tools/shell/logs.py +265 -0
  84. hanzo_mcp/tools/shell/npx.py +194 -0
  85. hanzo_mcp/tools/shell/npx_background.py +254 -0
  86. hanzo_mcp/tools/shell/npx_unified.py +101 -0
  87. hanzo_mcp/tools/shell/open.py +107 -0
  88. hanzo_mcp/tools/shell/pkill.py +262 -0
  89. hanzo_mcp/tools/shell/process_unified.py +131 -0
  90. hanzo_mcp/tools/shell/processes.py +279 -0
  91. hanzo_mcp/tools/shell/run_background.py +326 -0
  92. hanzo_mcp/tools/shell/run_command.py +3 -4
  93. hanzo_mcp/tools/shell/run_command_windows.py +3 -4
  94. hanzo_mcp/tools/shell/uvx.py +187 -0
  95. hanzo_mcp/tools/shell/uvx_background.py +249 -0
  96. hanzo_mcp/tools/shell/uvx_unified.py +101 -0
  97. hanzo_mcp/tools/todo/__init__.py +1 -1
  98. hanzo_mcp/tools/todo/base.py +1 -1
  99. hanzo_mcp/tools/todo/todo.py +265 -0
  100. hanzo_mcp/tools/todo/todo_read.py +3 -5
  101. hanzo_mcp/tools/todo/todo_write.py +3 -5
  102. hanzo_mcp/tools/vector/__init__.py +6 -1
  103. hanzo_mcp/tools/vector/git_ingester.py +3 -0
  104. hanzo_mcp/tools/vector/index_tool.py +358 -0
  105. hanzo_mcp/tools/vector/infinity_store.py +98 -0
  106. hanzo_mcp/tools/vector/project_manager.py +27 -5
  107. hanzo_mcp/tools/vector/vector.py +311 -0
  108. hanzo_mcp/tools/vector/vector_index.py +1 -1
  109. hanzo_mcp/tools/vector/vector_search.py +12 -7
  110. hanzo_mcp-0.6.1.dist-info/METADATA +336 -0
  111. hanzo_mcp-0.6.1.dist-info/RECORD +134 -0
  112. hanzo_mcp-0.6.1.dist-info/entry_points.txt +3 -0
  113. hanzo_mcp-0.5.1.dist-info/METADATA +0 -276
  114. hanzo_mcp-0.5.1.dist-info/RECORD +0 -68
  115. hanzo_mcp-0.5.1.dist-info/entry_points.txt +0 -2
  116. {hanzo_mcp-0.5.1.dist-info → hanzo_mcp-0.6.1.dist-info}/WHEEL +0 -0
  117. {hanzo_mcp-0.5.1.dist-info → hanzo_mcp-0.6.1.dist-info}/licenses/LICENSE +0 -0
  118. {hanzo_mcp-0.5.1.dist-info → hanzo_mcp-0.6.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,127 @@
1
+ """Remove MCP servers."""
2
+
3
+ from typing import Annotated, TypedDict, Unpack, final, override
4
+
5
+ from mcp.server.fastmcp import Context as MCPContext
6
+ from pydantic import Field
7
+
8
+ from hanzo_mcp.tools.common.base import BaseTool
9
+ from hanzo_mcp.tools.common.context import create_tool_context
10
+ from hanzo_mcp.tools.mcp.mcp_add import McpAddTool
11
+
12
+
13
+ ServerName = Annotated[
14
+ str,
15
+ Field(
16
+ description="Name of the server to remove",
17
+ min_length=1,
18
+ ),
19
+ ]
20
+
21
+ Force = Annotated[
22
+ bool,
23
+ Field(
24
+ description="Force removal even if server is running",
25
+ default=False,
26
+ ),
27
+ ]
28
+
29
+
30
+ class McpRemoveParams(TypedDict, total=False):
31
+ """Parameters for MCP remove tool."""
32
+
33
+ name: str
34
+ force: bool
35
+
36
+
37
+ @final
38
+ class McpRemoveTool(BaseTool):
39
+ """Tool for removing MCP servers."""
40
+
41
+ def __init__(self):
42
+ """Initialize the MCP remove tool."""
43
+ pass
44
+
45
+ @property
46
+ @override
47
+ def name(self) -> str:
48
+ """Get the tool name."""
49
+ return "mcp_remove"
50
+
51
+ @property
52
+ @override
53
+ def description(self) -> str:
54
+ """Get the tool description."""
55
+ return """Remove previously added MCP servers.
56
+
57
+ This removes MCP servers that were added with mcp_add.
58
+ If the server is running, it will be stopped first.
59
+
60
+ Examples:
61
+ - mcp_remove --name filesystem
62
+ - mcp_remove --name github --force
63
+
64
+ Use 'mcp_stats' to see all servers before removing.
65
+ """
66
+
67
+ @override
68
+ async def call(
69
+ self,
70
+ ctx: MCPContext,
71
+ **params: Unpack[McpRemoveParams],
72
+ ) -> str:
73
+ """Remove an MCP server.
74
+
75
+ Args:
76
+ ctx: MCP context
77
+ **params: Tool parameters
78
+
79
+ Returns:
80
+ Result of removing the server
81
+ """
82
+ tool_ctx = create_tool_context(ctx)
83
+ await tool_ctx.set_tool_info(self.name)
84
+
85
+ # Extract parameters
86
+ name = params.get("name")
87
+ if not name:
88
+ return "Error: name is required"
89
+
90
+ force = params.get("force", False)
91
+
92
+ # Get current servers
93
+ servers = McpAddTool.get_servers()
94
+
95
+ if name not in servers:
96
+ return f"Error: Server '{name}' not found. Use 'mcp_stats' to see available servers."
97
+
98
+ server = servers[name]
99
+
100
+ await tool_ctx.info(f"Removing MCP server '{name}'")
101
+
102
+ # Check if server is running
103
+ if server.get("status") == "running" and server.get("process_id"):
104
+ if not force:
105
+ return f"Error: Server '{name}' is currently running. Use --force to remove anyway."
106
+ else:
107
+ # TODO: Stop the server process
108
+ await tool_ctx.info(f"Stopping running server '{name}'")
109
+
110
+ # Remove from registry
111
+ del McpAddTool._mcp_servers[name]
112
+ McpAddTool._save_servers()
113
+
114
+ output = [
115
+ f"Successfully removed MCP server '{name}'",
116
+ f" Type: {server.get('type', 'unknown')}",
117
+ f" Command: {' '.join(server.get('command', []))}",
118
+ ]
119
+
120
+ if server.get("tools"):
121
+ output.append(f" Tools removed: {len(server['tools'])}")
122
+
123
+ return "\n".join(output)
124
+
125
+ def register(self, mcp_server) -> None:
126
+ """Register this tool with the MCP server."""
127
+ pass
@@ -0,0 +1,165 @@
1
+ """MCP server statistics."""
2
+
3
+ import json
4
+ from typing import TypedDict, Unpack, final, override
5
+ from datetime import datetime
6
+
7
+ from mcp.server.fastmcp import Context as MCPContext
8
+
9
+ from hanzo_mcp.tools.common.base import BaseTool
10
+ from hanzo_mcp.tools.common.context import create_tool_context
11
+ from hanzo_mcp.tools.mcp.mcp_add import McpAddTool
12
+
13
+
14
+ class McpStatsParams(TypedDict, total=False):
15
+ """Parameters for MCP stats tool."""
16
+ pass
17
+
18
+
19
+ @final
20
+ class McpStatsTool(BaseTool):
21
+ """Tool for showing MCP server statistics."""
22
+
23
+ def __init__(self):
24
+ """Initialize the MCP stats tool."""
25
+ pass
26
+
27
+ @property
28
+ @override
29
+ def name(self) -> str:
30
+ """Get the tool name."""
31
+ return "mcp_stats"
32
+
33
+ @property
34
+ @override
35
+ def description(self) -> str:
36
+ """Get the tool description."""
37
+ return """Show statistics about added MCP servers.
38
+
39
+ Displays:
40
+ - Total number of servers
41
+ - Server types (Python, Node.js)
42
+ - Server status (running, stopped, error)
43
+ - Available tools from each server
44
+ - Resource usage per server
45
+
46
+ Example:
47
+ - mcp_stats
48
+ """
49
+
50
+ @override
51
+ async def call(
52
+ self,
53
+ ctx: MCPContext,
54
+ **params: Unpack[McpStatsParams],
55
+ ) -> str:
56
+ """Get MCP server statistics.
57
+
58
+ Args:
59
+ ctx: MCP context
60
+ **params: Tool parameters
61
+
62
+ Returns:
63
+ MCP server statistics
64
+ """
65
+ tool_ctx = create_tool_context(ctx)
66
+ await tool_ctx.set_tool_info(self.name)
67
+
68
+ # Get all servers
69
+ servers = McpAddTool.get_servers()
70
+
71
+ if not servers:
72
+ return "No MCP servers have been added yet.\n\nUse 'mcp_add' to add servers."
73
+
74
+ output = []
75
+ output.append("=== MCP Server Statistics ===")
76
+ output.append(f"Total Servers: {len(servers)}")
77
+ output.append("")
78
+
79
+ # Count by type
80
+ type_counts = {}
81
+ status_counts = {}
82
+ total_tools = 0
83
+ total_resources = 0
84
+
85
+ for server in servers.values():
86
+ # Count types
87
+ server_type = server.get("type", "unknown")
88
+ type_counts[server_type] = type_counts.get(server_type, 0) + 1
89
+
90
+ # Count status
91
+ status = server.get("status", "unknown")
92
+ status_counts[status] = status_counts.get(status, 0) + 1
93
+
94
+ # Count tools and resources
95
+ total_tools += len(server.get("tools", []))
96
+ total_resources += len(server.get("resources", []))
97
+
98
+ # Server types
99
+ output.append("Server Types:")
100
+ for stype, count in sorted(type_counts.items()):
101
+ output.append(f" {stype}: {count}")
102
+ output.append("")
103
+
104
+ # Server status
105
+ output.append("Server Status:")
106
+ for status, count in sorted(status_counts.items()):
107
+ output.append(f" {status}: {count}")
108
+ output.append("")
109
+
110
+ # Tools and resources
111
+ output.append(f"Total Tools Available: {total_tools}")
112
+ output.append(f"Total Resources Available: {total_resources}")
113
+ output.append("")
114
+
115
+ # Individual server details
116
+ output.append("=== Server Details ===")
117
+
118
+ for name, server in sorted(servers.items()):
119
+ output.append(f"\n{name}:")
120
+ output.append(f" Type: {server.get('type', 'unknown')}")
121
+ output.append(f" Status: {server.get('status', 'unknown')}")
122
+ output.append(f" Command: {' '.join(server.get('command', []))}")
123
+
124
+ if server.get("process_id"):
125
+ output.append(f" Process ID: {server['process_id']}")
126
+
127
+ if server.get("error"):
128
+ output.append(f" Error: {server['error']}")
129
+
130
+ tools = server.get("tools", [])
131
+ if tools:
132
+ output.append(f" Tools ({len(tools)}):")
133
+ for tool in tools[:5]: # Show first 5
134
+ output.append(f" - {tool}")
135
+ if len(tools) > 5:
136
+ output.append(f" ... and {len(tools) - 5} more")
137
+
138
+ resources = server.get("resources", [])
139
+ if resources:
140
+ output.append(f" Resources ({len(resources)}):")
141
+ for resource in resources[:5]: # Show first 5
142
+ output.append(f" - {resource}")
143
+ if len(resources) > 5:
144
+ output.append(f" ... and {len(resources) - 5} more")
145
+
146
+ if server.get("env"):
147
+ output.append(f" Environment vars: {list(server['env'].keys())}")
148
+
149
+ # Common MCP servers hint
150
+ output.append("\n=== Available MCP Servers ===")
151
+ output.append("Common servers you can add:")
152
+ output.append(" - @modelcontextprotocol/server-filesystem")
153
+ output.append(" - @modelcontextprotocol/server-github")
154
+ output.append(" - mcp-server-git")
155
+ output.append(" - @modelcontextprotocol/server-postgres")
156
+ output.append(" - @modelcontextprotocol/server-browser-use")
157
+ output.append(" - @modelcontextprotocol/server-iterm2")
158
+ output.append(" - @modelcontextprotocol/server-linear")
159
+ output.append(" - @modelcontextprotocol/server-slack")
160
+
161
+ return "\n".join(output)
162
+
163
+ def register(self, mcp_server) -> None:
164
+ """Register this tool with the MCP server."""
165
+ pass