hanzo-mcp 0.1.21__py3-none-any.whl → 0.1.25__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 CHANGED
@@ -1,3 +1,3 @@
1
1
  """Hanzo MCP - Implementation of Hanzo Platform capabilities using MCP."""
2
2
 
3
- __version__ = "0.1.8"
3
+ __version__ = "0.1.22"
hanzo_mcp/cli.py CHANGED
@@ -7,11 +7,11 @@ import sys
7
7
  from pathlib import Path
8
8
  from typing import Any, cast
9
9
 
10
- from hanzo_mcp.server import HanzoDevServer
10
+ from hanzo_mcp.server import HanzoMCPServer
11
11
 
12
12
 
13
13
  def main() -> None:
14
- """Run the CLI for the Hanzo Dev MCP server."""
14
+ """Run the CLI for the Hanzo MCP server."""
15
15
  parser = argparse.ArgumentParser(
16
16
  description="MCP server for accessing Hanzo APIs and Platform capabilities"
17
17
  )
@@ -70,7 +70,7 @@ def main() -> None:
70
70
  allowed_paths.append(project_dir)
71
71
 
72
72
  # Run the server
73
- server = HanzoDevServer(name=name, allowed_paths=allowed_paths)
73
+ server = HanzoMCPServer(name=name, allowed_paths=allowed_paths)
74
74
  # Transport will be automatically cast to Literal['stdio', 'sse'] by the server
75
75
  server.run(transport=transport)
76
76
 
hanzo_mcp/server.py CHANGED
@@ -12,7 +12,7 @@ from hanzo_mcp.tools.shell.command_executor import CommandExecutor
12
12
 
13
13
 
14
14
  @final
15
- class HanzoDevServer:
15
+ class HanzoMCPServer:
16
16
  """MCP server for accessing Hanzo APIs and Platform capabilities."""
17
17
 
18
18
  def __init__(
@@ -21,7 +21,7 @@ class HanzoDevServer:
21
21
  allowed_paths: list[str] | None = None,
22
22
  mcp_instance: FastMCP | None = None,
23
23
  ):
24
- """Initialize the Hanzo Dev server.
24
+ """Initialize the Hanzo server.
25
25
 
26
26
  Args:
27
27
  name: The name of the server
@@ -117,7 +117,7 @@ def main():
117
117
  allowed_paths: list[str] | None = args.allowed_paths
118
118
 
119
119
  # Create and run the server
120
- server = HanzoDevServer(name=name, allowed_paths=allowed_paths)
120
+ server = HanzoMCPServer(name=name, allowed_paths=allowed_paths)
121
121
  server.run(transport=transport, allowed_paths=allowed_paths or [])
122
122
 
123
123
 
@@ -1 +1 @@
1
- """Common utilities for Hanzo Dev MCP tools."""
1
+ """Common utilities for Hanzo MCP tools."""
@@ -1,4 +1,4 @@
1
- """Enhanced Context for Hanzo Dev MCP tools.
1
+ """Enhanced Context for Hanzo MCP tools.
2
2
 
3
3
  This module provides an enhanced Context class that wraps the MCP Context
4
4
  and adds additional functionality specific to Claude Code tools.
@@ -17,7 +17,7 @@ from mcp.server.lowlevel.helper_types import ReadResourceContents
17
17
 
18
18
  @final
19
19
  class ToolContext:
20
- """Enhanced context for Hanzo Dev MCP tools.
20
+ """Enhanced context for Hanzo MCP tools.
21
21
 
22
22
  This class wraps the MCP Context and adds additional functionality
23
23
  for tracking tool execution, progress reporting, and resource access.
@@ -1,4 +1,4 @@
1
- """Permission system for the Hanzo Dev MCP server."""
1
+ """Permission system for the Hanzo MCP server."""
2
2
 
3
3
  import json
4
4
  import os
@@ -11,29 +11,65 @@ T = TypeVar("T")
11
11
  P = TypeVar("P")
12
12
 
13
13
 
