Meta-framework for service ecosystems
Stand up and operate entire service ecosystems. Consistently, locally.
An AI-native meta-framework with agents as first-class developers. Every repo has
its own layout, its own env-var loading order, its own half-documented way to
start the stack. Humans burn onboarding time relearning it, agents burn tokens
re-exploring it. mx makes the shape of a project the one thing
nobody has to relearn.
curl -fsSL https://mechcrate.dev/install.sh | sh # or with Homebrew: brew install unyform-ai/tap/mechcrate
Downloads the release for your platform, verifies its checksum, and installs the
mx binary to ~/.local/bin. No sudo. Then
mx doctor tells you what else your machine needs.
Runs on macOS 11 or later (Apple silicon and Intel), Linux x86_64 and aarch64, and Windows through WSL 2. Platform matrix
The subset problem
You can’t run all twelve services locally
Real ecosystems have ten or more services, and most of them are irrelevant to the feature you are building today. Running the lot on a laptop is not feasible, and pretending otherwise is how dev environments rot.
mx makes the subset the unit of work. Every service gets its own atomic compose file: a baseline that describes its production shape, plus a dev override that adds hot-reload mounts, debug ports and relaxed health checks. Nothing forces all-or-nothing, and nothing about “what runs where” lives in tribal knowledge.
make dev # the whole stack make dev s=api # just the one you're on - docker/compose/<service>.yml: the baseline, the same shape you deploy.
- <service>.dev.yml: the override, merged only by
make dev.
The context-switch problem
Switching organizations shouldn’t mean tearing down your stack
Work across two organizations (or just two products) and the usual routine is misery: spin down ecosystem A’s containers so ecosystem B’s ports don’t collide, lose your state, repeat tomorrow.
The mx router is a single global Traefik instance that every
mx project registers with. Application services publish no HTTP host ports;
Traefik routes to them by hostname, so two ecosystems’ web apps never
collide. Multiple ecosystems coexist on one machine, and switching context is
cd, not teardown.
http://api.localhost http://admin.localhost http://docs.localhost - One router per machine. Installed once with
mx router install && mx router up, it serves every project you ever scaffold. - Backing services still get ports. Dev overrides expose Postgres and Redis on their conventional ports for local GUI tools (per compose file, easy to change).
The scaffolding problem
Scaffolding should carry wisdom, not boilerplate
Starting a new service usually means cobbling: copy a Dockerfile from the last project, hand-port the test harness, rediscover the admin-panel setup, re-solve deployment. Piecemeal, every time.
mx recipes are production-shaped service definitions that
carry the accumulated decisions of the stacks they came from: dependency
choices, testing setup, admin tooling, dev overrides, deploy configuration,
all applied in one motion. And projects don’t fork away from the framework:
mx upgrade is how an existing project adopts newer scaffolding as
the templates improve.
mx new my-platform mx add api --recipe rust-api \ --domain api.localhost make dev Being straight with you: mx upgrade used to fail
before it did anything, tracked as mech-crate-z5i with a red test
asserting the behaviour we owed you. That test is green and in the gate now, and
the upgrade page shows a real run along
with the one migration it asks of you. What is still open gets named the same
way: thirteen defects sit in the
known-broken lane with a red test each, not in a
backlog nobody reads.
The everything-else problem
The cobbled-together everything else
Environment loading, the local CLI, where files live, how you check the machine is healthy. These are the concerns every team solves badly, differently, once per project. mx standardises them once, in a folder contract that is deliberately non-negotiable.
That contract is the point. It is what lets one make dev work
everywhere, one router serve everything, and one MCP server understand any
project without being told about it first.
- Environment config. One documented loading order:
.env.shared→.env.secrets(gitignored) →.env.<service>, all underdocker/.config/. - A consistent CLI.
make dev / up / down / logs / sh / ps / build / doctorbehave identically in every project, andmxmirrors the same verbs globally. - Filesystem discipline. 1:1 host-to-container mounts under
docker/system/. What you see is what the container sees. - Documentation and health.
mx docscompiles project Markdown to PDF and HTML;mx doctorandmake doctorcheck dependencies before they ruin your afternoon.
The AI layer
AI that helps without leaking or wasting
Most “AI-enabled” development bolts a chatbot onto chaos. mx inverts it: make the terrain legible first, then arm the agent. Identical layouts and stable conventions mean an agent lands in familiar ground every session instead of re-deriving project shape before its first useful edit.
-
One MCP server, forty-plus tools
mx-mcp-servergroups its tools into four families: scaffold, operate, understand, retrieve. An agent can create a service, start the right subset of the stack, tail its logs and consult the corpus before writing a line. How the AI layer works → -
A techniques corpus you host yourself
RAG over curated engineering docs on pgvector, stored in a Postgres you control: a Neon project or a local container, never a third-party AI vendor’s store. Embeddings go through any OpenAI-compatible
/embeddingsendpoint: OpenAI by default, or pointembedding_base_urlat Ollama or LM Studio to keep ingestion and queries local too. Browse the published corpus → -
A corpus that grows on schedule
A research skill runs weekly: it picks a topic, corroborates claims against primary sources, and opens a pull request carrying provenance frontmatter and a full source list. A human merges. The corpus grows on purpose, with an audit trail. Research log and backlog →
Quality
Proven gates, and a public list of what is broken
The three blocking gates (lint, test, coverage) are proven, not assumed. Each was demonstrated failing on a deliberately broken branch before the baseline landed, so we know they catch what they claim to catch. A release tag cannot ship unless its commit passes all three.
- Blocking gate
make testUnit and integration suite plus doc-tests, on every PR and push to main.
- Blocking gate
make lintClippy with warnings denied. One useless format string fails the build.
- Blocking gate
make coverageLine coverage against a ratcheting floor. Drops fail CI; raises are opt-in.
- Report
make test-known-brokenA TDD lane where every open, testable defect has a red test asserting its fixed behaviour.
- Report
make test-e2eScaffold → router → live URL against real Docker, on a dispatched workflow.
- Report
make test-mutantsScheduled mutation testing over the core library, as a weekly report.
The known-broken lane
We would rather publicly index our own defects than pretend there aren’t
any. Thirteen are open and named, the corpus’s measurably weak lexical
retrieval arm (mech-crate-4jw) among them, each with a red test
that asserts the behaviour we owe you.
Un-ignoring that test is the fix’s definition of done, and
mx upgrade (mech-crate-z5i) is the first row to leave
the lane that way. The lane is a report, not a gate, which is exactly why it can
afford to be honest.
See the lane and the research log →
A developer who knows one mx project knows all of them
Install the CLI, bring up the router once, and scaffold your first project. The second one will look exactly like it. That is the whole idea.
curl -fsSL https://mechcrate.dev/install.sh | sh # or: brew install unyform-ai/tap/mechcrate mx router install && mx router up mx new my-app # and you're building