hanzo-mcp 0.8.13__tar.gz → 0.8.14__tar.gz
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-0.8.13 → hanzo_mcp-0.8.14}/PKG-INFO +1 -1
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/__init__.py +1 -1
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/server.py +11 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/permissions.py +35 -2
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/editor/neovim_edit.py +2 -2
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/command_executor.py +7 -7
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp.egg-info/PKG-INFO +1 -1
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/pyproject.toml +1 -1
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/README.md +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/__main__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/analytics/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/analytics/posthog_analytics.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/bridge.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/cli.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/cli_enhanced.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/cli_plugin.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/compute_nodes.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/config/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/config/settings.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/config/tool_config.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/core/base_agent.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/core/model_registry.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/dev_server.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/prompts/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/prompts/compact_conversation.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/prompts/create_release.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/prompts/enhanced_prompts.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/prompts/example_custom_prompt.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/prompts/project_system.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/prompts/project_todo_reminder.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/prompts/tool_explorer.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/prompts/utils.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/server_enhanced.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/agent.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/agent_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/agent_tool_v1_deprecated.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/clarification_protocol.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/clarification_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/claude_cli_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/claude_desktop_auth.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/cli_agent_base.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/cli_tools.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/code_auth.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/code_auth_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/codex_cli_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/critic_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/gemini_cli_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/grok_cli_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/iching_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/network_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/prompt.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/review_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/swarm_alias.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/swarm_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/swarm_tool_v1_deprecated.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/tool_adapter.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/agent/unified_cli_tools.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/base.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/batch_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/config_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/context.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/context_fix.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/critic_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/decorators.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/enhanced_base.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/fastmcp_pagination.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/forgiving_edit.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/mode.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/mode_loader.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/paginated_base.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/paginated_response.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/pagination.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/personality.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/plugin_loader.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/stats.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/test_helpers.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/thinking_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/tool_disable.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/tool_enable.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/tool_list.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/truncate.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/common/validation.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/config/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/config/config_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/config/index_config.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/config/mode_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/database_manager.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/graph.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/graph_add.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/graph_query.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/graph_remove.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/graph_search.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/graph_stats.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/sql.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/sql_query.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/sql_search.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/database/sql_stats.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/editor/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/editor/neovim_command.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/editor/neovim_session.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/ast_multi_edit.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/ast_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/base.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/batch_search.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/content_replace.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/diff.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/directory_tree.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/directory_tree_paginated.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/edit.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/find.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/find_files.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/git_search.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/grep.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/multi_edit.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/read.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/rules_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/search_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/symbols_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/tree.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/unix_aliases.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/watch.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/write.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/jupyter/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/jupyter/base.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/jupyter/jupyter.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/jupyter/notebook_edit.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/jupyter/notebook_read.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/llm/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/llm/consensus_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/llm/llm_manage.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/llm/llm_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/llm/llm_unified.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/llm/provider_tools.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/lsp/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/lsp/lsp_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/mcp/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/mcp/mcp_add.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/mcp/mcp_remove.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/mcp/mcp_stats.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/mcp/mcp_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/memory/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/memory/knowledge_tools.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/memory/memory_tools.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/search/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/search/find_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/search/unified_search.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/auto_background.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/base.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/base_process.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/bash_session.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/bash_session_executor.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/bash_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/logs.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/npx.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/npx_background.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/npx_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/open.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/pkill.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/process_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/processes.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/run_background.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/run_command.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/run_command_windows.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/session_manager.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/session_storage.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/streaming_command.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/uvx.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/uvx_background.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/uvx_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/shell/zsh_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/todo/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/todo/base.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/todo/todo.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/todo/todo_read.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/todo/todo_write.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/vector/__init__.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/vector/ast_analyzer.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/vector/git_ingester.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/vector/index_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/vector/infinity_store.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/vector/mock_infinity.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/vector/project_manager.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/vector/vector.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/vector/vector_index.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/vector/vector_search.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/types.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp.egg-info/SOURCES.txt +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp.egg-info/dependency_links.txt +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp.egg-info/entry_points.txt +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp.egg-info/requires.txt +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp.egg-info/top_level.txt +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/setup.cfg +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_agent_tools_ci.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_async_support.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_batch_tool_edge_cases.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_cli.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_cli_agents_consolidated.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_cli_tools.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_e2e_demo.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_e2e_simple.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_failure_cases.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_find_tool_ffind.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_find_tool_integration.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_find_tool_registration.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_git_ingestion.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_hanzo_agents_integration.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_hanzo_mcp_integration.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_hanzo_mcp_local.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_hanzo_mcp_simple.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_hanzo_network_integration.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_litellm_warnings.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_lsp_tool.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_manual.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_memory_base.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_memory_basic.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_memory_consolidated.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_memory_simple.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_memory_utils.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_new_tools.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_no_stubs.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_performance.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_search.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_search_quality.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_shell_features.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_shell_tools.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_simple.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_stdio_protocol.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_stdio_simple.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_streaming_command.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_swarm_simple.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_tools_suite.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_unified_search.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_utils.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_vector_store.py +0 -0
- {hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/tests/test_web3_integration.py +0 -0
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import os
|
|
4
4
|
import atexit
|
|
5
5
|
import signal
|
|
6
|
+
import secrets
|
|
6
7
|
import logging
|
|
7
8
|
import warnings
|
|
8
9
|
import threading
|
|
@@ -53,6 +54,7 @@ class HanzoMCPServer:
|
|
|
53
54
|
port: int = 8888,
|
|
54
55
|
enabled_tools: dict[str, bool] | None = None,
|
|
55
56
|
disabled_tools: list[str] | None = None,
|
|
57
|
+
auth_token: str | None = None,
|
|
56
58
|
):
|
|
57
59
|
"""Initialize the Hanzo AI server.
|
|
58
60
|
|
|
@@ -80,6 +82,15 @@ class HanzoMCPServer:
|
|
|
80
82
|
# Use enhanced server for automatic context normalization
|
|
81
83
|
self.mcp = mcp_instance if mcp_instance is not None else EnhancedFastMCP(name)
|
|
82
84
|
|
|
85
|
+
# Initialize authentication token
|
|
86
|
+
self.auth_token = auth_token or os.environ.get('HANZO_MCP_TOKEN')
|
|
87
|
+
if not self.auth_token:
|
|
88
|
+
# Generate a secure random token if none provided
|
|
89
|
+
self.auth_token = secrets.token_urlsafe(32)
|
|
90
|
+
logger = logging.getLogger(__name__)
|
|
91
|
+
logger.warning(f"No auth token provided. Generated token: {self.auth_token}")
|
|
92
|
+
logger.warning("Set HANZO_MCP_TOKEN environment variable for persistent auth")
|
|
93
|
+
|
|
83
94
|
# Initialize permissions and command executor
|
|
84
95
|
self.permission_manager = PermissionManager()
|
|
85
96
|
|
|
@@ -112,7 +112,7 @@ class PermissionManager:
|
|
|
112
112
|
self.excluded_patterns.append(pattern)
|
|
113
113
|
|
|
114
114
|
def is_path_allowed(self, path: str) -> bool:
|
|
115
|
-
"""Check if a path is allowed.
|
|
115
|
+
"""Check if a path is allowed with security validation.
|
|
116
116
|
|
|
117
117
|
Args:
|
|
118
118
|
path: The path to check
|
|
@@ -120,7 +120,24 @@ class PermissionManager:
|
|
|
120
120
|
Returns:
|
|
121
121
|
True if the path is allowed, False otherwise
|
|
122
122
|
"""
|
|
123
|
-
|
|
123
|
+
# Security check: Reject paths with traversal attempts
|
|
124
|
+
if ".." in str(path) or "~" in str(path):
|
|
125
|
+
return False
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
# Resolve the path (follows symlinks and makes absolute)
|
|
129
|
+
resolved_path: Path = Path(path).resolve(strict=False)
|
|
130
|
+
|
|
131
|
+
# Security check: Ensure resolved path doesn't escape allowed directories
|
|
132
|
+
# by checking if it's actually under an allowed path after resolution
|
|
133
|
+
original_path = Path(path)
|
|
134
|
+
if original_path.is_absolute() and str(resolved_path) != str(original_path.resolve(strict=False)):
|
|
135
|
+
# Path resolution changed the path significantly, might be symlink attack
|
|
136
|
+
# Additional check: is the resolved path still under allowed paths?
|
|
137
|
+
pass # Continue to normal checks
|
|
138
|
+
except (OSError, RuntimeError) as e:
|
|
139
|
+
# Path resolution failed, deny access
|
|
140
|
+
return False
|
|
124
141
|
|
|
125
142
|
# Check exclusions first
|
|
126
143
|
if self._is_path_excluded(resolved_path):
|
|
@@ -129,12 +146,28 @@ class PermissionManager:
|
|
|
129
146
|
# Check if the path is within any allowed path
|
|
130
147
|
for allowed_path in self.allowed_paths:
|
|
131
148
|
try:
|
|
149
|
+
# This will raise ValueError if resolved_path is not under allowed_path
|
|
132
150
|
resolved_path.relative_to(allowed_path)
|
|
151
|
+
# Additional check: ensure no symlinks are escaping the allowed directory
|
|
152
|
+
if resolved_path.exists() and resolved_path.is_symlink():
|
|
153
|
+
link_target = Path(os.readlink(resolved_path))
|
|
154
|
+
if link_target.is_absolute():
|
|
155
|
+
# Absolute symlink - check if it points within allowed paths
|
|
156
|
+
if not any(self._is_subpath(link_target, ap) for ap in self.allowed_paths):
|
|
157
|
+
return False
|
|
133
158
|
return True
|
|
134
159
|
except ValueError:
|
|
135
160
|
continue
|
|
136
161
|
|
|
137
162
|
return False
|
|
163
|
+
|
|
164
|
+
def _is_subpath(self, child: Path, parent: Path) -> bool:
|
|
165
|
+
"""Check if child is a subpath of parent."""
|
|
166
|
+
try:
|
|
167
|
+
child.resolve().relative_to(parent.resolve())
|
|
168
|
+
return True
|
|
169
|
+
except ValueError:
|
|
170
|
+
return False
|
|
138
171
|
|
|
139
172
|
def _is_path_excluded(self, path: Path) -> bool:
|
|
140
173
|
"""Check if a path is excluded.
|
|
@@ -252,7 +252,7 @@ Or visit: https://neovim.io/"""
|
|
|
252
252
|
end if
|
|
253
253
|
end tell"""
|
|
254
254
|
|
|
255
|
-
subprocess.run(["osascript", "-e", applescript])
|
|
255
|
+
subprocess.run(["osascript", "-e", applescript], timeout=10)
|
|
256
256
|
return f"Opened {file_path} in Neovim (new terminal window)"
|
|
257
257
|
|
|
258
258
|
elif shutil.which("gnome-terminal"):
|
|
@@ -272,7 +272,7 @@ Or visit: https://neovim.io/"""
|
|
|
272
272
|
|
|
273
273
|
else:
|
|
274
274
|
# Run and wait for completion
|
|
275
|
-
result = subprocess.run(cmd)
|
|
275
|
+
result = subprocess.run(cmd, timeout=120)
|
|
276
276
|
|
|
277
277
|
if result.returncode == 0:
|
|
278
278
|
return f"Successfully edited {file_path} in Neovim"
|
|
@@ -109,13 +109,12 @@ class CommandExecutor:
|
|
|
109
109
|
if shell_basename in ["wsl", "wsl.exe"]:
|
|
110
110
|
# For WSL, handle commands with shell operators differently
|
|
111
111
|
if any(char in command for char in ";&|<>(){}[]$\"'`"):
|
|
112
|
-
#
|
|
113
|
-
|
|
114
|
-
escaped_command = command.replace('"', '\\"')
|
|
112
|
+
# Use shlex.quote for proper escaping to prevent command injection
|
|
113
|
+
escaped_command = shlex.quote(command)
|
|
115
114
|
if use_login_shell:
|
|
116
|
-
formatted_command = f'{user_shell} bash -l -c
|
|
115
|
+
formatted_command = f'{user_shell} bash -l -c {escaped_command}'
|
|
117
116
|
else:
|
|
118
|
-
formatted_command = f'{user_shell} bash -c
|
|
117
|
+
formatted_command = f'{user_shell} bash -c {escaped_command}'
|
|
119
118
|
else:
|
|
120
119
|
# # For simple commands without special characters
|
|
121
120
|
# # Still respect login shell preference
|
|
@@ -125,8 +124,9 @@ class CommandExecutor:
|
|
|
125
124
|
formatted_command = f"{user_shell} {command}"
|
|
126
125
|
|
|
127
126
|
elif shell_basename in ["powershell", "powershell.exe", "pwsh", "pwsh.exe"]:
|
|
128
|
-
#
|
|
129
|
-
|
|
127
|
+
# Use proper escaping for PowerShell to prevent injection
|
|
128
|
+
# PowerShell requires different escaping than POSIX shells
|
|
129
|
+
escaped_command = command.replace('"', '`"').replace("'", "``'").replace('$', '`$')
|
|
130
130
|
formatted_command = f'"{user_shell}" -Command "{escaped_command}"'
|
|
131
131
|
|
|
132
132
|
else:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "hanzo-mcp"
|
|
7
|
-
version = "0.8.
|
|
7
|
+
version = "0.8.14"
|
|
8
8
|
description = "The Zen of Hanzo MCP: One server to rule them all. The ultimate MCP that orchestrates all others."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hanzo_mcp-0.8.13 → hanzo_mcp-0.8.14}/hanzo_mcp/tools/filesystem/directory_tree_paginated.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|