Warning
This plugin, like Monty itself, is experimental. Expect breaking changes and incomplete functionality.
A hyper-mcp plugin that executes Python code in a sandboxed Monty interpreter, compiled to WebAssembly.
monty-plugin exposes a single MCP tool called run that accepts Python source code (and optional input variables), executes it inside the Monty interpreter, and returns the captured stdout output along with the result value.
Because the plugin compiles to a .wasm module (wasm32-wasip1), it runs in a fully sandboxed environment — there is no access to the host system beyond what the plugin explicitly provides.
| Name | Type | Required | Description |
|---|---|---|---|
code |
string |
✅ | The Python code to execute. |
inputs |
map<string, MontyObject> |
No | Input variables passed into the Python runtime. |
resource_limits |
ResourceLimits |
No | Execution resource limits for the interpreter. |
All fields are optional. When omitted, the corresponding limit is not enforced (except max_recursion_depth, which defaults to 1000).
| Field | Type | Description |
|---|---|---|
max_allocations |
integer |
Maximum number of heap allocations allowed. |
max_duration |
{secs: integer, nanos: integer} |
Maximum execution time. |
max_memory |
integer |
Maximum heap memory in bytes (approximate). |
gc_interval |
integer |
Run garbage collection every N allocations. |
max_recursion_depth |
integer |
Maximum recursion depth (function call stack depth). |
| Field | Type | Description |
|---|---|---|
output |
string |
Captured print/stdout output produced by the Python code. |
result |
MontyObject |
The return value of the Python code. |
The following functions are available to Python code running inside the plugin:
http_request(
url: str,
method: str | None = None,
headers: dict[str, str] | None = None,
body: str | bytes | None = None,
) -> tuple[int, dict[str, str], str | bytes]
Make HTTP requests from within the sandbox. Returns a tuple of (status_code, response_headers, response_body).
notify_progress(
message: str | None,
progress: int | float,
total: int | float | None = None,
) -> None
Report progress back to the MCP client. Requires a progressToken in the request context.
The plugin implements a subset of Python's pathlib.Path API:
Path.exists(*, follow_symlinks=True) -> boolPath.is_file(*, follow_symlinks=True) -> boolPath.is_dir(*, follow_symlinks=True) -> boolPath.is_symlink() -> boolPath.read_text(encoding=None, errors=None, newline=None) -> strPath.read_bytes() -> bytesPath.write_text(data, encoding=None, errors=None, newline=None) -> NonePath.write_bytes(data) -> NonePath.mkdir(mode=0o777, parents=False, exist_ok=False) -> NonePath.unlink(missing_ok=False) -> NonePath.rmdir() -> NonePath.iterdir() -> list[str]Path.stat(*, follow_symlinks=True) -> os.stat_resultPath.rename(target) -> NonePath.resolve(strict=False) -> strPath.absolute() -> str
os.getenv(key, default=None) -> str | None
datetime.datetime.now(tz=None) -> datetime.datetimedatetime.date.today() -> datetime.date
- Rust 1.94+ (pinned via
rust-toolchain.toml) - The
wasm32-wasip1target
rustup target add wasm32-wasip1cargo build --release --target wasm32-wasip1The compiled plugin will be at target/wasm32-wasip1/release/plugin.wasm.
Add the plugin to your hyper-mcp configuration. You can reference the OCI artifact published to GitHub Container Registry:
{
"name": "monty",
"oci": "ghcr.io/hyper-mcp-rs/monty-plugin:latest"
}Or pin to a specific version tag:
{
"name": "monty",
"oci": "ghcr.io/hyper-mcp-rs/monty-plugin:v0.1.0"
}You can pull the artifact directly with ORAS:
oras pull ghcr.io/hyper-mcp-rs/monty-plugin:latestAll release artifacts are signed with Cosign. Verify with:
cosign verify \
--certificate-identity-regexp "https://github.com/hyper-mcp-rs/monty-plugin/.github/workflows/" \
--certificate-oidc-issuer-regexp "https://token.actions.githubusercontent.com" \
ghcr.io/hyper-mcp-rs/monty-plugin:latestA minimal scratch-based Docker image is provided for packaging the .wasm artifact:
# First build the plugin
cargo build --release --target wasm32-wasip1
cp target/wasm32-wasip1/release/plugin.wasm .
# Then build the Docker image
docker build -t monty-plugin .monty-plugin/
├── src/
│ ├── lib.rs # MCP entry-points and Monty execution loop
│ ├── types.rs # RunArguments, RunResponse, MontyObject wrapper
│ ├── function_calls.rs # http_request, notify_progress implementations
│ ├── os_calls.rs # pathlib.Path and os.* operation handlers
│ ├── python_args.rs # Positional/keyword argument resolution helpers
│ ├── monty_object.schema.json # JSON Schema for MontyObject
│ └── pdk/ # Plugin Development Kit glue
│ ├── mod.rs
│ ├── exports.rs # Extism-exported MCP handler functions
│ ├── imports.rs # Host-imported functions
│ └── types.rs # MCP protocol types
├── Cargo.toml
├── Dockerfile
├── rust-toolchain.toml
└── LICENSE
This project is licensed under the Apache License 2.0.