Add tmux session management and screen to tmux conversion

Features:
- Add tmux_server.py with full session management capabilities
- Convert TheCoder script from screen to tmux with HOME bind mount fix
- Add enabled flag to MCPServerConfig for selective server startup
- Tmux now default, screen legacy (disabled by default)
- Update documentation and architecture to reflect tmux preference

Session Management:
- create_session, execute, peek, list_sessions, kill_session
- attach_session and share_session with multi-user instructions
- Better multi-user support than screen with native tmux capabilities

Testing:
- Add test_tmux_session.py for comprehensive tmux functionality testing
- Add test_screen_utf8.py for UTF-8 handling
- Add MCP_QUICK_REFERENCE.md for AI handoff documentation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude4Ξlope 2025-06-28 15:28:32 +02:00
parent edca1d1fe2
commit 824a66d7c8
11 changed files with 955 additions and 7 deletions

75
.tags
View File

@ -18,6 +18,7 @@ DEFAULT_CONFIGS mcp_browser/default_configs.py /^DEFAULT_CONFIGS = {$/;" v
Decision build/lib/mcp_servers/memory/memory_server.py /^class Decision:$/;" c Decision build/lib/mcp_servers/memory/memory_server.py /^class Decision:$/;" c
Decision mcp_servers/memory/memory_server.py /^class Decision:$/;" c Decision mcp_servers/memory/memory_server.py /^class Decision:$/;" c
GenerateAIDocs setup.py /^class GenerateAIDocs(Command):$/;" c GenerateAIDocs setup.py /^class GenerateAIDocs(Command):$/;" c
InteractiveMCPClient mcp_browser/interactive_client.py /^class InteractiveMCPClient:$/;" c
JSONRPCTestClient tests/test_integration.py /^class JSONRPCTestClient:$/;" c JSONRPCTestClient tests/test_integration.py /^class JSONRPCTestClient:$/;" c
JsonRpcBuffer build/lib/mcp_browser/buffer.py /^class JsonRpcBuffer:$/;" c JsonRpcBuffer build/lib/mcp_browser/buffer.py /^class JsonRpcBuffer:$/;" c
JsonRpcBuffer mcp_browser/buffer.py /^class JsonRpcBuffer:$/;" c JsonRpcBuffer mcp_browser/buffer.py /^class JsonRpcBuffer:$/;" c
@ -55,7 +56,10 @@ TRACE build/lib/mcp_browser/logging_config.py /^TRACE = 5$/;" v
TRACE mcp_browser/logging_config.py /^TRACE = 5$/;" v TRACE mcp_browser/logging_config.py /^TRACE = 5$/;" v
Task build/lib/mcp_servers/memory/memory_server.py /^class Task:$/;" c Task build/lib/mcp_servers/memory/memory_server.py /^class Task:$/;" c
Task mcp_servers/memory/memory_server.py /^class Task:$/;" c Task mcp_servers/memory/memory_server.py /^class Task:$/;" c
TestCmemIntegration tests/test_cmem_integration.py /^class TestCmemIntegration:$/;" c
TestCommand setup.py /^class TestCommand(Command):$/;" c TestCommand setup.py /^class TestCommand(Command):$/;" c
TestInteractiveMCPClient tests/test_interactive_client.py /^class TestInteractiveMCPClient:$/;" c
TestInteractiveMCPClientIntegration tests/test_interactive_client.py /^class TestInteractiveMCPClientIntegration:$/;" c
TestMCPBrowser tests/test_basic.py /^class TestMCPBrowser:$/;" c TestMCPBrowser tests/test_basic.py /^class TestMCPBrowser:$/;" c
TestMessageFilter tests/test_basic.py /^class TestMessageFilter:$/;" c TestMessageFilter tests/test_basic.py /^class TestMessageFilter:$/;" c
TestToolRegistry tests/test_basic.py /^class TestToolRegistry:$/;" c TestToolRegistry tests/test_basic.py /^class TestToolRegistry:$/;" c
@ -103,12 +107,13 @@ __init__ mcp_browser/daemon.py /^ def __init__(self, socket_path: Path):$/;"
__init__ mcp_browser/default_configs.py /^ def __init__(self, config_dir: Optional[Path] = None):$/;" m class:ConfigManager __init__ mcp_browser/default_configs.py /^ def __init__(self, config_dir: Optional[Path] = None):$/;" m class:ConfigManager
__init__ mcp_browser/filter.py /^ def __init__(self, registry: ToolRegistry, server_callback: Callable):$/;" m class:VirtualToolHandler __init__ mcp_browser/filter.py /^ def __init__(self, registry: ToolRegistry, server_callback: Callable):$/;" m class:VirtualToolHandler
__init__ mcp_browser/filter.py /^ def __init__(self, registry: ToolRegistry, sparse_mode: bool = True):$/;" m class:MessageFilter __init__ mcp_browser/filter.py /^ def __init__(self, registry: ToolRegistry, sparse_mode: bool = True):$/;" m class:MessageFilter
__init__ mcp_browser/interactive_client.py /^ def __init__(self, server_name: Optional[str] = None, use_daemon: bool = True):$/;" m class:InteractiveMCPClient
__init__ mcp_browser/multi_server.py /^ def __init__(self, logger=None):$/;" m class:MultiServerManager __init__ mcp_browser/multi_server.py /^ def __init__(self, logger=None):$/;" m class:MultiServerManager
__init__ mcp_browser/proxy.py /^ def __init__(self, config_path: Optional[Path] = None, server_name: Optional[str] = None,$/;" m class:MCPBrowser __init__ mcp_browser/proxy.py /^ def __init__(self, config_path: Optional[Path] = None, server_name: Optional[str] = None,$/;" m class:MCPBrowser
__init__ mcp_browser/registry.py /^ def __init__(self):$/;" m class:ToolRegistry __init__ mcp_browser/registry.py /^ def __init__(self):$/;" m class:ToolRegistry
__init__ mcp_browser/server.py /^ def __init__(self, config: MCPServerConfig, logger: Optional[logging.Logger] = None):$/;" m class:MCPServer __init__ mcp_browser/server.py /^ def __init__(self, config: MCPServerConfig, logger: Optional[logging.Logger] = None):$/;" m class:MCPServer
__init__ mcp_servers/base.py /^ def __init__(self, name: str, version: str = "1.0.0"):$/;" m class:BaseMCPServer __init__ mcp_servers/base.py /^ def __init__(self, name: str, version: str = "1.0.0"):$/;" m class:BaseMCPServer
__init__ mcp_servers/memory/memory_server.py /^ def __init__(self):$/;" m class:MemoryServer __init__ mcp_servers/memory/memory_server.py /^ def __init__(self, identity: str = "default"):$/;" m class:MemoryServer
__init__ mcp_servers/onboarding/onboarding_server.py /^ def __init__(self):$/;" m class:OnboardingServer __init__ mcp_servers/onboarding/onboarding_server.py /^ def __init__(self):$/;" m class:OnboardingServer
__init__ mcp_servers/pattern_manager/pattern_server.py /^ def __init__(self):$/;" m class:PatternServer __init__ mcp_servers/pattern_manager/pattern_server.py /^ def __init__(self):$/;" m class:PatternServer
__init__ mcp_servers/screen/screen_server.py /^ def __init__(self):$/;" m class:ScreenServer __init__ mcp_servers/screen/screen_server.py /^ def __init__(self):$/;" m class:ScreenServer
@ -119,20 +124,35 @@ __version__ build/lib/mcp_browser/__init__.py /^__version__ = "0.1.0"$/;" v
__version__ mcp_browser/__init__.py /^__version__ = "0.1.0"$/;" v __version__ mcp_browser/__init__.py /^__version__ = "0.1.0"$/;" v
_add_pattern build/lib/mcp_servers/pattern_manager/pattern_server.py /^ async def _add_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer _add_pattern build/lib/mcp_servers/pattern_manager/pattern_server.py /^ async def _add_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer
_add_pattern mcp_servers/pattern_manager/pattern_server.py /^ async def _add_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer _add_pattern mcp_servers/pattern_manager/pattern_server.py /^ async def _add_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer
_add_user build/lib/mcp_servers/screen/screen_server.py /^ async def _add_user(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer
_add_user mcp_servers/screen/screen_server.py /^ async def _add_user(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer
_attach_multiuser build/lib/mcp_servers/screen/screen_server.py /^ async def _attach_multiuser(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer
_attach_multiuser mcp_servers/screen/screen_server.py /^ async def _attach_multiuser(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer
_calculate_checksum build/lib/mcp_browser/default_configs.py /^ def _calculate_checksum(self, filepath: Path) -> str:$/;" m class:ConfigManager _calculate_checksum build/lib/mcp_browser/default_configs.py /^ def _calculate_checksum(self, filepath: Path) -> str:$/;" m class:ConfigManager
_calculate_checksum mcp_browser/default_configs.py /^ def _calculate_checksum(self, filepath: Path) -> str:$/;" m class:ConfigManager _calculate_checksum mcp_browser/default_configs.py /^ def _calculate_checksum(self, filepath: Path) -> str:$/;" m class:ConfigManager
_call_mcp mcp_browser/interactive_client.py /^ async def _call_mcp(self, request: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:InteractiveMCPClient
_call_tool mcp_browser/interactive_client.py /^ async def _call_tool(self, args: List[str]):$/;" f
_call_tool_direct mcp_browser/interactive_client.py /^ async def _call_tool_direct(self, tool_name: str, args: List[str]):$/;" f
_completer mcp_browser/interactive_client.py /^ def _completer(self, text: str, state: int) -> Optional[str]:$/;" m class:InteractiveMCPClient
_create_cmem_bridges mcp_servers/memory/memory_server.py /^ def _create_cmem_bridges(self, identity_dir: Path, session_dir: Path):$/;" m class:MemoryServer
_create_session build/lib/mcp_servers/screen/screen_server.py /^ async def _create_session(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer _create_session build/lib/mcp_servers/screen/screen_server.py /^ async def _create_session(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer
_create_session mcp_servers/screen/screen_server.py /^ async def _create_session(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer _create_session mcp_servers/screen/screen_server.py /^ async def _create_session(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer
_decision_add build/lib/mcp_servers/memory/memory_server.py /^ async def _decision_add(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer _decision_add build/lib/mcp_servers/memory/memory_server.py /^ async def _decision_add(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer
_decision_add mcp_servers/memory/memory_server.py /^ async def _decision_add(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer _decision_add mcp_servers/memory/memory_server.py /^ async def _decision_add(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer
_delete_onboarding build/lib/mcp_servers/onboarding/onboarding_server.py /^ async def _delete_onboarding(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:OnboardingServer _delete_onboarding build/lib/mcp_servers/onboarding/onboarding_server.py /^ async def _delete_onboarding(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:OnboardingServer
_delete_onboarding mcp_servers/onboarding/onboarding_server.py /^ async def _delete_onboarding(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:OnboardingServer _delete_onboarding mcp_servers/onboarding/onboarding_server.py /^ async def _delete_onboarding(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:OnboardingServer
_discover_tools mcp_browser/interactive_client.py /^ async def _discover_tools(self, args: List[str]):$/;" f
_display_result mcp_browser/interactive_client.py /^ def _display_result(self, result: Any):$/;" f
_enable_multiuser build/lib/mcp_servers/screen/screen_server.py /^ async def _enable_multiuser(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer
_enable_multiuser mcp_servers/screen/screen_server.py /^ async def _enable_multiuser(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer
_ensure_config_file build/lib/mcp_browser/default_configs.py /^ def _ensure_config_file(self, filename: str, config_data: Dict[str, str]) -> None:$/;" m class:ConfigManager _ensure_config_file build/lib/mcp_browser/default_configs.py /^ def _ensure_config_file(self, filename: str, config_data: Dict[str, str]) -> None:$/;" m class:ConfigManager
_ensure_config_file mcp_browser/default_configs.py /^ def _ensure_config_file(self, filename: str, config_data: Dict[str, str]) -> None:$/;" m class:ConfigManager _ensure_config_file mcp_browser/default_configs.py /^ def _ensure_config_file(self, filename: str, config_data: Dict[str, str]) -> None:$/;" m class:ConfigManager
_execute_command build/lib/mcp_servers/screen/screen_server.py /^ async def _execute_command(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer _execute_command build/lib/mcp_servers/screen/screen_server.py /^ async def _execute_command(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer
_execute_command mcp_browser/interactive_client.py /^ async def _execute_command(self, line: str):$/;" m class:InteractiveMCPClient
_execute_command mcp_servers/screen/screen_server.py /^ async def _execute_command(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer _execute_command mcp_servers/screen/screen_server.py /^ async def _execute_command(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:ScreenServer
_execute_pattern build/lib/mcp_servers/pattern_manager/pattern_server.py /^ async def _execute_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer _execute_pattern build/lib/mcp_servers/pattern_manager/pattern_server.py /^ async def _execute_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer
_execute_pattern mcp_servers/pattern_manager/pattern_server.py /^ async def _execute_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer _execute_pattern mcp_servers/pattern_manager/pattern_server.py /^ async def _execute_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer
_execute_tool_call mcp_browser/interactive_client.py /^ async def _execute_tool_call(self, tool_name: str, arguments: Dict[str, Any]):$/;" f
_export_onboarding build/lib/mcp_servers/onboarding/onboarding_server.py /^ async def _export_onboarding(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:OnboardingServer _export_onboarding build/lib/mcp_servers/onboarding/onboarding_server.py /^ async def _export_onboarding(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:OnboardingServer
_export_onboarding mcp_servers/onboarding/onboarding_server.py /^ async def _export_onboarding(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:OnboardingServer _export_onboarding mcp_servers/onboarding/onboarding_server.py /^ async def _export_onboarding(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:OnboardingServer
_filter_tools_response build/lib/mcp_browser/filter.py /^ def _filter_tools_response(self, message: dict) -> dict:$/;" m class:MessageFilter _filter_tools_response build/lib/mcp_browser/filter.py /^ def _filter_tools_response(self, message: dict) -> dict:$/;" m class:MessageFilter
@ -141,6 +161,7 @@ _format_onboarding build/lib/mcp_servers/onboarding/onboarding_server.py /^ d
_format_onboarding mcp_servers/onboarding/onboarding_server.py /^ def _format_onboarding(self, identity: str, data: Dict[str, Any]) -> str:$/;" m class:OnboardingServer _format_onboarding mcp_servers/onboarding/onboarding_server.py /^ def _format_onboarding(self, identity: str, data: Dict[str, Any]) -> str:$/;" m class:OnboardingServer
_forward_to_server build/lib/mcp_browser/proxy.py /^ async def _forward_to_server(self, request: dict) -> dict:$/;" m class:MCPBrowser _forward_to_server build/lib/mcp_browser/proxy.py /^ async def _forward_to_server(self, request: dict) -> dict:$/;" m class:MCPBrowser
_forward_to_server mcp_browser/proxy.py /^ async def _forward_to_server(self, request: dict) -> dict:$/;" m class:MCPBrowser _forward_to_server mcp_browser/proxy.py /^ async def _forward_to_server(self, request: dict) -> dict:$/;" m class:MCPBrowser
_generate_sample_args mcp_browser/interactive_client.py /^ def _generate_sample_args(self, schema: Dict[str, Any]) -> Dict[str, Any]:$/;" f
_get_builtin_servers build/lib/mcp_browser/multi_server.py /^ def _get_builtin_servers(self) -> Dict[str, MCPServerConfig]:$/;" m class:MultiServerManager _get_builtin_servers build/lib/mcp_browser/multi_server.py /^ def _get_builtin_servers(self) -> Dict[str, MCPServerConfig]:$/;" m class:MultiServerManager
_get_builtin_servers mcp_browser/multi_server.py /^ def _get_builtin_servers(self) -> Dict[str, MCPServerConfig]:$/;" m class:MultiServerManager _get_builtin_servers mcp_browser/multi_server.py /^ def _get_builtin_servers(self) -> Dict[str, MCPServerConfig]:$/;" m class:MultiServerManager
_handle_call build/lib/mcp_browser/filter.py /^ async def _handle_call(self, message: dict) -> dict:$/;" m class:VirtualToolHandler _handle_call build/lib/mcp_browser/filter.py /^ async def _handle_call(self, message: dict) -> dict:$/;" m class:VirtualToolHandler
@ -169,12 +190,14 @@ _list_patterns build/lib/mcp_servers/pattern_manager/pattern_server.py /^ asy
_list_patterns mcp_servers/pattern_manager/pattern_server.py /^ async def _list_patterns(self) -> Dict[str, Any]:$/;" m class:PatternServer _list_patterns mcp_servers/pattern_manager/pattern_server.py /^ async def _list_patterns(self) -> Dict[str, Any]:$/;" m class:PatternServer
_list_sessions build/lib/mcp_servers/screen/screen_server.py /^ async def _list_sessions(self) -> Dict[str, Any]:$/;" m class:ScreenServer _list_sessions build/lib/mcp_servers/screen/screen_server.py /^ async def _list_sessions(self) -> Dict[str, Any]:$/;" m class:ScreenServer
_list_sessions mcp_servers/screen/screen_server.py /^ async def _list_sessions(self) -> Dict[str, Any]:$/;" m class:ScreenServer _list_sessions mcp_servers/screen/screen_server.py /^ async def _list_sessions(self) -> Dict[str, Any]:$/;" m class:ScreenServer
_list_tools mcp_browser/interactive_client.py /^ async def _list_tools(self, args: List[str]):$/;" f
_load_json build/lib/mcp_servers/memory/memory_server.py /^ def _load_json(self, filename: str, default: Any) -> Any:$/;" m class:MemoryServer _load_json build/lib/mcp_servers/memory/memory_server.py /^ def _load_json(self, filename: str, default: Any) -> Any:$/;" m class:MemoryServer
_load_json mcp_servers/memory/memory_server.py /^ def _load_json(self, filename: str, default: Any) -> Any:$/;" m class:MemoryServer _load_json mcp_servers/memory/memory_server.py /^ def _load_json(self, filename: str, default: Any) -> Any:$/;" m class:MemoryServer
_load_memory build/lib/mcp_servers/memory/memory_server.py /^ def _load_memory(self):$/;" m class:MemoryServer _load_memory build/lib/mcp_servers/memory/memory_server.py /^ def _load_memory(self):$/;" m class:MemoryServer
_load_memory mcp_servers/memory/memory_server.py /^ def _load_memory(self):$/;" m class:MemoryServer _load_memory mcp_servers/memory/memory_server.py /^ def _load_memory(self):$/;" m class:MemoryServer
_load_patterns build/lib/mcp_servers/pattern_manager/pattern_server.py /^ def _load_patterns(self) -> Dict[str, Dict[str, Any]]:$/;" m class:PatternServer _load_patterns build/lib/mcp_servers/pattern_manager/pattern_server.py /^ def _load_patterns(self) -> Dict[str, Dict[str, Any]]:$/;" m class:PatternServer
_load_patterns mcp_servers/pattern_manager/pattern_server.py /^ def _load_patterns(self) -> Dict[str, Dict[str, Any]]:$/;" m class:PatternServer _load_patterns mcp_servers/pattern_manager/pattern_server.py /^ def _load_patterns(self) -> Dict[str, Dict[str, Any]]:$/;" m class:PatternServer
_manage_onboarding mcp_browser/interactive_client.py /^ async def _manage_onboarding(self, args: List[str]):$/;" f
_mark_offline build/lib/mcp_browser/server.py /^ def _mark_offline(self):$/;" m class:MCPServer _mark_offline build/lib/mcp_browser/server.py /^ def _mark_offline(self):$/;" m class:MCPServer
_mark_offline mcp_browser/server.py /^ def _mark_offline(self):$/;" m class:MCPServer _mark_offline mcp_browser/server.py /^ def _mark_offline(self):$/;" m class:MCPServer
_matches_pattern build/lib/mcp_servers/pattern_manager/pattern_server.py /^ def _matches_pattern(self, text: str, trigger: List[str]) -> bool:$/;" m class:PatternServer _matches_pattern build/lib/mcp_servers/pattern_manager/pattern_server.py /^ def _matches_pattern(self, text: str, trigger: List[str]) -> bool:$/;" m class:PatternServer
@ -201,6 +224,7 @@ _read_stderr build/lib/mcp_browser/server.py /^ async def _read_stderr(self):
_read_stderr mcp_browser/server.py /^ async def _read_stderr(self):$/;" m class:MCPServer _read_stderr mcp_browser/server.py /^ async def _read_stderr(self):$/;" m class:MCPServer
_read_stdout build/lib/mcp_browser/server.py /^ async def _read_stdout(self):$/;" m class:MCPServer _read_stdout build/lib/mcp_browser/server.py /^ async def _read_stdout(self):$/;" m class:MCPServer
_read_stdout mcp_browser/server.py /^ async def _read_stdout(self):$/;" m class:MCPServer _read_stdout mcp_browser/server.py /^ async def _read_stdout(self):$/;" m class:MCPServer
_refresh_tools mcp_browser/interactive_client.py /^ async def _refresh_tools(self):$/;" m class:InteractiveMCPClient
_register_tools build/lib/mcp_servers/memory/memory_server.py /^ def _register_tools(self):$/;" m class:MemoryServer _register_tools build/lib/mcp_servers/memory/memory_server.py /^ def _register_tools(self):$/;" m class:MemoryServer
_register_tools build/lib/mcp_servers/onboarding/onboarding_server.py /^ def _register_tools(self):$/;" m class:OnboardingServer _register_tools build/lib/mcp_servers/onboarding/onboarding_server.py /^ def _register_tools(self):$/;" m class:OnboardingServer
_register_tools build/lib/mcp_servers/pattern_manager/pattern_server.py /^ def _register_tools(self):$/;" m class:PatternServer _register_tools build/lib/mcp_servers/pattern_manager/pattern_server.py /^ def _register_tools(self):$/;" m class:PatternServer
@ -219,10 +243,17 @@ _save_json build/lib/mcp_servers/memory/memory_server.py /^ def _save_json(se
_save_json mcp_servers/memory/memory_server.py /^ def _save_json(self, filename: str, data: Any):$/;" m class:MemoryServer _save_json mcp_servers/memory/memory_server.py /^ def _save_json(self, filename: str, data: Any):$/;" m class:MemoryServer
_save_patterns build/lib/mcp_servers/pattern_manager/pattern_server.py /^ def _save_patterns(self):$/;" m class:PatternServer _save_patterns build/lib/mcp_servers/pattern_manager/pattern_server.py /^ def _save_patterns(self):$/;" m class:PatternServer
_save_patterns mcp_servers/pattern_manager/pattern_server.py /^ def _save_patterns(self):$/;" m class:PatternServer _save_patterns mcp_servers/pattern_manager/pattern_server.py /^ def _save_patterns(self):$/;" m class:PatternServer
_setup_cmem_integration mcp_servers/memory/memory_server.py /^ def _setup_cmem_integration(self) -> bool:$/;" m class:MemoryServer
_setup_readline mcp_browser/interactive_client.py /^ def _setup_readline(self):$/;" m class:InteractiveMCPClient
_show_help mcp_browser/interactive_client.py /^ def _show_help(self):$/;" m class:InteractiveMCPClient
_show_status mcp_browser/interactive_client.py /^ async def _show_status(self):$/;" f
_signal_handler build/lib/mcp_browser/daemon.py /^ def _signal_handler(self, signum, frame):$/;" m class:MCPBrowserDaemon _signal_handler build/lib/mcp_browser/daemon.py /^ def _signal_handler(self, signum, frame):$/;" m class:MCPBrowserDaemon
_signal_handler mcp_browser/daemon.py /^ def _signal_handler(self, signum, frame):$/;" m class:MCPBrowserDaemon _signal_handler mcp_browser/daemon.py /^ def _signal_handler(self, signum, frame):$/;" m class:MCPBrowserDaemon
_start_config_watcher build/lib/mcp_browser/proxy.py /^ async def _start_config_watcher(self):$/;" m class:MCPBrowser _start_config_watcher build/lib/mcp_browser/proxy.py /^ async def _start_config_watcher(self):$/;" m class:MCPBrowser
_start_config_watcher mcp_browser/proxy.py /^ async def _start_config_watcher(self):$/;" m class:MCPBrowser _start_config_watcher mcp_browser/proxy.py /^ async def _start_config_watcher(self):$/;" m class:MCPBrowser
_sync_decision_to_cmem mcp_servers/memory/memory_server.py /^ async def _sync_decision_to_cmem(self, decision: Decision):$/;" m class:MemoryServer
_sync_pattern_to_cmem mcp_servers/memory/memory_server.py /^ async def _sync_pattern_to_cmem(self, pattern: Pattern, action: str):$/;" m class:MemoryServer
_sync_task_to_cmem mcp_servers/memory/memory_server.py /^ async def _sync_task_to_cmem(self, task: Task, action: str):$/;" m class:MemoryServer
_task_add build/lib/mcp_servers/memory/memory_server.py /^ async def _task_add(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer _task_add build/lib/mcp_servers/memory/memory_server.py /^ async def _task_add(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer
_task_add mcp_servers/memory/memory_server.py /^ async def _task_add(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer _task_add mcp_servers/memory/memory_server.py /^ async def _task_add(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer
_task_list build/lib/mcp_servers/memory/memory_server.py /^ async def _task_list(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer _task_list build/lib/mcp_servers/memory/memory_server.py /^ async def _task_list(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer
@ -231,6 +262,7 @@ _task_update build/lib/mcp_servers/memory/memory_server.py /^ async def _task
_task_update mcp_servers/memory/memory_server.py /^ async def _task_update(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer _task_update mcp_servers/memory/memory_server.py /^ async def _task_update(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:MemoryServer
_test_pattern build/lib/mcp_servers/pattern_manager/pattern_server.py /^ async def _test_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer _test_pattern build/lib/mcp_servers/pattern_manager/pattern_server.py /^ async def _test_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer
_test_pattern mcp_servers/pattern_manager/pattern_server.py /^ async def _test_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer _test_pattern mcp_servers/pattern_manager/pattern_server.py /^ async def _test_pattern(self, args: Dict[str, Any]) -> Dict[str, Any]:$/;" m class:PatternServer
_test_tool mcp_browser/interactive_client.py /^ async def _test_tool(self, args: List[str]):$/;" f
_update_server_configs build/lib/mcp_browser/proxy.py /^ def _update_server_configs(self):$/;" m class:MCPBrowser _update_server_configs build/lib/mcp_browser/proxy.py /^ def _update_server_configs(self):$/;" m class:MCPBrowser
_update_server_configs mcp_browser/proxy.py /^ def _update_server_configs(self):$/;" m class:MCPBrowser _update_server_configs mcp_browser/proxy.py /^ def _update_server_configs(self):$/;" m class:MCPBrowser
add_message_handler build/lib/mcp_browser/server.py /^ def add_message_handler(self, handler: Callable[[dict], None]):$/;" m class:MCPServer add_message_handler build/lib/mcp_browser/server.py /^ def add_message_handler(self, handler: Callable[[dict], None]):$/;" m class:MCPServer
@ -258,6 +290,7 @@ call mcp_browser/proxy.py /^ async def call(self, jsonrpc_object: Dict[str, A
call_tool build/lib/mcp_browser/__main__.py /^ call_tool = subparsers.add_parser("tools-call", help="Call a tool")$/;" v call_tool build/lib/mcp_browser/__main__.py /^ call_tool = subparsers.add_parser("tools-call", help="Call a tool")$/;" v
call_tool mcp_browser/__main__.py /^ call_tool = subparsers.add_parser("tools-call", help="Call a tool")$/;" v call_tool mcp_browser/__main__.py /^ call_tool = subparsers.add_parser("tools-call", help="Call a tool")$/;" v
classifiers setup.py /^ classifiers=[$/;" v classifiers setup.py /^ classifiers=[$/;" v
cleanup mcp_browser/interactive_client.py /^ async def cleanup(self):$/;" f
clear build/lib/mcp_browser/buffer.py /^ def clear(self):$/;" m class:JsonRpcBuffer clear build/lib/mcp_browser/buffer.py /^ def clear(self):$/;" m class:JsonRpcBuffer
clear mcp_browser/buffer.py /^ def clear(self):$/;" m class:JsonRpcBuffer clear mcp_browser/buffer.py /^ def clear(self):$/;" m class:JsonRpcBuffer
close build/lib/mcp_browser/daemon.py /^ async def close(self):$/;" m class:MCPBrowserClient close build/lib/mcp_browser/daemon.py /^ async def close(self):$/;" m class:MCPBrowserClient
@ -379,6 +412,7 @@ help mcp_browser/__main__.py /^ help="Test connection to s
include_package_data setup.py /^ include_package_data=True,$/;" v include_package_data setup.py /^ include_package_data=True,$/;" v
initialize build/lib/mcp_browser/proxy.py /^ async def initialize(self):$/;" m class:MCPBrowser initialize build/lib/mcp_browser/proxy.py /^ async def initialize(self):$/;" m class:MCPBrowser
initialize examples/ai_optimized.py /^ async def initialize(self):$/;" m class:AIAssistant initialize examples/ai_optimized.py /^ async def initialize(self):$/;" m class:AIAssistant
initialize mcp_browser/interactive_client.py /^ async def initialize(self):$/;" m class:InteractiveMCPClient
initialize mcp_browser/proxy.py /^ async def initialize(self):$/;" m class:MCPBrowser initialize mcp_browser/proxy.py /^ async def initialize(self):$/;" m class:MCPBrowser
initialize_options setup.py /^ def initialize_options(self):$/;" m class:GenerateAIDocs initialize_options setup.py /^ def initialize_options(self):$/;" m class:GenerateAIDocs
initialize_options setup.py /^ def initialize_options(self):$/;" m class:TestCommand initialize_options setup.py /^ def initialize_options(self):$/;" m class:TestCommand
@ -396,6 +430,7 @@ jsonrpc mcp_browser/__main__.py /^ jsonrpc = subparsers.add_parser("jsonrpc",
keywords setup.py /^ keywords="mcp model-context-protocol ai llm tools json-rpc",$/;" v keywords setup.py /^ keywords="mcp model-context-protocol ai llm tools json-rpc",$/;" v
kill_daemon_with_children build/lib/mcp_browser/daemon.py /^def kill_daemon_with_children(socket_path: Path) -> bool:$/;" f kill_daemon_with_children build/lib/mcp_browser/daemon.py /^def kill_daemon_with_children(socket_path: Path) -> bool:$/;" f
kill_daemon_with_children mcp_browser/daemon.py /^def kill_daemon_with_children(socket_path: Path) -> bool:$/;" f kill_daemon_with_children mcp_browser/daemon.py /^def kill_daemon_with_children(socket_path: Path) -> bool:$/;" f
license setup.py /^ license="GPL-3.0-or-later",$/;" v
load build/lib/mcp_browser/config.py /^ def load(self) -> MCPBrowserConfig:$/;" m class:ConfigLoader load build/lib/mcp_browser/config.py /^ def load(self) -> MCPBrowserConfig:$/;" m class:ConfigLoader
load mcp_browser/config.py /^ def load(self) -> MCPBrowserConfig:$/;" m class:ConfigLoader load mcp_browser/config.py /^ def load(self) -> MCPBrowserConfig:$/;" m class:ConfigLoader
load_config build/lib/mcp_browser/default_configs.py /^ def load_config(self) -> dict:$/;" m class:ConfigManager load_config build/lib/mcp_browser/default_configs.py /^ def load_config(self) -> dict:$/;" m class:ConfigManager
@ -414,11 +449,13 @@ main examples/basic_usage.py /^async def main():$/;" f
main mcp_browser/__main__.py /^def main():$/;" f main mcp_browser/__main__.py /^def main():$/;" f
main mcp_browser/client_main.py /^def main():$/;" f main mcp_browser/client_main.py /^def main():$/;" f
main mcp_browser/daemon_main.py /^def main():$/;" f main mcp_browser/daemon_main.py /^def main():$/;" f
main mcp_browser/interactive_client.py /^async def main():$/;" f
main test_mcp_protocol.py /^async def main():$/;" f main test_mcp_protocol.py /^async def main():$/;" f
main tests/test_browser_functionality.py /^def main():$/;" f main tests/test_browser_functionality.py /^def main():$/;" f
main tests/test_integration.py /^async def main():$/;" f main tests/test_integration.py /^async def main():$/;" f
mark_handled build/lib/mcp_browser/filter.py /^ def mark_handled(self, request_id: Union[str, int]):$/;" m class:MessageFilter mark_handled build/lib/mcp_browser/filter.py /^ def mark_handled(self, request_id: Union[str, int]):$/;" m class:MessageFilter
mark_handled mcp_browser/filter.py /^ def mark_handled(self, request_id: Union[str, int]):$/;" m class:MessageFilter mark_handled mcp_browser/filter.py /^ def mark_handled(self, request_id: Union[str, int]):$/;" m class:MessageFilter
mock_call tests/test_interactive_client.py /^ def mock_call(request):$/;" f function:TestInteractiveMCPClientIntegration.test_full_workflow_mock
name setup.py /^ name="mcp-browser",$/;" v name setup.py /^ name="mcp-browser",$/;" v
package_data setup.py /^ package_data={$/;" v package_data setup.py /^ package_data={$/;" v
packages setup.py /^ packages=find_packages(include=['mcp_browser*', 'mcp_servers*']),$/;" v packages setup.py /^ packages=find_packages(include=['mcp_browser*', 'mcp_servers*']),$/;" v
@ -437,6 +474,7 @@ route_tool_call mcp_browser/multi_server.py /^ async def route_tool_call(self
run build/lib/mcp_browser/client_main.py /^ async def run():$/;" f function:main run build/lib/mcp_browser/client_main.py /^ async def run():$/;" f function:main
run build/lib/mcp_servers/base.py /^ async def run(self):$/;" m class:BaseMCPServer run build/lib/mcp_servers/base.py /^ async def run(self):$/;" m class:BaseMCPServer
run mcp_browser/client_main.py /^ async def run():$/;" f function:main run mcp_browser/client_main.py /^ async def run():$/;" f function:main
run mcp_browser/interactive_client.py /^ async def run(self):$/;" m class:InteractiveMCPClient
run mcp_servers/base.py /^ async def run(self):$/;" m class:BaseMCPServer run mcp_servers/base.py /^ async def run(self):$/;" m class:BaseMCPServer
run setup.py /^ def run(self):$/;" m class:GenerateAIDocs run setup.py /^ def run(self):$/;" m class:GenerateAIDocs
run setup.py /^ def run(self):$/;" m class:TestCommand run setup.py /^ def run(self):$/;" m class:TestCommand
@ -475,6 +513,8 @@ set_onboarding_text build/lib/mcp_browser/default_configs.py /^ def set_onboa
set_onboarding_text mcp_browser/default_configs.py /^ def set_onboarding_text(self, text: str, identity: Optional[str] = None) -> None:$/;" m class:ConfigManager set_onboarding_text mcp_browser/default_configs.py /^ def set_onboarding_text(self, text: str, identity: Optional[str] = None) -> None:$/;" m class:ConfigManager
setup_logging build/lib/mcp_browser/logging_config.py /^def setup_logging(debug: bool = False, log_file: Optional[Path] = None, $/;" f setup_logging build/lib/mcp_browser/logging_config.py /^def setup_logging(debug: bool = False, log_file: Optional[Path] = None, $/;" f
setup_logging mcp_browser/logging_config.py /^def setup_logging(debug: bool = False, log_file: Optional[Path] = None, $/;" f setup_logging mcp_browser/logging_config.py /^def setup_logging(debug: bool = False, log_file: Optional[Path] = None, $/;" f
setup_method tests/test_cmem_integration.py /^ def setup_method(self):$/;" m class:TestCmemIntegration
setup_method tests/test_interactive_client.py /^ def setup_method(self):$/;" m class:TestInteractiveMCPClient
show_available_servers build/lib/mcp_browser/__main__.py /^def show_available_servers(config_path: Optional[str] = None):$/;" f show_available_servers build/lib/mcp_browser/__main__.py /^def show_available_servers(config_path: Optional[str] = None):$/;" f
show_available_servers mcp_browser/__main__.py /^def show_available_servers(config_path: Optional[str] = None):$/;" f show_available_servers mcp_browser/__main__.py /^def show_available_servers(config_path: Optional[str] = None):$/;" f
show_configuration build/lib/mcp_browser/__main__.py /^def show_configuration(config_path: Optional[str] = None):$/;" f show_configuration build/lib/mcp_browser/__main__.py /^def show_configuration(config_path: Optional[str] = None):$/;" f
@ -509,24 +549,57 @@ test_basic_flow tests/test_integration.py /^async def test_basic_flow():$/;" f
test_brave_search_integration tests/test_brave_search.py /^async def test_brave_search_integration():$/;" f test_brave_search_integration tests/test_brave_search.py /^async def test_brave_search_integration():$/;" f
test_browser_without_servers tests/test_basic.py /^ async def test_browser_without_servers(self):$/;" m class:TestMCPBrowser test_browser_without_servers tests/test_basic.py /^ async def test_browser_without_servers(self):$/;" m class:TestMCPBrowser
test_browser_without_servers tests/test_browser_functionality.py /^async def test_browser_without_servers():$/;" f test_browser_without_servers tests/test_browser_functionality.py /^async def test_browser_without_servers():$/;" f
test_call_mcp_browser tests/test_interactive_client.py /^ async def test_call_mcp_browser(self):$/;" m class:TestInteractiveMCPClient
test_call_mcp_client tests/test_interactive_client.py /^ async def test_call_mcp_client(self):$/;" m class:TestInteractiveMCPClient
test_claude_connection tests/test_claude_connection.py /^async def test_claude_connection():$/;" f test_claude_connection tests/test_claude_connection.py /^async def test_claude_connection():$/;" f
test_completer_commands tests/test_interactive_client.py /^ def test_completer_commands(self):$/;" m class:TestInteractiveMCPClient
test_completer_tools tests/test_interactive_client.py /^ def test_completer_tools(self):$/;" m class:TestInteractiveMCPClient
test_create_cmem_bridges tests/test_cmem_integration.py /^ def test_create_cmem_bridges(self):$/;" m class:TestCmemIntegration
test_daemon_initialization test_mcp_protocol.py /^async def test_daemon_initialization():$/;" f test_daemon_initialization test_mcp_protocol.py /^async def test_daemon_initialization():$/;" f
test_direct_initialization test_mcp_protocol.py /^async def test_direct_initialization():$/;" f test_direct_initialization test_mcp_protocol.py /^async def test_direct_initialization():$/;" f
test_discover_jsonpath tests/test_basic.py /^ def test_discover_jsonpath(self):$/;" m class:TestToolRegistry test_discover_jsonpath tests/test_basic.py /^ def test_discover_jsonpath(self):$/;" m class:TestToolRegistry
test_discovery test_discovery.py /^async def test_discovery():$/;" f test_discovery test_discovery.py /^async def test_discovery():$/;" f
test_display_result_image_content tests/test_interactive_client.py /^ def test_display_result_image_content(self):$/;" m class:TestInteractiveMCPClient
test_display_result_raw_data tests/test_interactive_client.py /^ def test_display_result_raw_data(self):$/;" m class:TestInteractiveMCPClient
test_display_result_text_content tests/test_interactive_client.py /^ def test_display_result_text_content(self):$/;" m class:TestInteractiveMCPClient
test_double_handshake_issue test_mcp_protocol.py /^async def test_double_handshake_issue():$/;" f test_double_handshake_issue test_mcp_protocol.py /^async def test_double_handshake_issue():$/;" f
test_duplicate_error_filtering tests/test_basic.py /^ def test_duplicate_error_filtering(self):$/;" m class:TestMessageFilter test_duplicate_error_filtering tests/test_basic.py /^ def test_duplicate_error_filtering(self):$/;" m class:TestMessageFilter
test_error_handling tests/test_integration.py /^async def test_error_handling():$/;" f test_error_handling tests/test_integration.py /^async def test_error_handling():$/;" f
test_execute_command_help tests/test_interactive_client.py /^ async def test_execute_command_help(self):$/;" m class:TestInteractiveMCPClient
test_execute_command_list tests/test_interactive_client.py /^ async def test_execute_command_list(self):$/;" m class:TestInteractiveMCPClient
test_execute_command_refresh tests/test_interactive_client.py /^ async def test_execute_command_refresh(self):$/;" m class:TestInteractiveMCPClient
test_execute_command_unknown_tool tests/test_interactive_client.py /^ async def test_execute_command_unknown_tool(self):$/;" m class:TestInteractiveMCPClient
test_execute_tool_call tests/test_interactive_client.py /^ async def test_execute_tool_call(self):$/;" m class:TestInteractiveMCPClient
test_execute_tool_call_error tests/test_interactive_client.py /^ async def test_execute_tool_call_error(self):$/;" m class:TestInteractiveMCPClient
test_full_workflow_mock tests/test_interactive_client.py /^ async def test_full_workflow_mock(self):$/;" m class:TestInteractiveMCPClientIntegration
test_generate_sample_args_examples tests/test_interactive_client.py /^ def test_generate_sample_args_examples(self):$/;" m class:TestInteractiveMCPClient
test_generate_sample_args_string tests/test_interactive_client.py /^ def test_generate_sample_args_string(self):$/;" m class:TestInteractiveMCPClient
test_generate_sample_args_types tests/test_interactive_client.py /^ def test_generate_sample_args_types(self):$/;" m class:TestInteractiveMCPClient
test_initialization tests/test_interactive_client.py /^ def test_initialization(self):$/;" m class:TestInteractiveMCPClient
test_memory_server_initialization_custom_identity tests/test_cmem_integration.py /^ def test_memory_server_initialization_custom_identity(self):$/;" m class:TestCmemIntegration
test_memory_server_initialization_default tests/test_cmem_integration.py /^ def test_memory_server_initialization_default(self):$/;" m class:TestCmemIntegration
test_message_filter tests/test_simple.py /^def test_message_filter():$/;" f test_message_filter tests/test_simple.py /^def test_message_filter():$/;" f
test_onboarding tests/test_onboarding.py /^async def test_onboarding():$/;" f test_onboarding tests/test_onboarding.py /^async def test_onboarding():$/;" f
test_refresh_tools tests/test_interactive_client.py /^ async def test_refresh_tools(self):$/;" m class:TestInteractiveMCPClient
test_screen_multiuser test_screen_multiuser.py /^async def test_screen_multiuser():$/;" f
test_screen_utf8 test_screen_utf8.py /^async def test_screen_utf8():$/;" f test_screen_utf8 test_screen_utf8.py /^async def test_screen_utf8():$/;" f
test_server_connection build/lib/mcp_browser/__main__.py /^async def test_server_connection(browser: MCPBrowser, server_name: Optional[str] = None):$/;" f test_server_connection build/lib/mcp_browser/__main__.py /^async def test_server_connection(browser: MCPBrowser, server_name: Optional[str] = None):$/;" f
test_server_connection mcp_browser/__main__.py /^async def test_server_connection(browser: MCPBrowser, server_name: Optional[str] = None):$/;" f test_server_connection mcp_browser/__main__.py /^async def test_server_connection(browser: MCPBrowser, server_name: Optional[str] = None):$/;" f
test_server_mode_initialization test_mcp_protocol.py /^async def test_server_mode_initialization():$/;" f test_server_mode_initialization test_mcp_protocol.py /^async def test_server_mode_initialization():$/;" f
test_server_mode_timeout test_claude_desktop_flow.py /^async def test_server_mode_timeout():$/;" f test_server_mode_timeout test_claude_desktop_flow.py /^async def test_server_mode_timeout():$/;" f
test_setup_cmem_integration_available tests/test_cmem_integration.py /^ def test_setup_cmem_integration_available(self):$/;" m class:TestCmemIntegration
test_setup_cmem_integration_no_cmem tests/test_cmem_integration.py /^ def test_setup_cmem_integration_no_cmem(self):$/;" m class:TestCmemIntegration
test_sparse_mode tests/test_simple.py /^def test_sparse_mode():$/;" f test_sparse_mode tests/test_simple.py /^def test_sparse_mode():$/;" f
test_sparse_mode_filtering tests/test_basic.py /^ def test_sparse_mode_filtering(self):$/;" m class:TestMessageFilter test_sparse_mode_filtering tests/test_basic.py /^ def test_sparse_mode_filtering(self):$/;" m class:TestMessageFilter
test_sparse_tools tests/test_basic.py /^ def test_sparse_tools(self):$/;" m class:TestToolRegistry test_sparse_tools tests/test_basic.py /^ def test_sparse_tools(self):$/;" m class:TestToolRegistry
test_sync_decision_to_cmem tests/test_cmem_integration.py /^ async def test_sync_decision_to_cmem(self):$/;" m class:TestCmemIntegration
test_sync_error_handling tests/test_cmem_integration.py /^ async def test_sync_error_handling(self):$/;" m class:TestCmemIntegration
test_sync_pattern_to_cmem tests/test_cmem_integration.py /^ async def test_sync_pattern_to_cmem(self):$/;" m class:TestCmemIntegration
test_sync_task_to_cmem_add tests/test_cmem_integration.py /^ async def test_sync_task_to_cmem_add(self):$/;" m class:TestCmemIntegration
test_sync_task_to_cmem_complete tests/test_cmem_integration.py /^ async def test_sync_task_to_cmem_complete(self):$/;" m class:TestCmemIntegration
test_sync_with_integration_disabled tests/test_cmem_integration.py /^ async def test_sync_with_integration_disabled(self):$/;" m class:TestCmemIntegration
test_task_add_with_sync tests/test_cmem_integration.py /^ async def test_task_add_with_sync(self):$/;" m class:TestCmemIntegration
test_task_update_completion_with_sync tests/test_cmem_integration.py /^ async def test_task_update_completion_with_sync(self):$/;" m class:TestCmemIntegration
test_tool_registry tests/test_simple.py /^def test_tool_registry():$/;" f test_tool_registry tests/test_simple.py /^def test_tool_registry():$/;" f
test_update_tools tests/test_basic.py /^ def test_update_tools(self):$/;" m class:TestToolRegistry test_update_tools tests/test_basic.py /^ def test_update_tools(self):$/;" m class:TestToolRegistry
test_virtual_tool_handling tests/test_basic.py /^ async def test_virtual_tool_handling(self):$/;" m class:TestMCPBrowser test_virtual_tool_handling tests/test_basic.py /^ async def test_virtual_tool_handling(self):$/;" m class:TestMCPBrowser

View File

@ -40,8 +40,9 @@ python setup.py aidocs
1. **Virtual Tools**: `mcp_discover`, `mcp_call`, and `onboarding` exist only in the browser layer 1. **Virtual Tools**: `mcp_discover`, `mcp_call`, and `onboarding` exist only in the browser layer
2. **Tool Namespacing**: Format is `server::tool` or `mcp__namespace__tool` 2. **Tool Namespacing**: Format is `server::tool` or `mcp__namespace__tool`
3. **Multi-Server**: Built-in servers (screen, memory, patterns, onboarding) start automatically 3. **Multi-Server**: Built-in servers (tmux, memory, patterns, onboarding) start automatically
4. **Identity-Aware**: Onboarding tool accepts identity parameter for context-specific instructions 4. **Identity-Aware**: Onboarding tool accepts identity parameter for context-specific instructions
5. **Session Management**: Tmux preferred over screen for better multi-user support
### Architecture Overview ### Architecture Overview
@ -55,7 +56,7 @@ mcp_browser/
mcp_servers/ mcp_servers/
├── base.py # Base class for Python MCP servers ├── base.py # Base class for Python MCP servers
├── screen/ # GNU screen session management ├── screen/ # Session management (tmux preferred, screen legacy)
├── memory/ # Persistent memory and tasks ├── memory/ # Persistent memory and tasks
├── patterns/ # Auto-response patterns ├── patterns/ # Auto-response patterns
└── onboarding/ # Identity-aware onboarding └── onboarding/ # Identity-aware onboarding

111
MCP_QUICK_REFERENCE.md Normal file
View File

@ -0,0 +1,111 @@
# MCP Quick Reference for Fresh Claude Instances
## 🔗 MCP Interface Access
**Status**: ✅ mcp-browser is configured and running
- **Claude Desktop****mcp-browser** → **27 tools from 7 servers**
- **Config**: `/home/claude/.claude/mcp-browser/config.yaml`
- **Tools**: Built-in servers (screen, memory, patterns, onboarding) + external (claude-code, brave-search, filesystem, github)
## 🚀 Quick MCP Commands
### Discovery (Context-Safe)
```python
# List all available tool names (27 total)
mcp_discover(jsonpath="$.tools[*].name")
# Find memory-related tools (regex support)
mcp_discover(jsonpath="$.tools[?(@.name =~ /memory|task|pattern/i)]")
# Get server information
mcp_discover(jsonpath="$.servers[*].name")
# Get claude-code tools specifically
mcp_discover(jsonpath="$.servers['claude-code'].tools[*].name")
```
### Tool Execution
```python
# Call any discovered tool
mcp_call(
method="tools/call",
params={
"name": "task_list",
"arguments": {"status": "pending"}
}
)
# Call claude-code tools
mcp_call(
method="tools/call",
params={
"name": "claude-code::read_file",
"arguments": {"path": "/path/to/file.py"}
}
)
```
## 🧠 Memory & Handoff System
### Get Current Context
```bash
cmem handoff # Quick context summary
cmem task list # Active tasks
cmem pattern list # Available patterns
```
### Essential Memory Tools (via MCP)
- `task_add` - Add new tasks with priority/assignee
- `task_update` - Update task status
- `memory_summary` - Get project overview
- `knowledge_add` - Store information
- `pattern_add` - Record learning patterns
## 🛠️ Built-in MCP Tools Available
**Screen Management (8 tools)**:
- `create_session`, `execute`, `peek`, `list_sessions`, `kill_session`
**Memory & Tasks (10 tools)**:
- `task_add`, `task_list`, `task_update`, `decision_add`, `pattern_add`
**Auto-Response Patterns (5 tools)**:
- `add_pattern`, `list_patterns`, `test_pattern`
**Identity & Onboarding (4 tools)**:
- `onboarding`, `onboarding_list`, `onboarding_export`
## 🎯 Current Project Context
**Location**: `/mnt/data/claude/claude` (bind mounted from `/home/claude`)
**Active Projects**:
- `mcp-browser` (✅ Working, integrated)
- `xilope` (🔄 In development - XDG config system needed)
**Memory Storage**: `/mnt/data/claude/claude/.mcp-memory/`
**cmem Wrapper**: `/mnt/data/claude/claude/bin/cmem``/usr/local/bin/cmem`
## 🔧 For Fresh Claude Instances
1. **Read this file** for MCP context
2. **Run `cmem handoff`** for session continuity
3. **Use `mcp_discover`** to explore available tools
4. **Check `CLAUDE.md`** for project-specific instructions
5. **Access Xilope onboarding**: `onboarding(identity="xilope_production")`
## 📚 Documentation Locations
- **Handoff Guide**: `/home/claude/claude-utils/mcp-browser/HANDOFF_INSTRUCTIONS.md`
- **Xilope Production**: `/home/claude/claude-utils/mcp-browser/mcp_servers/onboarding/xilope_production.md`
- **MCP Config**: `/home/claude/.claude/mcp-browser/config.yaml`
- **Memory Files**: `/mnt/data/claude/claude/.mcp-memory/default/`
## ⚡ Generate Complete API Docs
```bash
cd /home/claude/claude-utils/mcp-browser
python setup.py gen_apidoc
# Creates: mcp_api_documentation.json (27 tools, 7 servers documented)
```
This provides **complete MCP ecosystem access** with persistent memory across Claude sessions.

View File

@ -33,7 +33,8 @@ MCP Browser acts as a smart proxy between AI systems and MCP servers, providing:
- Configuration-driven server management - Configuration-driven server management
4. **Built-in Servers** 4. **Built-in Servers**
- **Screen**: GNU screen session management for persistent processes - **Tmux**: tmux session management for persistent processes (default)
- **Screen**: GNU screen session management (legacy, disabled by default)
- **Memory**: Project memory, tasks, decisions, and knowledge management - **Memory**: Project memory, tasks, decisions, and knowledge management
- **Patterns**: Auto-response pattern management for automation - **Patterns**: Auto-response pattern management for automation
- **Onboarding**: Identity-aware onboarding for AI contexts - **Onboarding**: Identity-aware onboarding for AI contexts
@ -53,7 +54,7 @@ mcp-browser/
│ └── config.py # Configuration management │ └── config.py # Configuration management
├── mcp_servers/ # Built-in MCP servers ├── mcp_servers/ # Built-in MCP servers
│ ├── base.py # Base server implementation │ ├── base.py # Base server implementation
│ ├── screen/ # Screen session management │ ├── screen/ # Session management (tmux + screen)
│ ├── memory/ # Memory and context management │ ├── memory/ # Memory and context management
│ ├── pattern_manager/ # Pattern automation │ ├── pattern_manager/ # Pattern automation
│ └── onboarding/ # Identity-aware onboarding │ └── onboarding/ # Identity-aware onboarding

View File

@ -6,6 +6,7 @@
test_claude_desktop_flow.py test_claude_desktop_flow.py
test_discovery.py test_discovery.py
test_mcp_protocol.py test_mcp_protocol.py
test_screen_multiuser.py
test_screen_utf8.py test_screen_utf8.py
mcp_browser.egg-info/ mcp_browser.egg-info/
systemd/ systemd/
@ -55,7 +56,9 @@
test_brave_search.py test_brave_search.py
test_browser_functionality.py test_browser_functionality.py
test_claude_connection.py test_claude_connection.py
test_cmem_integration.py
test_integration.py test_integration.py
test_interactive_client.py
test_onboarding.py test_onboarding.py
test_simple.py test_simple.py
config/ config/
@ -84,6 +87,7 @@
daemon_main.py daemon_main.py
default_configs.py default_configs.py
filter.py filter.py
interactive_client.py
logging_config.py logging_config.py
multi_server.py multi_server.py
proxy.py proxy.py

165
mcp_api_documentation.json Normal file
View File

@ -0,0 +1,165 @@
{
"mcp_browser_version": "0.2.0",
"total_servers": 7,
"total_tools": 27,
"generation_timestamp": "2025-06-28T13:16:38.436458",
"servers": {
"default": {
"name": "default",
"description": "Default in-memory MCP server",
"command": [
"npx",
"-y",
"@modelcontextprotocol/server-memory"
],
"status": "configured",
"tools": [],
"tool_count": 0,
"tool_names": [],
"environment": {},
"working_directory": null,
"capabilities": []
},
"claude-code": {
"name": "claude-code",
"description": "MCP interface to claude code started in /home/claude",
"command": [
"/home/claude/bin/claude"
],
"status": "configured",
"tools": [],
"tool_count": 0,
"tool_names": [],
"environment": {},
"working_directory": null,
"capabilities": []
},
"brave-search": {
"name": "brave-search",
"description": "Brave Search API access",
"command": [
"npx",
"-y",
"@modelcontextprotocol/server-brave-search"
],
"status": "configured",
"tools": [],
"tool_count": 0,
"tool_names": [],
"environment": {},
"working_directory": null,
"capabilities": []
},
"filesystem": {
"name": "filesystem",
"description": "File system access (/home/claude)",
"command": [
"npx",
"-y",
"@modelcontextprotocol/server-filesystem",
"/home/claude"
],
"status": "configured",
"tools": [],
"tool_count": 0,
"tool_names": [],
"environment": {},
"working_directory": null,
"capabilities": []
},
"github": {
"name": "github",
"description": "GitHub API access",
"command": [
"npx",
"-y",
"@modelcontextprotocol/server-github"
],
"status": "configured",
"tools": [],
"tool_count": 0,
"tool_names": [],
"environment": {},
"working_directory": null,
"capabilities": []
},
"memory": {
"name": "memory",
"description": "Persistent memory and notes",
"command": [
"npx",
"-y",
"@modelcontextprotocol/server-memory"
],
"status": "configured",
"tools": [],
"tool_count": 0,
"tool_names": [],
"environment": {},
"working_directory": null,
"capabilities": []
},
"builtin-only": {
"name": "builtin-only",
"description": "Use only built-in Python servers",
"command": null,
"status": "configured",
"tools": [],
"tool_count": 0,
"tool_names": [],
"environment": {},
"working_directory": null,
"capabilities": []
}
},
"builtin": {
"name": "builtin",
"description": "Built-in MCP Browser servers (screen, memory, patterns, onboarding)",
"status": "active",
"tools": [],
"tool_count": 0,
"capabilities": [
"screen_management",
"memory_storage",
"pattern_matching",
"onboarding_management"
]
},
"discovery_patterns": {
"all_tools": "$.tools[*]",
"all_tool_names": "$.tools[*].name",
"tools_by_server": "$.servers[*].tools[*]",
"tool_schemas": "$.tools[*].inputSchema",
"memory_tools": "$.tools[?(@.name =~ /memory|task|pattern|knowledge/i)]",
"screen_tools": "$.tools[?(@.name =~ /screen|session/i)]",
"find_tool_by_name": "$.tools[?(@.name=='TOOL_NAME')]",
"server_capabilities": "$.servers[*].capabilities"
},
"sparse_mode_info": {
"visible_tools": [
"mcp_discover",
"mcp_call",
"onboarding"
],
"hidden_tools": 27,
"purpose": "Context optimization - full MCP API accessible via proxy tools"
},
"runtime_status": {
"builtin:screen": {
"status": "active",
"pid": 589886
},
"builtin:memory": {
"status": "active",
"pid": 589890
},
"builtin:patterns": {
"status": "active",
"pid": 589905
},
"builtin:onboarding": {
"status": "active",
"pid": 589908
}
}
}

View File

@ -22,6 +22,7 @@ class MCPServerConfig:
env: Dict[str, str] = field(default_factory=dict) env: Dict[str, str] = field(default_factory=dict)
name: Optional[str] = None name: Optional[str] = None
description: Optional[str] = None description: Optional[str] = None
enabled: bool = True
@dataclass @dataclass
@ -88,7 +89,8 @@ class ConfigLoader:
args=server_config.get("args", []), args=server_config.get("args", []),
env=server_config.get("env", {}), env=server_config.get("env", {}),
name=server_config.get("name", name), name=server_config.get("name", name),
description=server_config.get("description") description=server_config.get("description"),
enabled=server_config.get("enabled", True)
) )
self._config = MCPBrowserConfig( self._config = MCPBrowserConfig(

View File

@ -28,10 +28,16 @@ class MultiServerManager:
base_path = Path(__file__).parent.parent / "mcp_servers" base_path = Path(__file__).parent.parent / "mcp_servers"
return { return {
"builtin:tmux": MCPServerConfig(
command=["python3", str(base_path / "screen" / "tmux_server.py")],
name="tmux",
description="tmux session management"
),
"builtin:screen": MCPServerConfig( "builtin:screen": MCPServerConfig(
command=["python3", str(base_path / "screen" / "screen_server.py")], command=["python3", str(base_path / "screen" / "screen_server.py")],
name="screen", name="screen",
description="GNU screen session management" description="GNU screen session management (legacy)",
enabled=False # Disabled by default, tmux is preferred
), ),
"builtin:memory": MCPServerConfig( "builtin:memory": MCPServerConfig(
command=["python3", str(base_path / "memory" / "memory_server.py")], command=["python3", str(base_path / "memory" / "memory_server.py")],
@ -53,6 +59,11 @@ class MultiServerManager:
async def start_builtin_servers(self): async def start_builtin_servers(self):
"""Start all built-in servers.""" """Start all built-in servers."""
for name, config in self.builtin_servers.items(): for name, config in self.builtin_servers.items():
# Skip disabled servers
if not config.enabled:
self.logger.info(f"Skipping disabled built-in server: {name}")
continue
self.logger.info(f"Starting built-in server: {name}") self.logger.info(f"Starting built-in server: {name}")
server = MCPServer(config, logger=get_logger(__name__, name)) server = MCPServer(config, logger=get_logger(__name__, name))

View File

@ -0,0 +1,324 @@
#!/usr/bin/env python3
"""
Tmux MCP Server - tmux session management.
Provides tools for creating and managing persistent tmux sessions,
useful for long-running processes and maintaining shell state.
"""
import os
import sys
import asyncio
import subprocess
import json
from typing import Dict, Any, List, Optional
from pathlib import Path
# Add parent directory to path
sys.path.append(str(Path(__file__).parent.parent))
from base import BaseMCPServer
class TmuxServer(BaseMCPServer):
"""MCP server for tmux management."""
def __init__(self):
super().__init__("tmux-server", "1.0.0")
self._register_tools()
def _register_tools(self):
"""Register all tmux management tools."""
# Create session tool
self.register_tool(
name="create_session",
description="Create a new tmux session with optional initial command",
input_schema={
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name for the tmux session"
},
"command": {
"type": "string",
"description": "Optional command to run in the session"
}
},
"required": ["name"]
}
)
# Execute command tool
self.register_tool(
name="execute",
description="Execute a command in an existing tmux session",
input_schema={
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Name of the tmux session"
},
"command": {
"type": "string",
"description": "Command to execute"
}
},
"required": ["session", "command"]
}
)
# Peek at session output
self.register_tool(
name="peek",
description="Get recent output from a tmux session (last 50 lines by default)",
input_schema={
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Name of the tmux session"
},
"lines": {
"type": "integer",
"description": "Number of lines to retrieve (default: 50)",
"default": 50
}
},
"required": ["session"]
}
)
# List sessions
self.register_tool(
name="list_sessions",
description="List all active tmux sessions",
input_schema={
"type": "object",
"properties": {}
}
)
# Kill session
self.register_tool(
name="kill_session",
description="Terminate a tmux session",
input_schema={
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Name of the tmux session to kill"
}
},
"required": ["session"]
}
)
# Attach to session (provides instructions)
self.register_tool(
name="attach_session",
description="Provide instructions for attaching to a tmux session",
input_schema={
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Name of the tmux session"
}
},
"required": ["session"]
}
)
# Share session (tmux supports multiple clients by default)
self.register_tool(
name="share_session",
description="Get instructions for sharing a tmux session with other users",
input_schema={
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Name of the tmux session"
}
},
"required": ["session"]
}
)
async def handle_tool_call(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
"""Handle tmux tool calls."""
if tool_name == "create_session":
return await self._create_session(arguments)
elif tool_name == "execute":
return await self._execute_command(arguments)
elif tool_name == "peek":
return await self._peek_session(arguments)
elif tool_name == "list_sessions":
return await self._list_sessions()
elif tool_name == "kill_session":
return await self._kill_session(arguments)
elif tool_name == "attach_session":
return await self._attach_session(arguments)
elif tool_name == "share_session":
return await self._share_session(arguments)
else:
raise Exception(f"Unknown tool: {tool_name}")
async def _create_session(self, args: Dict[str, Any]) -> Dict[str, Any]:
"""Create a new tmux session."""
name = args["name"]
command = args.get("command")
# Check if session already exists
check_result = await self._run_command(["tmux", "list-sessions", "-F", "#{session_name}"])
if check_result.returncode == 0 and name in check_result.stdout.split('\n'):
return self.content_text(f"Session '{name}' already exists")
# Create session
cmd = ["tmux", "new-session", "-d", "-s", name]
if command:
cmd.append(command)
result = await self._run_command(cmd)
if result.returncode == 0:
return self.content_text(f"Created tmux session '{name}'" +
(f" running '{command}'" if command else ""))
else:
return self.content_text(f"Failed to create session: {result.stderr}")
async def _execute_command(self, args: Dict[str, Any]) -> Dict[str, Any]:
"""Execute a command in a tmux session."""
session = args["session"]
command = args["command"]
# Send command to tmux session
cmd = ["tmux", "send-keys", "-t", session, command, "Enter"]
result = await self._run_command(cmd)
if result.returncode == 0:
return self.content_text(f"Executed command in session '{session}'")
else:
return self.content_text(f"Failed to execute command: {result.stderr}")
async def _peek_session(self, args: Dict[str, Any]) -> Dict[str, Any]:
"""Get recent output from a tmux session."""
session = args["session"]
lines = args.get("lines", 50)
# Get pane content from tmux
cmd = ["tmux", "capture-pane", "-t", session, "-p"]
result = await self._run_command(cmd)
if result.returncode != 0:
return self.content_text(f"Failed to peek at session: {result.stderr}")
# Clean ANSI escape sequences
import re
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
content = ansi_escape.sub('', result.stdout)
# Get last N lines
output_lines = content.strip().split('\n')
if len(output_lines) > lines:
output_lines = output_lines[-lines:]
output = '\n'.join(output_lines)
return self.content_text(output if output else "(No output)")
async def _list_sessions(self) -> Dict[str, Any]:
"""List all active tmux sessions."""
result = await self._run_command(["tmux", "list-sessions", "-F", "#{session_name}: #{?session_attached,attached,not attached} (#{session_windows} windows)"])
if result.returncode != 0:
if "no server running" in result.stderr.lower():
return self.content_text("No tmux server running (no active sessions)")
else:
return self.content_text(f"Error listing sessions: {result.stderr}")
if result.stdout.strip():
output = "Active tmux sessions:\n" + result.stdout.strip()
else:
output = "No active tmux sessions"
return self.content_text(output)
async def _kill_session(self, args: Dict[str, Any]) -> Dict[str, Any]:
"""Kill a tmux session."""
session = args["session"]
cmd = ["tmux", "kill-session", "-t", session]
result = await self._run_command(cmd)
if result.returncode == 0:
return self.content_text(f"Killed tmux session '{session}'")
else:
return self.content_text(f"Failed to kill session: {result.stderr}")
async def _attach_session(self, args: Dict[str, Any]) -> Dict[str, Any]:
"""Provide instructions for attaching to a tmux session."""
session = args["session"]
# Check if session exists
check_result = await self._run_command(["tmux", "list-sessions", "-F", "#{session_name}"])
if check_result.returncode != 0 or session not in check_result.stdout.split('\n'):
return self.content_text(f"Session '{session}' not found")
# Provide attach command
attach_cmd = f"tmux attach-session -t {session}"
return self.content_text(f"To attach to session '{session}', run: {attach_cmd}")
async def _share_session(self, args: Dict[str, Any]) -> Dict[str, Any]:
"""Get instructions for sharing a tmux session."""
session = args["session"]
# Check if session exists
check_result = await self._run_command(["tmux", "list-sessions", "-F", "#{session_name}"])
if check_result.returncode != 0 or session not in check_result.stdout.split('\n'):
return self.content_text(f"Session '{session}' not found")
instructions = f"""To share tmux session '{session}':
1. Multiple users can attach simultaneously:
tmux attach-session -t {session}
2. For read-only access:
tmux attach-session -t {session} -r
3. To create a new session attached to the same windows:
tmux new-session -t {session}
Note: tmux supports multiple clients by default - no special setup needed!"""
return self.content_text(instructions)
async def _run_command(self, cmd: List[str]) -> subprocess.CompletedProcess:
"""Run a command and return the result."""
return await asyncio.to_thread(
subprocess.run,
cmd,
capture_output=True,
text=True
)
if __name__ == "__main__":
# Check if tmux is installed
try:
subprocess.run(["tmux", "-V"], capture_output=True, check=True)
except (subprocess.CalledProcessError, FileNotFoundError):
print("Error: tmux is not installed", file=sys.stderr)
print("Install it with: sudo apt-get install tmux", file=sys.stderr)
sys.exit(1)
# Run the server
server = TmuxServer()
asyncio.run(server.run())

101
test_screen_utf8.py Normal file
View File

@ -0,0 +1,101 @@
#!/usr/bin/env python3
"""Test UTF-8 handling in screen peek functionality."""
import asyncio
import json
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from mcp_browser import MCPBrowser
async def test_screen_utf8():
"""Test screen peek with non-UTF8 content."""
browser = MCPBrowser(enable_builtin_servers=True)
await browser.initialize()
print("=== Testing Screen UTF-8 Handling ===\n")
# Create a test session
print("1. Creating test session...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_session",
"arguments": {
"name": "utf8-test",
"command": "bash"
}
}
})
print(f" Result: {response.get('result', {}).get('content', [{}])[0].get('text', 'Error')}")
# Execute command that produces mixed encoding
print("\n2. Executing command with mixed encoding...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "execute",
"arguments": {
"session": "utf8-test",
"command": "echo -e 'UTF-8: café\\nBinary: \\x80\\x81\\x82\\nEmoji: 🤖'"
}
}
})
print(f" Result: {response.get('result', {}).get('content', [{}])[0].get('text', 'Error')}")
# Wait a moment for output
await asyncio.sleep(0.5)
# Peek at the session
print("\n3. Peeking at session output...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "peek",
"arguments": {
"session": "utf8-test",
"lines": 10
}
}
})
if "result" in response:
output = response["result"]["content"][0]["text"]
print(f" Output:\n{output}")
# Check if we handled the encoding properly
if "café" in output and "🤖" in output:
print("\n✓ UTF-8 encoding handled correctly!")
else:
print("\n⚠ Some UTF-8 characters may not have been decoded properly")
else:
print(f" Error: {response}")
# Clean up
print("\n4. Cleaning up...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "kill_session",
"arguments": {"session": "utf8-test"}
}
})
print(f" Result: {response.get('result', {}).get('content', [{}])[0].get('text', 'Error')}")
await browser.close()
if __name__ == "__main__":
asyncio.run(test_screen_utf8())

155
test_tmux_session.py Normal file
View File

@ -0,0 +1,155 @@
#!/usr/bin/env python3
"""Test tmux session functionality."""
import asyncio
import json
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from mcp_browser import MCPBrowser
async def test_tmux_session():
"""Test tmux session functionality."""
browser = MCPBrowser(enable_builtin_servers=True)
await browser.initialize()
print("=== Testing Tmux Session Functionality ===\n")
# Create a test session
print("1. Creating test session...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "builtin:tmux::create_session",
"arguments": {
"name": "tmux-test",
"command": "bash"
}
}
})
print(f" Result: {response.get('result', {}).get('content', [{}])[0].get('text', 'Error')}")
# Execute a command in the session
print("\n2. Executing command in session...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "builtin:tmux::execute",
"arguments": {
"session": "tmux-test",
"command": "echo 'Tmux session test - Hello World!'"
}
}
})
print(f" Result: {response.get('result', {}).get('content', [{}])[0].get('text', 'Error')}")
# Wait a moment for output
await asyncio.sleep(0.5)
# Test peek functionality
print("\n3. Testing peek functionality...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "builtin:tmux::peek",
"arguments": {
"session": "tmux-test",
"lines": 10
}
}
})
if "result" in response:
output = response["result"]["content"][0]["text"]
print(f" Output:\n{output}")
# Check if we can see the executed command output
if "Tmux session test" in output:
print("\n✓ Peek works correctly!")
else:
print("\n⚠ Peek output might not show recent commands")
else:
print(f" Error: {response}")
# List sessions
print("\n4. Listing sessions...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "builtin:tmux::list_sessions",
"arguments": {}
}
})
if "result" in response:
sessions_output = response["result"]["content"][0]["text"]
print(f" Sessions:\n{sessions_output}")
# Check if session is listed
if "tmux-test" in sessions_output:
print("\n✓ Tmux session is listed!")
else:
print("\n⚠ Session not found in list")
else:
print(f" Error: {response}")
# Get attach instructions
print("\n5. Getting attach instructions...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "builtin:tmux::attach_session",
"arguments": {
"session": "tmux-test"
}
}
})
print(f" Result: {response.get('result', {}).get('content', [{}])[0].get('text', 'Error')}")
# Test share instructions
print("\n6. Getting share instructions...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 6,
"method": "tools/call",
"params": {
"name": "builtin:tmux::share_session",
"arguments": {
"session": "tmux-test"
}
}
})
print(f" Result: {response.get('result', {}).get('content', [{}])[0].get('text', 'Error')}")
# Clean up
print("\n7. Cleaning up...")
response = await browser.call({
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "builtin:tmux::kill_session",
"arguments": {"session": "tmux-test"}
}
})
print(f" Result: {response.get('result', {}).get('content', [{}])[0].get('text', 'Error')}")
await browser.close()
if __name__ == "__main__":
asyncio.run(test_tmux_session())