Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

dofile

Run Stata-syntax .do files without a Stata license, and expose them to AI agents over MCP.

Status: early preview (0.1.x, alpha). Emulates Stata 14.

Install

Pre-releases only so far, so pip needs --pre:

pip install --pre dofile            # the dofile command
pip install --pre "dofile[mcp]"     # adds the dofile-mcp server

Python 3.12 or newer. From a source checkout, use uv sync --extra mcp and uv run instead.

Command line

dofile run analysis.do --json results.json

Prints the log like stata -b and exits 1 if the do-file stops on an error. --json also writes {rc, error, error_command, results, versions}, where results holds e() and r() in the same form as the MCP server's (see MCP-SCHEMA.md). It runs with the sandbox on (see below): code writes only to the working folder (the current one, or --workdir), and reads from it, from the do-file's own folder (so nested do files work) and from any --read-dir folders. --unsafe turns the sandbox off for trusted code that needs shell, cd or erase.

MCP server

Install with pip install --pre "dofile[mcp]", then add it to Claude Code (stdio; the session works in the folder you launch it from):

claude mcp add dofile -- dofile-mcp --workdir "$PWD"

From a source checkout: claude mcp add dofile -- uv run --directory /path/to/dofile --extra mcp dofile-mcp --workdir "$PWD".

Tools: run_do (run Stata code; returns log, rc, error, e()/r() as JSON and new files), describe_data, get_file (exported graphs as images, logs and CSVs as text in pages), get_matrix (one matrix, or part of it, at full precision), upload_file, start_session, request_upload and request_download (HTTP), reset. Resources: dofile://commands lists the supported commands, dofile://about the versions. Data stays in memory between run_do calls. Full inputs, outputs and return codes: MCP-SCHEMA.md.

Readable logs in Claude Code (optional): Claude Code shows an MCP result as JSON, so a log is one string full of \n. The dofile-log plugin prints each run_do log in the terminal under the call, colored and between two rules, and keeps it out of the model's context. It needs jq, works with stdio and HTTP, and shows the log in the result (cut for long runs; the bar names the file with the full log):

/plugin marketplace add jeffzyliu/dofile
/plugin install dofile-log@dofile

Source: plugins/dofile-log. The same text is always in the log_file the result names.

HTTP: dofile-mcp --http --port 8000 (localhost only by default). Call start_session first and pass its token as session; each session gets its own temporary folder, deleted when the session ends.

Large files never need to pass through the model's context:

  • stdio: start with --read-dir /path/to/data. The folders are listed in the server's instructions, and code reads files in place by absolute path (use "/path/to/data/file.dta"). They are read-only; output goes to the working folder.
  • HTTP: the agent calls request_upload(name, session) and gets a one-time URL (valid 10 minutes), then sends the file itself, e.g. curl --fail -T file.dta <url>. Behind a proxy or in a container, set --public-url to the address clients reach the server at. (--read-dir here means folders on the server.)

--file-limit sets the largest upload in MB (default 1024). Small files the agent writes itself (CSV, .do) go inline with upload_file(name, text=...). Uploads never overwrite an existing file unless the agent passes replace=true, as with Stata's save, replace: over stdio the working folder is your own.

Sandbox (on by default; --unsafe turns it off): shell/!, erase/rm, rmdir, mkdir, cd, copy and webuse are disabled. Files can only be written in the working folder, and read from it, from --read-dir folders and from the Python installation. No subprocesses or network. Each call has a timeout (--timeout, default 60 s); a call that runs too long or is cancelled is interrupted like Stata's Break key (rc 1, data kept), and only code that does not stop, or a crash, resets that session (rc 9998). The sandbox is a policy layer, not a security boundary: run public HTTP deployments in a container.

Development

Check the local MCP server with the MCP Inspector (needs Node):

npx @modelcontextprotocol/inspector uv run --extra mcp dofile-mcp        # web UI: list tools, call run_do
npx @modelcontextprotocol/inspector --cli uv run --extra mcp dofile-mcp --method tools/call \
  --tool-name run_do --tool-arg 'code=display 2+2'                       # scripted check

For HTTP mode, start uv run --extra mcp dofile-mcp --http and connect the Inspector to http://127.0.0.1:8000/mcp (call start_session first).

uv sync --extra mcp
uv run poe test          # in parallel, ~35 s; skips the slow Stata 14 log comparison
uv run poe test tests    # dofile's own tests only, without OpenDTA's suite in tests_opendta/
uv run poe slow          # the Stata 14 log comparison (~75 s)
uv run poe ci            # everything, as CI does
  • tests/conformance/: dofile's corpus with reference values from statsmodels/linearmodels, plus breadth probes. Known engine gaps are strict xfails, so a fix in OpenDTA shows up as a failure to remove.
  • scripts/vendor_opendta.py [COMMIT]: re-vendor OpenDTA, then run the full suite.
  • CI: Ubuntu and macOS, Python 3.12–3.14 (.github/workflows/ci.yml); the web demo has its own workflow (.github/workflows/web.yml). Dev default is 3.14 (.python-version).

Web demo

web/ runs the same engine in the browser (Pyodide in a Web Worker, no server): an editor, files kept in the browser, Run and Break, the log and graphs. Its README lists the scripts (dev server, build, tests, the memory snapshot) and what each folder holds. CI for it is .github/workflows/web.yml.

Engine

A vendored copy of OpenDTA (MIT), pinned in src/dofile/_vendor/opendta/VENDORED. dofile's own changes to it are patches in scripts/patches/ (r(table) after estimation, and fixes for engine bugs listed in docs/opendta-issues.md), re-applied by the vendor script. Not affiliated with StataCorp; Stata is a registered trademark of StataCorp LLC.

License

MIT (LICENSE). Contributions follow the clean-room and license rules in LICENSE-POLICY.md: no StataCorp files or text, no GPL code.

Metadata

Release files for dofile 0.1.0.dev0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dofile 0.1.0.dev0
File Size Uploaded Provenance Actions
dofile-0.1.0.dev0.tar.gz 3.2 MB Without provenance Details for dofile-0.1.0.dev0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for dofile 0.1.0.dev0
File Interpreter ABI Platform Actions
dofile-0.1.0.dev0-py3-none-any.whl Python 3 none any Details for dofile-0.1.0.dev0-py3-none-any.whl

Total release size: 6.1 MB

Release files / dofile-0.1.0.dev0.tar.gz

Download URL dofile-0.1.0.dev0.tar.gz
Size 3.2 MB
Tags Source
SHA-256 checksum
How to use checksums
1058589f1b8be02b6fdc8d468f1b0b110a67148970eaa535376c8b5ec382714d
BLAKE2b-256 checksum
How to use checksums
12fbbcc191691fab6b280a69cff63f6524f43c63a498eb7e4df33f93485520ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / dofile-0.1.0.dev0-py3-none-any.whl

Download URL dofile-0.1.0.dev0-py3-none-any.whl
Size 2.9 MB
Tags Python 3
SHA-256 checksum
How to use checksums
cdee5e88ff1e497b1b0be544e312c4c9652bb55b1562953a448b86ec75c3a6d3
BLAKE2b-256 checksum
How to use checksums
ed21498a6f2f057e7d13296c8f0f9b5a0d8cf04ddb3390c43c3ab81feac34845
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for dofile 0.1.0.dev0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page