MCP server: let AI agents run your flows

Expose your flows to Claude Code, Cursor, and other MCP clients: list, read, run, replay, heal, import, create, and edit, straight from the agent.

6 min read

Because flows are plain text, an AI agent can genuinely work on them: read the YAML, run the flow, see exactly which node failed and what it sent, edit the file, run again. The Bandura MCP server (started with bandura mcp) packages that loop as Model Context Protocol tools for Claude Code, Cursor, and any other MCP client.

It’s a stdio server over the same engine, parser, and importers as the app and CLI: no Electron, no network service, runs on your machine. For what that changes about how an agent works on a suite, and where an agent still shouldn’t be the one deciding pass or fail, read Bandura as an API testing MCP server; this page is the setup.

Connecting a client

The MCP server ships with the bandura CLI (install it first) and starts with bandura mcp. One install gives you both the CI runner and the agent surface. Register it as a stdio server in your client. For Claude Code:

claude mcp add bandura -- bandura mcp

Or in a JSON-style MCP config:

{
  "mcpServers": {
    "bandura": {
      "command": "bandura",
      "args": ["mcp"],
      "env": { "BANDURA_WORKSPACE": "/path/to/your/api-tests" }
    }
  }
}

The workspace root resolves in this order: a root argument on the tool call, the BANDURA_WORKSPACE environment variable, or the server’s working directory.

Run an agent in the Bandura terminal

The client does not have to be in another window. Bandura’s built-in terminal is a real terminal, so a terminal-based agent runs inside the app, in the same folder as the flows you are looking at:

# once, from anywhere
npm install -g @bandura/cli
claude mcp add bandura -- bandura mcp

# then, in Bandura: open the bottom panel with Ctrl+backtick and run
claude

The session starts at your workspace root, so bandura mcp picks that up as its working directory and the flows the agent lists are the flows in your explorer. Nothing else has to be configured, and you can keep the graph on screen while the agent works: when it writes a file, the editor picks the change up from disk and the canvas redraws.

Two things worth knowing before you try it:

  • Save first. A tab with unsaved edits is never overwritten from disk, so an unsaved flow keeps showing your version while the agent edits a different one.
  • The approval prompt is your agent’s, not ours. The MCP server validates and confines writes (see the tools below), but whether you are asked before one lands is the client’s decision. Claude Code asks; check yours before pointing an agent at a repository you care about.

The in-app assistant covers a lot of the same ground without leaving the sidebar, and it has its own approve-or-discard gate on every write: AI chat. Use the terminal agent when you want one agent working across the whole repository, code and flows together.

The tools

ToolWhat it does
list_flowsEnumerate the .aether files under the workspace root: path, name, node count.
read_flowReturn a flow’s raw YAML.
run_flowExecute a flow and return structured results: per-node pass/fail, captured variables, and request/response snapshots sized for a model’s context (fullBody: true for untruncated payloads). Accepts variables overrides. ai-action nodes run when an AI provider is set in the server’s environment (ANTHROPIC_API_KEY, or BANDURA_AI_BASE_URL for any OpenAI-compatible endpoint). A data-driven flow also returns a rows tally with each failing row’s values, and every node result carries the row it ran in. Anything the flow printed with log() comes back as a logs array on the node, including for a node that failed.
detect_driftCompare a flow against an OpenAPI spec and return findings with proposed fixes, the same deterministic check as self-healing.
importConvert curl/OpenAPI/Postman/Insomnia/HAR source text into .aether, written to a directory or returned inline. A HAR becomes one flow replaying the captured requests in order, with credential header values swapped for variables.
export_openapiThe inverse of import: generate an OpenAPI 3.0 spec from the workspace’s flows, deterministic and offline, like detect_drift. Return it inline or write it into the repo with outPath. Feed the result straight back to detect_drift to close the loop.
create_flowWrite a new .aether file. The content is validated first, so a flow that doesn’t parse is rejected with the error, and an existing path is never overwritten.
edit_flowReplace the full YAML of an existing flow: the same read → edit → re-run loop, for clients without their own file tools. Validated before writing; a missing path is rejected.
list_runsList the runs this server session has executed, newest first, with runId, flow, pass/fail, and duration. In-memory: it lasts the session, and it is separate from the desktop app’s history.
read_runReplay a recorded run by runId: per-node request/response snapshots and the timestamped event log, with bodies as captured at run time. fullBody: true (or a nodeId filter) inspects a payload that run_flow returned truncated, without re-executing a flow that has side effects.
describe_node_typesReturn the .aether schema itself: every node type’s fields, which are required, and the values each enum accepts. It is read from the parser’s own validator at call time, so the agent writes a flow against the syntax this build actually accepts rather than syntax it half-remembers from training data.
lint_flowCheck one flow or the whole workspace for problems without running anything: nodes nothing routes to, loops with no body, TLS verification turned off, credentials written as literals where an ${{ env.* }} reference belongs, and flows with no assertions. Deterministic, the same rules bandura lint runs in CI.
search_flowsFind nodes across every flow by type, a URL or gRPC-target substring, effective auth type, or free text, without reading each file in turn. Useful once a workspace is larger than a model’s context.
get_project_statusWhat this workspace and this build actually contain: how many flows, how many nodes of each type they use, which node and auth types are supported, and any flow that fails to parse.

The last four are there so the agent can check rather than recall. An assistant writing .aether from memory gets the schema subtly wrong; describe_node_types removes the guessing, and it cannot go out of date because it is generated from the validator rather than written down.

What that enables

Ask your agent things like:

  • “Run the checkout flow and tell me why it fails.” The agent runs it, reads the failing node’s actual request and response, and reasons from ground truth instead of guessing.
  • “Fix it.” The flow is a text file, so the agent rewrites it with edit_flow (or its own file tools) and re-runs to verify. create_flow covers “write me a flow for X” the same way; both validate the YAML before anything touches disk.
  • “Check all flows against openapi.yaml and fix the drift.” That’s list_flows + detect_drift per flow, apply fixes, re-run.
  • “Show me the full response that run got.” read_run with fullBody: true replays the payload as it was captured, so a flow with side effects (a POST, a charge, a delete) never has to be re-executed just to see what came back.

The results the agent sees are the same results you see in the editor’s Result tabs: one engine, one file format, three ways in (app, CLI, agent).

For the case for the arrangement, rather than the setup, see an MCP server for your API tests. To keep the agent’s model on your own hardware, point the provider at a local model.

Last updated

Looking for something else? All 37 articles are on one page in the Help Center.