14
+ def normalize_path(path: str) -> Path:
15
+ """Normalize a path with proper user directory expansion.
16
+
17
+ This utility function handles path normalization with proper handling of
18
+ tilde (~) for home directory expansion and ensures consistent path handling
19
+ across the application.
20
+
21
+ Args:
22
+ path: The path to normalize (can include ~ for home directory)
23
+
24
+ Returns:
25
+ A normalized Path object with user directories expanded and resolved to
26
+ its absolute canonical form.
27
+ """
28
+ # Expand the user directory, handling the tilde (~) if present.
29
+ expanded_path = os.path.expanduser(path)
30
+ # Resolve the expanded path to its absolute form.
31
+ resolved_path = Path(expanded_path).resolve()
32
+ return resolved_path
33
+
34
+
14
35
  @final
15
36
  class PermissionManager:
16
- """Manages permissions for file and command operations."""
37
+ """Manages permissions for file and command operations.
38
+
39
+ This class is responsible for tracking allowed file system paths as well as
40
+ paths and patterns that should be excluded from permitted operations.
41
+ """
17
42
 
18
43
  def __init__(self) -> None:
19
- """Initialize the permission manager."""
20
- # Allowed paths
44
+ """Initialize the permission manager with default allowed and excluded paths.
45
+
46
+ Allowed paths are those where operations (read, write, execute, etc.) are permitted,
47
+ while excluded paths and patterns represent paths and file patterns that are sensitive
48
+ and should be disallowed.
49
+ """
50
+ # Allowed paths: operations are permitted on these paths.
21
51
  self.allowed_paths: set[Path] = set(
22
52
  [Path("/tmp").resolve(), Path("/var").resolve()]
23
53
  )
24
54
 
25
- # Excluded paths
55
+ # Excluded paths: specific paths that are explicitly disallowed.
26
56
  self.excluded_paths: set[Path] = set()
57
+
58
+ # Excluded patterns: patterns for sensitive directories and file names.
27
59
  self.excluded_patterns: list[str] = []
28
60
 
29
- # Default excluded patterns
61
+ # Add default exclusions for sensitive files and directories.
30
62
  self._add_default_exclusions()
31
63
 
32
64
  def _add_default_exclusions(self) -> None:
