A Model Context Protocol (MCP) server that connects AI agents to a local Stata installation.
If you'd like a fully integrated VS Code extension to run Stata code without leaving your IDE, and also allow AI agent interaction, check out my other project:
Stata Workbench.
Built by Thomas Monk, London School of Economics.
This server enables LLMs to:
- Execute Stata code: run any Stata command (e.g.
sysuse auto,regress price mpg). - Inspect data: retrieve dataset summaries and variable codebooks.
- Export graphics: generate and view Stata graphs (histograms, scatterplots).
- Verify results: programmatically check stored results (
r(),e()) for accurate validation.
- Stata 17+ (required for
pystataintegration) - Python 3.11+ (recommended)
- uv (recommended for install/run)
uvx --from mcp-stata mcp-statauvx is an alias for uv tool run and runs the tool in an isolated, cached environment.
This server attempts to automatically discover your Stata installation (supporting standard paths and StataNow).
If auto-discovery fails, set the STATA_PATH environment variable to your Stata executable:
# macOS example
export STATA_PATH="/Applications/StataNow/StataMP.app/Contents/MacOS/stata-mp"
# Windows example (cmd.exe)
set STATA_PATH="C:\Program Files\Stata18\StataMP-64.exe"If you prefer, add STATA_PATH to your MCP config's env for any IDE shown below. It's optional and only needed when discovery cannot find Stata.
Optional env example (add inside your MCP server entry):
"env": {
"STATA_PATH": "/Applications/StataNow/StataMP.app/Contents/MacOS/stata-mp"
}This MCP server uses the stdio transport (the IDE launches the process and communicates over stdin/stdout).
Open Claude Desktop → Settings → Developer → Edit Config. Config file locations include:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"mcp-stata": {
"command": "uvx",
"args": ["--from", "mcp-stata", "mcp-stata"]
}
}
}After editing, fully quit and restart Claude Desktop to reload MCP servers.
Cursor supports MCP config at:
- Global:
~/.cursor/mcp.json - Project:
.cursor/mcp.json
{
"mcpServers": {
"mcp-stata": {
"command": "uvx",
"args": ["--from", "mcp-stata", "mcp-stata"]
}
}
}Windsurf supports MCP plugins and also allows manual editing of mcp_config.json. After adding/editing a server, use the UI’s refresh so it re-reads the config.
A common location is ~/.codeium/windsurf/mcp_config.json.
{
"mcpServers": {
"mcp-stata": {
"command": "uvx",
"args": ["--from", "mcp-stata", "mcp-stata"]
}
}
}In Antigravity, MCP servers are managed from the MCP store/menu; you can open Manage MCP Servers and then View raw config to edit mcp_config.json.
{
"mcpServers": {
"mcp-stata": {
"command": "uvx",
"args": ["--from", "mcp-stata", "mcp-stata"]
}
}
}VS Code supports MCP servers via a .vscode/mcp.json file. The top-level key is servers (not mcpServers).
Create .vscode/mcp.json:
{
"servers": {
"mcp-stata": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "mcp-stata", "mcp-stata"],
}
}
}VS Code documents .vscode/mcp.json and the servers schema, including type and command/args.
- Skill file (for Claude/Codex): skill/SKILL.md
run_command(code, echo=True, as_json=True, trace=False, raw=False): Execute Stata syntax. JSON envelope by default;raw=Truereturns plain stdout/stderr.load_data(source, clear=True, as_json=True, raw=False): Heuristic loader (sysuse/webuse/use/path/URL) with JSON envelope unlessraw=True.get_data(start=0, count=50): View dataset rows (JSON response, capped to 500 rows).describe(): View dataset structure via Statadescribe.list_graphs(): See available graphs in memory (JSON list with anactiveflag).export_graph(graph_name=None, format="pdf"): Export a graph to a file path (default PDF; useformat="png"for PNG).export_graphs_all(): Export all in-memory graphs as base64-encoded PNGs (JSON response).get_help(topic, plain_text=False): Markdown-rendered Stata help by default;plain_text=Truestrips formatting.codebook(variable, as_json=True, trace=False, raw=False): Variable-level metadata (JSON envelope by default; supportstrace=True).run_do_file(path, echo=True, as_json=True, trace=False, raw=False): Execute a .do file with rich error capture (JSON by default).get_stored_results(): Getr()ande()scalars/macros as JSON.get_variable_list(): JSON list of variables and labels.
Resources exposed for MCP clients:
stata://data/summary→summarizestata://data/metadata→describestata://graphs/list→ graph list (resource handler delegates tolist_graphstool)stata://variables/list→ variable list (resource wrapper)stata://results/stored→ stored r()/e() results
This project is licensed under the GNU Affero General Public License v3.0 or later. See the LICENSE file for the full text.
- All tools that execute Stata commands support JSON envelopes (
as_json=true) carrying:rc(from r()/c(rc)),stdout,stderr,message, optionalline(when Stata reports it),command, and asnippetexcerpt of error output.
- Stata-specific cues are preserved:
r(XXX)codes are parsed when present in output.- “Red text” is captured via stderr where available.
trace=trueaddsset trace onaround the command/do-file to surface program-defined errors; the trace is turned off afterward.
Set MCP_STATA_LOGLEVEL (e.g., DEBUG, INFO) to control server logging. Logs include discovery details (edition/path) and command-init traces for easier troubleshooting.
To set up the development environment, synchronize dependencies using the following commands:
uv sync --no-install-project: Installs the main dependencies listed inpyproject.tomlwithout installing the project itself.uv sync --extra dev --no-install-project: Installs the main dependencies plus any additional development dependencies (such as testing or linting tools), again without installing the project itself.