Skip to main content

README.md

# Marea

`Marea` is an **extensible CLI for the lifecycle of Elixir applications**building, packaging, running, deploying and operating them. It is plugin-based
end-to-end: every command, every config field, every workflow comes from a
[`Malla`](https://github.com/netkubes/malla) plugin, so the same binary covers
local development, container builds, Helm + Kubernetes deploys, AWS plumbing,
or whatever you wire in. The set bundled today (see
[What's in the box](#whats-in-the-box) below) covers the workflows most Elixir
projects need; adding a plugin of your own — a different registry, a custom
deploy target, an extra build step — is typically a few-dozen-line module, not
a fork.

Marea is also, by philosophy, a thin and transparent wrapper around the tools it drives. Every shell call is printed before it runs, making its actions completely visible. There is no hidden orchestrator, no cluster-side controller, no daemon, and no lock-in.

> **In production today.** Marea currently powers the day-to-day deploy and operational
> workflow of a complex telemedicine project, with dozens of releases shipping across
> several Kubernetes environments and nearly daily deployments. The patterns documented
> here are the ones running on real clusters every day.

## LLM-ready, MCP-native

Marea was designed with LLM coding agents (Claude Code, Cursor, …) in
mind, and it works very well with them **even without** MCP. Every
command is a short, standard CLI invocation (`marea build docker`,
`marea helm upgrade`, `marea run release`) and every shell call Marea
makes — `mix`, `docker`, `helm`, `kubectl`, `aws` — is printed before
it runs and its output is captured in the session. An agent reading
the transcript sees exactly what happened, learns the workflow from
any guide or `--help` page, and can copy-paste-debug from real tool
error messages just like a human operator. There is no proprietary
DSL to teach the agent and no hidden framework state to infer.

**Turn on MCP and it gets better — and under control.**
`marea mcp serve` exposes every leaf subcommand as a typed
[Model Context Protocol](https://modelcontextprotocol.io) tool, with a
JSON Schema auto-derived from the same plugin metadata that drives the
CLI — so every plugin you load contributes tools for free. Destructive
operations (`helm delete`, `helm rollback`, AWS deletes) are tagged
with `destructiveHint: true`; read-only ones with `readOnlyHint: true`.
The MCP client allowlists exactly the tools the agent may call,
requires confirmation for the dangerous ones, and feeds typed
arguments instead of free-form shell strings. The agent never has to
escape its own sandbox to talk to AWS, Kubernetes or Docker — Marea
runs outside that sandbox and does it on the agent's behalf, one typed
tool call at a time. See the [MCP Plugin](guides/plugins/mcp.md) guide.

## What's in the box

Currently Marea bundles following plugins, convering:

* Configuring, building and deploying complex Elixir application.
* Targets can be local, docker or kubernetes/helm.
* Tools availale for AWS.

| Plugin | Description |
|--------|-------------|
| [base.md](guides/plugins/base.md)     | The glue every other plugin hooks into. Adds global flags and a command to inspect your project's effective configuration. |
| [setup.md](guides/plugins/setup.md)   | Scaffolds a new umbrella project and wires Marea into it, ready to build and deploy. |
| [build.md](guides/plugins/build.md)   | Builds Elixir releases locally — the standard `mix release` flow with the rough edges smoothed out. Plugins like _docker_ and _helm_ expands the build capabilities |
| [run.md](guides/plugins/run.md)       | Runs your system on your laptop, either straight from `mix` or as the same release that ships to production. |
| [mcp.md](guides/plugins/mcp.md)       | Exposes Marea's full command tree as a [Model Context Protocol](https://modelcontextprotocol.io) stdio server, so LLM agents (Claude Code, …) can drive builds, deploys, Helm and AWS operations through structured tool calls instead of shelling out. Auto-derives JSON Schema for every leaf command from the same plugin metadata that defines the CLI. |
| [docker.md](guides/plugins/docker.md) | Packages Elixir releases (or arbitrary Dockerfiles) into Docker images — small, reproducible, ready to push. See also [docker/python](guides/plugins/docker-python.md) to add a Python environment inside the release's Docker image, for projects that mix Elixir with Python tooling.|
| [helm.md](guides/plugins/helm.md)     | Turns your project into a Helm chart, deploys it to Kubernetes, and manages upgrades, history and rollbacks. |
| [k8s.md](guides/plugins/k8s.md)       | Day-to-day operations against running pods: tail logs, open a shell, attach a remote IEx console, restart a deploy. |
| [aws.md](guides/plugins/aws.md)       | Wraps the AWS bits most projects need: ECR registry login, Route53 DNS records, S3 bucket sync. |

## Highlights

- **Out of the box.** Covers everything you need to deploy a modern, complex
  distributed application: configs, secrets, Erlang clustering, k8s templates, etc.
- **Fast time-to-production.** Once set up, most changes-to-production cycles take 1-2 minutes.
  Marea uses a number of tricks to make deployments extremely easy, fast and convenient.
- **Extensible by design.** Custom logic — extra commands, alternative build pipelines,
  additional cloud providers — is added via `Malla` plugins, no need to edit core code.
  Because every callback is a Malla chain, a plugin can also *modify* the built-in
  commands: intercept `build docker` to run a linter first, add a flag to
  `helm upgrade`, inject a field into another plugin's schema. Most customisations are
  a few-dozen-line plugin, not a fork. While Marea is based on `Malla`, your projects
  do not need to use Malla at all.
- **Commands are short, consistent and visible.** `marea build docker`,
  `marea helm upgrade`, `marea run release`. Every shell call is printed before it
  runs, along with the command's output. That is heaven for **LLM agents**.
- **First-class LLM agent integration.** `marea mcp serve` exposes every
  command as a typed [Model Context Protocol](https://modelcontextprotocol.io)
  tool, so Claude Code (or any MCP client) can drive Marea through structured
  tool calls — auto-derived JSON Schema, per-tool allowlisting, destructive
  operations gated with `destructiveHint`. The agent never has to bypass its
  sandbox to talk to AWS, Kubernetes or Docker: Marea does it on its behalf.
  See the [MCP Plugin](guides/plugins/mcp.md) guide.
- **Umbrella-native.** A single `marea.yaml` describes a whole project, whatever shape
  it has: a single BEAM with everything, a few releases grouping related apps, or one
  release per app. The same `marea build` / `marea helm` commands work on all three.
  For develop you launch all-as-one in your local machine, while you send specific releases to production.
- **EEx-driven templates.** Both the Dockerfile that builds your images and the
  Kubernetes manifests that ship them are rendered through `EEx`. At expansion time you
  have full Elixir — pattern matching, comprehensions, file-driven config — and for
  Helm, EEx and Helm's own `{{ .Values… }}` coexist: EEx runs at `marea helm chart`,
  Helm runs at `helm upgrade`.
- **Not just Elixir.** Releases can also be plain Docker images (`type:
  dockerfile_dir`) o full Helm packages for companion services like sidecars, 
  migrations or auth proxies that ride along with your Elixir apps.
- **Operational tooling, not just deploys.** Marea also helps you connect to running
  pods (via `kubectl exec`) for debugging and hot-fixes against a live release.
- **Self-contained binary or Mix tasks.** Ships as a `marea` executable (an `escript`
  wrapped in a shell header), or can be used also as family of `Mix` tasks


## Quick example

```yaml
# marea.d/marea.yaml
plugins:
  - Marea.Plugins.Helm
  - Marea.Plugins.K8s
  - Marea.Plugins.Aws

aws:
  default:
    profile: my-aws-profile
    region: eu-west-1
    account_id: "123456789012"
    ecr:
      image_header: my-org/

deploys:
  staging:
    helm:
      namespace: my-app-staging
      kube_context: staging-cluster
    releases:
      api:
        type: elixir
        helm:
          template: deployment.yaml
        domains:
          - api.staging.example.com
```

```bash
mix marea aws ecr login-docker
mix marea build helm --deploy staging --release api --upgrade
```

A full walkthrough lives in [guides/03-quick-start.md](guides/03-quick-start.md).

## Documentation

The `guides/` folder contains progressively numbered topic guides:

| Guide | Description |
|-------|-------------|
| [01-introduction.md](guides/01-introduction.md) | What Marea is, the plugins it ships, and the design principles behind it. |
| [02-installation.md](guides/02-installation.md) | Building the binary, linking it into projects, scaffolding new umbrellas. |
| [03-quick-start.md](guides/03-quick-start.md) | A complete deploy from empty project to running pod. |
| [04-marea-yaml.md](guides/04-marea-yaml.md) | Full reference for the `marea.yaml` deploy file, including the `marea.d/` directory layout, YAML includes, and secret references. |
| [05-architecture.md](guides/05-architecture.md) | How the plugin system, callback chains, and deferred shell execution actually work. |
| [06-plugin-development.md](guides/06-plugin-development.md) | Write your own plugin: schema fields, CLI subcommands, command dispatch. |
| [07-operations.md](guides/07-operations.md) | Day-2 workflow: remote IEx console, hot-fixes, rollback. |
| [08-commands.md](guides/08-commands.md) | Top-level command tree, global flags, links to per-plugin command lists. |

Per-plugin reference guides live in _guides/plugins_ — see [What's in the box](#whats-in-the-box) above for the current list.

## License

See the repository for current licensing terms.