hanzo-mcp 0.1.21__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.
@@ -0,0 +1,65 @@
1
+ """Thinking tool for Hanzo MCP.
2
+
3
+ This module provides a tool for Claude to engage in structured thinking
4
+ when performing complex multi-step operations or reasoning through policies.
5
+ Following the pattern described in Anthropic's "Claude Think Tool" article.
6
+ """
7
+
8
+ from typing import final
9
+
10
+ from mcp.server.fastmcp import Context as MCPContext
11
+ from mcp.server.fastmcp import FastMCP
12
+
13
+ from hanzo_mcp.tools.common.context import create_tool_context
14
+
15
+
16
+ @final
17
+ class ThinkingTool:
18
+ """Think tool for Hanzo MCP.
19
+
20
+ This class provides a "think" tool that enables Claude to engage in more structured
21
+ thinking when processing complex information or making multi-step decisions.
22
+ """
23
+
24
+ def __init__(self) -> None:
25
+ """Initialize the thinking tool."""
26
+ pass
27
+
28
+ def register_tools(self, mcp_server: FastMCP) -> None:
29
+ """Register thinking tools with the MCP server.
30
+
31
+ Args:
32
+ mcp_server: The FastMCP server instance
33
+ """
34
+
35
+ @mcp_server.tool()
36
+ async def think(thought: str, ctx: MCPContext) -> str:
37
+ """Use the tool to think about something.
38
+
39
+ It will not obtain new information or make any changes to the repository, but just log the thought. Use it when complex reasoning or brainstorming is needed. For example, if you explore the repo and discover the source of a bug, call this tool to brainstorm several unique ways of fixing the bug, and assess which change(s) are likely to be simplest and most effective. Alternatively, if you receive some test results, call this tool to brainstorm ways to fix the failing tests.
40
+
41
+ Args:
42
+ thought: Your thoughts or analysis
43
+
44
+ Returns:
45
+ Confirmation that the thinking process has been recorded
46
+ """
47
+ tool_ctx = create_tool_context(ctx)
48
+ tool_ctx.set_tool_info("think")
49
+
50
+ # Validate required thought parameter
51
+ if not thought:
52
+ await tool_ctx.error(
53
+ "Parameter 'thought' is required but was None or empty"
54
+ )
55
+ return "Error: Parameter 'thought' is required but was None or empty"
56
+
57
+ if thought.strip() == "":
58
+ await tool_ctx.error("Parameter 'thought' cannot be empty")
59
+ return "Error: Parameter 'thought' cannot be empty"
60
+
61
+ # Log the thought but don't take action
62
+ await tool_ctx.info("Thinking process recorded")
63
+
64
+ # Return confirmation
65
+ return "I've recorded your thinking process. You can continue with your next action based on this analysis."
@@ -0,0 +1,124 @@
1
+ """Parameter validation utilities for Hanzo Dev MCP tools.
2
+
3
+ This module provides utilities for validating parameters in tool functions.
4
+ """
5
+
6
+ from typing import Any, TypeVar, final
7
+
8
+ T = TypeVar("T")
9
+
10
+
11
+ @final
12
+ class ValidationResult:
13
+ """Result of a parameter validation."""
14
+
15
+ def __init__(self, is_valid: bool, error_message: str = ""):
16
+ """Initialize a validation result.
17
+
18
+ Args:
19
+ is_valid: Whether the parameter is valid
20
+ error_message: Optional error message for invalid parameters
21
+ """
22
+ self.is_valid: bool = is_valid
23
+ self.error_message: str = error_message
24
+
25
+ @property
26
+ def is_error(self) -> bool:
27
+ """Check if the validation resulted in an error.
28
+
29
+ Returns:
30
+ True if there was a validation error, False otherwise
31
+ """
32
+ return not self.is_valid
33
+
34
+
35
+ def validate_parameter(
36
+ parameter: Any, parameter_name: str, allow_empty: bool = False
37
+ ) -> ValidationResult:
38
+ """Validate a single parameter.
39
+
40
+ Args:
41
+ parameter: The parameter value to validate
42
+ parameter_name: The name of the parameter (for error messages)
43
+ allow_empty: Whether to allow empty strings, lists, etc.
44
+
45
+ Returns:
46
+ A ValidationResult indicating whether the parameter is valid
47
+ """
48
+ # Check for None
49
+ if parameter is None:
50
+ return ValidationResult(
51
+ is_valid=False,
52
+ error_message=f"Parameter '{parameter_name}' is required but was None",
53
+ )
54
+
55
+ # Check for empty strings
56
+ if isinstance(parameter, str) and not allow_empty and parameter.strip() == "":
57
+ return ValidationResult(
58
+ is_valid=False,
59
+ error_message=f"Parameter '{parameter_name}' is required but was empty string",
60
+ )
61
+
62
+ # Check for empty collections
63
+ if (
64
+ isinstance(parameter, (list, tuple, dict, set))
65
+ and not allow_empty
66
+ and len(parameter) == 0
67
+ ):
68
+ return ValidationResult(
69
+ is_valid=False,
70
+ error_message=f"Parameter '{parameter_name}' is required but was empty {type(parameter).__name__}",
71
+ )
72
+
73
+ # Parameter is valid
74
+ return ValidationResult(is_valid=True)
75
+
76
+
77
+ def validate_path_parameter(
78
+ path: str | None, parameter_name: str = "path"
79
+ ) -> ValidationResult:
80
+ """Validate a path parameter.
81
+
82
+ Args:
83
+ path: The path parameter to validate
84
+ parameter_name: The name of the parameter (for error messages)
85
+
86
+ Returns:
87
+ A ValidationResult indicating whether the parameter is valid
88
+ """
89
+ # Check for None
90
+ if path is None:
91
+ return ValidationResult(
92
+ is_valid=False,
93
+ error_message=f"Path parameter '{parameter_name}' is required but was None",
94
+ )
95
+
96
+ # Check for empty path
97
+ if path.strip() == "":
98
+ return ValidationResult(
99
+ is_valid=False,
100
+ error_message=f"Path parameter '{parameter_name}' is required but was empty string",
101
+ )
102
+
103
+ # Path is valid
104
+ return ValidationResult(is_valid=True)
105
+
106
+
107
+ def validate_parameters(**kwargs: Any) -> ValidationResult:
108
+ """Validate multiple parameters.
109
+
110
+ Accepts keyword arguments where the key is the parameter name and the value is the parameter value.
111
+
112
+ Args:
113
+ **kwargs: Parameters to validate as name=value pairs
114
+
115
+ Returns:
116
+ A ValidationResult for the first invalid parameter, or a valid result if all are valid
117
+ """
118
+ for name, value in kwargs.items():
119
+ result = validate_parameter(value, name)
120
+ if result.is_error:
121
+ return result
122
+
123
+ # All parameters are valid
124
+ return ValidationResult(is_valid=True)
@@ -0,0 +1,9 @@
1
+ """Filesystem tools for Hanzo Dev MCP.
2
+
3
+ This module provides comprehensive tools for interacting with the filesystem,
4
+ including reading, writing, editing files, directory operations, and searching.
5
+ """
6
+
7
+ from hanzo_mcp.tools.filesystem.file_operations import FileOperations
8
+
9
+ __all__ = ["FileOperations"]