# Flute CLI MCP

Flute CLI MCP is an MCP (Model Context Protocol) server for the Flute payments platform.
It lets an AI agent drive the `flute` command-line tool through a standard protocol.
The server spawns a `flute` process for each tool call and returns structured JSON.
It reports both successful results and the CLI error envelope back to the agent.

Credentials are never handled directly by this server.
They live in the OS keychain through `flute auth login`, or in environment variables.
The active profile is pinned at startup, so run one instance for each environment.
A production instance refuses write actions unless an explicit environment variable allows them.

## Installing the Flute CLI Prerequisite

Flute CLI MCP wraps the `flute` command-line tool and does not replace it.
Install `flute`, then authenticate once for each profile by running `flute auth login`.

Note the installed location of both binaries during this step.
A later configuration step may require their absolute paths.

## Installing Flute CLI MCP

Download and install the application for your platform.
Flute CLI MCP requires the `flute` CLI to already be installed and authenticated.

**macOS / Linux (cURL)**

Use the following command to install the application for macOS or Linux using cURL.

```bash
curl -LsSf https://github.com/getflute/flute-cli-mcp/releases/latest/download/flute-cli-mcp-installer.sh | sh
```

**macOS / Linux (Homebrew)**

Use the following command to install the application for macOS or Linux using Homebrew.

```bash
brew install getflute/flute-cli-mcp/flute-cli-mcp
```

**Windows**

Use the following command from any location with either a Windows Command Prompt or a Windows PowerShell.
This does not require elevated permissions.

```powershell
irm https://github.com/getflute/flute-cli-mcp/releases/latest/download/flute-cli-mcp-installer.ps1 | iex
```

### Configuring a Host Application

Most host applications read MCP server settings from their own configuration file.
The following example configures Claude Desktop with two separate profiles.

```json
{
  "mcpServers": {
    "flute-sandbox": {
      "command": "flute-cli-mcp",
      "env": { "FLUTE_PROFILE": "sandbox" }
    },
    "flute-prod-readonly": {
      "command": "flute-cli-mcp",
      "env": { "FLUTE_PROFILE": "production" }
    }
  }
}
```

The `flute-prod-readonly` instance serves only reads.
Add `"FLUTE_MCP_ALLOW_PROD_WRITES": "1"` to its environment to allow production writes.

Codex stores its MCP server settings in `~/.codex/config.toml`.
The Codex app, the Codex CLI, and the Codex IDE extension all share this file.

```toml
[mcp_servers.flute-sandbox]
command = "flute-cli-mcp"
env = { FLUTE_PROFILE = "sandbox" }

[mcp_servers.flute-prod-readonly]
command = "flute-cli-mcp"
env = { FLUTE_PROFILE = "production" }
```

## Configuring Flute CLI MCP

Flute CLI MCP is configured entirely through environment variables.
No configuration file is used by this server.

The following are the recognized environment variables.

| Variable | Default | Purpose |
|  --- | --- | --- |
| `FLUTE_PROFILE` | `sandbox` | Specifies the environment. Accepted values are `sandbox` or `production`, aliased as `prod`. This value is pinned at startup. |
| `FLUTE_BIN` | resolved on `PATH` | Overrides the location of the `flute` binary. |
| `FLUTE_MERCHANT_ID` | unset | Pins the ISV merchant identifier used by token tools. A per-call `merchant_id` argument overrides this value. |
| `FLUTE_MCP_TIMEOUT_SECS` | `30` | Sets the timeout, in seconds, for each spawned `flute` process. |
| `FLUTE_MCP_DEBUG` | off | Set to `1` to route `flute` standard error output into this server's own tracing. |
| `FLUTE_MCP_ALLOW_PROD_WRITES` | off | Set to `1` to allow write actions on a production instance. Any other value keeps the write guard in place. |
| `RUST_LOG` | `info` | Sets the tracing filter used by this server. Log output is written only to standard error. |


## Available Tools

Flute CLI MCP exposes forty-seven tools, grouped by command area.
Reads are always allowed, on both the sandbox and production profiles.
On a guarded production instance, every write action is refused before the CLI runs.
A refused write returns a `client` error and never spawns the `flute` process.

List tools use zero-based pagination.
A `page` value of zero, or an omitted `page` value, returns the first page.
The `limit` value maps directly to the page size used by the API.
A nonzero `total` value with an empty result list usually means the page is past the last one.

The following command groups are available.

| Command Group | Available Tools |
|  --- | --- |
| transactions | `get`, `list`, `inspect`, `sale`, `auth`, `capture`, `void`, `refund`, `settle`, `tip_adjust` |
| ach | `debit`, `credit`, `void`, `refund` |
| customers | `get`, `list`, `methods`, `create`, `update`, `delete`, `add_card`, `add_ach`, `remove_method` |
| terminals | `list`, `status` |
| devices | `list`, `get`, `ttp_jwt`, `register`, `ttp_activate` |
| pos | `get`, `list`, `create`, `cancel` |
| settlements | `list`, `get` |
| subscriptions | `get`, `list`, `payments`, `create`, `terminate` |
| tokens | `list`, `create`, `revoke` |
| standalone | `ping`, `version`, `auth_status` |


A small number of `flute` commands are intentionally excluded from this server.
Interactive authentication commands, such as login, logout, and switch, are excluded.
The `update` and `completion` commands are excluded, since both are operator-only actions.
The `pos create --wait` flag is excluded, since a long-polling call does not fit a single tool call.

## Handling Errors

A tool result should be checked using the MCP `isError` flag, never by inspecting its shape.
Success and error results are shaped differently, and this is by design.

A successful result returns the same envelope produced by the `flute` CLI.
This envelope contains an `object` field, a `data` field, and a `meta` field.

An error result returns a flat structure instead.
This structure contains a `kind`, a `message`, and, in most cases, a `status`.
A `correlation_id` is also included when the CLI provides one.

For example, fetching a deleted customer returns an error result with a status of 404.
This is the expected response for a missing resource, not a malformed error.

The following are the possible values of the `kind` field.

| Kind | Meaning |
|  --- | --- |
| `api` | The Flute API returned an error response, along with a status code. |
| `transport` | A network or connection problem prevented the request from completing. |
| `auth` | Credentials are missing, invalid, or not configured on this host. |
| `decode` | The CLI produced output that this server could not parse. |
| `client` | The request was refused before the CLI ran, such as a guarded write. |
| `spawn` | The `flute` process could not be started. |
| `timeout` | The `flute` process did not finish within the configured timeout. |
| `bad_output` | The CLI produced output that was not valid JSON. |


Errors with a `kind` of `transport`, or an `api` status between 500 and 504, are safe to retry.
An `auth` error means credentials must be configured on the host running this server.

## Security

This server passes sensitive values to the `flute` CLI as command-line arguments.
These values can include card numbers, security codes, and bank account numbers.

While a tool call is running, these arguments are visible to other processes on the same host.
Tools such as `ps`, or reading `/proc/<pid>/cmdline` on Linux, can reveal them.
Run this server only on a trusted host, under a dedicated user account.
Avoid passing real card or bank data on a shared or multi-tenant machine.

Flute CLI MCP does not read or log the configured client credentials.
They are inherited directly by the `flute` process that this server spawns.

The `auth_status` tool returns only an authentication flag and a profile name.
The bearer token itself is never returned by this tool.

The `tokens_create` tool returns a one-time client secret from the API.
This secret must be captured and stored securely, since the API will not return it again.

When the CLI produces output that is not valid JSON, the raw output is captured in a `bad_output` error.
This raw output is truncated to four kilobytes, so a large or sensitive body is not echoed back in full.

## License

MIT.