Msha Mines
FreeNot checkedMSHA mine records — search a US mine by operator or mine name, or look up
About
MSHA mine records — search a US mine by operator or mine name, or look up
README
Search US mines by operator or mine name, or look up a known MSHA Mine ID for its status, recent inspections, violations (with assessed penalties), and quarterly employment/production — from MSHA (Mine Safety and Health Administration) records.
Part of Pipeworx — an MCP gateway connecting AI agents to 1745+ live data sources. This is an independent, unofficial integration — not affiliated with, endorsed by, or published by the upstream provider.
Tools
msha_mine_search(query, state?, status?, limit?)— search by operator, controller, or mine name. Returns matching mines with their MSHA Mine ID, status (Active, Abandoned, Intermittent, etc.), mine type (Surface/Underground/Facility), coal vs. metal/non-metal classification, commodity, state, and current operator/controller. Use this to find a company's Mine ID(s) before callingmsha_mine_detail.msha_mine_detail(mine_id, violations_limit?, inspections_limit?)— a known MSHA Mine ID's current status, type, commodity, operator and controller, plus recent inspections, recent violations (with assessed penalties, S&S flag, and abatement/termination dates), and recent quarterly employment and coal production summed across subunits. A Mine ID with no match returnsfound: falsewithdata_as_of— not an error.
Auth
Keyless.
Data sources
- https://arlweb.msha.gov/OpenGovernmentData/OGIMSHA.asp — MSHA's own
Open Government Data portal, listing downloadable pipe-delimited files
refreshed roughly weekly. Four are loaded:
Mines.zip(the master list of every mine ever assigned a Mine ID — status, type, commodity, current operator/controller),Violations.zip(citations/orders with assessed penalties),Inspections.zip(inspection events), andMinesProdQuarterly.zip(quarterly employment and coal production by subunit). US federal data, public domain.ControllerOperatorHistory.zipships at the same URL but is out of scope for this pack's first capability —Mines.zipalready carries each mine's current operator/controller, which covers search and detail.
Why this is a local-copy pack, not a live proxy
MSHA's Mine Data Retrieval System (msha.gov/mdrs) is a MicroStrategy BI
application embedded in an iframe tag (confirmed 2026-10-08: the page's
src is microstrategy.msha.gov/MicroStrategy/asp/Main.aspx) — not a JSON
endpoint a Worker can call per request. The only queryable path is the bulk
pipe-delimited files. This pack reads a Supabase mirror (msha_mines,
msha_violations, msha_inspections, msha_employment_production; schema
in supabase/migrations/237_msha_mines.sql) loaded weekly by
scripts/ingest-msha-mines.mjs
(.github/workflows/msha-mines-refresh.yml). Every successful response
carries data_as_of from the backing table's own loaded_at.
Fetched directly from MSHA, not routed through the gateway. Unlike
registry.faa.gov (Akamai-fronted, blocks on header shape — see
mcps/faa-aircraft-registry's README), arlweb.msha.gov answered a plain
fetch() from a throwaway wrangler dev --remote Worker on the prod
Cloudflare account the same clean HTTP 200 it gives a laptop curl —
verified 2026-10-08 against Mines_Definition_File.txt (byte-identical,
10,285 bytes) and the full 120,770,798-byte Violations.zip. No blocking to
work around, so the ingest script calls MSHA directly from wherever it runs.
Bounded on purpose
Violations.zip unzips to 1.44 GB (~3.1M rows back to 2000); Inspections.zip
to 348 MB (~1.16M rows); MinesProdQuarterly.zip to 262 MB (~2.76M rows).
Loading the full history of any of them is not worth it for a lookup tool
whose job is "is this mine okay lately" — the ingest script keeps only the
most recent 5 calendar years of each (recomputed from the current date every
run, so the window slides forward on its own). msha_mines (the ~92k-row
master list) is loaded in full — it is the smallest file and the one every
other table joins against. Every response that touches the bounded tables
carries a bound field saying so, so a short violations/inspections list
never reads as "this mine has no older history" — it has history, it just
isn't loaded.
The DB load is TRUNCATE + psql \copy per table, all four in one
transaction, using the pooled connection string the ingest script reads from
its environment — a full weekly snapshot, not an incremental upsert. A parse
failure on any of the four files rolls the whole transaction back, so last
week's data stays live rather than a table going half-replaced.
Natural keys are not unique
VIOLATION_NO has 51 duplicate values and EVENT_NO has at least 1, across
MSHA's full un-bounded files (verified 2026-10-08 with sort | uniq -d over
the extracted .txt files) — so msha_violations and msha_inspections
use a surrogate bigserial id, not the natural key, as primary key.
msha_mines.mine_id is a real primary key — MSHA's own definition file
calls it the unique join key across every other table.
Empty-registry guard
If the weekly refresh has never completed a successful run, the backing
tables are empty but a query against them still succeeds — so a naive read
would answer a confident found: false for every mine, indistinguishable
from a genuine miss against good data. Both tools check for at least one
loaded row before answering and throw a loud dataset_unavailable-class
error naming that condition instead (same pattern as
mcps/faa-aircraft-registry, fleet #2790).
Quick Start
Add to your MCP client (Claude Desktop, Cursor, Windsurf, etc.):
{
"mcpServers": {
"msha-mines": {
"url": "https://gateway.pipeworx.io/msha-mines/mcp"
}
}
}
What this endpoint actually serves
tools/list at https://gateway.pipeworx.io/msha-mines/mcp returns the tools in the table
above plus the shared Pipeworx meta-tools — ask_pipeworx,
discover_tools, search_within, remember/recall and the rest of the
gateway-wide set. So the tool count you see is larger than this table: a
single-pack endpoint currently lists roughly 30 shared tools alongside the
pack's own. The connection's initialize response states its exact scope, and
is the authoritative answer for a given day.
This is deliberate, not multiplexing by accident. The meta-tools are what let a
scoped connection answer a question this pack does not cover — via
ask_pipeworx, which routes across the whole catalog — without you adding a
second MCP server. There is currently no way to mount a pack endpoint without
them; if the extra schemas cost you more context than the routing is worth,
connect to the full gateway once rather than to several pack endpoints.
Or connect to the full Pipeworx gateway to get every pack's tools listed directly, instead of just this one's:
{
"mcpServers": {
"pipeworx": {
"url": "https://gateway.pipeworx.io/mcp"
}
}
}
Both URLs reach the same gateway and the same 1745+ data sources. The
only difference is which pack's tools are listed directly; ask_pipeworx
reaches all of them from either one.
No MCP client? Call it over HTTP
curl -X POST https://gateway.pipeworx.io/v1/tools/msha_mine_search \
-H 'Content-Type: application/json' \
-d '{"query":"Peabody"}'
No account needed for the first calls. Inspect any tool: GET https://gateway.pipeworx.io/v1/tools/msha_mine_search. Find one: POST https://gateway.pipeworx.io/v1/tools/search_packs with {"query":"..."}.
Standalone (no gateway account)
This package also runs as a local stdio MCP server — no Pipeworx account, no gateway round-trip:
{
"mcpServers": {
"msha-mines": {
"command": "npx",
"args": ["-y", "@pipeworx/mcp-msha-mines"]
}
}
}
Or run it directly to confirm it starts:
npx -y @pipeworx/mcp-msha-mines
It speaks MCP over stdin/stdout and answers initialize/tools/list/tools/call
for only this pack's tools — none of the shared meta-tools the gateway
connection above adds. Same source, same tools, no ask_pipeworx routing.
Using with ask_pipeworx
Instead of calling tools directly, you can ask questions in plain English — this works on the pack endpoint above as well as on the full gateway:
ask_pipeworx({ question: "your question about Msha Mines data" })
The gateway picks the right tool and fills the arguments automatically.
More
License
MIT
Install Msha Mines in Claude Desktop, Claude Code & Cursor
unyly install msha-minesInstalls into Claude Desktop, Claude Code, Cursor & VS Code — handles npx, uvx and build-from-source repos for you.
First time? Get the CLI: curl -fsSL https://unyly.org/install | sh
Or configure manually
Run in your terminal:
claude mcp add msha-mines -- npx -y github:pipeworx-io/mcp-msha-minesStep-by-step: how to install Msha Mines
FAQ
Is Msha Mines MCP free?
Yes, Msha Mines MCP is free — one-click install via Unyly at no cost.
Does Msha Mines need an API key?
No, Msha Mines runs without API keys or environment variables.
Is Msha Mines hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Msha Mines in Claude Desktop, Claude Code or Cursor?
Open Msha Mines on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Unyly Deploy
Deploy sites and MCP servers to Unyly straight from your AI agent
by UnylyAmap Maps Mcp Server
MCP server for using the AMap Maps API
by duxiaohuiPayMCP
Lightweight payments layer for MCP servers: turn tools into paid endpoints with a two-line decorator. [PyPI](https://pypi.org/project/paymcp/) · [npm](https://w
by blustAITemplate MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectSupabase
Database, auth and storage
by SupabaseEverything
Reference / test server with prompts, resources, and tools.
Git
Tools to read, search, and manipulate Git repositories.
Compare Msha Mines with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
