Atlas / MCP servers / tmonk / Stata

StataBLOCK

mcp/tmonk/stata-2

A lightweight Model Context Protocol (MCP) server for Stata. Execute commands, inspect data, retrieve stored results (r()/e()), and view graphs in your chat interface. Built for economists who want to integrate LLM assistance into their Stata workflow.

Verdict
BLOCK
Grade
F
Trust score
57 /100
Exposed tools
—
Transport
stdio
License
AGPL-3.0
Stars
86
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

mcp-stata is an agentic toolkit for empirical researchers. It gives AI agents native control over a local Stata installation, allowing agents to run do-files, inspect data, check stored results, and export graphs. Contains a skills catalog for workflows researchers use often: auditing data, replication and robustness checks, specification comparisons, publication QA, referee responses, and modernization of legacy code. Featured in News.

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).
  • Streaming graph caching: automatically cache graphs during command e
Read from source at commit 581ba21d4c81OBSERVED · 2026-10-07
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (pypi)
claude mcp add mcp-stata -- None mcp-stata==3.3.0
03

Trust audit

BLOCKgrade F · trust 57/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (7 observation(s))
Network
declared (5 observation(s))
Shell
declared (4 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (25)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/mcp_stata/stata_client.py:4602
ok = bool(eval(code, {"__builtins__": {}}, env))
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
src/mcp_stata/server.py:1912
".netrc",
Why it matters. touches a credential store
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
src/mcp_stata/server.py:1913
"id_rsa",
Why it matters. touches a credential store
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
src/mcp_stata/server.py:1914
"id_ed25519",
Why it matters. touches a credential store
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.agents
.agents
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.claude-plugin
.claude-plugin
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.codex-plugin
.codex-plugin
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.mcp.json
.mcp.json
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
plugin/.agents/skills
plugin/.agents/skills
Why it matters. link not followed
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
worker/dashboard/server.py:211
print(f"Dashboard → http://127.0.0.1:{PORT}")
LOWInventory / provenance · inv.hidden_file · CWE-1104
.envrc.example
.envrc.example
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
scripts/benchmarks/benchmark_rust_ops.py:81
if eval(code, {"__builtins__": {}}, env):
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/mcp_stata/discovery.py:615
return hashlib.md5(fingerprint_raw.encode("utf-8")).hexdigest()
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/mcp_stata/stata_client.py:5448
return hashlib.md5(data).hexdigest()
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/mcp_stata/stata_client.py:5513
suffix = hashlib.md5((name or "").encode("utf-8")).hexdigest()[:8]
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/mcp_stata/stata_client.py:5702
suffix = hashlib.md5((sig or "").encode("utf-8")).hexdigest()[:8]
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/mcp_stata/ui_http.py:152
return hashlib.sha1(json.dumps(payload, sort_keys=True).encode("utf-8")).hexdigest()
LOWInformation disclosure · disclose.log_secret · CWE-209, CWE-532
scripts/benchmarks/run_e2e_benchmark.py:51
print(f"Token: {channel_info.token}")
LOWNetwork egress · net.env_exfil · CWE-200, CWE-319
tests/installer/test_installer_telemetry_e2e.py:113
os.environ.copy() ... curl
Why it matters. reads secrets in the same file that sends data out
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:416
"baseUrl": "http://127.0.0.1:53741",
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/installer/powershell/e2e.tests.ps1:37
$env:MCP_STATA_TELEMETRY_URL = "http://255.255.255.255/unreachable"
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
scripts/benchmarks/js_benchmark/package.json
apache-arrow, node-fetch
Why it matters. 2 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWInventory / provenance · mcp.no_tools_extracted · CWE-1104
server.json
Why it matters. the tool list is enumerated at runtime by tools/list, not declared in source
Fix. the page says so rather than showing an empty table
INFOSupply chain · prompt.pipe_to_shell · CWE-829, CWE-1357
CHANGELOG.md:347
- README, use curl | bash for installer commands
INFOSupply chain · prompt.pipe_to_shell · CWE-829, CWE-1357
README.md:28
curl -LsSf https://mcp-stata-install.tdmonk.com/install.sh | bash

Gates applied: no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha 581ba21d4c81full audit observations/trust-audit/mcp-server/tmonk__stata-2.json · Report an issue / request a re-scan
04

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-07581ba21d4c81BLOCKF57first audit
05

Questions

What is the Stata MCP server?

A lightweight Model Context Protocol (MCP) server for Stata. Execute commands, inspect data, retrieve stored results (r()/e()), and view graphs in your chat interface. Built for economists who want to integrate LLM assistance into their Stata workflow.

Is Stata safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (57/100) and found 4 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does Stata need?

It reads CF_API_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does Stata run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as mcp-stata-installer-worker at 3.3.0.

How current is this page?

The grade is for one exact copy of the source (581ba21d4c81), read on 2026-10-07. The repository is watched and re-audited when it changes.

Advertisement