2 Commits

Author SHA1 Message Date
Xavier Bouthillier
1f28d83bf3 feat: add option for custom docker host socket
Why:

The socket is different when we use rootless mode with docker.
2025-04-16 09:28:44 -04:00
Xavier Bouthillier
cfb54b2cc1 fix: handle removing MCP in no sessions
Why:

The attribute mcps doesn't seem to be set in any session object anywhere
in the codebase.
2025-04-16 09:27:07 -04:00
5 changed files with 17 additions and 5 deletions

View File

@@ -3,7 +3,7 @@
MC (Monadical Container) is a command-line tool for managing ephemeral MC (Monadical Container) is a command-line tool for managing ephemeral
containers that run AI tools and development environments. It works with both containers that run AI tools and development environments. It works with both
local Docker and a dedicated remote web service that manages containers in a local Docker and a dedicated remote web service that manages containers in a
Docker-in-Docker (DinD) environment. MC also supports connecting to MCP (Model Context Protocol) servers to extend AI tools with additional capabilities. Docker-in-Docker (DinD) environment. MC also supports connecting to MCP (Model Control Protocol) servers to extend AI tools with additional capabilities.
## Quick Reference ## Quick Reference
@@ -265,7 +265,7 @@ Service credentials like API keys configured in `~/.config/mc/config.yaml` are a
## MCP Server Management ## MCP Server Management
MCP (Model Context Protocol) servers provide tool-calling capabilities to AI models, enhancing their ability to interact with external services, databases, and systems. MC supports multiple types of MCP servers: MCP (Model Control Protocol) servers provide tool-calling capabilities to AI models, enhancing their ability to interact with external services, databases, and systems. MC supports multiple types of MCP servers:
1. **Remote HTTP SSE servers** - External MCP servers accessed over HTTP 1. **Remote HTTP SSE servers** - External MCP servers accessed over HTTP
2. **Docker-based MCP servers** - Local MCP servers running in Docker containers 2. **Docker-based MCP servers** - Local MCP servers running in Docker containers

View File

@@ -1282,14 +1282,17 @@ def mcp_logs(
@mcp_app.command("remove") @mcp_app.command("remove")
def remove_mcp(name: str = typer.Argument(..., help="MCP server name")) -> None: def remove_mcp(name: str = typer.Argument(..., help="MCP server name")) -> None:
"""Remove an MCP server configuration""" """Remove an MCP server configuration.
It does not stop the server nor remove it from docker.
"""
try: try:
# Check if any active sessions might be using this MCP # Check if any active sessions might be using this MCP
active_sessions = container_manager.list_sessions() active_sessions = container_manager.list_sessions()
affected_sessions = [] affected_sessions = []
for session in active_sessions: for session in active_sessions:
if session.mcps and name in session.mcps: if getattr(session, 'mcps', []) and name in session.mcps:
affected_sessions.append(session) affected_sessions.append(session)
# Just warn users about affected sessions # Just warn users about affected sessions
@@ -1344,6 +1347,9 @@ def add_mcp(
env: List[str] = typer.Option( env: List[str] = typer.Option(
[], "--env", "-e", help="Environment variables (format: KEY=VALUE)" [], "--env", "-e", help="Environment variables (format: KEY=VALUE)"
), ),
docker_host: Optional[str] = typer.Option(
None, "--docker-host", help="Docker host socket file that should be mounted on the MCP container",
),
no_default: bool = typer.Option( no_default: bool = typer.Option(
False, "--no-default", help="Don't add MCP server to defaults" False, "--no-default", help="Don't add MCP server to defaults"
), ),
@@ -1377,6 +1383,7 @@ def add_mcp(
proxy_options, proxy_options,
environment, environment,
host_port, host_port,
docker_host,
add_as_default=not no_default, add_as_default=not no_default,
) )

View File

@@ -28,6 +28,7 @@ class ContainerManager:
): ):
self.config_manager = config_manager or ConfigManager() self.config_manager = config_manager or ConfigManager()
self.session_manager = session_manager or SessionManager() self.session_manager = session_manager or SessionManager()
self.user_config_manager = user_config_manager or UserConfigManager() self.user_config_manager = user_config_manager or UserConfigManager()
self.mcp_manager = MCPManager(config_manager=self.user_config_manager) self.mcp_manager = MCPManager(config_manager=self.user_config_manager)

View File

@@ -179,6 +179,7 @@ class MCPManager:
proxy_options: Dict[str, Any] = None, proxy_options: Dict[str, Any] = None,
env: Dict[str, str] = None, env: Dict[str, str] = None,
host_port: Optional[int] = None, host_port: Optional[int] = None,
docker_host: Optional[str] = None,
add_as_default: bool = True, add_as_default: bool = True,
) -> Dict[str, Any]: ) -> Dict[str, Any]:
"""Add a proxy-based MCP server. """Add a proxy-based MCP server.
@@ -191,6 +192,7 @@ class MCPManager:
proxy_options: Options for the MCP proxy proxy_options: Options for the MCP proxy
env: Environment variables to set in the container env: Environment variables to set in the container
host_port: Host port to bind the MCP server to (auto-assigned if not specified) host_port: Host port to bind the MCP server to (auto-assigned if not specified)
docker_host: Docker host socket file that should be mounted on the MCP container
add_as_default: Whether to add this MCP to the default MCPs list add_as_default: Whether to add this MCP to the default MCPs list
Returns: Returns:
@@ -223,6 +225,7 @@ class MCPManager:
proxy_options=proxy_options or {}, proxy_options=proxy_options or {},
env=env or {}, env=env or {},
host_port=host_port, host_port=host_port,
docker_host=docker_host or "/var/run/docker.sock",
) )
# Add to the configuration # Add to the configuration
@@ -570,7 +573,7 @@ ENTRYPOINT ["/entrypoint.sh"]
detach=True, detach=True,
network=None, # Start without network, we'll add it with aliases network=None, # Start without network, we'll add it with aliases
volumes={ volumes={
"/var/run/docker.sock": { mcp_config.get("docker_host", "/var/run/docker.sock"): {
"bind": "/var/run/docker.sock", "bind": "/var/run/docker.sock",
"mode": "rw", "mode": "rw",
} }

View File

@@ -79,6 +79,7 @@ class ProxyMCP(BaseModel):
proxy_options: Dict[str, Any] = Field(default_factory=dict) proxy_options: Dict[str, Any] = Field(default_factory=dict)
env: Dict[str, str] = Field(default_factory=dict) env: Dict[str, str] = Field(default_factory=dict)
host_port: Optional[int] = None # External port to bind the SSE port to on the host host_port: Optional[int] = None # External port to bind the SSE port to on the host
docker_host: Optional[str] = None # Docker host to use for the proxy container
MCP = Union[RemoteMCP, DockerMCP, ProxyMCP] MCP = Union[RemoteMCP, DockerMCP, ProxyMCP]