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:
parent
edca1d1fe2
commit
824a66d7c8
75
.tags
75
.tags
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
@ -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())
|
||||||
|
|
@ -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())
|
||||||
Loading…
Reference in New Issue