MDK is under active development and is not yet considered stable.
Current release: v0.3.0.
- Overview
- Architecture
- Releases
- Getting Started
- Build and develop
- Documentation
- Support
- Contributing
- License
- Acknowledgments
This repository is the monorepo for the Mining Development Kit MDK, a JavaScript-based SDK that provides a modular and extensible foundation for:
- Monitoring mining infrastructure
- Controlling devices and containers
- Collecting telemetry and operational data
- Building custom mining applications and integrations
MDK ships as 3 packages:
- core — ORK (orchestration kernel), App-node, MDK SDK, IPC client, mock control service
- workers — protocol translators for data sources, e.g., miners, pools, power meters, sensors, containers
- ui-client — headless UI Core and framework adapters
MDK is a Node.js SDK for operating bitcoin mining hardware. Give it device credentials and it polls those devices continuously for telemetry, lets you send commands to them, and exposes everything through a stable kernel that your agent, app, dashboard, or automation can query over IPC. The hardware never talks to the app-layer directly, it all goes through MDK:
Layer 4 — Browser UI (Optional dashboard/app layer)
│ HTTP / WebSocket
▼
Layer 3 — App-node (Your Node.js server)
│ IPC (UNIX socket)
▼
Layer 2 — ORK (Orchestration Kernel)
│ MDK Protocol over Hyperswarm DHT + HRPC
▼
Layer 1 — Workers (Protocol translators)
│ HTTP + vendor auth
▼
Layer 0 — Data sources (Hardware, external APIs, facility platforms)
Physical hardware (e.g., miners, power meters, temperature sensors), facility management platforms (e.g., Antspace, Bitdeer), and pool APIs (e.g., OceanPool, F2Pool). Workers at Layer 1 translate each source into the common MDK protocol.
Workers live in backend/workers/ organized by categories, for example:
| Category | Examples |
|---|---|
miners |
antminer (S19XP, S19XPH, S21, S21PRO), whatsminer (M56S) |
minerpools |
ocean, f2pool |
power-meter |
abb, satec, schneider, electricity |
temperature |
seneca |
containers |
antspace, bitdeer, microbt |
Each worker has:
- A Manager class, e.g.,
AM_S19XP. Knows how to talk the source's native API. You instantiate it viastartWorker(). - A
mdk-contract.json, the engineering source of truth. Declares every telemetry field (name, unit, type) and every command (name, params). - A mock server, a local HTTP server with canned responses for hardware-free development.
Lives in backend/core/ork/. ORK discovers Workers via Hyperswarm DHT and pulls
data from them on a fixed schedule.
| Module | What it does |
|---|---|
discovery |
Joins Hyperswarm DHT, finds workers by topic key |
transport |
Opens HRPC channels to each discovered worker |
modules |
Device registry, telemetry store, health state |
storage |
Persists the registry to disk between restarts |
protocol |
Message envelope format for IPC and HRPC |
ORK is pull-only and passive — it never pushes to your app. You query it over a UNIX socket (ork.sock). It fans the query out to online workers
and aggregates the response.
Lives in backend/core/app-node/. The App-node is where your business logic is defined. It's your Node.js server that
connects to ORK over the UNIX socket
sends typed queries and receives aggregated responses. You decide what happens to your telemetry data.
// list devices + telemetry
ipc(SOCK, ACTIONS.TELEMETRY_PULL, { query: { type: 'metrics' } }, deviceId)
// what can this device do?
ipc(SOCK, ACTIONS.DEVICE_CAPABILITIES, {}, deviceId)Lives in ui/. Optional app layer that composes to give you a fully wired mining dashboard. The browser-facing
read layer on top of whatever your App-node pulls from ORK.
You may use UI Core (@tetherto/mdk-ui-core), the headless framework-agnostic state layer independently, or
leverage the packages provided for React (Vue, Svelte, and Web Components on the roadmap) whose components consume it directly.
The latest development code is available on the main branch. MDK follows Semantic Versioning 2.0.0: 0.y.z versions are initial development (public API not stable until 1.0.0); 1.0.0 and above denote a stable public API.
Releases have notes docs/reference/release-notes/](docs/reference/release-notes/) and the full version history is detailed in the [CHANGELOG.md`.
Pick the path that matches your goal.
One command produces a working Vite + React + MDK app, with the agent-context files (.mdk/context.md, Cursor / Claude rules) seeded so an LLM can
iterate on it from day one:
npx mdk-ui create my-app
cd my-app
npm run dev # http://localhost:5173Then iterate from inside the app:
npx mdk-ui add feature alerts # full blueprint
npx mdk-ui add page Hashrate # single pageFull CLI reference: ui/README.md and the agent-first quickstart.
Install the three runtime packages (@tetherto/mdk-ui-core, @tetherto/mdk-react-adapter, @tetherto/mdk-react-devkit) and wrap your app in <MdkProvider>.
Full snippet in ui/README.md.
The end-to-end demo starts a mock data source + worker + ORK in one process. Browse
examples/backend/ for the full catalogue, including the full-site demo,
the single-process site demo, and the site-monitor UI example.
Start from a worker's mdk-contract.json and the worker docs.
The base worker is the template for new categories.
If you're an LLM being pointed at this repo, read these three first:
ui/AGENTS.md— contract overview and a quick recipeui/docs/AGENT_FIRST.md— manifests, blueprints, registryexamples/backend/README.md— runnable shapes of the backend
The repo is federated: each domain keeps its own package manager, lockfile, and install scripts, and a thin root package.json forwards commands to them. There is no shared root dependency graph, no root workspaces, and no Turbo at the root.
| Domain | Location | Tooling |
|---|---|---|
| UI | ui/ |
npm workspace (apps/* + packages/*) driven by Turbo |
| Core (backend) | backend/core/ |
independent per-process installs via install-packages.sh |
| Workers (backend) | backend/workers/ |
independent per-process installs via install-packages.sh |
Run any task once from the repo root and it fans out to all three domains:
npm run setup # install every domain (UI workspace + backend per-process installs)
npm run build # build all domains (no-op where a domain has no build step)
npm run test # test all domains
npm run lint # lint all domains
npm run typecheck # typecheck all domains (no-op where a domain has no typecheck step)Each task also has per-domain variants when you only need one: :ui, :core, :workers (e.g. npm run test:ui, npm run lint:core). Use npm run ci instead of npm run setup for clean, lockfile-faithful installs in CI, and npm run clean to tear down build artifacts and installed dependencies.
Note:
setup/ciis the one-command installer; there is no rootinstallscript, so a plainnpm installat the root installs nothing (the root has no dependencies of its own).
Browse this repo's documentation or pick your role:
- New here. Start with the product, then the stack:
| Topic | Where |
|---|---|
| What MDK is and why it exists | concepts/about.md |
| How the pieces fit together | concepts/architecture.md |
- Engineer. Build applications on MDK, or integrate a new device / pool / data feed:
| Topic | Where |
|---|---|
| Worker runtime contracts (telemetry, commands, health, errors) | backend/workers/<family>/<provider>/mdk-contract.json + USAGE.md + examples/ |
| Core SDK | backend/core/docs/ |
| Workers (lifecycle, install pattern) | backend/workers/docs/ |
| UI toolkit | ui/docs/ |
- Contributor: Follow the contribution flow
Alternatively, browse docs.mdk.tether.io: published end-user documentation.
Request updates to docs via
docs-neededissue. Update documentation in this repository directly via the contribution flow.
For support, raise a GitHub Issue or chat to the community on Discord.
Contributions are welcome.
- Fork this repository.
- Clone your fork locally.
- Create a new branch.
- Make your changes.
- Submit a Pull Request.
Learn more about contributing.
For security vulnerability reporting, see the Security policy.
MDK is released under Apache License Version 2.0.
Built with contributions from the mining operations team.