Code Execution Server¶
code_execution_server (doc_processing_std_tools.code_execution, MCP name code-execution-tools)
gives an agent a shell session that remembers its working directory between calls. It is how an
agent runs scripts and creates documents with code. It needs no extra.
from doc_processing_std_tools import code_execution_server
Tools¶
| Tool | Key parameters | Returns |
|---|---|---|
execute_command |
command, timeout (seconds, optional) |
JSON: stdout, stderr, exit_code (int), timed_out (bool) |
restart_session |
— | Confirmation naming the working directory it reset to |
command can use pipes, redirects and chaining (&&, ||, ;).
How the session works¶
- Each
execute_commandruns in a fresh subprocess, started in the session's current working directory. After the command ends, the session records the directory the command finished in, so acdcarries over to the next call. - Only the working directory carries over. Variables set with
export FOO=barorsource .envare gone on the next call. Set them in the same command (source .env && python job.py), or write them to a file and read it each time. Files written to disk do persist. restart_sessionreturns to the directory the server started in.- On Linux and macOS the command runs in
/bin/bash -c. On Windows it runs incmd.exethrough a temporary batch file, so usecmdsyntax there. - There is one session per server process, shared by every caller of that process. Calls are serialised, so two commands never run at once in the same session.
Environment variables¶
| Variable | Default | Effect here |
|---|---|---|
DPTTOOLS_SANDBOX_TIMEOUT |
30 |
The default timeout and the ceiling: a larger timeout argument is lowered to this value |
DPTTOOLS_OUTPUT_TRUNCATION_LIMIT |
50000 |
stdout and stderr are each cut at this many characters |
Examples¶
Tool calls are written as Python calls; the model sends the same arguments as JSON.
execute_command(command="cd /workspace/reports && ls -la")
execute_command(command="python make_summary.py --month 2026-09", timeout=120)
execute_command(command='python -c "import docx; print(docx.__version__)"')
A result:
{"stdout": "1.1.2\n", "stderr": "", "exit_code": 0, "timed_out": false}
Pitfalls¶
- The timeout cannot exceed
DPTTOOLS_SANDBOX_TIMEOUT. To allow long jobs, raise the variable. On timeout the whole process tree is killed and the result has"timed_out": trueand"exit_code": -1, with whatever output was captured. - A zero or negative
timeoutreturnsexit_code: -1with an explanation instderr. - Commands are not filtered. The command runs with the server process's permissions. The container is the security boundary — see Architecture.
- Interactive commands are not supported. There is no terminal, and a command that waits for
input can block until the timeout. Pass flags such as
-yor--yes. - Background processes. On Linux and macOS, a process started with
&that keeps the command's output open makes the call wait until the timeout, and is then killed with the rest of the process group. Redirect its output (job > job.log 2>&1 &) if it must outlive the call. - The working directory is per server process. Restarting the server, or using a second server process, starts again from the process's own working directory.
- Long commands no longer block other tools in the composed launcher (new in 0.6.0): it runs each call on a worker thread, so file, search and document calls proceed while a command runs. Commands still take turns in the one session. A command cannot be cancelled from the client; it runs until it finishes or reaches its timeout.