Execute MCP tools through generated Python code interfaces
Project description
maco
maco (mcp-as-code) lets an MCP client interact with many upstream MCP tools through a small code-execution interface.
It follows Anthropic's code-execution-with-MCP pattern: keep the large MCP surface area behind a gateway, then let agents write short Python programs for loops, filtering, joins, retries, and structured output. Instead of loading hundreds of tool schemas into the context window, the client gets a compact interface for shell discovery and Python execution.
At a glance
- Point
macoat a Claude-stylemcp.jsoncontaining one or many MCP servers. - Run
maco serve-mcpto expose one Streamable HTTP MCP endpoint. - Connect your MCP client to that endpoint; it sees only
bashandcode_execute. - Agents thrive on discovery with
rgandfd, so maco gives thembashaccess to navigate the tool interface as a real filesystem. - Use
code_executeto call upstream MCP tools from Python withfrom tools.<server> import <tool>.
Why it helps
- Small context footprint: the client starts with two tools, not every upstream schema.
- Programmatic leverage: use Python for paging, filtering, joining, caching, retries, and local intermediate files.
- Progressive discovery: inspect only the generated wrappers relevant to the task.
- Flexible isolation: run code locally for fast iteration or inside Docker/Matchlock for stronger isolation.
- Works with existing MCP servers: stdio, Streamable HTTP, and SSE server configs are supported.
How it works
MCP client
│ sees only bash + code_execute
▼
maco serve-mcp ── sandbox ──▶ Python code imports generated tools
│
▼
managed maco gateway
│
▼
upstream MCP servers from mcp.json
maco serve-mcp starts a managed gateway for the upstream MCP servers, prepares a generated Python SDK for the sandbox, and serves a compact MCP endpoint for downstream clients.
Installation
Install the Python package mcp-as-code; it provides the maco executable:
uv tool install mcp-as-code
Then verify the CLI:
maco version
Quick start
Create a Claude-style mcp.json:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
}
}
Start the maco MCP server:
maco serve-mcp --config mcp.json --provider docker
Use --provider local for a faster, non-isolated local feedback loop.
By default this serves Streamable HTTP MCP at http://127.0.0.1:8789/mcp.
Configure an MCP client to connect to that endpoint:
Codex
codex mcp add maco --url http://127.0.0.1:8789/mcp
Claude Code
claude mcp add --transport http maco http://127.0.0.1:8789/mcp
From the client, the agent uses the MCP bash tool for code navigation inside the sandbox:
rg --files /workspace/macosdk/tools
sed -n '1,160p' /workspace/macosdk/tools/filesystem/__init__.py
Then use code_execute to call tools in a context-efficient manner, using loops and conditions instead of traditional linear tool-call chaining:
from tools.filesystem import listDirectory
for path in ["/tmp", "/var/tmp"]:
listing = listDirectory(path=path)
entries = listing if isinstance(listing, list) else getattr(listing, "entries", [])
if not entries:
print(f"{path}: empty")
else:
print(f"{path}: {len(entries)} entries")
See examples/serve-mcp for a complete example that wraps multiple upstream MCP servers behind one maco endpoint.
If you are using the source checkout directly, the script wrapper is equivalent:
./scripts/maco-serve-mcp --config mcp.json --provider docker
MCP config
maco expects Claude-style JSON with a top-level mcpServers object. Supported upstream transports are stdio, http/streamable_http, and sse.
Minimal stdio example:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
}
}
Minimal Streamable HTTP example:
{
"mcpServers": {
"remote": {
"type": "http",
"url": "http://127.0.0.1:8000/mcp",
"headers": {"Authorization": "Bearer ${TOKEN}"}
}
}
}
For remote HTTP/SSE servers without a static Authorization header, maco can perform OAuth from the upstream server's HTTP 401 Bearer challenge. See docs/mcp-config.md for the full config reference, including environment expansion, headers, OAuth hints, token caching, and tool filtering.
Sandbox providers
Choose the execution provider with --provider:
local— fastest feedback loop; runs commands as local subprocesses.docker— runs commands in a long-lived Docker container.matchlock— runs commands in a long-lived Matchlock micro-VM.
The default Docker/Matchlock image is ghcr.io/jingkaihe/maco:<VERSION>-alpine, where <VERSION> comes from VERSION.txt. It includes maco, Python 3.12, uv, pydantic, rg, and fd.
Development
make check
make build
make image
Safety notes
maco serve-mcpexposes code execution to whatever can reach its HTTP MCP endpoint; bind and firewall it accordingly.- The managed gateway uses a bearer token by default. Do not commit
.maco/gateway.json. - Sandbox providers change the isolation boundary, not the authority of the upstream MCP servers. Treat generated tool calls like direct MCP tool calls.
- Inspect unfamiliar generated wrappers before running code that calls them.
License
Apache License 2.0. See LICENSE.
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 mcp_as_code-0.1.2.tar.gz.
File metadata
- Download URL: mcp_as_code-0.1.2.tar.gz
- Upload date:
- Size: 44.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e2e578adb8e1eef9a71b6591d6485941ee89eff7ebd348979d19bd05712cc61
|
|
| MD5 |
246d69fa6678179f94ba9990056bd7f7
|
|
| BLAKE2b-256 |
97e488a4ee5078fbe9b03247ada2863dcc654065d55ce5597326eb556b3bc451
|
Provenance
The following attestation bundles were made for mcp_as_code-0.1.2.tar.gz:
Publisher:
release.yml on jingkaihe/maco
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_as_code-0.1.2.tar.gz -
Subject digest:
8e2e578adb8e1eef9a71b6591d6485941ee89eff7ebd348979d19bd05712cc61 - Sigstore transparency entry: 1828981848
- Sigstore integration time:
-
Permalink:
jingkaihe/maco@e680ca8b394a20cf951bc0645e452696710ed7de -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/jingkaihe
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e680ca8b394a20cf951bc0645e452696710ed7de -
Trigger Event:
push
-
Statement type:
File details
Details for the file mcp_as_code-0.1.2-py3-none-any.whl.
File metadata
- Download URL: mcp_as_code-0.1.2-py3-none-any.whl
- Upload date:
- Size: 53.9 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 |
8fc04a5a1ff630b2b927a5d43f30e3e7dfc03d04f0959aef175c2ffb26ea5cb3
|
|
| MD5 |
242e9a5689aed3a80b8e527c7e4d0085
|
|
| BLAKE2b-256 |
1435de93709a4a676d6fedb72b059bc43e4f16db7f9510f3bb7355cff38d0911
|
Provenance
The following attestation bundles were made for mcp_as_code-0.1.2-py3-none-any.whl:
Publisher:
release.yml on jingkaihe/maco
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_as_code-0.1.2-py3-none-any.whl -
Subject digest:
8fc04a5a1ff630b2b927a5d43f30e3e7dfc03d04f0959aef175c2ffb26ea5cb3 - Sigstore transparency entry: 1828981906
- Sigstore integration time:
-
Permalink:
jingkaihe/maco@e680ca8b394a20cf951bc0645e452696710ed7de -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/jingkaihe
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e680ca8b394a20cf951bc0645e452696710ed7de -
Trigger Event:
push
-
Statement type: