Code-Mode Gateway Reference¶
The code-mode gateway has two user-facing layers. The
gateway server exposes search and execution
tools over MCP, while the runtime client installs the mcp_tools.<server> import hook
used inside sandboxed Python scripts. The wrapper factory is responsible for turning upstream MCP
schemas into importable sync and async Python callables.
Runtime Behavior¶
Code-mode runs user Python in a child process with generated wrapper modules on
PYTHONPATH. The wrapper modules expose each upstream MCP tool as
mcp_tools.<server>.<tool_name> and <tool_name>_async.
There are two separate serialization paths to keep in mind:
Wrapper return deserialization happens when sandboxed code calls an imported MCP tool wrapper.
Sandbox
RESULTserialization happens when the sandbox process exits and returns the value assigned toRESULTback to the gateway ornomad code-mode-exec.
Wrapper Return Values¶
Generated wrappers normalize the upstream MCP response before returning it to your sandboxed Python code:
If the MCP response has
structuredContent, wrappers return that value.If
structuredContentis an object with only aresultkey, wrappers unwrap and returnstructuredContent["result"].If
structuredContentis absent and the response has MCPcontentblocks, wrappers normalize those content blocks into plain Python data where possible.Both sync and async wrappers apply the same normalization.
After normalization, wrappers apply schema-guided deserialization for Nomad
media fields. Today the supported Nomad media type is
application/vnd.nomad.tensor, which is encoded on the wire as a base64
zstd-compressed torch serialization. If the MCP outputSchema marks a field,
array item, additionalProperties value, or anyOf/oneOf branch with that
media type, the wrapper reconstructs it as a torch.Tensor before
returning it.
This deserialization is recursive and resolves local JSON Schema $ref values.
It does not reconstruct arbitrary Pydantic models or domain objects around
the deserialized values. For example, a tool that returns a
WellFormat-shaped object may return a plain
dict whose tensor fields have already been decoded; call
WellFormat.model_validate(result) when you need the Pydantic object.
Sandbox RESULT Values¶
execute_mcp_code(),
execute_mcp_script(), and
nomad code-mode-exec return the final value
assigned to the global name RESULT. If RESULT is never assigned, the
returned result is null. If it is assigned multiple times, only the final
value is kept.
The sandbox writes RESULT through JSON. The fallback serializer preserves
common values as follows:
Python value |
Returned JSON value |
|---|---|
unchanged |
|
JSON array, with values serialized recursively |
|
JSON object, with keys and values serialized recursively |
|
|
|
Nomad tensor wire payload string |
|
Other types |
|
This means wrapper return values and final RESULT values do not have the same
type guarantees. A wrapper may return a torch.Tensor inside the
sandbox, but RESULT = tensor serializes that tensor back to a JSON string
payload when the sandbox exits. For large or binary outputs, prefer writing
files in the workspace and returning a small JSON-friendly summary in RESULT.
CLI Entry Point¶
nomad code-mode-exec is the CLI entry point for
running one script through run_script()
without starting a long-lived gateway. It returns a serialized
SandboxResult; see
nomad code-mode-exec for command syntax, output
handling, workspace selection, and script argument forwarding.
Execution Environment¶
Sandboxed code runs with the generated wrapper package, the workspace directory,
standard-library paths, and installed package paths visible on sys.path. The
gateway uses the configured workspace_root as the child process working
directory. If that workspace contains .venv/bin/python or
.venv/Scripts/python.exe, the gateway uses that interpreter for sandbox
execution.
For persistent outputs, write files under the workspace directory. Temporary implementation directories used by the gateway and generated wrappers are cleaned up by the gateway process.
Gateway Server¶
- class nomad.gateway.server.CodeModeGateway(config)¶
Expose a minimal async MCP proxy for sandboxed execution.
- Parameters:
config (GatewayConfig)
- property fastmcp: FastMCP¶
- async serve(transport=None, **transport_kwargs)¶
- async search_code_tools(query, server_filter=None, detail_level='brief', limit=None)¶
Discover MCP-backed helpers available inside the code-mode sandbox.
- Parameters:
query (str | None) – Optional keyword search across tool names, descriptions, and argument metadata. Returns results for all tools, limited to
limit, ifNone.server_filter (str | None) – Restrict results to a specific upstream server ID.
detail_level (Literal['brief', 'full']) –
"brief"(default) returnspython_import_path,descriptionandsignature."full"returnspython_import_pathplus the directinputSchema/outputSchemapayload and description.limit (int | None) – Maximum number of matching tools to return. Pass
Noneto return all matches.
- Returns:
A list of dicts describing each matching tool.
- Return type:
- Notes:
Typical flow:
Call this tool to locate the wrapper import path and inspect the target helper.
Import the generated wrapper in your snippet and call
some_tool(...)orawait some_tool_async(...)while running withinexecute_mcp_codeorexecute_mcp_script.Example import:
from mcp_tools.some_server import some_tool, some_tool_async
- async execute_mcp_script(script_path, ctx, env=None)¶
Like execute_mcp_code but takes in a path to a python script to evaluate
- See execute_mcp_code for more details. Keep
RESULTunder about 16 KiB and write larger outputs to files instead.
- Parameters:
script_path (pathlib.Path)
ctx (Context)
- See execute_mcp_code for more details. Keep
- async execute_mcp_code(code, ctx, env=None)¶
Run Python inside the Nomad sandbox and optionally call MCP tools.
- Parameters:
code (str) – Python source to execute. Printed output is captured in
stdoutandstderr. To return a value, assign it toRESULT(for example,RESULT = {"answer": 42}). IfRESULTis assigned multiple times, only the final value is kept. With no assignment,resultisNone. KeepRESULTunder about 16 KiB and write larger outputs to files.env (dict[str, str] | None) – Extra environment variables for the run.
ctx (Context)
- Returns:
A payload that includes
stdout,stderr, the value assigned toRESULT(if any),duration_seconds, and error details when present.- Return type:
- Notes:
Tool wrappers are auto-generated under
mcp_tools.<server>and expose both synchronous and asynchronous helpers:from mcp_tools.some_server import some_tool, some_tool_async RESULT = some_tool(param="value") # synchronous call import asyncio async def main(): return await some_tool_async(param="value") RESULT = asyncio.run(main()) # asynchronous call
These helpers normalize the MCP payload into plain Python objects.
Prefer using the async helpers over synchronous helpers.
Sandbox rules for filesystem/network access and approval policy still apply to any code or tool use inside the sandbox
- async run_script(script_path, env=None, *, script_args=(), timeout_seconds=<object object>, capture_stdio=True)¶
- Parameters:
- Return type:
- nomad.gateway.server.run_gateway(config, transport=None, *, log_level='INFO', log_file_handler=None, **kwargs)¶
Run a code-mode gateway from an already-loaded config.
- Parameters:
config (GatewayConfig)
transport (str | None)
log_level (str)
log_file_handler (Handler | None)
kwargs (Any)
- Return type:
None
Sandbox Result¶
- class nomad.gateway.sandbox.SandboxResult(stdout, stderr, result, returncode, duration_seconds, tool_calls)¶
Result captured from a sandboxed Python execution.
- Parameters:
Runtime Client¶
- exception nomad.gateway.runtime.client.BridgeError¶
Raised when the gateway bridge returns an error.
- exception nomad.gateway.runtime.client.ToolCallError¶
Raised when an upstream MCP tool returns an error result.
- async nomad.gateway.runtime.client.call_tool_async(server, tool, arguments=None)¶
Call an upstream MCP tool through the active sandbox bridge.
- nomad.gateway.runtime.client.call_tool_sync(server, tool, arguments=None)¶
Synchronously call an upstream MCP tool through the sandbox bridge.
- nomad.gateway.runtime.client.install_wrapper_importer()¶
Install the import hook that exposes generated MCP wrapper modules.
- Return type:
None
Wrapper Factory¶
- class nomad.gateway.runtime.wrapper_factory.ToolParameter(name, annotation, optional, description)¶
Parameter metadata derived from an MCP tool input schema.
- nomad.gateway.runtime.wrapper_factory.build_tool_signature(schema)¶
Build a Python call signature from an MCP tool schema.
- nomad.gateway.runtime.wrapper_factory.build_server_module(module, spec)¶
Populate
modulewith sync and async wrappers for one MCP server.- Parameters:
module (ModuleType)
- Return type:
None