Skip to main content

ansible-flow-mcp

Give agents Ansible. Not the keys.

MCP server that exposes real Ansible modules and playbooks to AI agents — and a SSH hub/spoke fabric so multi-host automation is enrolled, bastion-scoped, and check-first by default.

Hero: agent hub session and enrolled inventory rail

Track What you get
Agent loop search → schema → check → execute on allowlisted collections
Fleet fabric One hub · join tokens · SSH ForceCommand spokes · fixed inventory

OpenFlow dual-track · Marketing site · Campaign storyboard · Hub/spoke ops · Apache-2.0

Not affiliated with Red Hat or the Ansible project beyond using the public Ansible CLI and docs.

New here? Marketing site (story + Schema Lab) · full step-by-step docs/QUICKSTART.md — local MCP · compose lab · bare-metal hub/spoke · editor wiring.

./scripts/site_preview.sh   # http://127.0.0.1:8765/  (gallery + live schemas)

Visual tour

Why it exists Agent loop
Why: god-mode control node vs enrolled bastion Agent ritual: search → schema → check → execute
Hub / spoke fabric Operators
SSH hub/spoke topology and enrollment Operator TUI, hub MCP tools, lab demo

Screenshots live in docs/images/campaign-*.png. Re-shoot from docs/campaign/ with ./capture.sh.


Why this exists

Agents on a god-mode control node invent inventory, reach for shell, and treat every worker as an entrypoint. That is not a security model.

Without a fabric vs ansible-flow-mcp controls

You need this when:

  • You want Cursor / Claude / OpenCode to run Ansible like an operator, not freestyle root across the fleet
  • Multi-host must mean bastion ops you already understand (SSH, inventory, enrollment) — not a mesh hop plane
  • Prompt injection will still ask for bad ops — policy and topology must refuse

Two tracks

1. Agent loop — search → schema → check → execute

Curated module gallery. Slim argSpec before any run. Check mode default. Free-form modules denied. Playbooks path-jailed.

Agent ritual and MCP tools

Tool Purpose
search_modules Gallery search
get_module_schema Slim argSpec for FQCN
run_module Ad-hoc Ansible (check_mode default true)
run_playbook ansible-playbook on a path-jailed .yml
list_collections Collections in gallery

Ritual (modules): search_modules → get_module_schema → run_module(..., check_mode=true) → apply only if appropriate.

Ritual (playbooks): confirm path under allowlisted roots → check → apply.

2. Hub/spoke — nothing is a target until enrolled

Secure multi-host mode: agent attaches to the hub only. Hub reaches spokes over SSH only. Spokes execute localhost and cannot lateral-move via this fabric.

SSH hub/spoke topology and enrollment

Full mesh (withdrawn) Hub/spoke (shipped)
Worker compromise Could MCP-hop fleet-wide No lateral MCP
Inventory Gossip / replicas Hub is source of truth
Agent attach Any node Hub only
Ops model Mesh OS Classic Ansible bastion

Enrollment: hub init → issue-token (TTL, one-time jti) → spoke join (token + SSH identity) → hub inventory. Runtime: ForceCommand MCP session — no shell on the hub→spoke path.

Hub tools: list_nodes / hub_status, issue_token, revoke_node, groups (create_group, set_group_members, …), spoke_call, plus catalog run_* against enrolled hosts or groups only. Client-supplied -i is rejected in hub mode.

Deep ops: docs/HUB.md.


Operators

Day-2 surface matches the agent: enroll, group, hand the hub to OpenCode.

Operator TUI, hub MCP tools, lab demo

ansible-flow-mcp hub init --name ctrl-01
ansible-flow-mcp hub issue-token --name web-03 --ttl 15m
ansible-flow-mcp spoke join --token "$TOKEN" --hub user@hub:22 --public-addr web-03.example.com
ansible-flow-mcp hub session          # MCP stdio for the agent
ansible-flow-mcp tui                  # servers · groups · invite · OpenCode
ansible-flow-mcp hub spoke-call --node web-03 --tool list_collections

Lab one-shot

cd lab && ./scripts/demo.sh
# then: ./scripts/tui.sh  |  ./scripts/opencode-host.sh

See lab/README.md.


Quick start

Full guide (all paths, verify, troubleshooting): docs/QUICKSTART.md

