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_modulesget_module_schemarun_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 initissue-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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ansible_flow_mcp-0.1.3.tar.gz (12.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ansible_flow_mcp-0.1.3-py3-none-any.whl (34.2 MB view details)

Uploaded Python 3

File details

Details for the file ansible_flow_mcp-0.1.3.tar.gz.

File metadata

  • Download URL: ansible_flow_mcp-0.1.3.tar.gz
  • Upload date:
  • Size: 12.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ansible_flow_mcp-0.1.3.tar.gz
Algorithm Hash digest
SHA256 ed43716bc5d54e30976514910438d254ca0c348a831b608daa546caf11260236
MD5 4f20339d13e1e8149f60f2858b941e6c
BLAKE2b-256 e040028c5b14a3bc372126341efc73208c5c46c76f383d3742c68bdbcf97bfeb

See more details on using hashes here.

Provenance

The following attestation bundles were made for ansible_flow_mcp-0.1.3.tar.gz:

Publisher: publish.yml on real-limitless/ansible-flow-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ansible_flow_mcp-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for ansible_flow_mcp-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 51fa7612ec5d4334cccd8bc03581c0fb1415c8ef5425d50860e1a86ef7a4837f
MD5 2e73c85a52dc71c7c832e764dce304f5
BLAKE2b-256 52793845067173bb5ee2b4b679ddfdb34b30f602f0a6289a1c1acb685316adfa

See more details on using hashes here.

Provenance

The following attestation bundles were made for ansible_flow_mcp-0.1.3-py3-none-any.whl:

Publisher: publish.yml on real-limitless/ansible-flow-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page