MCP server for Contree container management system
Project description
ConTree MCP Server
Run code in isolated cloud containers. ConTree gives AI agents secure sandboxed execution environments with full root access, network, and persistent images.
Why ConTree?
Fearless experimentation. Agents can:
- Run destructive commands (
rm -rf /,dd, kernel exploits) - nothing escapes the sandbox - Make mistakes freely - revert to any previous image UUID at zero cost
- Execute potentially dangerous user requests - ConTree IS the safe runtime for risky operations
- Break things on purpose - corrupt filesystems, crash kernels, test failure modes
Every container is isolated. Every image is immutable. Branching is cheap. Mistakes are free.
Quick Setup
1. Get an API Token
Contree is in Early Access. To get an API token, fill out the request form at contree.dev.
2. Create Config File
contree-mcp reads the same auth.ini that
contree-cli
writes, so a single login covers all contree-related tools.
Recommended: install contree-cli (see
installation guide)
and manage credentials with it rather than editing the file by hand:
contree auth --help # add, switch, list, remove profiles
Default location: $XDG_CONFIG_HOME/contree/auth.ini (typically
~/.config/contree/auth.ini). Override the directory with
CONTREE_HOME.
If you really need to write it by hand:
[DEFAULT]
profile = default
[profile:default]
type = iam
url = https://api.tokenfactory.nebius.com/sandboxes
token = <TOKEN HERE>
project = <NEBIUS PROJECT ID>
For the legacy JWT flow (contree.dev), use:
[profile:default]
type = jwt
url = https://contree.dev
token = <TOKEN HERE>
3. Configure Your MCP Client
Claude Code
claude mcp add --transport stdio contree -- $(which uvx) contree-mcp
Restart Claude Code or run /mcp to verify.
OpenAI Codex CLI
Add to ~/.codex/config.toml:
[mcp_servers.contree]
command = "uvx"
args = ["contree-mcp"]
Claude Desktop
Add to config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{"mcpServers": {"contree": {"command": "uvx", "args": ["contree-mcp"]}}}
Note: You can alternatively pass credentials via environment variables (
CONTREE_TOKEN,CONTREE_URL,CONTREE_PROJECT,CONTREE_PROFILE) in your MCP client config, but this is not recommended as tokens may appear in process listings.
Manual Installation
# Using uv
uv pip install contree-mcp
# Using pip
pip install contree-mcp
# Run manually (IAM auth)
contree-mcp --token YOUR_TOKEN --project YOUR_PROJECT
# Or pick a profile from ~/.config/contree/auth.ini
contree-mcp --profile staging
# HTTP mode (for network access)
contree-mcp --mode http --http-port 9452 --profile default
# Visit http://localhost:9452/ for interactive documentation with
# setup guides, tool reference, and best practices.
Container Installation (Alpine/Ubuntu/Debian)
These distros enable PEP 668, which protects the system Python from pip install mutations. Use an isolated tool installer:
# Recommended: isolated install, no PEP 668 conflicts
uv tool install contree-mcp
# or
pipx install contree-mcp
Both put contree-mcp on your PATH while keeping its dependencies in a private venv. uvx contree-mcp (used by the MCP-client snippets above) also works without installation since it spawns an ephemeral env per invocation.
If you really must install into the system Python
pip install --break-system-packages contree-mcp
--break-system-packages overrides PEP 668 protections and can put your system Python in an inconsistent state. Prefer uv tool install / pipx unless you have a specific reason.
Configuration
| Argument | Environment Variable | Default |
|---|---|---|
| - | CONTREE_HOME |
$XDG_CONFIG_HOME/contree (~/.config/contree) |
--profile |
CONTREE_PROFILE |
active profile from config |
--token |
CONTREE_TOKEN |
from config |
--url |
CONTREE_URL |
from config (IAM default: https://api.tokenfactory.nebius.com/sandboxes) |
--project |
CONTREE_PROJECT |
from config (required for IAM auth) |
--mode |
- | stdio |
--http-port |
- | 9452 |
--log-level |
- | warning |
Resolution priority for credentials: CLI flag > environment variable >
profile in config.ini.
Available Tools
Command Execution
| Tool | Description |
|---|---|
contree_run |
Execute command in container (spawns microVM). Supports wait=false for async execution. |
Image Management
| Tool | Description |
|---|---|
contree_list_images |
List available container images |
contree_get_image |
Get image details by UUID or tag |
contree_import_image |
Import OCI image from registry (requires authentication) |
contree_registry_token_obtain |
Open browser to create PAT for registry authentication |
contree_registry_auth |
Validate and store registry credentials |
contree_set_tag |
Set or remove a tag for an image |
File Transfer
| Tool | Description |
|---|---|
contree_upload |
Upload a file to ConTree for use in containers |
contree_download |
Download a file from a container image to local filesystem |
contree_rsync |
Sync local files to ConTree with caching and deduplication |
Image Inspection
| Tool | Description |
|---|---|
contree_list_files |
List files and directories in an image (no VM needed) |
contree_read_file |
Read a file from an image (no VM needed) |
Operations
| Tool | Description |
|---|---|
contree_list_operations |
List operations (running or completed) |
contree_get_operation |
Get operation status and result |
contree_wait_operations |
Wait for multiple async operations to complete |
contree_cancel_operation |
Cancel a running operation |
Documentation
| Tool | Description |
|---|---|
contree_get_guide |
Get agent guide sections (workflow, quickstart, async, etc.) |
Resource Templates
MCP resource templates expose image files and documentation directly via URIs. Fast operations, no VM required.
| Resource | URI Template | Description |
|---|---|---|
contree_image_read |
contree://image/{image}/read/{path} |
Read a file from an image |
contree_image_ls |
contree://image/{image}/ls/{path} |
List directory in an image |
contree_image_lineage |
contree://image/{image}/lineage |
View image parent-child relationships |
contree_guide |
contree://guide/{section} |
Agent guide and best practices |
URI Examples:
contree://image/abc-123-uuid/read/etc/passwd- Read file by image UUIDcontree://image/tag:alpine:latest/read/etc/os-release- Read file by tagcontree://image/abc-123-uuid/ls/.- List root directorycontree://image/tag:python:3.11/ls/usr/local/lib- List nested directorycontree://image/abc-123-uuid/lineage- View image ancestry and childrencontree://guide/reference- Tool referencecontree://guide/quickstart- Common workflow patterns
Guide Sections: workflow, reference, quickstart, state, async, tagging, errors
Examples
Prepare a Reusable Environment (Recommended First Step)
Step 1: Check for existing environment
// contree_list_images
{"tag_prefix": "common/python-ml"}
Step 2: If not found, build and tag it
// contree_import_image
{"registry_url": "docker://docker.io/python:3.11-slim"}
// contree_run (install packages)
{"command": "pip install numpy pandas scikit-learn", "image": "<result_image>", "disposable": false}
// contree_set_tag
{"image_uuid": "<result_image>", "tag": "common/python-ml/python:3.11-slim"}
Step 3: Use the prepared environment
// contree_run
{"command": "python train_model.py", "image": "tag:common/python-ml/python:3.11-slim"}
Run a command
contree_run:
{"command": "python -c 'print(\"Hello from ConTree!\")'", "image": "tag:python:3.11"}
Parallel Execution (Async Pattern)
Launch multiple instances simultaneously with wait: false, then poll for results:
contree_run (x3):
{"command": "python experiment_a.py", "image": "tag:python:3.11", "wait": false}
{"command": "python experiment_b.py", "image": "tag:python:3.11", "wait": false}
{"command": "python experiment_c.py", "image": "tag:python:3.11", "wait": false}
Each returns immediately with operation_id. Poll with contree_get_operation:
{"operation_id": "op-1"}
Trie-like Exploration Tree
Build branching structures where results become new source images.
contree_run - create branch point with disposable: false:
{"command": "pip install numpy pandas", "image": "tag:python:3.11", "disposable": false}
Returns result_image: "img-with-deps".
contree_run - branch into parallel experiments:
{"command": "python test_numpy.py", "image": "img-with-deps", "wait": false}
{"command": "python test_pandas.py", "image": "img-with-deps", "wait": false}
Sync Local Files to Container
contree_rsync - sync a project directory:
{
"source": "/path/to/project",
"destination": "/app",
"exclude": ["__pycache__", "*.pyc", ".git", "node_modules"]
}
Returns directory_state_id: "ds_abc123".
contree_run - run with injected files:
{
"command": "python /app/main.py",
"image": "tag:python:3.11",
"directory_state_id": "ds_abc123"
}
List images
contree_list_images:
{"tag_prefix": "python"}
Read a file (Resource Template)
Use the contree_image_file resource template:
contree://image/tag:busybox:latest/read/etc/passwd
Import an image
Step 1: Authenticate with registry (first time only)
// contree_registry_token_obtain - opens browser for PAT creation
{"registry_url": "docker://docker.io/alpine:latest"}
// contree_registry_auth - validate and store credentials
{"registry_url": "docker://docker.io/alpine:latest", "username": "myuser", "token": "dckr_pat_xxx"}
Step 2: Import the image
// contree_import_image
{"registry_url": "docker://docker.io/alpine:latest"}
To make it reusable, tag after importing:
// contree_set_tag
{"image_uuid": "<result_image>", "tag": "common/base/alpine:latest"}
Track Image Lineage
View parent-child relationships and navigate image history using the contree_image_lineage resource:
contree://image/abc-123-uuid/lineage
Returns:
{
"image": "abc-123-uuid",
"parent": {"image": "parent-uuid", "command": "pip install numpy", "exit_code": 0},
"children": [{"image": "child-uuid", "command": "python test.py", ...}],
"ancestors": [/* parent chain up to root */],
"root": {"image": "root-uuid", "registry_url": "docker://python:3.11", "is_import": true},
"depth": 2,
"is_known": true
}
Use this to rollback to any ancestor or understand how an image was created.
Download a build artifact
contree_download:
{"image": "img-build-result", "path": "/app/dist/binary", "destination": "./binary", "executable": true}
Dependencies
mcp- Model Context Protocol SDKhttpx- Async HTTP clientargclass- Argument parsingaiosqlite- Async SQLite databasepydantic- Data validation
Development
Requirements: Python 3.10+
git clone https://github.com/nebius/contree-mcp.git
cd contree-mcp
make install
Development Workflow
make check # lint + typecheck + tests (run before pushing)
make test # tests only (quiet)
make format # auto-fix formatting and lint
make help # full target list
When making changes:
- Edit code in
contree_mcp/ - Run
make check— must pass before opening a PR - Update documentation if behavior changes:
README.md— user-facing docs, examples, tool descriptionsllm.txt— shared context for AI agents (architecture, class hierarchy, internals)
Without make
If you'd rather not use make, the underlying uv run commands are:
uv sync --group dev # install
uv run pytest tests/ -q # test
uv run ruff check contree_mcp # lint
uv run ruff format contree_mcp # format
uv run mypy contree_mcp # typecheck
uv run pytest tests/tools/test_run_command.py -v # single test file
Testing GitHub Actions Locally
Use act to run GitHub Actions workflows locally before pushing:
# Install act
brew install act # macOS
sudo pacman -S act # Arch Linux
sudo apt install act # Debian/Ubuntu (via nix or manual install)
# List available jobs
act -l
# Run lint and typecheck jobs (fast)
act -j lint
act -j typecheck
# Run tests for Linux only (act simulates Linux)
act -j test --matrix os:ubuntu-latest
# Run specific Python version
act -j test --matrix os:ubuntu-latest --matrix python-version:3.12
# Run all jobs sequentially (stop on first failure)
act -j lint && act -j typecheck && act -j test --matrix os:ubuntu-latest
# Dry run (show what would execute)
act -n
Note: act uses Docker containers that simulate Linux runners. macOS/Windows matrix jobs will run in Linux
containers, so use --matrix os:ubuntu-latest for accurate local testing.
Copyright
Nebius B.V. 2026, Licensed under the Apache License, Version 2.0 (see "LICENSE" file).
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file contree_mcp-0.2.0.tar.gz.
File metadata
- Download URL: contree_mcp-0.2.0.tar.gz
- Upload date:
- Size: 393.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d37e8c5b46e3795261617049328af023d21aa29b132715e5378f550a40aed99d
|
|
| MD5 |
674bdc4ff78eb34b2f66ed004c0ff08b
|
|
| BLAKE2b-256 |
89b1e41b05b5a8c6a95d4076d61593b72bb6f3299ce2790dbf445019b8601aaf
|
Provenance
The following attestation bundles were made for contree_mcp-0.2.0.tar.gz:
Publisher:
publish.yml on nebius/contree-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
contree_mcp-0.2.0.tar.gz -
Subject digest:
d37e8c5b46e3795261617049328af023d21aa29b132715e5378f550a40aed99d - Sigstore transparency entry: 1568803340
- Sigstore integration time:
-
Permalink:
nebius/contree-mcp@16684509bae55f5cdaedc6b1d4ab1224fe00374a -
Branch / Tag:
refs/tags/0.2.0 - Owner: https://github.com/nebius
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@16684509bae55f5cdaedc6b1d4ab1224fe00374a -
Trigger Event:
release
-
Statement type:
File details
Details for the file contree_mcp-0.2.0-py3-none-any.whl.
File metadata
- Download URL: contree_mcp-0.2.0-py3-none-any.whl
- Upload date:
- Size: 97.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
196639a13478e8756a8862727a9237eb36b631ea17e94a3e7ac2459ec50baf5f
|
|
| MD5 |
fdc31556ce71b11e52494346b61c6047
|
|
| BLAKE2b-256 |
7c3e2b39a902cb9ed1ef3bb6d70f1a1d13042f743cdcec2d670a65eaf2f2a5a7
|
Provenance
The following attestation bundles were made for contree_mcp-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on nebius/contree-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
contree_mcp-0.2.0-py3-none-any.whl -
Subject digest:
196639a13478e8756a8862727a9237eb36b631ea17e94a3e7ac2459ec50baf5f - Sigstore transparency entry: 1568803407
- Sigstore integration time:
-
Permalink:
nebius/contree-mcp@16684509bae55f5cdaedc6b1d4ab1224fe00374a -
Branch / Tag:
refs/tags/0.2.0 - Owner: https://github.com/nebius
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@16684509bae55f5cdaedc6b1d4ab1224fe00374a -
Trigger Event:
release
-
Statement type: