ansible-flow-mcp
Provides tools for searching Ansible module galleries, retrieving module schemas, and running Ansible modules and playbooks with optional check mode and security restrictions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ansible-flow-mcpSearch for the apt module, get its schema, and run it in check mode to update all packages"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ansible-flow-mcp
Give agents Ansible. Not the keys.
This branch (CORE) is documentation only: why it exists, campaign screenshots, and the marketing site. The runnable MCP and hub live on DEVELOPMENT. main stays a product alias.
License | |
Install / code | |
Marketing site | |
Hub ops | |
Branches | |
Species | |
Voice |
Visual tour
Why it exists | Agent loop |
|
|
Hub / spoke fabric | Operators |
|
|
Screenshots live in docs/images/campaign-*.png. Re-shoot from docs/campaign/ with ./capture.sh.
Related MCP server: AAP MCP Server
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.

Typical cases:
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.

Tool | Purpose |
| Gallery search |
| Slim argSpec for FQCN |
| Ad-hoc Ansible ( |
|
|
| 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.

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.

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_collectionsLab one-shot
cd lab && ./scripts/demo.sh
# then: ./scripts/tui.sh | ./scripts/opencode-host.shSee lab/README.md.
Quick start
Full guide (all paths, verify, troubleshooting): docs/QUICKSTART.md
Path | Guide section |
Local MCP + Cursor/Claude | |
Compose lab (hub + 3 spokes) | |
Bare-metal hub/spoke |
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-mcpOr install via pypi.org
pip install ansible-flow-mcp
ansible-galaxy collection install ansible.posix
ansible-flow-mcpEditor 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 |
|
Check mode | Default true on |
Playbook jail | Allowlisted roots · size limit · |
No shell interpolation | argv-only subprocess |
Hub inventory | Enrolled hosts only · no client |
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 modulescatalog/gallery.json+catalog/schemas/: searchable galleryRegenerate:
python scripts/generate_catalog.pyGalaxy factory TUI: scripts/factory/README.md
OpenFlow reads this gallery for its Ansible canvas (plan · umbrella).
OpenFlow | This MCP server |
Palette Ansible gallery |
|
Form | JSON module options |
|
Playbook resource |
|
Control-node SSH / become | Inventory + Ansible config · hub→spoke SSH in hub mode |
Env (common)
Variable | Meaning |
| Override catalog path |
| Comma-separated allowlist override |
| Default |
| Seconds (default 120 module / 300 playbook) |
| Extra playbook roots ( |
| Hub state (default: |
| Spoke state (same pattern under |
License & publish
Apache-2.0
pip install build twine && python -m build
# twine upload dist/*uvx --from ansible-flow-mcp ansible-flow-mcpFamily
Written standard: private TheFLOW.
OpenFlow: reads this Ansible gallery
mcp-flow: MCP gateway
skill-flow: Agent Skills
wiki-flow, roster-flow, CleanFlow, ProjectEverflow: siblings
Available Tools
5 toolsget_module_schemaA
Return slim arg schema for a module FQCN (when catalog has it).
| Name | Required | Description | Default |
|---|---|---|---|
| module | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full burden of behavioral disclosure. It mentions 'slim' and 'when catalog has it,' but fails to specify what happens when the module is missing from the catalog (e.g., error, empty result) or what 'slim' entails. This leaves the agent uncertain about failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no filler. Every term adds meaning, including 'slim' and 'when catalog has it,' making it efficiently front-loaded and appropriately sized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one parameter and has an output schema, so return values are presumably covered. However, the description lacks guidance on missing-module behavior and does not situate this tool relative to siblings like search_modules, leaving practical edge cases unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides only a 'module' string with no description (0% coverage). The description adds critical semantic meaning by specifying that the parameter expects a module FQCN (fully qualified class name), clarifying the required input format beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the clear verb 'Return' and specifies the resource: 'slim arg schema for a module FQCN'. This distinguishes it from sibling tools like search_modules and run_module, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'when catalog has it' implies a conditional context but does not explicitly contrast with alternatives like search_modules. There is no explicit when-to-use or when-not-to-use guidance, though the intended usage is somewhat inferable from sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_collectionsA
List collections present in the committed gallery.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It implies a read-only operation through the word 'List,' and 'committed gallery' adds scope context, but it does not disclose any side effects, permissions, or edge cases. The minimal disclosure is adequate for a simple listing tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that immediately states the action and scope. Every word earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless listing tool with an output schema, the description is sufficiently complete. It tells the agent what the tool does and what data it operates on, and the output schema will provide the return structure. No additional context is necessary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline of 4 applies. The description does not need to explain parameter semantics, and the input schema confirms no arguments are required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List') and resource ('collections') with a location qualifier ('committed gallery'), distinguishing it from sibling tools that operate on modules. It is slightly more informative than the tool name alone, though 'committed gallery' is domain-specific and not elaborated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided about when to use this tool versus alternatives. The description only states what the tool does, with no context about when it is appropriate or how it compares to the sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_moduleB
Run an Ansible module via local ansible CLI. Prefer check_mode=true first.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | ||
| hosts | No | localhost | |
| become | No | ||
| module | Yes | ||
| timeout | No | ||
| inventory | No | ||
| check_mode | No | ||
| connection | No | ||
| become_user | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden for behavioral disclosure. It only advises check mode first, but fails to mention that the tool can execute arbitrary Ansible modules with potentially destructive side effects, requires permissions, or what happens on failure. This is a significant transparency gap for a tool running arbitrary code.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences, front-loaded with the core purpose and a safety tip. Every word contributes to the message, and it is easily scannable. It is concise without unnecessary verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite its conciseness, the description is severely incomplete for a tool with 9 parameters, no annotations, and no schema descriptions. It fails to explain how to use arguments, inventory, become, connection, or when this tool is appropriate versus run_playbook. The presence of an output schema does not compensate for the missing operational guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema description coverage at 0%, the description is expected to compensate for missing parameter explanations. It does not explain any of the 9 parameters beyond implicitly referring to module and check_mode. Args, hosts, become, timeout, inventory, connection, and become_user are left entirely to the schema, which lacks descriptions. The description adds no meaningful semantic value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Run' and the resource 'Ansible module via local ansible CLI', distinguishing it from sibling tools like run_playbook. It is specific and unambiguous, making the tool's primary function immediately clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a usage tip to prefer check_mode=true, which is helpful, but it lacks explicit guidance on when to use this tool versus alternatives like run_playbook. The context of running a single module is implied but no exclusions or alternative suggestions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_playbookA
Run ansible-playbook on a path under allowlisted roots. Prefer check_mode=true first.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | ||
| limit | No | ||
| become | No | ||
| timeout | No | ||
| playbook | Yes | ||
| inventory | No | ||
| skip_tags | No | ||
| check_mode | No | ||
| connection | No | ||
| extra_vars | No | ||
| become_user | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries responsibility for disclosing side effects. It mentions 'allowlisted roots' and suggests using check mode, implying the tool can make changes, but it does not explicitly state that it may modify systems or require elevated privileges.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, each contributing distinct information: what it does and how to use it safely. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 11 parameters and no annotations, the description is too sparse. It lacks information about parameter roles, error behavior, and the consequences of running playbooks with check_mode=false, making it incomplete for safe use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, yet the description provides no information about any of the 11 parameters. The parameter names are in the schema, but the description adds no semantic value to compensate for the missing descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs ansible-playbook with a specific path constraint (allowlisted roots). This is distinct from sibling tools which focus on modules (search_modules, run_module, etc.).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description advises to prefer check_mode=true first, which provides a clear usage guideline. It does not explicitly name alternative tools, but the tool's purpose is obvious against module-related siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_modulesA
Search allowlisted Ansible modules (gallery) by name, FQCN, collection, or description.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses the 'allowlisted' restriction and searchable fields, which is useful behavioral context. However, it does not describe behavior like empty queries, default limits, or search matching semantics, leaving the agent with incomplete expectations for a read-only search tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, sentence-length description that immediately conveys the tool's purpose and scope. No filler, front-loaded with the verb, and every word adds meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple search tool with an output schema and available sibling context, the description covers the essential purpose and searchable attributes. Minor gaps like edge-case search behavior and the meaning of 'allowlisted' are not critical for invocation, but there is slight room for more context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must clarify parameters. It does so for 'query' by specifying the search fields (name, FQCN, collection, description), but 'limit' is left to the schema's default without additional context. This provides partial compensation for the lack of schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Search' and identifies the resource as 'allowlisted Ansible modules (gallery)' with explicit search criteria (name, FQCN, collection, description). This distinguishes it from sibling tools like list_collections and get_module_schema, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies its use for finding modules by various attributes, which is distinct from listing collections or retrieving schemas. However, it does not explicitly state when to prefer this over alternatives or mention exclusions, so guidance is somewhat implicit but still clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.3- First observed
get_module_schema - First observed
list_collections - First observed
run_module - First observed
run_playbook - First observed
search_modules
TDQS
Scored across 5 tools
Each tool targets a distinct action: searching the module catalog, retrieving module schemas, running a module, running a playbook, and listing collections. There is no functional overlap between any of the tools, making selection unambiguous.
All tool names follow a consistent verb_noun pattern using snake_case: search_modules, get_module_schema, run_module, run_playbook, list_collections. The naming is predictable and uniform across the entire set.
With 5 tools, the set is well-scoped for an Ansible flow server. It covers the essential operations of discovering, inspecting, and executing Ansible content without unnecessary bloat or heaviness.
The toolset covers the core lifecycle: discover (search/list), inspect (get schema), and execute (run module/playbook). A minor gap is the lack of a direct way to list playbooks or manage inventory, but these are not essential for the stated flow-centric purpose.
Maintenance
Related MCP Connectors
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
Related MCP Servers
- AlicenseCqualityFmaintenanceThis Model Context Protocol server enables AI assistants to interact directly with Ansible, allowing them to execute playbooks, manage inventory, check syntax, and perform other Ansible operations.1826MIT
- AlicenseBqualityDmaintenanceEnterprise-grade MCP server exposing Ansible Automation Platform 2.x as a complete AI interface for LLMs, enabling natural language management of automation resources.861Apache 2.0
- FlicenseAqualityDmaintenanceAn MCP server that lets AI agents discover Ansible Galaxy collection input/output contracts, including module arguments, return values, and role facts, to help generate accurate playbooks.6-
- FlicenseNot gradedqualityDmaintenanceIndustry-standard MCP server for AWX/AAP/Ansible Tower automation, enabling AI agents to manage job templates, launch and monitor jobs, and handle inventories and projects through natural language.11-