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.
- hanzo_mcp/__init__.py +1 -1
- hanzo_mcp/cli.py +32 -0
- hanzo_mcp/dev_server.py +246 -0
- hanzo_mcp/prompts/__init__.py +1 -1
- hanzo_mcp/prompts/project_system.py +43 -7
- hanzo_mcp/server.py +5 -1
- hanzo_mcp/tools/__init__.py +168 -6
- hanzo_mcp/tools/agent/__init__.py +1 -1
- hanzo_mcp/tools/agent/agent.py +401 -0
- hanzo_mcp/tools/agent/agent_tool.py +3 -4
- hanzo_mcp/tools/common/__init__.py +1 -1
- hanzo_mcp/tools/common/base.py +9 -4
- hanzo_mcp/tools/common/batch_tool.py +3 -5
- hanzo_mcp/tools/common/config_tool.py +1 -1
- hanzo_mcp/tools/common/context.py +1 -1
- hanzo_mcp/tools/common/palette.py +344 -0
- hanzo_mcp/tools/common/palette_loader.py +108 -0
- hanzo_mcp/tools/common/stats.py +261 -0
- hanzo_mcp/tools/common/thinking_tool.py +3 -5
- hanzo_mcp/tools/common/tool_disable.py +144 -0
- hanzo_mcp/tools/common/tool_enable.py +182 -0
- hanzo_mcp/tools/common/tool_list.py +260 -0
- hanzo_mcp/tools/config/__init__.py +10 -0
- hanzo_mcp/tools/config/config_tool.py +212 -0
- hanzo_mcp/tools/config/index_config.py +176 -0
- hanzo_mcp/tools/config/palette_tool.py +166 -0
- hanzo_mcp/tools/database/__init__.py +71 -0
- hanzo_mcp/tools/database/database_manager.py +246 -0
- hanzo_mcp/tools/database/graph.py +482 -0
- hanzo_mcp/tools/database/graph_add.py +257 -0
- hanzo_mcp/tools/database/graph_query.py +536 -0
- hanzo_mcp/tools/database/graph_remove.py +267 -0
- hanzo_mcp/tools/database/graph_search.py +348 -0
- hanzo_mcp/tools/database/graph_stats.py +345 -0
- hanzo_mcp/tools/database/sql.py +411 -0
- hanzo_mcp/tools/database/sql_query.py +229 -0
- hanzo_mcp/tools/database/sql_search.py +296 -0
- hanzo_mcp/tools/database/sql_stats.py +254 -0
- hanzo_mcp/tools/editor/__init__.py +11 -0
- hanzo_mcp/tools/editor/neovim_command.py +272 -0
- hanzo_mcp/tools/editor/neovim_edit.py +290 -0
- hanzo_mcp/tools/editor/neovim_session.py +356 -0
- hanzo_mcp/tools/filesystem/__init__.py +52 -13
- hanzo_mcp/tools/filesystem/base.py +1 -1
- hanzo_mcp/tools/filesystem/batch_search.py +812 -0
- hanzo_mcp/tools/filesystem/content_replace.py +3 -5
- hanzo_mcp/tools/filesystem/diff.py +193 -0
- hanzo_mcp/tools/filesystem/directory_tree.py +3 -5
- hanzo_mcp/tools/filesystem/edit.py +3 -5
- hanzo_mcp/tools/filesystem/find.py +443 -0
- hanzo_mcp/tools/filesystem/find_files.py +348 -0
- hanzo_mcp/tools/filesystem/git_search.py +505 -0
- hanzo_mcp/tools/filesystem/grep.py +2 -2
- hanzo_mcp/tools/filesystem/multi_edit.py +3 -5
- hanzo_mcp/tools/filesystem/read.py +17 -5
- hanzo_mcp/tools/filesystem/{grep_ast_tool.py → symbols.py} +17 -27
- hanzo_mcp/tools/filesystem/symbols_unified.py +376 -0
- hanzo_mcp/tools/filesystem/tree.py +268 -0
- hanzo_mcp/tools/filesystem/unified_search.py +465 -443
- hanzo_mcp/tools/filesystem/unix_aliases.py +99 -0
- hanzo_mcp/tools/filesystem/watch.py +174 -0
- hanzo_mcp/tools/filesystem/write.py +3 -5
- hanzo_mcp/tools/jupyter/__init__.py +9 -12
- hanzo_mcp/tools/jupyter/base.py +1 -1
- hanzo_mcp/tools/jupyter/jupyter.py +326 -0
- hanzo_mcp/tools/jupyter/notebook_edit.py +3 -4
- hanzo_mcp/tools/jupyter/notebook_read.py +3 -5
- hanzo_mcp/tools/llm/__init__.py +31 -0
- hanzo_mcp/tools/llm/consensus_tool.py +351 -0
- hanzo_mcp/tools/llm/llm_manage.py +413 -0
- hanzo_mcp/tools/llm/llm_tool.py +346 -0
- hanzo_mcp/tools/llm/llm_unified.py +851 -0
- hanzo_mcp/tools/llm/provider_tools.py +412 -0
- hanzo_mcp/tools/mcp/__init__.py +15 -0
- hanzo_mcp/tools/mcp/mcp_add.py +263 -0
- hanzo_mcp/tools/mcp/mcp_remove.py +127 -0
- hanzo_mcp/tools/mcp/mcp_stats.py +165 -0
- hanzo_mcp/tools/mcp/mcp_unified.py +503 -0
- hanzo_mcp/tools/shell/__init__.py +21 -23
- hanzo_mcp/tools/shell/base.py +1 -1
- hanzo_mcp/tools/shell/base_process.py +303 -0
- hanzo_mcp/tools/shell/bash_unified.py +134 -0
- hanzo_mcp/tools/shell/logs.py +265 -0
- hanzo_mcp/tools/shell/npx.py +194 -0
- hanzo_mcp/tools/shell/npx_background.py +254 -0
- hanzo_mcp/tools/shell/npx_unified.py +101 -0
- hanzo_mcp/tools/shell/open.py +107 -0
- hanzo_mcp/tools/shell/pkill.py +262 -0
- hanzo_mcp/tools/shell/process_unified.py +131 -0
- hanzo_mcp/tools/shell/processes.py +279 -0
- hanzo_mcp/tools/shell/run_background.py +326 -0
- hanzo_mcp/tools/shell/run_command.py +3 -4
- hanzo_mcp/tools/shell/run_command_windows.py +3 -4
- hanzo_mcp/tools/shell/uvx.py +187 -0
- hanzo_mcp/tools/shell/uvx_background.py +249 -0
- hanzo_mcp/tools/shell/uvx_unified.py +101 -0
- hanzo_mcp/tools/todo/__init__.py +1 -1
- hanzo_mcp/tools/todo/base.py +1 -1
- hanzo_mcp/tools/todo/todo.py +265 -0
- hanzo_mcp/tools/todo/todo_read.py +3 -5
- hanzo_mcp/tools/todo/todo_write.py +3 -5
- hanzo_mcp/tools/vector/__init__.py +6 -1
- hanzo_mcp/tools/vector/git_ingester.py +3 -0
- hanzo_mcp/tools/vector/index_tool.py +358 -0
- hanzo_mcp/tools/vector/infinity_store.py +98 -0
- hanzo_mcp/tools/vector/project_manager.py +27 -5
- hanzo_mcp/tools/vector/vector.py +311 -0
- hanzo_mcp/tools/vector/vector_index.py +1 -1
- hanzo_mcp/tools/vector/vector_search.py +12 -7
- hanzo_mcp-0.6.1.dist-info/METADATA +336 -0
- hanzo_mcp-0.6.1.dist-info/RECORD +134 -0
- hanzo_mcp-0.6.1.dist-info/entry_points.txt +3 -0
- hanzo_mcp-0.5.1.dist-info/METADATA +0 -276
- hanzo_mcp-0.5.1.dist-info/RECORD +0 -68
- hanzo_mcp-0.5.1.dist-info/entry_points.txt +0 -2
- {hanzo_mcp-0.5.1.dist-info → hanzo_mcp-0.6.1.dist-info}/WHEEL +0 -0
- {hanzo_mcp-0.5.1.dist-info → hanzo_mcp-0.6.1.dist-info}/licenses/LICENSE +0 -0
- {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
|