Documentation menu

AI agents

MCP for AI coding agents

Uses the Ahena CLI (beta). Install it with npm install -g @ahena/cli, or prefix commands with npx @ahena/cli. See Installation. The dashboard covers projects, connections, Doctor, the Stack Graph, plans and approvals without it.

ahena mcp runs an MCP server on stdio, so AI coding agents can understand a project's whole external stack through Ahena, and change it only with the developer's approval.

It runs on the developer's machine in the project directory and calls the same Core API as the CLI and dashboard, as the signed-in user: Ahena's RBAC applies, every call is audited, and the activity log labels these calls via mcp.

Agent sessions

ahena mcp doesn't use your CLI login for its requests. From it, the server creates an agent session (a token starting ahena_agent_, labelled MCP: <client name>, valid 12 hours) and uses only that; it makes a new one when the old one expires or stops working. Ahena knows from the session itself that a request came through MCP (no header decides it), and whatever your role, it refuses an agent session:

  • approving or declining changes, or approving a CLI sign-in;
  • revealing secret values;
  • managing members, billing or the organization, or deleting projects;
  • creating CI tokens or further agent sessions.

Everything else (reading, Doctor, planning, asking for approval) works as you. See approvals.

Set up

ahena login
ahena mcp                 # read-only
ahena mcp --allow-write   # also lets the agent generate code and propose provider changes

Once @ahena/cli is published to npm, you can also run it without installing anything globally, through npx (the same server, fetched on first use):

claude mcp add ahena -- npx -y @ahena/cli mcp     # Claude Code
{ "mcpServers": { "ahena": { "command": "npx", "args": ["-y", "@ahena/cli", "mcp"] } } }

With the CLI installed (see installation; command ahena), most MCP clients take a stdio command. For example, a project-level .mcp.json:

{ "mcpServers": { "ahena": { "command": "ahena", "args": ["mcp"] } } }

VS Code (.vscode/mcp.json):

{ "servers": { "ahena": { "type": "stdio", "command": "ahena", "args": ["mcp"] } } }

TOML-configured clients:

[mcp_servers.ahena]
command = "ahena"
args = ["mcp"]

Tools

Tool Class What it does
inspect_project READ Project, environments, connections and health, your role, ahena.config.ts.
inspect_stack READ The Stack Graph: every capability's provider, connection, resources (bucket, domain, webhook endpoints, project ids), health, issues and next actions.
explain_stack READ The Stack Graph as plain, factual language.
list_integrations READ The capability registry and where each provider is connected.
list_recipes READ Recommended stacks (recipes).
inspect_environment READ Connections, secret names only, latest Doctor run.
inspect_provider READ Provider resources (no secrets).
run_doctor READ Doctor checks (recorded as a run). Each non-passing check has an explanation: what, why, where, impact, canAhenaFix, next.
get_required_actions READ Providers to connect, fixes Ahena can apply, code to generate, developer-only steps.
plan_changes READ ahena diff across providers.
validate_environment READ Environment safety (same checks as validate_deployment): test credentials in production, localhost callbacks/CORS, missing providers, drift.
validate_deployment READ Ready to deploy? Doctor failures and drift from ahena.lock.
connect_provider READ Returns the ahena connect command for the developer. Credentials never pass through agents.
generate_adapter SAFE_WRITE Integration layer in src/ahena/ (dry run by default; keeps your edits).
create_migration SAFE_WRITE Adds a SQL file under supabase/migrations. Never applies it.
plan_capability READ What adding a capability means for this app (from its type): provider and why, settings, everything it needs, costs, related packs.
add_capability SAFE_WRITE Declares the capability in ahena.config.ts and creates a stored plan (or says which ahena connect the developer runs first).
apply_plan BILLABLE Applies a stored plan under the approval policy below; reports partial failure exactly.
configure_provider BILLABLE Makes a provider match ahena.config.ts, under the approval policy below.
fix_issue BILLABLE Applies Doctor's fix for one check, under the same policy.

SAFE_WRITE tools change only local files (generated code, new migration files), never a provider. No tool has the SECRET_ACCESS class: secrets are never returned to an agent, and no tool accepts one.

Approval policy

Without --allow-write, WRITE and BILLABLE tools refuse. With it:

Change Development / staging Production
SAFE Applied Applied
CONFIRMATION_REQUIRED Developer approves in the client Developer approves in the dashboard
BILLABLE / DESTRUCTIVE Developer approves in the dashboard Developer approves in the dashboard

Every change that isn't SAFE needs the developer in every environment: a development connection can point at the same DNS zone or provider account as production, so the environment's kind doesn't lower the bar.

In the dashboard (changes that matter: production, billable, destructive): Ahena accepts approval only from the developer's signed-in browser, never from the agent's session or the CLI's token, so no prompt answered on the developer's machine can approve them. The tool stores the changes as a plan, asks for approval and returns, with nothing changed:

{
  "status": "needs_human",
  "approvalUrl": "https://app.ahena.io/approvals/apr_…",
  "planId": "pln_…",
  "proposed": ["~ Configure CORS on leo-production: https://example.com (production) [CONFIRMATION_REQUIRED]"],
  "message": "… Ask the developer to approve it in the Ahena dashboard: https://app.ahena.io/approvals/apr_…, then call apply_plan { \"plan_id\": \"pln_…\" } again."
}

The dashboard shows the developer exactly what Ahena will apply (built from its own re-plan, not from text the agent sent). Once approved (within 60 minutes), apply_plan applies that plan. Declined or expired: calling apply_plan again asks again; nothing runs without it. The client's elicitation isn't used for these, even when it could ask.

In the client (CONFIRMATION_REQUIRED outside production): MCP elicitation asks the person, not the model, with the exact list of changes. If any change in a plan needs approval, the whole plan waits for it (actions can depend on each other). If the client can't ask, nothing is changed and the tool tells the agent to ask the developer to review the changes and run ahena configure <provider> -e <environment> (or ahena apply <planId>) themselves; the agent isn't told to run it, and is never handed --yes. What's approved is exactly what was planned: Ahena applies with the plan's fingerprint and refuses if the provider changed in between.

Agents express intent by editing ahena.config.ts (git-safe and reviewable), then calling plan_changes / configure_provider. They can't send arbitrary provider payloads.

Intent example

Developer: Add payments to this marketplace.

  1. inspect_stack → it's a marketplace on Next.js; Stripe isn't declared.
  2. plan_capability { capability: "payments" } → Stripe Connect (because it's a marketplace), webhook + signing secret, handler route, env vars, the marketplace pack.
  3. add_capability { capability: "payments", environment: "production", domain: "leo.app" } → declared in ahena.config.ts; a stored plan pln_… (or "run ahena connect stripe").
  4. apply_plan { plan_id } → needs_human with the dashboard link (production). The agent gives the developer the link; they approve; apply_plan again → Ahena creates the webhook and stores its secret.
  5. The agent writes the application code against the generated ahena.payments; run_doctor verifies.

Example

Developer: Set up Stripe subscriptions for this application.

  1. inspect_stack → Stripe is connected in development.
  2. The agent adds payments.products and payments.webhook to ahena.config.ts.
  3. plan_changes { environment: "development" } → + Stripe webhook, + product Pro, + price pro_monthly.
  4. configure_provider → the developer approves in the client (creating products and webhooks isn't SAFE); applied in development. The webhook signing secret is stored encrypted in Ahena; the agent sees only its name.
  5. generate_adapter { write: true } → payments adapter, webhook route, env mappings.
  6. run_doctor → verified. In production the same steps stop for the developer's approval in the dashboard instead (needs_human with the link, then apply_plan).