Deploying the Ansible MCP Server with the Operator-Managed Platform
Let’s set the stage Last week I published a post about Model Context Protocol (MCP) servers in my homelab and how I’ve been using them with Cursor to give A...
Last week I published a post about Model Context Protocol (MCP) servers in my homelab and how I’ve been using them with Cursor to give AI assistants real context for Openshift, RHEL, and Ansible Automation Platform. That write-up was deliberately broad. I explained what MCP is, which three servers I run, and how they fit into my day-to-day work. I also said I’d follow up with more detail on deploying each one.
This is the first of those follow-ups.
If you’ve already read about my MCP setup, you know my AAP instance runs on Openshift under the operator. What I didn’t walk through last week is how I enabled the Ansible MCP server on that same production instance in the aap namespace. That’s what we’re covering today. The good news is that if you already have the Ansible Automation Platform operator installed and an AnsibleAutomationPlatform custom resource in place, adding MCP is a small edit to that CR. The operator handles the rest.
I’m only going to cover the command-line path here. For instructions regarding the UI, refer to the official Red Hat Documentation.
The Ansible MCP server is a technology preview feature in Ansible Automation Platform 2.6. It acts as a secure bridge between an external AI client (Cursor, Claude, VS Code, and others) and the Ansible Automation Platform API. When you ask an assistant to list job templates or launch a job, the MCP server validates the request and authenticates using your API token. What the assistant can do is bounded by both server-level settings and the RBAC permissions on that token.
Red Hat documents two permission layers:
allow_write_operations. When false (the default), the MCP server enforces a read-only posture at the MCP layer even if a user’s token could write. When true, the server may expose mutating API operations to MCP clients, subject to the user’s RBAC.allow_write_operations is true. A write-scoped token can only perform actions that user is already permitted to perform in the UI.Long story short, the MCP server does not bypass Ansible Automation Platform security. It exposes it to a new kind of client. Both layers have to allow an action before the assistant can carry it out.
Before you enable MCP on an existing operator deployment, you should have:
production in the aap namespace on ocp.bk.lab)The MCP feature is not something I’d run in production without understanding the technology preview terms. Red Hat is explicit that these previews are for testing and feedback, not production SLAs. My lab is the right place for it.
My Ansible Automation Platform instance runs on Openshift at ocp.bk.lab, deployed by the AAP operator into the aap namespace as a resource named production. Enabling MCP is a small addition to that existing AnsibleAutomationPlatform custom resource. You add an mcp block under spec, whether your instance is named production or something else.
Pull up your existing AnsibleAutomationPlatform manifest, or export the live resource.
oc get ansibleautomationplatform production -n aap -o yaml > production-aap.yaml
Under spec, add the MCP component. You can name the file something like production-aap-mcp.yaml if you prefer a separate manifest for the change.
apiVersion: aap.ansible.com/v1alpha1
kind: AnsibleAutomationPlatform
metadata:
name: production
namespace: aap
spec:
image_pull_policy: IfNotPresent
controller:
disabled: false
eda:
disabled: false
hub:
disabled: false
file_storage_size: 500Gi
file_storage_storage_class: <your-read-write-many-storage-class>
lightspeed:
disabled: true
mcp:
disabled: false
allow_write_operations: true
Setting mcp.disabled to false tells the operator to deploy the MCP server alongside the platform components you already have enabled.
In my lab I set allow_write_operations: true. That is not the default, and it is not what I would recommend for a production environment without careful thought. Here is what it changes and why I turned it on anyway.
With write operations allowed at the server level, the MCP toolsets can call mutating Ansible Automation Platform APIs when your OAuth token also has write scope. In practical terms, that means an assistant in Cursor can do more than query controller state. It can launch job templates and workflow jobs, trigger project or inventory updates where the API supports them, and perform other create/update/delete actions exposed through the MCP server’s job management, inventory management, user management, and platform configuration toolsets. That is exactly what I wanted for Configuration as Code work: I can ask the assistant to dispatch a CASC job, relaunch a failed run, or verify a template after editing YAML without leaving the IDE.
The security implications are real. Large language models can misinterpret a prompt or hallucinate a tool call. With allow_write_operations: true, a mistaken or overly broad request could launch an automation job, modify a resource, or trigger other changes in Ansible Automation Platform. The damage is still bounded by who owns the token. The assistant cannot exceed the RBAC permissions of the user who created it. I use a dedicated lab account with permissions scoped to the organizations and objects I care about, not my personal admin account. You should pair server-level write access with a write-scoped OAuth token only when you intend the assistant to act, and review what it proposes before accepting job launches in sensitive areas.
If you are experimenting, allow_write_operations: false plus a read-scoped token is the safer place to start. Enable write at the server level only when you have a concrete workflow that requires it and you understand what the exposed toolsets can change.
If you change allow_write_operations after MCP is already running, see the section below on recreating the AnsibleMCPServer custom resource.
If you want to see every field the operator supports for MCP, oc explain is your friend:
oc explain ansibleautomationplatform.spec.mcp --recursive
Apply the updated custom resource.
oc apply -f production-aap-mcp.yaml
Watch the namespace while the operator reconciles. You should see MCP-related resources appear alongside your existing controller, hub, EDA, and gateway pods.
watch "oc get pods -n aap | grep -E 'production|mcp'"
Confirm the MCP deployment exists.
oc get deployment -n aap | grep mcp
In my lab the route is named production-mcp and points at a deployment the operator created in the same aap namespace as the rest of the platform. Your naming may differ slightly depending on operator version, but you should see a clear MCP deployment alongside production-controller, production-hub, and the other platform pods.
Check the pod logs if anything stays in a crash loop. A clean startup should show the MCP server listening without certificate or API connection errors.
oc logs -n aap deployment/<your-mcp-deployment-name> --tail=50
If you change allow_write_operations on an instance that already has MCP running, Red Hat’s documentation calls out an extra step. You may need to delete the AnsibleMCPServer custom resource and let the operator recreate it. In the UI that’s under Resources, searching for AnsibleMCPServer, selecting the instance with the -mcp suffix, and deleting it so reconciliation can build a fresh one.
I had to do this once when I first enabled write access after deploying with read-only settings. It’s worth knowing before you toggle permissions on a live instance.
The operator creates an Openshift route for the MCP server the same way it does for the platform gateway and controller. You need that URL to configure Cursor or any other MCP client.
List routes in the AAP namespace.
oc get route -n aap
Look for the route whose name or host corresponds to your instance and MCP. In my lab that’s production-mcp-aap.apps.ocp.bk.lab. The platform gateway at production-aap.apps.ocp.bk.lab is a different route. You want the MCP one, not the login page.
Verify the MCP endpoint responds. The path your client needs is /mcp on that host. A simple check from your workstation:
curl -k -I "https://production-mcp-aap.apps.ocp.bk.lab/mcp"
You should get an HTTP response from the route even before you’ve configured a token in your client. An unauthorized response is fine at this stage. It means the route and service are wired up.
The MCP server authenticates to Ansible Automation Platform using an OAuth token you create in the platform. The assistant inherits whatever that user is allowed to do.
Log in to the Ansible Automation Platform UI with a user account that has the permissions you want the assistant to have. For lab work I use a dedicated account rather than my admin user.
Navigate to Access Management → OAuth Applications (or create a personal access token if your workflow allows leaving the application field blank).
Create a token with an appropriate scope:
allow_write_operations: false.allow_write_operations: true, I use a write-scoped token on a dedicated account so the assistant can dispatch automation when I ask it to.Copy the token when it is displayed. You will not see it again.
Store the token somewhere sensible. I keep mine in Cursor’s MCP configuration on my laptop, not in a git repository.
Once you have the route and the token, configuring Cursor is straightforward. Add an entry to ~/.cursor/mcp.json:
{
"mcpServers": {
"aap-mcp": {
"type": "http",
"url": "https://production-mcp-aap.apps.ocp.example.com/mcp",
"headers": {
"Authorization": "Bearer <your-oauth-token>"
}
}
}
}
Replace the host with your MCP route and paste the token you created in the previous section.
Red Hat’s documentation also shows separate MCP URLs per toolset (job management, inventory management, system monitoring, and so on). My operator deployment exposes a single /mcp endpoint on the instance route, which is simpler for Cursor. If your environment presents multiple toolset URLs, add one mcpServers entry per toolset following the same pattern. Keep each server name short. The docs mention a 64-character limit when the client combines server name and tool name.
Restart or refresh MCP in Cursor, then confirm connectivity. A read-only check:
What job templates are available in my Ansible Automation Platform?
If the server and token are correct, the assistant should call MCP tools and return real data from your controller. With write access enabled at both layers, you can follow up with an action you are willing to run in the lab, such as asking it to show the status of a recent job or launch a known-safe template with specific extra_vars you supply.
The Ansible MCP server is only one of three I run on the same Openshift cluster. The AAP MCP server talks to the automation API. openshift-mcp talks to the cluster API. rhel-mcp talks to Linux hosts over SSH. Deploying AAP MCP through the operator keeps it in the same namespace and lifecycle as the platform itself. I’m not maintaining a separate manifest stack or a one-off Deployment just for MCP.
That co-location matters when I’m doing Configuration as Code work. I edit job template YAML in the IDE, apply CASC changes through the platform, and ask the assistant to verify controller state through MCP without switching contexts. I described that workflow in last week’s post. This one is the installation story behind it.
A few practical notes from getting this working in the lab:
allow_write_operations: true in the lab because I want the assistant to launch jobs. That power is useful and risky. Use a scoped service account, write-scoped tokens only when needed, and read the proposed API calls before letting a job run.mcp.json instead of production-mcp-aap.apps.ocp.bk.lab. The names are similar enough that it’s an easy mix-up.When MCP does not connect, I work through this list:
oc get route -n aap show the MCP host you configured in mcp.json?allow_write_operations is true on the AnsibleAutomationPlatform CR and that the AnsibleMCPServer resource was recreated after you changed it.Most of my early issues were stale tokens or pointing Cursor at the gateway route instead of the MCP route.
Deploying the Ansible MCP server with the operator-managed platform is one of the smaller changes I’ve made in the homelab, but it has had an outsized impact on how I work with Configuration as Code and day-to-day automation tasks. The operator already knows how to run AAP. Adding spec.mcp just tells it to run the MCP bridge too.
If you read last week’s MCP overview, consider this the AAP-specific follow-up I promised at the end of that post. I’ll try to keep the series moving with something on Openshift MCP tokens next, assuming life doesn’t get in the way again.
For the authoritative procedure and troubleshooting steps, see Deploying Ansible MCP Server on OpenShift Container Platform and the broader deploying Ansible MCP server guide. Red Hat also has a good overview in Introducing the MCP server for Ansible Automation Platform.
As with everything I write about my lab, this is how I run things. Your instance names, namespaces, routes, and risk tolerance may differ. Use the technology preview accordingly, and keep secret data out of git.
Let’s set the stage Last week I published a post about Model Context Protocol (MCP) servers in my homelab and how I’ve been using them with Cursor to give A...
Let’s set the stage If you’ve been following along, you already know my homelab is built to represent an enterprise environment as closely as I can manage. ...
Let’s set the stage for all of my content As I build demos and content to share, it’s important that I have and easy, repeatable way to demonstrate capabili...
What’s going on with me in 2026 The beginning of every new calendar year comes with change especially when, like me, you work in a large Enterprise sales or...
It’s been a couple of months I was working hard on the Ansible + Terraform series…and was almost ready to complete part 3 (which is still coming, btw!), but...
There’s still more than one best tool In Part 1, I showed you how to configure a basic Terraform project and deploy some infrastructure, in particular EC2 i...
There’s more than one best tool Terraform and Ansible working together is a subject I get asked about fairly regularly. Most of the time, the way the conve...
Just like the environments we work with in datacenters and clouds, a homelab can consist of a variety of hardware, software, configurations, interdependencie...
Making visual improvements You’ll notice that I keep making visual changes to the site. As I find improvements or add pages, they will seem to just magical...
Slight snafu…easy fix! I made a little boo-boo and used a domain name and blog name that I shouldn’t have. All is well and I’ve updated the site to somethi...
Let’s configure custom DNS In my efforts to share knowledge about tech things, setting up a blog seemed like one of the easier things to do. It is a challe...
Welcome to Brad Does Tech This is where I’ll be posting about cool tech things I learn or demo for my customers. Stay tuned for more! –Brad