33
- """Add default exclusions for sensitive files and directories."""
34
- # Sensitive directories
65
+ """Add default exclusions for sensitive files and directories.
66
+
67
+ This method populates the excluded_patterns list with common sensitive
68
+ directories (e.g., .ssh, .gnupg) and file patterns (e.g., *.key, *.log)
69
+ that should be excluded from allowed operations.
70
+ """
71
+ # Sensitive directories (Note: .git is allowed by default)
35
72
  sensitive_dirs: list[str] = [
36
- # ".git" is now allowed by default
37
73
  ".ssh",
38
74
  ".gnupg",
39
75
  ".config",
@@ -64,59 +100,64 @@ class PermissionManager:
64
100
  self.excluded_patterns.extend(sensitive_patterns)
65
101
 
66
102
  def add_allowed_path(self, path: str) -> None:
67
- """Add a path to the allowed paths.
103
+ """Add a new path to the allowed paths.
68
104
 
69
105
  Args:
70
- path: The path to allow
106
+ path: The file system path to add to the allowed list.
71
107
  """
72
- resolved_path: Path = Path(path).resolve()
108
+ resolved_path: Path = normalize_path(path)
73
109
  self.allowed_paths.add(resolved_path)
74
110
 
75
111
  def remove_allowed_path(self, path: str) -> None:
76
112
  """Remove a path from the allowed paths.
77
113
 
78
114
  Args:
79
- path: The path to remove
115
+ path: The file system path to remove from the allowed list.
80
116
  """
81
- resolved_path: Path = Path(path).resolve()
117
+ resolved_path: Path = normalize_path(path)
82
118
  if resolved_path in self.allowed_paths:
83
119
  self.allowed_paths.remove(resolved_path)
84
120
 
85
121
  def exclude_path(self, path: str) -> None:
86
- """Exclude a path from allowed operations.
122
+ """Add a path to the exclusion list.
87
123
 
88
124
  Args:
89
- path: The path to exclude
125
+ path: The file system path to explicitly exclude from operations.
90
126
  """
91
- resolved_path: Path = Path(path).resolve()
127
+ resolved_path: Path = normalize_path(path)
92
128
  self.excluded_paths.add(resolved_path)
93
129
 
94
130
  def add_exclusion_pattern(self, pattern: str) -> None:
95
- """Add an exclusion pattern.
131
+ """Add a new exclusion pattern.
96
132
 
97
133
  Args:
98
- pattern: The pattern to exclude
134
+ pattern: A string pattern that matches file or directory names to exclude.
99
135
  """
100
136
  self.excluded_patterns.append(pattern)
101
137
 
102
138
  def is_path_allowed(self, path: str) -> bool:
103
- """Check if a path is allowed.
139
+ """Determine if a given path is allowed for operations.
140
+
141
+ The method normalizes the input path and then checks it against the list
142
+ of excluded paths and patterns. If the path is not excluded and is a
143
+ subpath of one of the allowed base paths, the method returns True.
104
144
 
105
145
  Args:
106
- path: The path to check
146
+ path: The file system path to check.
107
147
 
108
148
  Returns:
109
- True if the path is allowed, False otherwise
149
+ True if the path is allowed for operations, False otherwise.
110
150
  """
111
- resolved_path: Path = Path(path).resolve()
151
+ resolved_path: Path = normalize_path(path)
112
152
 
113
- # Check exclusions first
153
+ # First, check if the path matches any excluded paths or patterns.
114
154
  if self._is_path_excluded(resolved_path):
115
155
  return False
116
156
 
117
- # Check if the path is within any allowed path
157
+ # Check if the normalized path is within any allowed path.
118
158
  for allowed_path in self.allowed_paths:
119
159
  try:
160
+ # relative_to will succeed if resolved_path is a subpath of allowed_path.
120
161
  resolved_path.relative_to(allowed_path)
121
162
  return True
122
163
  except ValueError:
@@ -125,63 +166,74 @@ class PermissionManager:
125
166
  return False
126
167
 
127
168
  def _is_path_excluded(self, path: Path) -> bool:
128
- """Check if a path is excluded.
169
+ """Determine if a normalized path should be excluded.
170
+
171
+ The method checks two conditions:
172
+ 1. If the path exactly matches an entry in the excluded_paths set.
173
+ 2. If the path string contains any of the excluded patterns, either as a
174
+ suffix for wildcard patterns (e.g., "*.log") or as an exact match
175
+ within any of the path's components.
129
176
 
130
177
  Args:
131
- path: The path to check
178
+ path: The normalized path to check.
132
179
 
133
180
  Returns:
134
- True if the path is excluded, False otherwise
181
+ True if the path is excluded, False otherwise.
135
182
  """
136
-
137
- # Check exact excluded paths
183
+ # Direct match: Check if the path is in the explicitly excluded paths set.
138
184
  if path in self.excluded_paths:
139
185
  return True
140
186
 
141
- # Check excluded patterns
187
+ # Convert the path to a string for pattern matching.
142
188
  path_str: str = str(path)
143
189
 
144
- # Get path parts to check for exact directory/file name matches
190
+ # Split the path into its individual components (directories and file name).
145
191
  path_parts = path_str.split(os.sep)
146
192
 
193
+ # Iterate over each exclusion pattern to see if it matches.
147
194
  for pattern in self.excluded_patterns:
148
- # Handle wildcard patterns (e.g., "*.log")
195
+ # If the pattern starts with a wildcard, perform a suffix match.
149
196
  if pattern.startswith("*"):
150
197
  if path_str.endswith(pattern[1:]):
151
198
  return True
152
199
  else:
153
- # For non-wildcard patterns, check if any path component matches exactly
200
+ # For non-wildcard patterns, check if any path component exactly matches the pattern.
154
201
  if pattern in path_parts:
155
202
  return True
156
203
 
157
204
  return False
158
205
 
159
206
  def to_json(self) -> str:
160
- """Convert the permission manager to a JSON string.
207
+ """Serialize the permission manager's configuration to a JSON string.
208
+
209
+ The JSON representation includes the allowed paths, excluded paths, and
210
+ excluded patterns, which can be used to restore the configuration later.
161
211
 
162
212
  Returns:
163
- A JSON string representation of the permission manager
213
+ A JSON string representing the current state of the permission manager.
164
214
  """
165
215
  data: dict[str, Any] = {
166
216
  "allowed_paths": [str(p) for p in self.allowed_paths],
167
217
  "excluded_paths": [str(p) for p in self.excluded_paths],
168
218
  "excluded_patterns": self.excluded_patterns,
169
219
  }
170
-
171
220
  return json.dumps(data)
172
221
 
173
222
  @classmethod
174
223
  def from_json(cls, json_str: str) -> "PermissionManager":
175
- """Create a permission manager from a JSON string.
224
+ """Create a PermissionManager instance from a JSON string.
225
+
226
+ The JSON string should represent a configuration with allowed paths,
227
+ excluded paths, and exclusion patterns. This method rehydrates the state
228
+ accordingly.
176
229
 
177
230
  Args:
178
- json_str: The JSON string
231
+ json_str: The JSON string containing the permission manager configuration.
179
232
 
180
233
  Returns:
181
- A new PermissionManager instance
234
+ A new PermissionManager instance with configuration loaded from the JSON string.
182
235
  """
183
236
  data: dict[str, Any] = json.loads(json_str)
184
-
185
237
  manager = cls()
186
238
 
187
239
  for path in data.get("allowed_paths", []):
@@ -191,12 +243,16 @@ class PermissionManager:
191
243
  manager.exclude_path(path)
192
244
 
193
245
  manager.excluded_patterns = data.get("excluded_patterns", [])
194
-
195
246
  return manager
196
247
 
197
248
 
198
249
  class PermissibleOperation:
199
- """A decorator for operations that require permission."""
250
+ """A decorator for operations that require permission checks.
251
+
252
+ This decorator uses a PermissionManager instance to enforce that a given
253
+ operation (e.g., read, write, execute) is permitted on a provided file system
254
+ path before allowing the decorated function to execute.
255
+ """
200
256
 
201
257
  def __init__(
202
258
  self,
@@ -204,50 +260,54 @@ class PermissibleOperation:
204
260
  operation: str,
205
261
  get_path_fn: Callable[[list[Any], dict[str, Any]], str] | None = None,
206
262
  ) -> None:
207
- """Initialize the permissible operation.
263
+ """Initialize the PermissibleOperation decorator.
208
264
 
209
265
  Args:
210
- permission_manager: The permission manager
211
- operation: The operation type (read, write, execute, etc.)
212
- get_path_fn: Optional function to extract the path from args and kwargs
266
+ permission_manager: The PermissionManager instance used for permission checks.
267
+ operation: A string representing the operation type (e.g., 'read', 'write').
268
+ get_path_fn: Optional function to extract the file system path from the function's
269
+ arguments. If not provided, defaults to using the first positional argument
270
+ or the first value from keyword arguments.
213
271
  """
214
272
  self.permission_manager: PermissionManager = permission_manager
215
273
  self.operation: str = operation
216
- self.get_path_fn: Callable[[list[Any], dict[str, Any]], str] | None = (
217
- get_path_fn
218
- )
274
+ self.get_path_fn: Callable[[list[Any], dict[str, Any]], str] | None = get_path_fn
219
275
 
220
276
  def __call__(
221
277
  self, func: Callable[..., Awaitable[T]]
222
278
  ) -> Callable[..., Awaitable[T]]:
223
- """Decorate the function.
279
+ """Decorate the function to enforce permission checks before execution.
280
+
281
+ This method wraps the original asynchronous function, extracting a file system path
282
+ from its arguments and using the PermissionManager to verify if the specified operation
283
+ is allowed on that path. If permission is denied, a PermissionError is raised.
224
284
 
225
285
  Args:
226
- func: The function to decorate
286
+ func: The asynchronous function to decorate.
227
287
 
228
288
  Returns:
229
- The decorated function
289
+ An asynchronous function that includes permission checks prior to calling the original function.
230
290
  """
231
-
232
291
  async def wrapper(*args: Any, **kwargs: Any) -> T:
233
- # Extract the path
292
+ # Extract the file system path using the provided get_path_fn if available.
234
293
  if self.get_path_fn:
235
- # Pass args as a list and kwargs as a dict to the path function
236
294
  path = self.get_path_fn(list(args), kwargs)
237
295
  else:
238
- # Default to first argument
296
+ # Default extraction: use the first positional argument if available,
297
+ # otherwise use the first keyword argument value.
239
298
  path = args[0] if args else next(iter(kwargs.values()), None)
240
299
 
300
+ # Ensure that the extracted path is a string.
241
301
  if not isinstance(path, str):
242
- raise ValueError(f"Invalid path type: {type(path)}")
302
+ raise ValueError(f"Invalid path type: {type(path)}. Expected a string.")
243
303
 
244
- # Check permission
304
+ # Check if the operation is allowed on the specified path.
245
305
  if not self.permission_manager.is_path_allowed(path):
246
306
  raise PermissionError(
247
307
  f"Operation '{self.operation}' not allowed for path: {path}"
248
308
  )
249
309
 
250
- # Call the function
310
+ # Execute the original function if the permission check passes.
251
311
  return await func(*args, **kwargs)
252
312
 
253
313
  return wrapper
@@ -1,4 +1,4 @@
1
- """Parameter validation utilities for Hanzo Dev MCP tools.
1
+ """Parameter validation utilities for Hanzo MCP tools.
2
2
 
3
3
  This module provides utilities for validating parameters in tool functions.
4
4
  """
@@ -1,4 +1,4 @@
1
- """Filesystem tools for Hanzo Dev MCP.
1
+ """Filesystem tools for Hanzo MCP.
2
2
 
3
3
  This module provides comprehensive tools for interacting with the filesystem,
4
4
  including reading, writing, editing files, directory operations, and searching.
@@ -1,4 +1,4 @@
1
- """Filesystem operations tools for Hanzo Dev MCP.
1
+ """Filesystem operations tools for Hanzo MCP.
2
2
 
3
3
  This module provides comprehensive tools for interacting with the filesystem,
4
4
  including reading, writing, editing files, directory operations, and searching.
@@ -20,7 +20,7 @@ from hanzo_mcp.tools.common.validation import validate_path_parameter
20
20
 
21
21
  @final
22
22
  class FileOperations:
23
- """File and filesystem operations tools for Hanzo Dev MCP."""
23
+ """File and filesystem operations tools for Hanzo MCP."""
24
24
 
25
25
  def __init__(
26
26
  self, document_context: DocumentContext, permission_manager: PermissionManager
@@ -1,4 +1,4 @@
1
- """Jupyter notebook tools for Hanzo Dev MCP.
1
+ """Jupyter notebook tools for Hanzo MCP.
2
2
 
3
3
  This module provides tools for reading and editing Jupyter notebooks (.ipynb files).
4
4
  """
@@ -1,4 +1,4 @@
1
- """Jupyter notebook operations tools for Hanzo Dev MCP.
1
+ """Jupyter notebook operations tools for Hanzo MCP.
2
2
 
3
3
  This module provides tools for reading and editing Jupyter notebook (.ipynb) files.
4
4
  It supports reading notebook cells with their outputs and modifying notebook contents.
@@ -1 +1 @@
1
- """Project analysis and management tools for Hanzo Dev MCP."""
1
+ """Project analysis and management tools for Hanzo MCP."""
@@ -1,4 +1,4 @@
1
- """Project analysis tools for Hanzo Dev MCP.
1
+ """Project analysis tools for Hanzo MCP.
2
2
 
3
3
  This module provides tools for analyzing project structure and dependencies.
4
4
  """
@@ -84,7 +84,7 @@ print(json.dumps(result))
84
84
 
85
85
  # Execute script
86
86
  result = await self.command_executor.execute_script_from_file(
87
- script=script, language="python", cwd=project_dir, timeout=30.0
87
+ script=script, language="python", cwd=project_dir, timeout=600.0
88
88
  )
89
89
  code, stdout, stderr = result.return_code, result.stdout, result.stderr
90
90
 
@@ -204,7 +204,7 @@ try {
204
204
 
205
205
  # Execute script
206
206
  result = await self.command_executor.execute_script_from_file(
207
- script=script, language="javascript", cwd=project_dir, timeout=30.0
207
+ script=script, language="javascript", cwd=project_dir, timeout=600.0
208
208
  )
209
209
  code, stdout, stderr = result.return_code, result.stdout, result.stderr
210
210
 
@@ -286,7 +286,7 @@ print(json.dumps(result))
286
286
 
287
287
  # Execute script
288
288
  result = await self.command_executor.execute_script_from_file(
289
- script=script, language="python", cwd=project_dir, timeout=30.0
289
+ script=script, language="python", cwd=project_dir, timeout=600.0
290
290
  )
291
291
  code, stdout, stderr = result.return_code, result.stdout, result.stderr
292
292
 
@@ -795,7 +795,7 @@ class ProjectManager:
795
795
 
796
796
  @final
797
797
  class ProjectAnalysis:
798
- """Project analysis tools for Hanzo Dev MCP."""
798
+ """Project analysis tools for Hanzo MCP."""
799
799
 
800
800
  def __init__(
801
801
  self,
@@ -1 +1 @@
1
- """Shell and command execution tools for Hanzo Dev MCP."""
1
+ """Shell and command execution tools for Hanzo MCP."""
@@ -1,4 +1,4 @@
1
- """Command executor tools for Hanzo Dev MCP.
1
+ """Command executor tools for Hanzo MCP.
2
2
 
3
3
  This module provides tools for executing shell commands and scripts with
4
4
  comprehensive error handling, permissions checking, and progress tracking.
@@ -86,7 +86,7 @@ class CommandResult:
86
86
 
87
87
  @final
88
88
  class CommandExecutor:
89
- """Command executor tools for Hanzo Dev MCP.
89
+ """Command executor tools for Hanzo MCP.
90
90
 
91
91
  This class provides tools for executing shell commands and scripts with
92
92
  comprehensive error handling, permissions checking, and progress tracking.
@@ -193,7 +193,7 @@ class CommandExecutor:
193
193
  command: str,
194
194
  cwd: str | None = None,
195
195
  env: dict[str, str] | None = None,
196
- timeout: float | None = 60.0,
196
+ timeout: float | None = 600.0,
197
197
  use_login_shell: bool = True,
198
198
  ) -> CommandResult:
199
199
  """Execute a shell command with safety checks.
@@ -320,7 +320,7 @@ class CommandExecutor:
320
320
  interpreter: str = "bash",
321
321
  cwd: str | None = None,
322
322
  env: dict[str, str] | None = None,
323
- timeout: float | None = 60.0,
323
+ timeout: float | None = 600.0,
324
324
  use_login_shell: bool = True,
325
325
  ) -> CommandResult:
326
326
  """Execute a script with the specified interpreter.
@@ -368,7 +368,7 @@ class CommandExecutor:
368
368
  script: str,
369
369
  cwd: str | None = None,
370
370
  env: dict[str, str] | None = None,
371
- timeout: float | None = 60.0,
371
+ timeout: float | None = 600.0,
372
372
  use_login_shell: bool = True,
373
373
  ) -> CommandResult:
374
374
  """Execute a script by passing it to stdin of the interpreter.
@@ -458,7 +458,7 @@ class CommandExecutor:
458
458
  script: str,
459
459
  cwd: str | None = None,
460
460
  env: dict[str, str] | None = None,
461
- timeout: float | None = 60.0,
461
+ timeout: float | None = 600.0,
462
462
  ) -> CommandResult:
463
463
  """Special handler for Fish shell scripts.
464
464
 
@@ -533,7 +533,7 @@ class CommandExecutor:
533
533
  language: str,
534
534
  cwd: str | None = None,
535
535
  env: dict[str, str] | None = None,
536
- timeout: float | None = 60.0,
536
+ timeout: float | None = 600.0,
537
537
  args: list[str] | None = None,
538
538
  use_login_shell: bool = True,
539
539
  ) -> CommandResult:
@@ -773,7 +773,7 @@ class CommandExecutor:
773
773
 
774
774
  # Execute the command
775
775
  result: CommandResult = await self.execute_command(
776
- command, cwd=cwd, timeout=30.0, use_login_shell=use_login_shell
776
+ command, cwd=cwd, timeout=600.0, use_login_shell=use_login_shell
777
777
  )
778
778
 
779
779
  # Report result
@@ -869,7 +869,7 @@ class CommandExecutor:
869
869
  script=script,
870
870
  interpreter=interpreter,
871
871
  cwd=cwd, # cwd is now a required parameter
872
- timeout=30.0,
872
+ timeout=600.0,
873
873
  use_login_shell=use_login_shell,
874
874
  )
