Container-MCP provides a sandboxed environment for safely executing code, running commands, accessing files, and performing web operations requested by large language models. It implements the MCP protocol to expose these capabilities as tools that can be discovered and called by AI systems in a secure manner.
The architecture uses a domain-specific manager pattern with multi-layered security to ensure tools execute in isolated environments with appropriate restrictions, protecting the host system from potentially harmful operations.
BashManager
: Secure command executionPythonManager
: Sandboxed Python code executionFileManager
: Safe file operationsWebManager
: Secure web browsing and scrapingsystem_run_command
Executes bash commands in a secure sandbox environment.
{
"stdout": "file1.txt\nfile2.txt\n",
"stderr": "",
"exit_code": 0,
"success": true
}
system_run_python
Executes Python code in a secure sandbox environment.
{
"output": "Hello, world!\n",
"error": "",
"result": 42,
"success": true
}
system_env_var
Gets environment variable values.
{
"variables": {
"MCP_PORT": "8000",
"SANDBOX_ROOT": "/app/sandbox"
},
"requested_var": "8000"
}
file_read
Reads file contents safely.
{
"content": "This is the content of the file.",
"size": 31,
"modified": 1673452800.0,
"success": true
}
file_write
Writes content to a file safely.
{
"success": true,
"path": "data/myfile.txt"
}
file_list
Lists contents of a directory safely.
{
"entries": [
{
"name": "file1.txt",
"path": "file1.txt",
"is_directory": false,
"size": 1024,
"modified": 1673452800.0
},
{
"name": "data",
"path": "data",
"is_directory": true,
"size": null,
"modified": 1673452500.0
}
],
"path": "/",
"success": true
}
file_delete
Deletes a file safely.
{
"success": true,
"path": "temp/old_file.txt"
}
file_move
Moves or renames a file safely.
{
"success": true,
"source": "data/old_name.txt",
"destination": "data/new_name.txt"
}
web_search
Uses a search engine to find information on the web.
{
"results": [
{
"title": "Search Result Title",
"url": "https://example.com/page1",
"snippet": "Text snippet from the search result..."
}
],
"query": "example search query"
}
web_scrape
Scrapes a specific URL and returns the content.
{
"content": "This is the content of the web page...",
"url": "https://example.com/page",
"title": "Example Page",
"success": true,
"error": null
}
web_browse
Interactively browses a website using Playwright.
{
"content": "<!DOCTYPE html><html>...</html>",
"url": "https://example.com/after_redirect",
"title": "Example Page",
"success": true,
"error": null
}
The main Container-MCP service runs inside a container (using Podman or Docker) providing the first layer of isolation:
The Bash execution environment is configured with multiple isolation layers:
BASH_ALLOWED_COMMANDS
The Python execution environment is designed for secure code execution:
The file system environment controls access to files within the sandbox:
The web environment provides controlled access to external resources:
The project follows a modular architecture:
container-mcp/
├── cmcp/ # Main application code
│ ├── managers/ # Domain-specific managers
│ │ ├── bash_manager.py # Secure bash execution
│ │ ├── python_manager.py # Secure python execution
│ │ ├── file_manager.py # Secure file operations
│ │ └── web_manager.py # Secure web operations
│ ├── utils/ # Utility functions
│ ├── config.py # Configuration system
│ └── main.py # MCP server setup
├── apparmor/ # AppArmor profiles
├── config/ # Configuration files
├── bin/ # Build/run scripts
├── data/ # Data directory
├── logs/ # Log directory
├── sandbox/ # Sandboxed execution space
│ ├── bash/ # Bash sandbox
│ ├── python/ # Python sandbox
│ ├── files/ # File operation sandbox
│ └── browser/ # Web browser sandbox
├── temp/ # Temporary storage
└── tests/ # Test suites
Each manager follows consistent design patterns:
.from_env()
class method for environment-based initializationContainer-MCP implements multiple layers of security:
apt install firejail
or dnf install firejail
)apt install apparmor apparmor-utils
or dnf install apparmor apparmor-utils
)The quickest way to get started is to use the all-in-one script:
git clone https://github.com/container-mcp/container-mcp.git
cd container-mcp
chmod +x bin/00-all-in-one.sh
./bin/00-all-in-one.sh
You can also perform the installation steps individually:
shell
./bin/01-init.sh
shell
./bin/02-build-container.sh
shell
./bin/03-setup-environment.sh
shell
./bin/04-run-container.sh
shell
./bin/05-run-tests.sh
Once the container is running, you can connect to it using any MCP client implementation. The server will be available at http://localhost:8000
or the port specified in your configuration.
Important: When configuring your MCP client, you must set the endpoint URL to http://127.0.0.1:<port>/sse
(where <port>
is 8000 by default or the port you've configured). The /sse
path is required for proper server-sent events communication.
from mcp.client.sse import sse_client
from mcp import ClientSession
import asyncio
async def main():
# Connect to the Container-MCP server
# Note the /sse endpoint suffix required for SSE communication
sse_url = "http://127.0.0.1:8000/sse" # Or your configured port
# Connect to the SSE endpoint
async with sse_client(sse_url) as (read, write):
async with ClientSession(read, write) as session:
# Initialize the connection
await session.initialize()
# Discover available tools
result = await session.list_tools()
print(f"Available tools: {[tool.name for tool in result.tools]}")
# Execute a Python script
python_result = await session.execute_tool(
"system_run_python",
{"code": "print('Hello, world!')\nresult = 42\n_ = result"}
)
print(f"Python result: {python_result}")
# Execute a bash command
bash_result = await session.execute_tool(
"system_run_command",
{"command": "ls -la"}
)
print(f"Command output: {bash_result['stdout']}")
if __name__ == "__main__":
asyncio.run(main())
Container-MCP can be configured through environment variables, which can be set in volume/config/custom.env
:
# MCP Server Configuration
MCP_HOST=127.0.0.1
MCP_PORT=9001
DEBUG=true
LOG_LEVEL=INFO
# Bash Manager Configuration
BASH_ALLOWED_COMMANDS=ls,cat,grep,find,echo,pwd,mkdir,touch
BASH_TIMEOUT_DEFAULT=30
BASH_TIMEOUT_MAX=120
# Python Manager Configuration
PYTHON_MEMORY_LIMIT=256
PYTHON_TIMEOUT_DEFAULT=30
PYTHON_TIMEOUT_MAX=120
# File Manager Configuration
FILE_MAX_SIZE_MB=10
FILE_ALLOWED_EXTENSIONS=txt,md,csv,json,py
# Web Manager Configuration
WEB_TIMEOUT_DEFAULT=30
WEB_ALLOWED_DOMAINS=*
shell
python3.12 -m venv .venv
source .venv/bin/activate
shell
pip install -r requirements-dev.txt
shell
pip install -e .
# Run all tests
pytest
# Run only unit tests
pytest tests/unit
# Run only integration tests
pytest tests/integration
# Run with coverage report
pytest --cov=cmcp --cov-report=term --cov-report=html
To run the MCP server in development mode:
python -m cmcp.main --test-mode
This project is licensed under the Apache License 2.0.
Martin Bukowski
A podman ubuntu 24.04 container that serves a MCP server; with file, code execution, bash shell, and more.
No releases published
No packages published