> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formae.io/llms.txt
> Use this file to discover all available pages before exploring further.

# AI assistants

> Connect formae to Claude Code, Codex, OpenCode, Cursor, or any MCP client, and manage infrastructure through conversation.

formae ships an MCP server and a set of skills that teach AI coding assistants how
to manage infrastructure. Once connected, you can deploy, query, and change cloud
resources through natural conversation.

<Note>
  Release notes for the MCP server live in its
  [CHANGELOG](https://github.com/platform-engineering-labs/formae-mcp/blob/main/CHANGELOG.md)
  in the `formae-mcp` repository, not in these docs.
</Note>

## What you get

* **31 MCP tools** that give your assistant direct access to the formae agent API:
  querying resources, deploying infrastructure, updating your IaC codebase from
  reality, searching the plugin hub, and more.
* **19 skills** that teach your assistant proven workflows, from authoring new
  infrastructure end to end (infer the right plugins, pull version-matched
  examples, design stacks, simulate, apply) to absorbing out-of-band changes back
  into your IaC codebase.

<Note>
  Both pieces matter. The tools are the API access; the skills are the workflows
  that use them safely (simulate before applying, confirm before destroying). A
  client with skills but no MCP server registered will fail on every tool call.
</Note>

## Prerequisites

* Go 1.25+
* A running formae agent (`formae agent start`)

## Install

<Tabs>
  <Tab title="Claude Code">
    Claude Code has first-class support through the plugin marketplace. The MCP
    server is registered for you and the binary is built on first use.

    Register the marketplace:

    ```text theme={"languages":{"custom":["/languages/pkl.json"]}}
    /plugin marketplace add platform-engineering-labs/formae-marketplace
    ```

    Install the plugin:

    ```text theme={"languages":{"custom":["/languages/pkl.json"]}}
    /plugin install formae-mcp@formae-marketplace
    ```

    Run `/reload-plugins` (Claude Code v2.1.116+) to apply without restarting. On
    older versions, restart Claude Code.

    **Verify:** ask Claude to run `/formae-status`. You should get live agent
    status back, not an error.

    <Accordion title="Manual install (without the marketplace)">
      ```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
      git clone https://github.com/platform-engineering-labs/formae-mcp.git \
        ~/.claude/plugins/formae-mcp
      claude --plugin-dir ~/.claude/plugins/formae-mcp
      ```
    </Accordion>
  </Tab>

  <Tab title="Codex">
    Install the MCP server binary:

    ```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
    go install github.com/platform-engineering-labs/formae-mcp/cmd/formae-mcp@latest
    ```

    Register the server with Codex:

    ```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
    codex mcp add formae -- formae-mcp
    ```

    Or add it to `~/.codex/config.toml` directly:

    ```toml theme={"languages":{"custom":["/languages/pkl.json"]}}
    [mcp_servers.formae]
    command = "formae-mcp"
    ```

    Add the skills:

    ```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
    git clone https://github.com/platform-engineering-labs/formae-mcp.git \
      ~/.codex/formae-mcp
    mkdir -p ~/.agents/skills
    ln -s ~/.codex/formae-mcp/skills ~/.agents/skills/formae-mcp
    ```

    Restart Codex.

    **Verify:** ask it to check formae status. A working setup returns live agent
    data. If the skill runs but the tool call fails, the MCP server is not
    registered.
  </Tab>

  <Tab title="OpenCode">
    Install the MCP server binary:

    ```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
    go install github.com/platform-engineering-labs/formae-mcp/cmd/formae-mcp@latest
    ```

    Register the server in `opencode.json`:

    ```json theme={"languages":{"custom":["/languages/pkl.json"]}}
    {
      "$schema": "https://opencode.ai/config.json",
      "mcp": {
        "formae": {
          "type": "local",
          "command": ["formae-mcp"],
          "enabled": true
        }
      }
    }
    ```

    Add the skills:

    ```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
    git clone https://github.com/platform-engineering-labs/formae-mcp.git \
      ~/.config/opencode/formae-mcp
    mkdir -p ~/.config/opencode/skills
    ln -s ~/.config/opencode/formae-mcp/skills ~/.config/opencode/skills/formae-mcp
    ```

    Restart OpenCode.

    **Verify:** ask it to check formae status. A working setup returns live agent
    data.
  </Tab>

  <Tab title="Cursor">
    Install the MCP server binary:

    ```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
    go install github.com/platform-engineering-labs/formae-mcp/cmd/formae-mcp@latest
    ```

    Register the server in `.cursor/mcp.json` (project) or `~/.cursor/mcp.json`
    (global):

    ```json theme={"languages":{"custom":["/languages/pkl.json"]}}
    {
      "mcpServers": {
        "formae": {
          "command": "formae-mcp"
        }
      }
    }
    ```

    Reload Cursor, then check that the formae server shows as connected in
    **Settings → MCP**.

    <Note>
      Cursor consumes the MCP tools. The formae skills are not loaded, so you drive
      the workflows yourself rather than invoking `/formae-*` skills.
    </Note>
  </Tab>

  <Tab title="Other MCP clients">
    Any MCP client can use the formae tools. Install the binary:

    ```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
    go install github.com/platform-engineering-labs/formae-mcp/cmd/formae-mcp@latest
    ```

    Then register it using your client's standard MCP configuration. Most use this
    shape:

    ```json theme={"languages":{"custom":["/languages/pkl.json"]}}
    {
      "mcpServers": {
        "formae": {
          "command": "formae-mcp"
        }
      }
    }
    ```

    The server talks to the formae agent at `http://localhost:49684` by default.
    See [Configuration](#configuration) to point it elsewhere.
  </Tab>
</Tabs>

## Configuration

By default the MCP server connects to the formae agent at `http://localhost:49684`.
To point it somewhere else, or to work with more than one environment, use
**profiles** (requires formae >= 0.87.0).

The server reads the agent endpoint from your **active** profile, or from the
profile named by a tool's `profile` argument. Profiles live at
`~/.config/formae/profiles/<name>.pkl` and are managed with `formae profile`:

```kotlin theme={"languages":{"custom":["/languages/pkl.json"]}}
amends "formae:/Config.pkl"

cli {
  api {
    url = "http://my-agent-host"
    port = 8080
  }
}
```

### Targeting a specific environment

If you manage several formae environments as named profiles, every tool that talks
to an agent accepts an optional `profile` argument. That targets one environment
for a single call without changing which profile is active.

Your assistant prefers this per-command targeting over switching the active
profile, because the active profile is shared with your `formae` command line and
any other assistant sessions. Ask it to "check drift in staging" or "apply to
prod" and it targets that environment per command. Switching your default happens
only when you explicitly ask.

## Example workflows

<AccordionGroup>
  <Accordion title="Author new infrastructure from scratch">
    > "I want to deploy a vLLM server on my Kubernetes cluster with formae"

    Starting from just a description, the assistant works out whether to create a
    new project or build in one you already have, adds the plugins you need, pulls
    real examples for them, helps you group resources into stacks, and walks you
    through simulating before applying. You do not need to know the forma file
    layout up front.
  </Accordion>

  <Accordion title="Deploy infrastructure">
    > "Apply my VPC forma file at `infra/vpc.pkl`"

    The assistant simulates the deployment first, shows you what will be created,
    asks for confirmation, then applies.
  </Accordion>

  <Accordion title="Check for drift in your IaC codebase">
    > "Has anything changed in my production stack since the last reconcile?"

    The assistant queries the agent, cross-references your IaC code, and presents
    only the true delta: changes not yet reflected in your codebase.
  </Accordion>

  <Accordion title="Absorb out-of-band changes">
    > "Absorb out-of-band changes into my IaC code"

    The assistant extracts current state, edits your Pkl files to match, and
    verifies with a simulation that the code is back in sync.
  </Accordion>

  <Accordion title="Build a new plugin">
    > "Build a Cloudflare plugin for formae"

    The assistant researches the Cloudflare API, suggests resource types organized
    in implementation waves, scaffolds the plugin, and works through each CRUD
    operation with tests, following the [plugin SDK tutorial](/plugin-development).
  </Accordion>
</AccordionGroup>

## Available skills

Skills are workflows your assistant follows when you ask for an infrastructure
task. They enforce safe practices like simulating before applying and confirming
before destructive operations.

| Skill                         | Description                                                                                                         |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `/formae-author`              | Front door for authoring new infrastructure: triages intent, infers plugins, dispatches to the focused skills below |
| `/formae-project-init`        | Scaffold a new forma project with the right layout and config                                                       |
| `/formae-deps`                | Add or remove plugin schema dependencies in a project                                                               |
| `/formae-stack-design`        | Design how resources are grouped into stacks                                                                        |
| `/formae-apply`               | Deploy infrastructure (simulate, confirm, apply)                                                                    |
| `/formae-patch`               | Targeted change without a full reconcile                                                                            |
| `/formae-rename`              | Rename a resource's label via `alias` without recreating the cloud object                                           |
| `/formae-destroy`             | Tear down resources, stacks, or environments                                                                        |
| `/formae-fix-code-drift`      | Detect and absorb out-of-band changes into your IaC codebase                                                        |
| `/formae-policy`              | Set, remove, or inspect TTL and auto-reconcile policies on a stack                                                  |
| `/formae-discover`            | Find unmanaged resources in cloud accounts                                                                          |
| `/formae-import`              | Bring unmanaged resources under formae management                                                                   |
| `/formae-status`              | Check running commands, deployment progress, and failures                                                           |
| `/formae-stacks`              | View infrastructure stacks and resource counts                                                                      |
| `/formae-resources`           | Query resources by type, stack, label, or management status                                                         |
| `/formae-targets`             | List cloud targets and configured regions                                                                           |
| `/formae-plugin-new`          | Scaffold a new resource plugin from scratch                                                                         |
| `/formae-plugin-add-resource` | Add a resource type to an existing plugin                                                                           |
| `/formae-config`              | Manage formae config profiles (requires formae >= 0.87.0)                                                           |

## Available MCP tools

### Read-only

| Tool                                | Description                                               |
| ----------------------------------- | --------------------------------------------------------- |
| `list_resources`                    | Query resources with optional filters                     |
| `list_stacks`                       | Retrieve all stacks                                       |
| `list_targets`                      | Query configured cloud targets                            |
| `get_command_status`                | Get status of a specific command                          |
| `list_commands`                     | List commands with optional filters                       |
| `get_agent_stats`                   | Retrieve agent statistics                                 |
| `check_health`                      | Health check for the agent                                |
| `list_changes_since_last_reconcile` | List changes since last reconcile                         |
| `extract_resources`                 | Extract resources as Pkl code                             |
| `list_policies`                     | List reusable policies and the stacks they're attached to |
| `search_hub_plugins`                | Search the live plugin hub by keyword or resource type    |
| `get_hub_plugin`                    | Get details for a specific hub plugin                     |
| `list_plugin_examples`              | List version-matched examples for a hub plugin            |
| `get_plugin_example`                | Fetch a specific example from a hub plugin                |

### Mutation

| Tool                    | Description                                                         |
| ----------------------- | ------------------------------------------------------------------- |
| `apply_forma`           | Deploy or update infrastructure                                     |
| `destroy_forma`         | Remove infrastructure by file or query                              |
| `cancel_commands`       | Cancel running commands                                             |
| `force_sync`            | Trigger immediate resource synchronization                          |
| `force_discover`        | Trigger immediate resource discovery                                |
| `force_check_ttl`       | Trigger an immediate TTL expiry sweep across stacks                 |
| `force_reconcile_stack` | Force a one-shot reconcile on a stack with an auto-reconcile policy |
| `create_inline_policy`  | Plan a TTL or auto-reconcile policy edit on a stack                 |

### Profiles

Requires formae >= 0.87.0. Manage named formae environments (endpoint + targets)
from your assistant.

| Tool              | Description                                                                       |
| ----------------- | --------------------------------------------------------------------------------- |
| `list_profiles`   | List configuration profiles and which one is active                               |
| `current_profile` | Show the active profile                                                           |
| `use_profile`     | Switch the active profile (global; only on explicit "change my default" requests) |
| `save_profile`    | Snapshot the active profile under a new name                                      |
| `create_profile`  | Create a new profile from the starter template                                    |
| `delete_profile`  | Delete a profile (cannot be the active one)                                       |
| `diff_profiles`   | Compare two profiles, or one against the active                                   |
| `read_profile`    | Return a profile's Pkl contents                                                   |
| `write_profile`   | Replace a profile's Pkl (overwrite-only; refuses the active profile)              |
