From 824a66d7c802d576938b8635006174b8aa6192a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Claude4=CE=9Elope?= <xilope@esus.name>
Date: Sat, 28 Jun 2025 15:28:32 +0200
Subject: [PATCH] Add tmux session management and screen to tmux conversion
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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>
---
 .tags                             |  75 ++++++-
 CLAUDE.md                         |   5 +-
 MCP_QUICK_REFERENCE.md            | 111 ++++++++++
 README.md                         |   5 +-
 docs/STRUCTURE.md                 |   4 +
 mcp_api_documentation.json        | 165 +++++++++++++++
 mcp_browser/config.py             |   4 +-
 mcp_browser/multi_server.py       |  13 +-
 mcp_servers/screen/tmux_server.py | 324 ++++++++++++++++++++++++++++++
 test_screen_utf8.py               | 101 ++++++++++
 test_tmux_session.py              | 155 ++++++++++++++
 11 files changed, 955 insertions(+), 7 deletions(-)
 create mode 100644 MCP_QUICK_REFERENCE.md
 create mode 100644 mcp_api_documentation.json
 create mode 100644 mcp_servers/screen/tmux_server.py
 create mode 100644 test_screen_utf8.py
 create mode 100644 test_tmux_session.py

diff --git a/.tags b/.tags
index 99b6ca1..e2839ee 100644
--- a/.tags
+++ b/.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	mcp_servers/memory/memory_server.py	/^class Decision:$/;"	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
 JsonRpcBuffer	build/lib/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
 Task	build/lib/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
+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
 TestMessageFilter	tests/test_basic.py	/^class TestMessageFilter:$/;"	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/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/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/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/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/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/pattern_manager/pattern_server.py	/^    def __init__(self):$/;"	m	class:PatternServer
 __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
 _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_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	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	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	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	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	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	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_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_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	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
@@ -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
 _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
+_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	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
@@ -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_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_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	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	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	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	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
@@ -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_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
+_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/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
@@ -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_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
+_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	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	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	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
@@ -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
 _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_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	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
@@ -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	mcp_browser/__main__.py	/^    call_tool = subparsers.add_parser("tools-call", help="Call a tool")$/;"	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	mcp_browser/buffer.py	/^    def clear(self):$/;"	m	class:JsonRpcBuffer
 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
 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	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_options	setup.py	/^    def initialize_options(self):$/;"	m	class:GenerateAIDocs
 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
 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