875
875
 
@@ -974,7 +974,7 @@ class CommandExecutor:
974
974
  script=script,
975
975
  language=language,
976
976
  cwd=cwd, # cwd is now a required parameter
977
- timeout=30.0,
977
+ timeout=600.0,
978
978
  args=args,
979
979
  use_login_shell=use_login_shell,
980
980
  )
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hanzo-mcp
3
- Version: 0.1.21
3
+ Version: 0.1.25
4
4
  Summary: MCP server for accessing Hanzo APIs and Platform capabilities
5
- Author-email: Hanzo Dev <dev@hanzo.ai>
5
+ Author-email: Hanzo <dev@hanzo.ai>
6
6
  License: MIT
7
7
  Classifier: Programming Language :: Python :: 3
8
8
  Classifier: License :: OSI Approved :: MIT License
@@ -0,0 +1,24 @@
1
+ hanzo_mcp/__init__.py,sha256=MVDDvQWI8u1vdS9ynXjVvUoex3vbcRufg-NmZVPO1og,99
2
+ hanzo_mcp/cli.py,sha256=4hj3qRecA6tafsCeKSVDhT1TP4YNfZxWxeMQ8z8P4m0,4743
3
+ hanzo_mcp/server.py,sha256=Dk3IdFGAeu2qKZLeOlgE1rHjeCzRjiCkccDLsxXAXAg,4035
4
+ hanzo_mcp/tools/__init__.py,sha256=IsjWWWAIQW4e490k3RI2YLQ46ZvDfcttqZ0SCcC6aps,2507
5
+ hanzo_mcp/tools/common/__init__.py,sha256=p14VhL-SwjJxWKmAWB7Sze5ovJlNKVK_NAUplbuECTY,44
6
+ hanzo_mcp/tools/common/context.py,sha256=pv_oJ5aJM6YyOiKjAKU0LHZCQZQEvKRvh_9zOiQMSIw,12941
7
+ hanzo_mcp/tools/common/permissions.py,sha256=WL-cj2RTmjrwPlcwaQtOV5W-nZeKg2P8sboJHQ6b5fM,11710
8
+ hanzo_mcp/tools/common/thinking.py,sha256=0PRBTm8i8u0KBKfNaDasNSCn_R9kmFrAS3retEj_0J4,2630
9
+ hanzo_mcp/tools/common/validation.py,sha256=gB3uM_cbPZsH4Ez0hnTgIcdP-AUlHZU02aRmZEpk_6I,3648
10
+ hanzo_mcp/tools/filesystem/__init__.py,sha256=_J-n7elOW4zgVpnIm8nMV4AupmYudTF9gdkn1S40RAI,299
11
+ hanzo_mcp/tools/filesystem/file_operations.py,sha256=9SY8A5GzcH8u_yMCzDvWFoWSRRBlJj-i3HfcPuk5md8,46174
12
+ hanzo_mcp/tools/jupyter/__init__.py,sha256=H8t37ams4utRgVl-7RFi1lQFSdTJP6DdpkCVo3qVifI,245
13
+ hanzo_mcp/tools/jupyter/notebook_operations.py,sha256=Vzu4anFoGKHcdGuIk20mtiZVTyKx9HIhe3HKYocq0w8,23335
14
+ hanzo_mcp/tools/project/__init__.py,sha256=4V60vR_ZP1eEuMtH-JR1ADi5sIKHbeh93fPu5ANPhQ4,59
15
+ hanzo_mcp/tools/project/analysis.py,sha256=P0plRYwY6trb6ZGkJEA1bPOpdEayRd1hEKwU2EBBuOI,30361
16
+ hanzo_mcp/tools/shell/__init__.py,sha256=m9dH7LhiDpYU1AD6lwKPGD0E_a7MId2rAb9sGoJNeLM,55
17
+ hanzo_mcp/tools/shell/command_executor.py,sha256=4iBf3FmSljG6QEOXUjrO_4isUv9aWCTQKfE08PbQLlk,37401
18
+ hanzo_mcp-0.1.25.dist-info/licenses/LICENSE,sha256=dvWmlLGUAkNE8EJVn-UQ-F08hxW5jtjUWNe51OaH7IE,1077
19
+ hanzo_mcp-0.1.25.dist-info/METADATA,sha256=IRoZBImDFuOQh9pHq_gYlrupLTnu9s55TiDTcI4QfSk,7090
20
+ hanzo_mcp-0.1.25.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
21
+ hanzo_mcp-0.1.25.dist-info/entry_points.txt,sha256=aRKOKXtuQr-idSr-yH4efnRl2v8te94AcgN3ysqqSYs,49
22
+ hanzo_mcp-0.1.25.dist-info/top_level.txt,sha256=eGFANatA0MHWiVlpS56fTYRIShtibrSom1uXI6XU0GU,10
23
+ hanzo_mcp-0.1.25.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
24
+ hanzo_mcp-0.1.25.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.3)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1 @@
1
+
@@ -1,23 +0,0 @@
1
- hanzo_mcp/__init__.py,sha256=b9ZjldZaFEU7nk4qZ6WCjl0fChLTeK18USOW84f7DXQ,98
2
- hanzo_mcp/cli.py,sha256=vDB-5trIp-tfKwRXosWVZGBNTZAo_B7wTCoF-NVaLKc,4747
3
- hanzo_mcp/server.py,sha256=p7-0B99gSfC5ieyOGt7xJ233ddCw1FY9dZDujaHarLU,4039
4
- hanzo_mcp/tools/__init__.py,sha256=IsjWWWAIQW4e490k3RI2YLQ46ZvDfcttqZ0SCcC6aps,2507
5
- hanzo_mcp/tools/common/__init__.py,sha256=mUlTy1Py8zV-DBEhkds-DoB2zHOxDZnbnOo3WFHP7ro,48
6
- hanzo_mcp/tools/common/context.py,sha256=BuuuHDQqzmO8LaWPcdgj8Md4FHT2gGuWIo8mN7fMIOY,12949
7
- hanzo_mcp/tools/common/permissions.py,sha256=HHH3MM-4dTufJ0HYv6M5yDJHJJBGjcXVnUi4lCWmfRI,7388
8
- hanzo_mcp/tools/common/thinking.py,sha256=0PRBTm8i8u0KBKfNaDasNSCn_R9kmFrAS3retEj_0J4,2630
9
- hanzo_mcp/tools/common/validation.py,sha256=S8zj38jjAXSB4bmZAydXDCsh_j6hHGEs71SgK-oeeYI,3652
10
- hanzo_mcp/tools/filesystem/__init__.py,sha256=IBrOsd_8yDo8RIuujB4rNQmr-JmXuddxyhOv-0PUeig,303
11
- hanzo_mcp/tools/filesystem/file_operations.py,sha256=6LeSoemvaz-oIP0K7GL_vySgA-i8QqN0tI9O_HalSIQ,46182
12
- hanzo_mcp/tools/jupyter/__init__.py,sha256=XuRoN_02X6ChW_OVGoPIydkQTOlvMtL5hPWRzGW3LVU,249
13
- hanzo_mcp/tools/jupyter/notebook_operations.py,sha256=AzZXyrgxR55KU09s3B1D50wAdsozHWQZFMCFXsnoe3A,23339
14
- hanzo_mcp/tools/project/__init__.py,sha256=el-n7xVnHgk6wXqVhFtFCoEfdq11aDAo9DucIJdXBVw,63
15
- hanzo_mcp/tools/project/analysis.py,sha256=eQ1WgeFNf_d9g_LWdo1f3x5-c4PLzRXK2_j-JN8wM9w,30366
16
- hanzo_mcp/tools/shell/__init__.py,sha256=myuuFc03I1xGq3VxmLddkSlvvaQIddA3WoIKds8ABFo,59
17
- hanzo_mcp/tools/shell/command_executor.py,sha256=HyhAwG-aLw13f0Z-K4sCAWqt7qRWEiixnv8tmTTyJW8,37401
18
- hanzo_mcp-0.1.21.dist-info/licenses/LICENSE,sha256=dvWmlLGUAkNE8EJVn-UQ-F08hxW5jtjUWNe51OaH7IE,1077
19
- hanzo_mcp-0.1.21.dist-info/METADATA,sha256=34AG2iCwxvRc2SXiGT8jqCgjH6Q8eiXM4YhfAE6OMSY,7094
20
- hanzo_mcp-0.1.21.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
21
- hanzo_mcp-0.1.21.dist-info/entry_points.txt,sha256=aRKOKXtuQr-idSr-yH4efnRl2v8te94AcgN3ysqqSYs,49
22
- hanzo_mcp-0.1.21.dist-info/top_level.txt,sha256=eGFANatA0MHWiVlpS56fTYRIShtibrSom1uXI6XU0GU,10
23
- hanzo_mcp-0.1.21.dist-info/RECORD,,