容器
HTTP-SSE安全的容器化MCP服务器
安全的容器化MCP服务器
A secure, container-based implementation of the Model Context Protocol (MCP) for executing tools on behalf of large language models.
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.
Multi-layered Security
MCP Protocol Implementation
Domain-Specific Managers
BashManager: Secure command executionPythonManager: Sandboxed Python code executionFileManager: Safe file operationsWebManager: Secure web browsing and scrapingKnowledgeBaseManager: Structured document storage with semantic searchConfigurable Environment
system_run_commandExecutes bash commands in a secure sandbox environment.
command (string, required): The bash command to executeworking_dir (string, optional): Working directory (ignored in sandbox)stdout (string): Command standard outputstderr (string): Command standard errorexit_code (integer): Command exit codesuccess (boolean): Whether command completed successfully{ "stdout": "file1.txt\nfile2.txt\n", "stderr": "", "exit_code": 0, "success": true }
system_run_pythonExecutes Python code in a secure sandbox environment.
code (string, required): Python code to executeworking_dir (string, optional): Working directory (ignored in sandbox)output (string): Print output from the codeerror (string): Error output from the coderesult (any): Optional return value (available if code sets _ variable)success (boolean): Whether code executed successfully{ "output": "Hello, world!\n", "error": "", "result": 42, "success": true }
system_env_varGets environment variable values.
var_name (string, optional): Specific variable to retrievevariables (object): Dictionary of environment variablesrequested_var (string): Value of the requested variable (if var_name provided){ "variables": { "MCP_PORT": "8000", "SANDBOX_ROOT": "/app/sandbox" }, "requested_var": "8000" }
file_readReads file contents safely.
path (string, required): Path to the file (relative to sandbox root)encoding (string, optional): File encoding (default: "utf-8")content (string): File contentsize (integer): File size in bytesmodified (float): Last modified timestampsuccess (boolean): Whether the read was successful{ "content": "This is the content of the file.", "size": 31, "modified": 1673452800.0, "success": true }
file_writeWrites content to a file safely.
path (string, required): Path to the file (relative to sandbox root)content (string, required): Content to writeencoding (string, optional): File encoding (default: "utf-8")success (boolean): Whether the write was successfulpath (string): Path to the written file{ "success": true, "path": "data/myfile.txt" }
file_listLists contents of a directory safely.
path (string, optional): Path to the directory (default: "/")pattern (string, optional): Glob pattern to filter filesentries (array): List of directory entries with metadatapath (string): The listed directory pathsuccess (boolean): Whether the listing was successful{ "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_deleteDeletes a file safely.
path (string, required): Path of the file to deletesuccess (boolean): Whether the deletion was successfulpath (string): Path to the deleted file{ "success": true, "path": "temp/old_file.txt" }
file_moveMoves or renames a file safely.
source (string, required): Source file pathdestination (string, required): Destination file pathsuccess (boolean): Whether the move was successfulsource (string): Original file pathdestination (string): New file path{ "success": true, "source": "data/old_name.txt", "destination": "data/new_name.txt" }
web_searchUses a search engine to find information on the web.
query (string, required): The query to search forresults (array): List of search resultsquery (string): The original query{ "results": [ { "title": "Search Result Title", "url": "https://example.com/page1", "snippet": "Text snippet from the search result..." } ], "query": "example search query" }
web_scrapeScrapes a specific URL and returns the content.
url (string, required): The URL to scrapeselector (string, optional): CSS selector to target specific contentcontent (string): Scraped contenturl (string): The URL that was scrapedtitle (string): Page titlesuccess (boolean): Whether the scrape was successfulerror (string): Error message if scrape failed{ "content": "This is the content of the web page...", "url": "https://example.com/page", "title": "Example Page", "success": true, "error": null }
web_browseInteractively browses a website using Playwright.
url (string, required): Starting URL for browsing sessioncontent (string): Page HTML contenturl (string): The final URL after any redirectstitle (string): Page titlesuccess (boolean): Whether the browsing was successfulerror (string): Error message if browsing failed{ "content": "<!DOCTYPE html><html>...</html>", "url": "https://example.com/after_redirect", "title": "Example Page", "success": true, "error": null }
The knowledge base system provides structured document storage with semantic search capabilities, RDF-style relationships, and metadata management. Documents are organized in a hierarchical namespace structure and support preferences (arbitrary RDF triples) and references (links between documents).
Knowledge base documents use a structured path format: namespace/collection[/subcollection]*/name
Examples:
projects/docs/api-referenceresearch/papers/machine-learning/transformerspersonal/notes/meeting-2024-01-15kb_create_documentCreates a new document in the knowledge base with metadata but no content.
path (string, required): Document path in format "namespace/collection[/subcollection]*/name"metadata (object, optional): Document metadata (default: {})kb_write_content.{ "namespace": "projects", "collection": "docs", "name": "api-reference", "type": "document", "subtype": "text", "created_at": "2024-01-15T10:30:00.000Z", "updated_at": "2024-01-15T10:30:00.000Z", "content_type": "text/plain", "chunked": false, "fragments": {}, "preferences": [], "references": [], "referenced_by": [], "indices": [], "metadata": {"author": "John Doe", "version": "1.0"} }
kb_write_contentWrites content to an existing document in the knowledge base.
path (string, required): Document pathcontent (string, required): Document contentforce (boolean, optional): Whether to overwrite existing content (default: false)kb_create_document.{ "namespace": "projects", "collection": "docs", "name": "api-reference", "type": "document", "subtype": "text", "created_at": "2024-01-15T10:30:00.000Z", "updated_at": "2024-01-15T10:35:00.000Z", "content_type": "text/plain", "chunked": false, "fragments": {}, "preferences": [], "references": [], "referenced_by": [], "indices": [], "metadata": {"author": "John Doe", "version": "1.0"} }
kb_readReads document data from the knowledge base.
path (string, required): Document pathinclude_content (boolean, optional): Whether to include document content (default: true)include_index (boolean, optional): Whether to include document metadata (default: true){ "status": "success", "path": "projects/docs/api-reference", "content": "This is the API reference content...", "index": { "namespace": "projects", "collection": "docs", "name": "api-reference", "created_at": "2024-01-15T10:30:00Z", "metadata": {"author": "John Doe"} } }
kb_update_metadataUpdates metadata for a document in the knowledge base.
path (string, required): Document pathmetadata (object, required): Metadata to update{ "namespace": "projects", "collection": "docs", "name": "api-reference", "type": "document", "subtype": "text", "created_at": "2024-01-15T10:30:00.000Z", "updated_at": "2024-01-15T10:40:00.000Z", "content_type": "text/plain", "chunked": false, "fragments": {}, "preferences": [], "references": [], "referenced_by": [], "indices": [], "metadata": {"author": "John Doe", "version": "1.1", "reviewed": true} }
kb_manage_triplesManages RDF triples (preferences and references) for documents.
action (string, required): Action to perform ("add" or "remove")triple_type (string, required): Type of triple ("preference" or "reference")path (string, required): Source document pathpredicate (string, required): Predicate of the tripleobject (string, optional): Object of the triple (for preferences) or relation name (for references)ref_path (string, optional): Referenced document path (for references only)Adding a preference (arbitrary RDF triple):
{ "status": "updated", "preference_count": 3, "action": "add", "triple_type": "preference" }
Adding a reference (link to another document):
{ "status": "success", "message": "Reference added", "added": true, "action": "add", "triple_type": "reference" }
Removing a reference:
{ "status": "updated", "reference_count": 2, "action": "remove", "triple_type": "reference" }
kb_searchSearches the knowledge base using text queries and/or graph expansion.
query (string, optional): Text query for semantic search and rerankinggraph_seed_urns (array, optional): Starting URNs for graph expansiongraph_expand_hops (integer, optional): Number of relationship hops to expand (default: 0)filter_urns (array, optional): URNs to exclude from resultsrelation_predicates (array, optional): Predicates to follow during graph traversal (default: ["references"])top_k (integer, optional): Number of results to return (default: 10)include_content (boolean, optional): Whether to include document content (default: false)include_index (boolean, optional): Whether to include document metadata (default: false)use_reranker (boolean, optional): Whether to use semantic reranking (default: true){ "results": [ { "urn": "kb://projects/docs/api-reference", "sparse_score": 1.95, "content": "API reference content...", "index": { "namespace": "projects", "collection": "docs", "name": "api-reference", "type": "document", "subtype": "text", "created_at": "2025-07-02T23:13:17.362283Z", "updated_at": "2025-07-02T23:18:23.396660Z", "content_type": "text/plain", "chunked": false, "fragments": {}, "preferences": [], "references": [ [ "references", "kb://project/docs/api-dto" ] ], "referenced_by": [], "indices": [], "metadata": { "purpose": "testing_collection_organization", "created_for": "kb_exercise", "type": "test_document", "created_date": "2025-07-02", "topic": "search_performance", "related_to": "rebuild_test" } }, "rerank_score": 0.84, } ], "count": 1 }
kb_list_documentsLists documents in the knowledge base.
path (string, optional): Path prefix to filter byrecursive (boolean, optional): Whether to list recursively (default: true){ "documents": [ "projects/docs/api-reference", "projects/docs/user-guide", "research/papers/transformers" ], "count": 3 }
kb_manageManages knowledge base operations like moving documents and rebuilding search indices.
action (string, required): Management action to perform
"move_document": Move a document (requires path and new_path)"delete": Archive a document (requires path)"rebuild_search_index": Rebuild search indices (optional rebuild_all)Moving a document:
{ "action": "move_document", "status": "success", "old_path": "projects/docs/old-name", "new_path": "projects/docs/new-name", "result": { "namespace": "projects", "collection": "docs", "name": "new-name", "type": "document", "subtype": "text", "created_at": "2024-01-15T10:30:00.000Z", "updated_at": "2024-01-15T10:50:00.000Z", "content_type": "text/plain", "chunked": false, "fragments": {}, "preferences": [], "references": [], "referenced_by": [], "indices": [], "metadata": {} } }
Archiving a document:
{ "action": "delete", "status": "success", "path": "projects/docs/obsolete", "result": { "status": "archived", "message": "Document archived: kb://projects/docs/obsolete", "original_path": "projects/docs/obsolete", "archive_path": "archive/projects/docs/obsolete", "archive_urn": "kb://archive/projects/docs/obsolete" } }
Container-MCP provides isolated execution environments for different types of operations, each with its own security measures and resource constraints.
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_COMMANDSExample allowed commands:
ls, cat, grep, find, echo, pwd, mkdir, touch
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 knowledge base environment provides structured document storage and semantic search:
The project follows a modular architecture:
container-mcp/ ├── cmcp/ # Main application code │ ├── managers/ # Domain-specific managers │ │ ├── bash_manager.py # Secure bash execution │ │ ├── file_manager.py # Secure file operations │ │ ├── knowledge_base_manager.py # Knowledge base operations │ │ ├── python_manager.py # Secure python execution │ │ └── web_manager.py # Secure web operations │ ├── kb/ # Knowledge base components │ │ ├── document_store.py # Document storage and retrieval │ │ ├── models.py # Data models and schemas │ │ ├── path.py # Path parsing and validation │ │ └── search.py # Search indices and ranking │ ├── tools/ # MCP tool implementations │ │ ├── file.py # File operation tools │ │ ├── kb.py # Knowledge base tools │ │ ├── system.py # System operation tools │ │ └── web.py # Web operation tools │ ├── utils/ # Utility functions │ │ └── logging.py # Logging utilities │ ├── __init__.py │ ├── config.py # Configuration system │ └── main.py # MCP server setup ├── apparmor/ # AppArmor profiles │ ├── mcp-bash # Bash execution profile │ └── mcp-python # Python execution profile ├── bin/ # Build/run scripts │ ├── 00-all-in-one.sh # Complete setup script │ ├── 01-init.sh # Project initialization │ ├── 02-build-container.sh # Container build script │ ├── 03-setup-environment.sh # Environment setup │ ├── 04-run-container.sh # Container run script │ ├── 05-check-container.sh # Container health check │ ├── 06-run-tests.sh # Test execution │ ├── 07-attach-container.sh # Container shell access │ ├── 08-testnetwork.sh # Network testing │ ├── 09-view-logs.sh # Log viewing │ ├── zy-shutdown.sh # Container shutdown │ └── zz-teardown.sh # Complete teardown ├── tests/ # Test suites │ ├── integration/ # Integration tests │ ├── unit/ # Unit tests │ └── conftest.py # Test configuration ├── volume/ # Persistent storage │ ├── config/ # Configuration files │ ├── data/ # Data directory │ ├── kb/ # Knowledge base storage │ │ ├── search/ # Search indices │ │ │ ├── sparse_idx/ # Sparse search index │ │ │ └── graph_idx/ # Graph search index │ │ ├── archive/ # Archived documents │ ├── logs/ # Log files │ ├── sandbox/ # Sandboxed execution space │ │ ├── bash/ # Bash sandbox │ │ ├── browser/ # Web browser sandbox │ │ ├── files/ # File operation sandbox │ │ └── python/ # Python sandbox │ └── temp/ # Temporary storage ├── Containerfile # Container definition ├── podman-compose.yml # Container orchestration ├── pyproject.toml # Python project configuration ├── uv.lock # Dependency lock file ├── pytest.ini # Test configuration └── README.md # Project documentation
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/54rt1n/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:
Initialize the project:
./bin/01-init.sh
Build the container:
./bin/02-build-container.sh
Set up the environment:
./bin/03-setup-environment.sh
Run the container:
./bin/04-run-container.sh
Run tests (optional):
./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=*
# Knowledge Base Manager Configuration
CMCP_KB_STORAGE_PATH=/app/kb
KB_TIMEOUT_DEFAULT=30
KB_TIMEOUT_MAX=120
# Search Configuration
CMCP_KB_SEARCH_ENABLED=true
CMCP_KB_SPARSE_INDEX_PATH=/app/kb/search/sparse_idx
CMCP_KB_GRAPH_INDEX_PATH=/app/kb/search/graph_idx
CMCP_KB_RERANKER_MODEL=mixedbread-ai/mxbai-rerank-base-v1
CMCP_KB_SEARCH_RELATION_PREDICATES=references
CMCP_KB_SEARCH_GRAPH_NEIGHBOR_LIMIT=1000
# Tool Enable/Disable
TOOLS_ENABLE_KB=true
Create a Python virtual environment:
python3.12 -m venv .venv source .venv/bin/activate
Install dependencies:
pip install -r requirements-dev.txt
Install the package in development mode:
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