Skip to main content

MCP server exposing a hosted boxkite control-plane (sandbox lifecycle, exec, files) as native tools for MCP-compatible clients (Claude Code, Claude Desktop, Cursor, etc.).

Project description

boxkite-mcp

An MCP (Model Context Protocol) server over a hosted boxkite control-plane -- lets any MCP-compatible client (Claude Code, Claude Desktop, Cursor, etc.) attach a real sandboxed code-execution backend as a native tool source, with zero custom integration code.

Built on top of boxkite-client, the existing Python SDK for the hosted control-plane API -- this package adds no HTTP logic of its own, only the MCP tool surface.

Install

Not yet published to PyPI -- install both packages from this repo:

pip install -e ../sdk-python
pip install -e .

Configuration

Two environment variables, read at startup. The process fails fast with a clear error if either is missing:

Variable Meaning
BOXKITE_BASE_URL Base URL of the boxkite control-plane, e.g. https://boxkite-control-plane-316016512837.us-central1.run.app
BOXKITE_API_KEY A bxk_live_... API key for your account

Run

BOXKITE_BASE_URL=https://your-control-plane.example.com \
BOXKITE_API_KEY=bxk_live_... \
boxkite-mcp

Speaks MCP over stdio -- point an MCP client's config at the boxkite-mcp command (see the hosted docs site's MCP page for Claude Desktop / Claude Code config snippets).

Tools

Every per-sandbox tool takes session_id as a parameter (unlike boxkite_client.langchain_tools.create_sandbox_tools, which binds one pre-created session at factory time) -- the calling agent owns the full lifecycle: create a sandbox, run several things in it, destroy it, all within one conversation.

  • create_sandbox(label?, size?, storage_gb?, lifetime_minutes?, count?) -- create a sandbox (or a batch of count sandboxes), returns id/status per sandbox. size is a CPU/memory preset ("small" default, "medium", or "large"); storage_gb and lifetime_minutes override the sandbox's volume size and how long it stays alive. All four are optional and bounded by fair-use ceilings on the account, never a paid upgrade.
  • destroy_sandbox(session_id) -- tear one down
  • get_sandbox(session_id) -- look up one sandbox's status
  • list_sandboxes(active_only?) -- list the account's sandboxes
  • exec(session_id, command, timeout?) -- run a shell command
  • file_create(session_id, path, content) -- create/overwrite a file
  • view(session_id, path, view_range?) -- view a file or list a directory
  • str_replace(session_id, path, old_str, new_str, replace_all?) -- edit a file
  • ls(session_id, path?) -- list the direct children of a directory
  • glob(session_id, pattern, path?) -- find files by name pattern (e.g. **/*.py)
  • grep(session_id, pattern, path?, glob?, max_matches?) -- search file contents by regex

Security: the sandbox's own isolation is the trust boundary

exec runs arbitrary shell commands inside the sandbox with no client-side allowlist, confirmation step, or command-scoping; view/file_create/ str_replace operate on any path within the sandbox with no additional restriction at this layer. That's the correct design for a code-execution sandbox product -- the isolation boundary is the Kubernetes sandbox itself (see the root repo's SECURITY.md/README for what that isolation actually provides), not these MCP tools' argument validation. Two things follow from that:

  • Whatever the BOXKITE_API_KEY you configure can reach (network access, mounted storage, any other capability your control-plane deployment grants that account's sandboxes) is reachable by any MCP client wired up to this server, unconditionally. Don't point this at an account/control-plane whose sandboxes have broader privileges than you want an LLM agent to have unsupervised access to.
  • exec/view results are returned to the calling LLM as plain tool-result text, unsanitized. If a sandbox command produces attacker-influenced output (e.g. the agent clones an untrusted repo and then views a file from it), that content flows into the LLM's context like any other tool result -- treat it as untrusted input, same as you would for a web-fetch or file-read tool, not as trusted system output.

Error handling

Every tool catches BoxkiteApiError/BoxkiteConnectionError and returns a descriptive string as the tool result instead of raising -- mirrors the defensive pattern in boxkite_client.langchain_tools so a control-plane error (quota hit, sandbox not found, network failure) shows up as normal tool output the calling agent can react to, not a server crash.

Development

pip install -e ".[dev]"
pytest tests/

Unit tests mock the control-plane with httpx.MockTransport (same pattern as sdk-python/tests/) -- no real deployment needed. tests/live_smoke.py is a separate, non-CI manual script that drives the real server process over stdio via mcp's own ClientSession against a live control-plane:

BOXKITE_BASE_URL=https://your-control-plane.example.com \
BOXKITE_API_KEY=bxk_live_... \
python tests/live_smoke.py

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

boxkite_mcp-0.1.0.tar.gz (14.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

boxkite_mcp-0.1.0-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file boxkite_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: boxkite_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 14.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for boxkite_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 366f0260b6a431343434e62997c18ed15660d481e040e49c00ee9396671d93b2
MD5 88153f2d9dd160a5bd3f4d4f9f43e942
BLAKE2b-256 3a51514193a73e8cec23845cff3baaa6dba8714183301fe0b0b897c7677a5629

See more details on using hashes here.

File details

Details for the file boxkite_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: boxkite_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for boxkite_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0665b34e6e822e93251bcf5a916d0eb9e42618f5139bbd68f7983984e3c036ba
MD5 4961ab09885ae1f2e3f4ef26996d1455
BLAKE2b-256 16aa59a6554e9b5089624d9a4f315e46a38dca116bd947fe737ad4891eb8c6e6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page