Makefile MCP
README.md
# Makefile MCP
[](https://pypi.org/project/makefile-mcp/)
[](https://pypi.org/project/makefile-mcp/)
[](https://github.com/ai-ronin-systems/makefile-mcp/actions/workflows/ci.yml)
[](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/LICENSE)
<!-- mcp-name: io.github.ai-ronin-systems/makefile-mcp -->
**Expose trusted GNU Make targets to AI agents — without exposing a generic shell or replacing Make with another workflow system.**
Makefile MCP turns an existing Makefile into typed MCP tools. It is **zero-config and run-safe by default**, and **deny-by-default when governed**.
```text
Makefile → Makefile MCP → Codex / Claude / LangChain / Cursor / VS Code / MCP client
```
## Threat model
Design for a compromised agent: any text it reads can carry a prompt injection. Makefile MCP keeps the worst case short. A hijacked agent can run only the targets you listed, with values you typed, and a human approves the risky ones. **Read the [threat model](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/threat-model.md)** for the threats, controls, tests that prove them, and limits.
| Protected | Not protected |
| --- | --- |
| Agents cannot run arbitrary shell commands, only exposed Make targets. | A malicious or buggy Makefile: recipes are trusted code, not sandboxed. |
| Without config, agents can only run `test`, `lint`, `check`, and `fmt`. | A target the operator chose to expose doing something destructive. |
| Governed mode runs only allow-listed `(context, target)` pairs with typed, validated inputs. | Host or container privileges granted outside Makefile MCP. |
| `dangerous` tasks need explicit human approval through the MCP client; no approval, no run. | An MCP client that auto-approves elicitation without a human. |
| Every governed run attempt, refused, approved, or cancelled, can be written to an audit log, with secret inputs masked. | Secrets a recipe prints in ways that differ from the input value. |
| The approval prompt shows the exact arguments; agent-supplied text cannot reshape it. | An agent that can edit unpinned Make code or scripts: editing a recipe is a shell. |
| With `pin`, any edit to the Makefile, its includes, or listed scripts stops the server until a human restarts it. | Prompt injection in output the agent does read; `agent_output: tail` or `none` narrows it. |
| Audit records are hash-chained; `doctor` reports edits. A CI test replays a hijacked agent. | A same-user process rewriting the whole log and its chain. |
Details: [threat model](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/threat-model.md), [SECURITY.md](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/SECURITY.md), and [security model](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/security.md).
## Quick start
```bash
pipx install makefile-mcp # or: uv tool install makefile-mcp
makefile-mcp serve
```
Given:
```make
test: ## Run tests
pytest -q
lint: ## Run lint
ruff check .
```
Makefile MCP exposes `make_test` and `make_lint` as MCP tools. Other targets are listed but not runnable until you govern them.
```bash
makefile-mcp list
makefile-mcp doctor
makefile-mcp run test
makefile-mcp run test --preview # GNU Make --dry-run; not a sandbox
```
One-shot use: `uvx makefile-mcp serve`.
## Why Makefile MCP
Makefile MCP is intentionally narrow: the repository's Makefile remains the executable source of truth, while Makefile MCP supplies a governed agent-facing capability boundary.
| Principle | What it means |
| --- | --- |
| **Make stays authoritative** | No duplicate workflow DSL, plugin command language, scheduler, database, or second execution engine. |
| **No generic shell capability** | Agents invoke discovered or explicitly governed Make targets, not arbitrary host commands. |
| **Trusted Makefile, untrusted invocation** | Repository automation is trusted; caller-selected tasks and declared values are authorized, validated, and bounded. GNU Make's own variable/function semantics are treated as an interpreter boundary. |
| **One execution path** | CLI, direct MCP tools, generic MCP tools, preview, contexts, and capabilities share the same catalog, authorization, validation, and executor. |
| **Conservative discovery** | Makefile MCP statically exposes only Make syntax it can classify confidently; ambiguous constructs are omitted rather than guessed. |
| **Bounded Unix runtime** | Foreground execution has bounded input/output, timeout/cancellation cleanup, stdin isolation, process-group handling, and physical-context locking. |
See [Design rationale](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/design_rationale.md) for the full capability/property map and the alternatives deliberately left out.
## Architecture
```text
Makefile
|
conservative catalog
|
+-------------+-------------+
| |
auto governed
no config .makefile-mcp.yaml
| |
+-------------+-------------+
|
Application
+---------+---------+
| |
MCP direct MCP generic
+---------+---------+
|
Executor
|
exact `make -f`
```
One catalog. One execution path. Thin CLI and MCP adapters.
See [Architecture](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/architecture.md).
## Governed mode
Without `.makefile-mcp.yaml`, Makefile MCP runs in **auto mode**: every conservatively discovered root target is listed, but only `test`, `lint`, `check`, and `fmt` can run, with no caller-controlled Make variables. `--legacy-auto-run` restores the old run-everything behavior (deprecated).
Add `.makefile-mcp.yaml` to switch to explicit governance:
```yaml
schema_version: 1
contexts:
backend:
directory: backend
tasks:
test:
contexts: [root, backend]
risk: safe
deploy:
risk: dangerous
variables:
ENV:
type: enum
values: [staging, production]
required: true
capabilities:
verify: test
audit:
path: .makefile-mcp/audit.jsonl
pin:
paths: [scripts] # freeze Make code and scripts the agent must not change
```
Only enabled `(context, target)` pairs are callable. `dangerous` tasks additionally need human approval (`defaults.require_approval`), and `audit` writes one JSON line per call. See [Governed mode](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/governed_mode.md), [Configuration](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/configuration.md), and [Contexts and capabilities](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/contexts_and_capabilities.md).
## MCP presentations
Makefile MCP supports three MCP presentations over the same callable catalog. Choose the presentation that best fits your requirements.
```bash
makefile-mcp serve --tools direct # default: one typed tool per callable target
makefile-mcp serve --tools generic # list_tasks / describe_task / run_task
makefile-mcp serve --tools both # both views, same execution core
```
See [MCP presentations](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/mcp_presentations.md) and [client setup](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/clients.md).
## Security
Makefile MCP assumes the repository, Makefiles, included Make code, wrapper scripts, and provisioned tools are **trusted operator-controlled code**. The security boundary is the invocation: an MCP/CLI caller chooses an exposed task/context and, in governed mode, supplies declared values. Makefile MCP authorizes and validates that request; it does **not** sandbox hostile Makefiles.
Runtime bounds, cancellation/process-group cleanup, stdin isolation, and locking are primarily execution-correctness properties. They limit failure modes around trusted automation rather than turning Make into a sandbox. The built-in MCP server is **stdio-only**: no HTTP listener, remote-auth layer, TLS, tenancy, or network-service lifecycle is hidden inside the product.
See **[SECURITY.md](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/SECURITY.md)** for the security policy, reporting process, trust boundary, and limitations. Detailed implementation notes are in [docs/security.md](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/security.md).
## Intentional scope limits
- GNU Make on **Linux/macOS**; Windows is not currently supported.
- **Trusted repository** assumption: Makefiles, includes, scripts, and provisioned tools are operator-controlled code.
- Static discovery is deliberately conservative, not a complete GNU Make parser.
- Preview is GNU Make dry-run, **not sandboxing**; Make evaluation can still have side effects.
- Direct tool inventory is registered at startup; generic catalog calls can observe supported Makefile changes.
- `.makefile-mcp.yaml` is startup policy; changes require restart and fail closed until then.
- Foreground/bounded tasks only; deliberately detached daemons are outside Makefile MCP's process-group containment model.
- No HTTP server, auth stack, scheduler, job queue, workflow persistence, plugin execution framework, or arbitrary shell tool.
- Reload behavior:
- `.makefile-mcp.yaml` is startup policy. Restart Makefile MCP after adding, removing, or editing it.
- Makefile discovery refreshes when the conventional `Makefile` or tracked literal includes change.
- Generic calls see the refreshed catalog immediately.
- Direct tool inventory is a startup snapshot: adding or removing direct tools requires a restart. Existing direct tools still re-check the live catalog when invoked.
## Requirements
Python 3.11+ · GNU Make · Linux or macOS
## Documentation
1. [**Threat model**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/threat-model.md) — why agents should not get a shell, threats and controls, the policy and audit log, guarantees and limits. Start here.
2. [**Architecture**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/architecture.md) — runtime flow, responsibilities, lifecycle, invariants, and dependency rules.
3. [**Design rationale**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/design_rationale.md) — key tradeoffs, full product-property map, and deliberately rejected alternatives.
4. [**CLI reference**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/cli.md) — commands, options, result model, root detection, and exit codes.
5. [**Configuration**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/configuration.md) — authoritative `.makefile-mcp.yaml` fields, defaults, approval, audit log, and precedence.
6. [**Static Make discovery**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/discovery.md) — supported syntax, fail-closed behavior, includes, limitations, and cache semantics.
7. [**Governed mode**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/governed_mode.md) — explicit exposure, typed inputs, risk metadata, human approval, and operating model.
8. [**MCP presentations**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/mcp_presentations.md) — `direct`, `generic`, `both`, schemas, result/error semantics, naming, and lifecycle.
9. [**Contexts and capabilities**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/contexts_and_capabilities.md) — monorepo scoping, `(context, target)` authorization, and semantic mappings.
10. [**MCP client setup**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/clients.md) — Codex, Claude Code, LangChain/LangGraph, Cursor, VS Code, and `uvx` examples.
11. [**Security**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/security.md) — trust boundary, Make input safety, arbitrary strings, discovery, environment/path controls, and execution bounds.
12. [**Development**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/development.md) — contributor workflows, code ownership, regression expectations, and Definition of Done.
13. [**Deployment**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/deployment.md) — Docker/stdio deployment, production checklist, and provisioning custom tools plus Makefiles.
14. [**Releasing**](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/docs/releasing.md) — version/tag contract, clean-package smoke test, PyPI Trusted Publishing, provenance, GitHub Releases, and MCP Registry metadata.
Security reporting: [SECURITY.md](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/SECURITY.md).
Contributing: [CONTRIBUTING.md](https://github.com/ai-ronin-systems/makefile-mcp/blob/main/CONTRIBUTING.md).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo recent community issues