Profiles
A profile is a YAML file that declares which inventory to use and which modules and roles to expose as MCP tools. Rocannon reads one or more profiles at startup and registers the union of their tools.
Full profile reference
inventories:
- ./hosts # path to inventory file or directory
- ./hosts.d/ # multiple inventories are supported
modules:
- ansible.builtin.copy # a single module FQCN
- ansible.builtin # a whole collection → all its modules
- community # a namespace → all collections in it
- community.docker # mix module, collection, namespace specs freely
roles: # optional
- my_ns.my_coll.setup_web # FQCN for a collection role
- standalone_role # bare name for a standalone role (needs roles_path)
roles_path: ./roles # optional; resolves against the profile file's directory
ansible_cfg: ./ansible.cfg # optional; sets ANSIBLE_CONFIG for module runs
vault_password_file: ./vault.key # optional; sets ANSIBLE_VAULT_PASSWORD_FILE
extra_envvars: # optional; merged into the ansible-runner environment
CUSTOM_VAR: value
ANOTHER_VAR: other
timeouts: # optional; per-module execution timeout in seconds
ansible.builtin.command: 60 # default is 300s (5 minutes)
ansible.builtin.shell: 60
Configuration keys
| Key | Required | Description |
|---|---|---|
inventories |
required | List of paths to Ansible inventory files or directories. Rocannon delegates all parsing (group_vars, Jinja2, dynamic inventories) to ansible-inventory. |
modules |
required* | List of module, collection, or namespace specs. A namespace like community expands to every installed module in that namespace. Only modules become tools; filter and lookup plugins are skipped. *Required unless roles is set. |
roles |
optional | List of role names to expose. A collection role uses its FQCN (my_ns.my_coll.role). A standalone role uses its directory name. Roles without meta/argument_specs.yml are skipped (Rocannon cannot build a typed interface without a documented spec). |
roles_path |
optional | Directory containing standalone roles. Set this when roles are not in a collection and not on the default Ansible roles path. |
ansible_cfg |
optional | Path to an ansible.cfg file. Passed to ansible-runner as ANSIBLE_CONFIG. |
vault_password_file |
optional | Path to a Vault password file. Passed as ANSIBLE_VAULT_PASSWORD_FILE. Vault-encrypted variables in inventory or host_vars are decrypted automatically. |
extra_envvars |
optional | Key-value pairs merged into the subprocess environment for every module run. Useful for passing credentials that modules read from environment variables (e.g. AWS_PROFILE, ZOAU_HOME). |
timeouts |
optional | Per-module execution timeout in seconds. The global default is 300s (overridden by ROCANNON_TIMEOUT). Set shorter timeouts for modules that should fail fast, or longer ones for slow provisioning steps. |
Profile discovery
When you run rocannon mcp serve without --profile, Rocannon walks up from the current directory looking for .rocannon/profiles/. If it finds the directory, it loads every *.yml file in it as a named profile.
Default profile resolution order:
default.ymlas a symlink; the symlink target's stem becomes the active namedefault.ymlas a regular file- The only profile in the directory, if exactly one exists
- Falls back to
~/.rocannon/profiles/if no project-level directory is found
Runtime switching
Load multiple profiles in .rocannon/profiles/ and switch between them at runtime without restarting the server:
# In your MCP client or REPL:
rocannon_list_profiles → lists all profiles and which is active
rocannon_current_profile → returns the active profile's full config
rocannon_use_profile → switches to a named profile
Tool functions read the active profile's inventory, envvars, and timeouts on every call. A profile switch takes effect immediately for subsequent calls.
rocannon_use_profile, rather than failing inside ansible-runner.Example: dev/staging/prod
.rocannon/profiles/
dev.yml → dev inventory, full module set, permissive timeouts
staging.yml → staging inventory, same modules, tighter timeouts
prod.yml → production inventory, restricted module subset
default.yml → symlink → dev.yml
The agent sees all module tools on startup. rocannon_use_profile("prod") narrows execution to the production inventory and module subset without re-registering anything.
Example: network automation
inventories:
- ./inventory/network.yml # Arista and Cisco hosts
modules:
- arista.eos
- cisco.ios
- ansible.netcommon
ansible_cfg: ./ansible-network.cfg # network-optimised connection settings
timeouts:
arista.eos.eos_config: 120 # config pushes can be slow on large devices
Dependencies: modules with third-party libraries
Some modules require Python packages beyond ansible-core:
| Collection | Python dependency |
|---|---|
community.docker | pip install docker |
community.crypto | pip install cryptography |
community.mongodb | pip install pymongo |
community.postgresql | pip install psycopg2-binary |
amazon.aws | pip install boto3 |
kubernetes.core | pip install kubernetes |
Install these in the same environment as Rocannon. The quickstart profile pins ansible_python_interpreter so localhost modules use the right interpreter automatically.