hanzo-mcp 0.8.11__py3-none-any.whl → 0.9.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.
- hanzo_mcp/__init__.py +1 -3
- hanzo_mcp/analytics/posthog_analytics.py +3 -9
- hanzo_mcp/bridge.py +9 -25
- hanzo_mcp/cli.py +6 -15
- hanzo_mcp/cli_enhanced.py +5 -14
- hanzo_mcp/cli_plugin.py +3 -9
- hanzo_mcp/config/settings.py +6 -20
- hanzo_mcp/config/tool_config.py +1 -3
- hanzo_mcp/core/base_agent.py +88 -88
- hanzo_mcp/core/model_registry.py +238 -210
- hanzo_mcp/dev_server.py +5 -15
- hanzo_mcp/prompts/__init__.py +2 -6
- hanzo_mcp/prompts/project_todo_reminder.py +3 -9
- hanzo_mcp/prompts/tool_explorer.py +1 -3
- hanzo_mcp/prompts/utils.py +7 -21
- hanzo_mcp/server.py +2 -6
- hanzo_mcp/tools/__init__.py +26 -27
- hanzo_mcp/tools/agent/__init__.py +2 -1
- hanzo_mcp/tools/agent/agent.py +10 -30
- hanzo_mcp/tools/agent/agent_tool.py +22 -15
- hanzo_mcp/tools/agent/claude_desktop_auth.py +3 -9
- hanzo_mcp/tools/agent/cli_agent_base.py +7 -24
- hanzo_mcp/tools/agent/cli_tools.py +75 -74
- hanzo_mcp/tools/agent/code_auth.py +1 -3
- hanzo_mcp/tools/agent/code_auth_tool.py +2 -6
- hanzo_mcp/tools/agent/critic_tool.py +8 -24
- hanzo_mcp/tools/agent/iching_tool.py +12 -36
- hanzo_mcp/tools/agent/network_tool.py +7 -18
- hanzo_mcp/tools/agent/prompt.py +1 -5
- hanzo_mcp/tools/agent/review_tool.py +10 -25
- hanzo_mcp/tools/agent/swarm_alias.py +1 -3
- hanzo_mcp/tools/agent/unified_cli_tools.py +38 -38
- hanzo_mcp/tools/common/batch_tool.py +15 -45
- hanzo_mcp/tools/common/config_tool.py +9 -28
- hanzo_mcp/tools/common/context.py +1 -3
- hanzo_mcp/tools/common/critic_tool.py +1 -3
- hanzo_mcp/tools/common/decorators.py +2 -6
- hanzo_mcp/tools/common/enhanced_base.py +2 -6
- hanzo_mcp/tools/common/fastmcp_pagination.py +4 -12
- hanzo_mcp/tools/common/forgiving_edit.py +9 -28
- hanzo_mcp/tools/common/mode.py +1 -5
- hanzo_mcp/tools/common/paginated_base.py +3 -11
- hanzo_mcp/tools/common/paginated_response.py +10 -30
- hanzo_mcp/tools/common/pagination.py +3 -9
- hanzo_mcp/tools/common/path_utils.py +34 -0
- hanzo_mcp/tools/common/permissions.py +14 -13
- hanzo_mcp/tools/common/personality.py +983 -701
- hanzo_mcp/tools/common/plugin_loader.py +3 -15
- hanzo_mcp/tools/common/stats.py +6 -18
- hanzo_mcp/tools/common/thinking_tool.py +1 -3
- hanzo_mcp/tools/common/tool_disable.py +2 -6
- hanzo_mcp/tools/common/tool_list.py +2 -6
- hanzo_mcp/tools/common/validation.py +1 -3
- hanzo_mcp/tools/compiler/__init__.py +8 -0
- hanzo_mcp/tools/compiler/sandboxed_compiler.py +681 -0
- hanzo_mcp/tools/config/config_tool.py +7 -13
- hanzo_mcp/tools/config/index_config.py +1 -3
- hanzo_mcp/tools/config/mode_tool.py +5 -15
- hanzo_mcp/tools/database/database_manager.py +3 -9
- hanzo_mcp/tools/database/graph.py +1 -3
- hanzo_mcp/tools/database/graph_add.py +3 -9
- hanzo_mcp/tools/database/graph_query.py +11 -34
- hanzo_mcp/tools/database/graph_remove.py +3 -9
- hanzo_mcp/tools/database/graph_search.py +6 -20
- hanzo_mcp/tools/database/graph_stats.py +11 -33
- hanzo_mcp/tools/database/sql.py +4 -12
- hanzo_mcp/tools/database/sql_query.py +6 -10
- hanzo_mcp/tools/database/sql_search.py +2 -6
- hanzo_mcp/tools/database/sql_stats.py +5 -15
- hanzo_mcp/tools/editor/neovim_command.py +1 -3
- hanzo_mcp/tools/editor/neovim_session.py +7 -13
- hanzo_mcp/tools/environment/__init__.py +8 -0
- hanzo_mcp/tools/environment/environment_detector.py +594 -0
- hanzo_mcp/tools/filesystem/__init__.py +28 -26
- hanzo_mcp/tools/filesystem/ast_multi_edit.py +14 -43
- hanzo_mcp/tools/filesystem/ast_tool.py +3 -0
- hanzo_mcp/tools/filesystem/base.py +20 -12
- hanzo_mcp/tools/filesystem/content_replace.py +7 -12
- hanzo_mcp/tools/filesystem/diff.py +2 -10
- hanzo_mcp/tools/filesystem/directory_tree.py +285 -51
- hanzo_mcp/tools/filesystem/edit.py +10 -18
- hanzo_mcp/tools/filesystem/find.py +312 -179
- hanzo_mcp/tools/filesystem/git_search.py +12 -24
- hanzo_mcp/tools/filesystem/multi_edit.py +10 -18
- hanzo_mcp/tools/filesystem/read.py +14 -30
- hanzo_mcp/tools/filesystem/rules_tool.py +9 -17
- hanzo_mcp/tools/filesystem/search.py +1160 -0
- hanzo_mcp/tools/filesystem/watch.py +2 -4
- hanzo_mcp/tools/filesystem/write.py +7 -10
- hanzo_mcp/tools/framework/__init__.py +8 -0
- hanzo_mcp/tools/framework/framework_modes.py +714 -0
- hanzo_mcp/tools/jupyter/base.py +6 -20
- hanzo_mcp/tools/jupyter/jupyter.py +4 -12
- hanzo_mcp/tools/llm/consensus_tool.py +8 -24
- hanzo_mcp/tools/llm/llm_manage.py +2 -6
- hanzo_mcp/tools/llm/llm_tool.py +17 -58
- hanzo_mcp/tools/llm/llm_unified.py +18 -59
- hanzo_mcp/tools/llm/provider_tools.py +1 -3
- hanzo_mcp/tools/lsp/lsp_tool.py +621 -481
- hanzo_mcp/tools/mcp/mcp_add.py +1 -3
- hanzo_mcp/tools/mcp/mcp_stats.py +1 -3
- hanzo_mcp/tools/mcp/mcp_tool.py +9 -23
- hanzo_mcp/tools/memory/__init__.py +10 -27
- hanzo_mcp/tools/memory/conversation_memory.py +636 -0
- hanzo_mcp/tools/memory/knowledge_tools.py +7 -25
- hanzo_mcp/tools/memory/memory_tools.py +6 -18
- hanzo_mcp/tools/search/find_tool.py +12 -34
- hanzo_mcp/tools/search/unified_search.py +24 -78
- hanzo_mcp/tools/shell/__init__.py +16 -4
- hanzo_mcp/tools/shell/auto_background.py +2 -6
- hanzo_mcp/tools/shell/base.py +1 -5
- hanzo_mcp/tools/shell/base_process.py +5 -7
- hanzo_mcp/tools/shell/bash_session.py +7 -24
- hanzo_mcp/tools/shell/bash_session_executor.py +5 -15
- hanzo_mcp/tools/shell/bash_tool.py +3 -7
- hanzo_mcp/tools/shell/command_executor.py +26 -79
- hanzo_mcp/tools/shell/logs.py +4 -16
- hanzo_mcp/tools/shell/npx.py +2 -8
- hanzo_mcp/tools/shell/npx_tool.py +1 -3
- hanzo_mcp/tools/shell/pkill.py +4 -12
- hanzo_mcp/tools/shell/process_tool.py +2 -8
- hanzo_mcp/tools/shell/processes.py +5 -17
- hanzo_mcp/tools/shell/run_background.py +1 -3
- hanzo_mcp/tools/shell/run_command.py +1 -3
- hanzo_mcp/tools/shell/run_command_windows.py +1 -3
- hanzo_mcp/tools/shell/run_tool.py +56 -0
- hanzo_mcp/tools/shell/session_manager.py +2 -6
- hanzo_mcp/tools/shell/session_storage.py +2 -6
- hanzo_mcp/tools/shell/streaming_command.py +7 -23
- hanzo_mcp/tools/shell/uvx.py +4 -14
- hanzo_mcp/tools/shell/uvx_background.py +2 -6
- hanzo_mcp/tools/shell/uvx_tool.py +1 -3
- hanzo_mcp/tools/shell/zsh_tool.py +12 -20
- hanzo_mcp/tools/todo/todo.py +1 -3
- hanzo_mcp/tools/vector/__init__.py +97 -50
- hanzo_mcp/tools/vector/ast_analyzer.py +6 -20
- hanzo_mcp/tools/vector/git_ingester.py +10 -30
- hanzo_mcp/tools/vector/index_tool.py +3 -9
- hanzo_mcp/tools/vector/infinity_store.py +7 -27
- hanzo_mcp/tools/vector/mock_infinity.py +1 -3
- hanzo_mcp/tools/vector/node_tool.py +538 -0
- hanzo_mcp/tools/vector/project_manager.py +4 -12
- hanzo_mcp/tools/vector/unified_vector.py +384 -0
- hanzo_mcp/tools/vector/vector.py +2 -6
- hanzo_mcp/tools/vector/vector_index.py +8 -8
- hanzo_mcp/tools/vector/vector_search.py +7 -21
- {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.9.0.dist-info}/METADATA +2 -2
- hanzo_mcp-0.9.0.dist-info/RECORD +191 -0
- hanzo_mcp/tools/agent/agent_tool_v1_deprecated.py +0 -645
- hanzo_mcp/tools/agent/swarm_tool.py +0 -718
- hanzo_mcp/tools/agent/swarm_tool_v1_deprecated.py +0 -577
- hanzo_mcp/tools/filesystem/batch_search.py +0 -900
- hanzo_mcp/tools/filesystem/directory_tree_paginated.py +0 -350
- hanzo_mcp/tools/filesystem/find_files.py +0 -369
- hanzo_mcp/tools/filesystem/grep.py +0 -467
- hanzo_mcp/tools/filesystem/search_tool.py +0 -767
- hanzo_mcp/tools/filesystem/symbols_tool.py +0 -515
- hanzo_mcp/tools/filesystem/tree.py +0 -270
- hanzo_mcp/tools/jupyter/notebook_edit.py +0 -317
- hanzo_mcp/tools/jupyter/notebook_read.py +0 -147
- hanzo_mcp/tools/todo/todo_read.py +0 -143
- hanzo_mcp/tools/todo/todo_write.py +0 -374
- hanzo_mcp-0.8.11.dist-info/RECORD +0 -193
- {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.9.0.dist-info}/WHEEL +0 -0
- {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.9.0.dist-info}/entry_points.txt +0 -0
- {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.9.0.dist-info}/top_level.txt +0 -0
|
@@ -176,6 +176,9 @@ Examples:
|
|
|
176
176
|
return "Error: pattern is required"
|
|
177
177
|
|
|
178
178
|
path = params.get("path", os.getcwd())
|
|
179
|
+
|
|
180
|
+
# Expand path (handles ~, $HOME, etc.)
|
|
181
|
+
path = self.expand_path(path)
|
|
179
182
|
search_type = params.get("search_type", "content")
|
|
180
183
|
case_sensitive = params.get("case_sensitive", False)
|
|
181
184
|
max_count = params.get("max_count", 100)
|
|
@@ -256,9 +259,7 @@ Examples:
|
|
|
256
259
|
tool_ctx,
|
|
257
260
|
)
|
|
258
261
|
elif search_type == "blame":
|
|
259
|
-
return await self._search_blame(
|
|
260
|
-
abs_path, pattern, case_sensitive, file_pattern, tool_ctx
|
|
261
|
-
)
|
|
262
|
+
return await self._search_blame(abs_path, pattern, case_sensitive, file_pattern, tool_ctx)
|
|
262
263
|
else:
|
|
263
264
|
return f"Unknown search type: {search_type}"
|
|
264
265
|
|
|
@@ -307,9 +308,7 @@ Examples:
|
|
|
307
308
|
elif result.returncode == 1:
|
|
308
309
|
return f"No matches found for pattern: {pattern}"
|
|
309
310
|
else:
|
|
310
|
-
raise subprocess.CalledProcessError(
|
|
311
|
-
result.returncode, cmd, result.stdout, result.stderr
|
|
312
|
-
)
|
|
311
|
+
raise subprocess.CalledProcessError(result.returncode, cmd, result.stdout, result.stderr)
|
|
313
312
|
|
|
314
313
|
async def _search_commits(
|
|
315
314
|
self,
|
|
@@ -353,16 +352,11 @@ Examples:
|
|
|
353
352
|
lines = result.stdout.strip().split("\n")
|
|
354
353
|
if lines and lines[0]:
|
|
355
354
|
await tool_ctx.info(f"Found {len(lines)} commits")
|
|
356
|
-
return (
|
|
357
|
-
f"Found {len(lines)} commits matching '{pattern}':\n\n"
|
|
358
|
-
+ result.stdout
|
|
359
|
-
)
|
|
355
|
+
return f"Found {len(lines)} commits matching '{pattern}':\n\n" + result.stdout
|
|
360
356
|
else:
|
|
361
357
|
return f"No commits found matching: {pattern}"
|
|
362
358
|
else:
|
|
363
|
-
raise subprocess.CalledProcessError(
|
|
364
|
-
result.returncode, cmd, result.stdout, result.stderr
|
|
365
|
-
)
|
|
359
|
+
raise subprocess.CalledProcessError(result.returncode, cmd, result.stdout, result.stderr)
|
|
366
360
|
|
|
367
361
|
async def _search_diff(
|
|
368
362
|
self,
|
|
@@ -387,8 +381,7 @@ Examples:
|
|
|
387
381
|
import re
|
|
388
382
|
|
|
389
383
|
case_insensitive_pattern = "".join(
|
|
390
|
-
f"[{c.upper()}{c.lower()}]" if c.isalpha() else re.escape(c)
|
|
391
|
-
for c in pattern
|
|
384
|
+
f"[{c.upper()}{c.lower()}]" if c.isalpha() else re.escape(c) for c in pattern
|
|
392
385
|
)
|
|
393
386
|
search_flag = f"-G{case_insensitive_pattern}"
|
|
394
387
|
|
|
@@ -415,9 +408,7 @@ Examples:
|
|
|
415
408
|
|
|
416
409
|
if result.returncode == 0 and result.stdout.strip():
|
|
417
410
|
# Parse and highlight matching lines
|
|
418
|
-
output = self._highlight_diff_matches(
|
|
419
|
-
result.stdout, pattern, case_sensitive
|
|
420
|
-
)
|
|
411
|
+
output = self._highlight_diff_matches(result.stdout, pattern, case_sensitive)
|
|
421
412
|
matches = output.count("commit ")
|
|
422
413
|
await tool_ctx.info(f"Found {matches} commits with changes")
|
|
423
414
|
return f"Found {matches} commits with changes matching '{pattern}':\n\n{output}"
|
|
@@ -505,9 +496,8 @@ Examples:
|
|
|
505
496
|
|
|
506
497
|
if all_matches:
|
|
507
498
|
await tool_ctx.info(f"Found {len(all_matches)} matching lines")
|
|
508
|
-
return (
|
|
509
|
-
|
|
510
|
-
+ "\n".join(all_matches[:50])
|
|
499
|
+
return f"Found {len(all_matches)} lines matching '{pattern}':\n\n" + "\n".join(
|
|
500
|
+
all_matches[:50]
|
|
511
501
|
) # Limit output
|
|
512
502
|
else:
|
|
513
503
|
return f"No lines found matching: {pattern}"
|
|
@@ -534,9 +524,7 @@ Examples:
|
|
|
534
524
|
|
|
535
525
|
return f"Found matches for '{pattern}':\n" + "\n".join(output)
|
|
536
526
|
|
|
537
|
-
def _highlight_diff_matches(
|
|
538
|
-
self, diff_output: str, pattern: str, case_sensitive: bool
|
|
539
|
-
) -> str:
|
|
527
|
+
def _highlight_diff_matches(self, diff_output: str, pattern: str, case_sensitive: bool) -> str:
|
|
540
528
|
"""Highlight matching lines in diff output."""
|
|
541
529
|
lines = diff_output.split("\n")
|
|
542
530
|
output = []
|
|
@@ -159,6 +159,10 @@ If you want to create a new file, use:
|
|
|
159
159
|
await tool_ctx.error(path_validation.error_message)
|
|
160
160
|
return f"Error: {path_validation.error_message}"
|
|
161
161
|
|
|
162
|
+
# Expand path first (handles ~, $HOME, etc.)
|
|
163
|
+
expanded_path = self.expand_path(file_path)
|
|
164
|
+
file_path = expanded_path # Use expanded path for all operations
|
|
165
|
+
|
|
162
166
|
# Validate each edit
|
|
163
167
|
for i, edit in enumerate(edits):
|
|
164
168
|
if not isinstance(edit, dict):
|
|
@@ -170,15 +174,11 @@ If you want to create a new file, use:
|
|
|
170
174
|
expected_replacements = edit.get("expected_replacements", 1)
|
|
171
175
|
|
|
172
176
|
if old_string is None:
|
|
173
|
-
await tool_ctx.error(
|
|
174
|
-
f"Parameter 'old_string' in edit at index {i} is required but was None"
|
|
175
|
-
)
|
|
177
|
+
await tool_ctx.error(f"Parameter 'old_string' in edit at index {i} is required but was None")
|
|
176
178
|
return f"Error: Parameter 'old_string' in edit at index {i} is required but was None"
|
|
177
179
|
|
|
178
180
|
if new_string is None:
|
|
179
|
-
await tool_ctx.error(
|
|
180
|
-
f"Parameter 'new_string' in edit at index {i} is required but was None"
|
|
181
|
-
)
|
|
181
|
+
await tool_ctx.error(f"Parameter 'new_string' in edit at index {i} is required but was None")
|
|
182
182
|
return f"Error: Parameter 'new_string' in edit at index {i} is required but was None"
|
|
183
183
|
|
|
184
184
|
if (
|
|
@@ -192,12 +192,8 @@ If you want to create a new file, use:
|
|
|
192
192
|
return f"Error: Parameter 'expected_replacements' in edit at index {i} must be a non-negative number"
|
|
193
193
|
|
|
194
194
|
if old_string == new_string:
|
|
195
|
-
await tool_ctx.error(
|
|
196
|
-
|
|
197
|
-
)
|
|
198
|
-
return (
|
|
199
|
-
f"Error: Edit at index {i}: old_string and new_string are identical"
|
|
200
|
-
)
|
|
195
|
+
await tool_ctx.error(f"Edit at index {i}: old_string and new_string are identical")
|
|
196
|
+
return f"Error: Edit at index {i}: old_string and new_string are identical"
|
|
201
197
|
|
|
202
198
|
await tool_ctx.info(f"Applying {len(edits)} edits to file: {file_path}")
|
|
203
199
|
|
|
@@ -261,9 +257,7 @@ If you want to create a new file, use:
|
|
|
261
257
|
|
|
262
258
|
# Check if old_string exists in current content
|
|
263
259
|
if old_string not in current_content:
|
|
264
|
-
edit_index =
|
|
265
|
-
i + 1 if not creation_mode else i + 2
|
|
266
|
-
) # Adjust for display
|
|
260
|
+
edit_index = i + 1 if not creation_mode else i + 2 # Adjust for display
|
|
267
261
|
await tool_ctx.error(
|
|
268
262
|
f"Edit {edit_index}: The specified old_string was not found in the file content"
|
|
269
263
|
)
|
|
@@ -274,9 +268,7 @@ If you want to create a new file, use:
|
|
|
274
268
|
|
|
275
269
|
# Check if the number of occurrences matches expected_replacements
|
|
276
270
|
if occurrences != expected_replacements:
|
|
277
|
-
edit_index =
|
|
278
|
-
i + 1 if not creation_mode else i + 2
|
|
279
|
-
) # Adjust for display
|
|
271
|
+
edit_index = i + 1 if not creation_mode else i + 2 # Adjust for display
|
|
280
272
|
await tool_ctx.error(
|
|
281
273
|
f"Edit {edit_index}: Found {occurrences} occurrences of the specified old_string, but expected {expected_replacements}"
|
|
282
274
|
)
|
|
@@ -118,21 +118,17 @@ Usage:
|
|
|
118
118
|
await tool_ctx.error("Parameter 'file_path' is required but was None")
|
|
119
119
|
return "Error: Parameter 'file_path' is required but was None"
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
# Check if path is allowed
|
|
126
|
-
if not self.is_path_allowed(
|
|
127
|
-
await tool_ctx.error(
|
|
128
|
-
|
|
129
|
-
)
|
|
130
|
-
return (
|
|
131
|
-
f"Error: Access denied - path outside allowed directories: {file_path}"
|
|
132
|
-
)
|
|
121
|
+
# Expand path first (handles ~, $HOME, etc.)
|
|
122
|
+
expanded_path = self.expand_path(file_path)
|
|
123
|
+
await tool_ctx.info(f"Reading file: {expanded_path} (offset: {offset}, limit: {limit})")
|
|
124
|
+
|
|
125
|
+
# Check if path is allowed (using expanded path)
|
|
126
|
+
if not self.is_path_allowed(expanded_path):
|
|
127
|
+
await tool_ctx.error(f"Access denied - path outside allowed directories: {expanded_path}")
|
|
128
|
+
return f"Error: Access denied - path outside allowed directories: {expanded_path}"
|
|
133
129
|
|
|
134
130
|
try:
|
|
135
|
-
file_path_obj = Path(
|
|
131
|
+
file_path_obj = Path(expanded_path)
|
|
136
132
|
|
|
137
133
|
if not file_path_obj.exists():
|
|
138
134
|
await tool_ctx.error(f"File does not exist: {file_path}")
|
|
@@ -166,10 +162,7 @@ Usage:
|
|
|
166
162
|
|
|
167
163
|
# Truncate long lines
|
|
168
164
|
if len(line) > self.MAX_LINE_LENGTH:
|
|
169
|
-
line =
|
|
170
|
-
line[: self.MAX_LINE_LENGTH]
|
|
171
|
-
+ self.LINE_TRUNCATION_INDICATOR
|
|
172
|
-
)
|
|
165
|
+
line = line[: self.MAX_LINE_LENGTH] + self.LINE_TRUNCATION_INDICATOR
|
|
173
166
|
|
|
174
167
|
# Add line with line number (1-based)
|
|
175
168
|
lines.append(f"{i + 1:6d} {line.rstrip()}")
|
|
@@ -196,17 +189,12 @@ Usage:
|
|
|
196
189
|
|
|
197
190
|
# Truncate long lines
|
|
198
191
|
if len(line) > self.MAX_LINE_LENGTH:
|
|
199
|
-
line =
|
|
200
|
-
line[: self.MAX_LINE_LENGTH]
|
|
201
|
-
+ self.LINE_TRUNCATION_INDICATOR
|
|
202
|
-
)
|
|
192
|
+
line = line[: self.MAX_LINE_LENGTH] + self.LINE_TRUNCATION_INDICATOR
|
|
203
193
|
|
|
204
194
|
# Add line with line number (1-based)
|
|
205
195
|
lines.append(f"{i + 1:6d} {line.rstrip()}")
|
|
206
196
|
|
|
207
|
-
await tool_ctx.warning(
|
|
208
|
-
f"File read with latin-1 encoding: {file_path}"
|
|
209
|
-
)
|
|
197
|
+
await tool_ctx.warning(f"File read with latin-1 encoding: {file_path}")
|
|
210
198
|
|
|
211
199
|
except Exception:
|
|
212
200
|
await tool_ctx.error(f"Cannot read binary file: {file_path}")
|
|
@@ -236,9 +224,7 @@ Usage:
|
|
|
236
224
|
await tool_ctx.error(f"Error reading file: {str(e)}")
|
|
237
225
|
return f"Error: {str(e)}"
|
|
238
226
|
|
|
239
|
-
async def run(
|
|
240
|
-
self, ctx: MCPContext, file_path: str, offset: int = 0, limit: int = 2000
|
|
241
|
-
) -> str:
|
|
227
|
+
async def run(self, ctx: MCPContext, file_path: str, offset: int = 0, limit: int = 2000) -> str:
|
|
242
228
|
"""Run method for backwards compatibility with test scripts.
|
|
243
229
|
|
|
244
230
|
Args:
|
|
@@ -271,6 +257,4 @@ Usage:
|
|
|
271
257
|
offset: Offset = 0,
|
|
272
258
|
limit: Limit = 2000,
|
|
273
259
|
) -> str:
|
|
274
|
-
return await tool_self.call(
|
|
275
|
-
ctx, file_path=file_path, offset=offset, limit=limit
|
|
276
|
-
)
|
|
260
|
+
return await tool_self.call(ctx, file_path=file_path, offset=offset, limit=limit)
|
|
@@ -93,6 +93,9 @@ understand project-specific requirements and preferences."""
|
|
|
93
93
|
|
|
94
94
|
# Extract parameters
|
|
95
95
|
search_path = params.get("path", ".")
|
|
96
|
+
|
|
97
|
+
# Expand path (handles ~, $HOME, etc.)
|
|
98
|
+
search_path = self.expand_path(search_path)
|
|
96
99
|
|
|
97
100
|
# Validate path
|
|
98
101
|
path_validation = self.validate_path(search_path)
|
|
@@ -142,9 +145,7 @@ understand project-specific requirements and preferences."""
|
|
|
142
145
|
found_configs.append(
|
|
143
146
|
{
|
|
144
147
|
"path": str(config_path),
|
|
145
|
-
"relative_path": str(
|
|
146
|
-
config_path.relative_to(start_path)
|
|
147
|
-
),
|
|
148
|
+
"relative_path": str(config_path.relative_to(start_path)),
|
|
148
149
|
"content": content,
|
|
149
150
|
"size": len(content),
|
|
150
151
|
}
|
|
@@ -152,9 +153,7 @@ understand project-specific requirements and preferences."""
|
|
|
152
153
|
|
|
153
154
|
await tool_ctx.info(f"Found configuration: {config_path}")
|
|
154
155
|
except Exception as e:
|
|
155
|
-
await tool_ctx.warning(
|
|
156
|
-
f"Could not read {config_path}: {str(e)}"
|
|
157
|
-
)
|
|
156
|
+
await tool_ctx.warning(f"Could not read {config_path}: {str(e)}")
|
|
158
157
|
|
|
159
158
|
# Check if we've reached the root or a git repository root
|
|
160
159
|
if current_path.parent == current_path:
|
|
@@ -169,8 +168,7 @@ understand project-specific requirements and preferences."""
|
|
|
169
168
|
if (
|
|
170
169
|
config_path.exists()
|
|
171
170
|
and config_path.is_file()
|
|
172
|
-
and str(config_path)
|
|
173
|
-
not in [c["path"] for c in found_configs]
|
|
171
|
+
and str(config_path) not in [c["path"] for c in found_configs]
|
|
174
172
|
):
|
|
175
173
|
try:
|
|
176
174
|
if self.is_path_allowed(str(config_path)):
|
|
@@ -180,21 +178,15 @@ understand project-specific requirements and preferences."""
|
|
|
180
178
|
found_configs.append(
|
|
181
179
|
{
|
|
182
180
|
"path": str(config_path),
|
|
183
|
-
"relative_path": str(
|
|
184
|
-
config_path.relative_to(start_path)
|
|
185
|
-
),
|
|
181
|
+
"relative_path": str(config_path.relative_to(start_path)),
|
|
186
182
|
"content": content,
|
|
187
183
|
"size": len(content),
|
|
188
184
|
}
|
|
189
185
|
)
|
|
190
186
|
|
|
191
|
-
await tool_ctx.info(
|
|
192
|
-
f"Found configuration: {config_path}"
|
|
193
|
-
)
|
|
187
|
+
await tool_ctx.info(f"Found configuration: {config_path}")
|
|
194
188
|
except Exception as e:
|
|
195
|
-
await tool_ctx.warning(
|
|
196
|
-
f"Could not read {config_path}: {str(e)}"
|
|
197
|
-
)
|
|
189
|
+
await tool_ctx.warning(f"Could not read {config_path}: {str(e)}")
|
|
198
190
|
break
|
|
199
191
|
|
|
200
192
|
# Move to parent directory
|