Marea can be used in two ways: as a number of Mix tasks or as a self-contained executable
As a Mix task
As a mix task, you only new to add it to your project:
# mix.exs
defp deps do
[
{:marea, "~> 1.0", runtime: false, only: :dev}
]
endmix deps.get
mix compile
You can now use it as a mix task
mix marea help
The trade-off is the missing TTY. Commands that hand the parent shell
to an interactive program — mix marea k8s console — needs a full TTY, but the child
process sees a pipe instead of a real terminal. Line editing,
arrow-key history, password prompts and other TTY-dependent features
will misbehave. For interactive sessions, use method bellow.
As an script
You can also build it once from source and symlink it into each project that needs it. This allows all real-time capabilities of Marea, and allows for the MCP server to work.
git clone https://github.com/kalta/marea
cd marea
mix deps.get
mix marea.build # produces ./marea (a shell-wrapped escript)
This is what happens:
- Runs
mix escript.buildto produce a regular escript namedmarea. - Prepends a small shell header to the file. The header makes the
script executable as a normal binary and, after the escript exits,
runs
.marea/next_cmdif one was written. This is how interactive commands likemarea run localtake over the parent shell. - Copies the wrapped binary to
priv/mareaand replaces./mareawith a symlink to it.priv/mareais what gets shipped via the:mareadependency.
The binary is fully self-contained. To run it:
Then symlink marea escript into the root of your project
ln -s /path/to/marea .
./marea help
First run
The first time you invoke marea in a project that has no
marea.yaml, Marea looks for one at marea.yaml, config/marea.yaml
and marea.d/marea.yaml. If none exist, any non-setup command stops
and points you at the bootstrap command:
> marea
No marea.yaml found (tried: marea.yaml, config/marea.yaml, marea.d/marea.yaml).
Run `marea setup init-marea` to create one.
Run it to scaffold a marea.d/ directory with configs/, secrets/
and a stub marea.d/marea.yaml:
> marea setup init-marea
Created marea.d/marea.yaml and subdirs (configs/, secrets/)
Then edit marea.d/marea.yaml to start describing your deploys. The
setup commands (init, init-umbrella, init-release) are the only
ones that run without an existing config; the scaffolding commands also
remind you to run marea setup init-marea when they finish.
Bootstrapping a release in an existing app
Marea expects a standard umbrella Elixir application configured with
releases. If your project is already release-configured (a working
rel/env.sh.eex and a releases/0 in mix.exs), this step is not
needed — skip ahead to writing marea.yaml.
If you don't have a release set up yet, marea setup init-release
scaffolds one. For greenfield
projects, marea setup init-umbrella creates the whole umbrella with
Marea pre-wired. Both commands are documented in detail in the
Setup Plugin guide.
Verifying the install
./marea --help
./marea build show-docker-versions # introspects the alpine image used for builds
If ./marea --help prints the top-level command tree (setup, build,
run, mcp, plus anything contributed by plugins listed in your
marea.yaml), you're ready to move on to the
quick-start guide.
Registering Marea as an MCP server
Marea can also run as a Model Context Protocol server, so AI assistants (Claude Code and any other MCP client) can drive builds, deploys, Helm and AWS operations through structured tool calls. Every leaf subcommand becomes a tool; the JSON Schema is auto-derived from the same plugin metadata that drives the CLI.
The fastest way to register Marea with Claude Code is:
claude mcp add marea -- /absolute/path/to/marea mcp serve
Use the built binary, not
mix marea, formcp serve. The MCP protocol is newline-delimited JSON-RPC on stdout; any other byte on stdout breaks the client.mix marea mcp servedispatches to the same server, but Mix is free to print compile/boot messages (Compiling…,Generated marea app, deps output) to stdout before the loop starts, which corrupts the stream. The escript has no compile phase and a clean stdio. The one-shot debug commands (mix marea mcp tools,mix marea mcp call …) are fine over Mix — they print to your own terminal, not to an MCP client.
Run that from a project directory that already has a working
marea.yaml — the server reads it at startup to discover which
plugins (and therefore which tools) to expose. Then allowlist the
read-only tools in ~/.claude/settings.json (or per-project
.claude/settings.json):
{
"permissions": {
"allow": [
"mcp__marea__helm_list",
"mcp__marea__helm_history",
"mcp__marea__helm_values",
"mcp__marea__aws_ecr_list",
"mcp__marea__aws_route53_list"
]
}
}Destructive tools (mcp__marea__helm_delete, mcp__marea__helm_rollback,
mcp__marea__aws_*_delete) carry destructiveHint: true in their
descriptors and will prompt for confirmation on every call, so they
don't need an allowlist entry.
For inspection without a real MCP client:
marea mcp tools # JSON descriptors for every tool
marea mcp call --tool helm_list --json '{"deploy":"staging"}' # invoke a tool by hand
See the MCP Plugin guide for the full mapping of Optimus options to JSON Schema, the execution model, and the stdio discipline.