Path Guide section
Local MCP + Cursor/Claude Path A
Compose lab (hub + 3 spokes) Path B
Bare-metal hub/spoke Path C

Single-node / dev (short form)

Requirements: Python ≥ 3.11 · collection ansible.posix (JSON callback) · collections you will run.
pip install pulls ansible-core (provides ansible / ansible-playbook).

cd ansible-flow-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
ansible-galaxy collection install ansible.posix
pytest -q
ansible-flow-mcp

Editor snippets: examples/cursor-mcp.json, examples/claude-desktop.json.
Hub + OpenCode: examples/opencode-hub.jsonc · ansible-flow-mcp hub write-opencode-config.

{
  "mcpServers": {
    "ansible-flow": {
      "command": "/path/to/ansible-flow-mcp/.venv/bin/ansible-flow-mcp"
    }
  }
}

Security (honest)

Control Behavior
Collection allowlist Only configured collections
Module deny list command / shell / raw / script denied by default
Check mode Default true on run_module
Playbook jail Allowlisted roots · size limit · .yml/.yaml only
No shell interpolation argv-only subprocess
Hub inventory Enrolled hosts only · no client -i · host key checking on
Spoke path SSH ForceCommand · localhost exec · no peer fabric

Residual: hub compromise = fleet (same class as any Ansible control node). Harden the bastion — see docs/SECURITY.md and docs/HUB.md.


Catalog & OpenFlow

  • catalog/collections-allowlist.yml — allowlist + deny free-form modules
  • catalog/gallery.json + catalog/schemas/ — searchable gallery
  • Regenerate: python scripts/generate_catalog.py
  • Galaxy factory TUI: scripts/factory/README.md

Dual-tracked with OpenFlow Ansible canvas gallery
(plan · umbrella).

OpenFlow This MCP server
Palette Ansible gallery search_modules
Form | JSON module options get_module_schema + run_module
Playbook resource run_playbook
Control-node SSH / become Inventory + Ansible config · hub→spoke SSH in hub mode

Env (common)

Variable Meaning
ANSIBLE_FLOW_CATALOG_DIR Override catalog path
ANSIBLE_FLOW_COLLECTIONS Comma-separated allowlist override
ANSIBLE_FLOW_INVENTORY Default -i (non-hub / dev)
ANSIBLE_FLOW_TIMEOUT Seconds (default 120 module / 300 playbook)
ANSIBLE_FLOW_PLAYBOOK_ROOTS Extra playbook roots (:-separated)
ANSIBLE_FLOW_HUB_DIR Hub state (default: /var/lib/… if writable, else ~/.local/share/ansible-flow/hub)
ANSIBLE_FLOW_SPOKE_DIR Spoke state (same pattern under …/spoke)

License & publish

Apache-2.0

pip install build twine && python -m build
# twine upload dist/*
uvx --from ansible-flow-mcp ansible-flow-mcp

Metadata

Release files for ansible-flow-mcp 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ansible-flow-mcp 0.1.3
File Size Uploaded
ansible_flow_mcp-0.1.3.tar.gz 12.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for ansible-flow-mcp 0.1.3
File Interpreter ABI Platform
ansible_flow_mcp-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 46.2 MB

Release files / ansible_flow_mcp-0.1.3.tar.gz

Download URL ansible_flow_mcp-0.1.3.tar.gz
Size 12.0 MB
Tags Source
SHA-256 checksum
How to use checksums
ed43716bc5d54e30976514910438d254ca0c348a831b608daa546caf11260236
BLAKE2b-256 checksum
How to use checksums
e040028c5b14a3bc372126341efc73208c5c46c76f383d3742c68bdbcf97bfeb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.

Transparency log

Release files / ansible_flow_mcp-0.1.3-py3-none-any.whl

Download URL ansible_flow_mcp-0.1.3-py3-none-any.whl
Size 34.2 MB
Tags Python 3
SHA-256 checksum
How to use checksums
51fa7612ec5d4334cccd8bc03581c0fb1415c8ef5425d50860e1a86ef7a4837f
BLAKE2b-256 checksum
How to use checksums
52793845067173bb5ee2b4b679ddfdb34b30f602f0a6289a1c1acb685316adfa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page