+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	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
@@ -414,11 +449,13 @@ main	examples/basic_usage.py	/^async def main():$/;"	f
 main	mcp_browser/__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/interactive_client.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_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	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
 package_data	setup.py	/^    package_data={$/;"	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_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/interactive_client.py	/^    async def run(self):$/;"	m	class:InteractiveMCPClient
 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: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
 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_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	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
@@ -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_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_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_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_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_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_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_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_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_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_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_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_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_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_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
diff --git a/CLAUDE.md b/CLAUDE.md
index b5ab00b..cf58d8c 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -40,8 +40,9 @@ python setup.py aidocs
 
 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` 
-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
+5. **Session Management**: Tmux preferred over screen for better multi-user support
 
 ### Architecture Overview
 
@@ -55,7 +56,7 @@ mcp_browser/
 
 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
 ├── patterns/         # Auto-response patterns
 └── onboarding/       # Identity-aware onboarding
diff --git a/MCP_QUICK_REFERENCE.md b/MCP_QUICK_REFERENCE.md
new file mode 100644
index 0000000..f759a6b
--- /dev/null
+++ b/MCP_QUICK_REFERENCE.md
@@ -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.
\ No newline at end of file
diff --git a/README.md b/README.md
index d5ddab0..e92e349 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,8 @@ MCP Browser acts as a smart proxy between AI systems and MCP servers, providing:
    - Configuration-driven server management
 
 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
    - **Patterns**: Auto-response pattern management for automation
    - **Onboarding**: Identity-aware onboarding for AI contexts
@@ -53,7 +54,7 @@ mcp-browser/
 │   └── config.py         # Configuration management
 ├── mcp_servers/          # Built-in MCP servers
 │   ├── base.py           # Base server implementation
-│   ├── screen/           # Screen session management
+│   ├── screen/           # Session management (tmux + screen)
 │   ├── memory/           # Memory and context management
 │   ├── pattern_manager/  # Pattern automation
 │   └── onboarding/       # Identity-aware onboarding
diff --git a/docs/STRUCTURE.md b/docs/STRUCTURE.md
index fe0c072..be1433f 100644
--- a/docs/STRUCTURE.md
+++ b/docs/STRUCTURE.md
@@ -6,6 +6,7 @@
   test_claude_desktop_flow.py
   test_discovery.py
   test_mcp_protocol.py
+  test_screen_multiuser.py
   test_screen_utf8.py
   mcp_browser.egg-info/
   systemd/
@@ -55,7 +56,9 @@
     test_brave_search.py
     test_browser_functionality.py
     test_claude_connection.py
+    test_cmem_integration.py
     test_integration.py
+    test_interactive_client.py
     test_onboarding.py
     test_simple.py
   config/
@@ -84,6 +87,7 @@
     daemon_main.py
     default_configs.py
     filter.py
+    interactive_client.py
     logging_config.py
     multi_server.py
     proxy.py
diff --git a/mcp_api_documentation.json b/mcp_api_documentation.json
new file mode 100644
index 0000000..24db044
--- /dev/null
+++ b/mcp_api_documentation.json
@@ -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
+    }
+  }
+}
\ No newline at end of file
diff --git a/mcp_browser/config.py b/mcp_browser/config.py
index 2cfdb94..38ad328 100644
--- a/mcp_browser/config.py
+++ b/mcp_browser/config.py
@@ -22,6 +22,7 @@ class MCPServerConfig:
     env: Dict[str, str] = field(default_factory=dict)
     name: Optional[str] = None
     description: Optional[str] = None
+    enabled: bool = True
     
 
 @dataclass
@@ -88,7 +89,8 @@ class ConfigLoader:
                 args=server_config.get("args", []),
                 env=server_config.get("env", {}),
                 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(
diff --git a/mcp_browser/multi_server.py b/mcp_browser/multi_server.py
index aee399d..eb4df08 100644
--- a/mcp_browser/multi_server.py
+++ b/mcp_browser/multi_server.py
@@ -28,10 +28,16 @@ class MultiServerManager:
         base_path = Path(__file__).parent.parent / "mcp_servers"
         
         return {
+            "builtin:tmux": MCPServerConfig(
+                command=["python3", str(base_path / "screen" / "tmux_server.py")],
+                name="tmux",
+                description="tmux session management"
+            ),
             "builtin:screen": MCPServerConfig(
                 command=["python3", str(base_path / "screen" / "screen_server.py")],
                 name="screen",
-                description="GNU screen session management"
+                description="GNU screen session management (legacy)",
+                enabled=False  # Disabled by default, tmux is preferred
             ),
             "builtin:memory": MCPServerConfig(
                 command=["python3", str(base_path / "memory" / "memory_server.py")],
@@ -53,6 +59,11 @@ class MultiServerManager:
     async def start_builtin_servers(self):
         """Start all built-in servers."""
         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}")
             
             server = MCPServer(config, logger=get_logger(__name__, name))
diff --git a/mcp_servers/screen/tmux_server.py b/mcp_servers/screen/tmux_server.py
new file mode 100644
index 0000000..030adb7
--- /dev/null
+++ b/mcp_servers/screen/tmux_server.py
@@ -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())
\ No newline at end of file
diff --git a/test_screen_utf8.py b/test_screen_utf8.py
new file mode 100644
index 0000000..560b883
--- /dev/null
+++ b/test_screen_utf8.py
@@ -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())
\ No newline at end of file
diff --git a/test_tmux_session.py b/test_tmux_session.py
new file mode 100644
index 0000000..70b3d83
--- /dev/null
+++ b/test_tmux_session.py
@@ -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())
\ No newline at end of file
