An MCP (Model Context Protocol) server for OpenStack built with the official Go SDK.
This project provides an MCP server that exposes OpenStack resources as MCP tools, allowing AI assistants and MCP-compatible clients to interact with OpenStack environments through a standardized interface.
Currently implemented tools:
-
list_instances- List all instances in the current OpenStack project.
-
get_instance- Get detailed information about an instance by name.
-
list_networks- List available OpenStack networks.
-
list_images- List available OpenStack images.
-
list_flavors- List available OpenStack flavors.
Administrator tools:
-
admin_instance_action- Run lifecycle actions on an instance:
start,stop,reboot,pause,unpause,suspend,resume,shelve,unshelve,lock, orunlock. - For reboot, pass
reboot_typeassoftorhard.
- Run lifecycle actions on an instance:
-
create_instance- Create a new instance from an image, flavor, and network.
- Optional fields:
key_name,security_groups, andno_wait. - By default, the tool waits for OpenStack to finish building the instance.
-
delete_instance- Delete an instance by name.
- Requires
confirm_nameto exactly matchnamebefore deletion.
Agent workflow tools:
-
get_agent_memory- Read remembered OpenStack agent defaults and policy.
-
plan_instance_operation- Plan the MCP tool and arguments for an instance operation before execution.
- Applies remembered defaults for create requests.
- Blocks risky operations against protected instance patterns.
- This operation is read-only and does not call OpenStack.
-
summarize_agent_activity- Summarize recent administrator MCP audit activity.
- Groups successful, failed, and rejected work.
- Highlights destructive operations and events that need attention.
- This operation is read-only and does not call OpenStack.
-
record_agent_memory- Update non-secret operational memory such as default image/flavor/network and protected instance patterns.
- This modifies local MCP memory and should use write approval.
For Codex, keep read-only tools auto-approved and run administrator tools with write approval enabled. A typical MCP policy is:
default_tools_approval_mode = "writes"
[mcp_servers.openstack.tools.list_instances]
approval_mode = "approve"Administrator tools append JSONL audit events for every OpenStack state-changing operation. The log records the operation, target instance, OpenStack command arguments, success/failure status, and duration. Command output and OpenStack credentials are not written to the audit log.
The default audit path is:
~/.local/state/openstack-mcp/audit.jsonl
Override it with:
OPENSTACK_MCP_AUDIT_LOG=/path/to/audit.jsonl ./scripts/run-mcp-server.shExample event:
{"timestamp":"2026-08-07T03:00:00Z","source":"openstack-mcp","operation":"delete_instance","target":"demo","destructive":true,"openstack_args":["server","delete","demo"],"status":"success","duration_ms":912}If delete_instance is called without an exact confirm_name match, the server
records a rejected audit event and does not call OpenStack.
Use summarize_agent_activity to brief a human on recent MCP administrator
work:
{
"since_hours": 12,
"limit": 20
}This supports an operator workflow such as: "When I start work, summarize what the OpenStack agent did overnight and highlight failed, rejected, or destructive operations."
The audit log covers actions performed through this MCP server. It does not automatically include every OpenStack event that happened outside MCP.
To brief all overnight OpenStack activity, the server would need an additional event source such as Nova instance events, OpenStack service logs, Telemetry services, audit middleware, or the OpenStack notification bus. The current MCP design keeps that as a future read-only event ingestion layer, separate from the administrator write tools.
The server can remember non-secret operational defaults and safety rules. The default memory path is:
~/.config/openstack-mcp/memory.json
Create it from the example on the controller:
mkdir -p ~/.config/openstack-mcp
cp config/memory.example.json ~/.config/openstack-mcp/memory.json
chmod 600 ~/.config/openstack-mcp/memory.jsonOverride the path with:
OPENSTACK_MCP_MEMORY_FILE=/path/to/memory.json ./scripts/run-mcp-server.shThe planner uses this memory before recommending write tools. For example, a
create request without image/flavor/network will be planned with remembered
defaults such as RCP Ubuntu 22.04, m1.small, and demo-net. A destructive
request against an instance matching a protected pattern such as prod-* is
blocked at the planning step.
Use plan_instance_operation before write tools in agent workflows:
{
"operation": "create",
"name": "dev-box"
}Example result:
{
"recommended_tool": "create_instance",
"arguments": {
"name": "dev-box",
"image": "RCP Ubuntu 22.04",
"flavor": "m1.small",
"network": "demo-net"
},
"requires_approval": true,
"blocked": false
}Planner behavior is covered by deterministic evaluation tests in
internal/agent/planner_test.go. These cases verify that remembered defaults are
applied, deletes require exact confirmation, protected instances are blocked
for risky lifecycle operations, and restorative lifecycle operations can still
be planned.
Run:
go test ./...- Go 1.24+
- OpenStack CLI
- A configured OpenStack environment (
openrcsourced)
Clone the repository.
git clone https://github.com/haramj/openstack-mcp.git
cd openstack-mcpDownload dependencies.
go mod downloadBuild the server.
make buildBefore running the server, make sure your OpenStack credentials are loaded and
the openstack CLI is available.
source openrc
which openstack
openstack server listRun the MCP server.
./openstack-mcp-serverWhen OpenStack is only available on an Ubuntu controller, run the MCP server on that controller and connect to it from your laptop with an SSH tunnel.
Create a private OpenStack environment file on the controller.
mkdir -p ~/.config/openstack-mcp
chmod 700 ~/.config/openstack-mcp
cp config/openrc.example ~/.config/openstack-mcp/openrc
chmod 600 ~/.config/openstack-mcp/openrcEdit ~/.config/openstack-mcp/openrc with the controller's real OpenStack
values. Do not commit that file.
Create a local wrapper from the example.
cp scripts/run-mcp-server.sh.example scripts/run-mcp-server.sh
chmod +x scripts/run-mcp-server.shIf your OpenStack virtualenv is not /home/return/openstack-venv, set
OPENSTACK_VENV when running the wrapper.
OPENSTACK_VENV=/path/to/openstack-venv ./scripts/run-mcp-server.shYou can test the server using the official MCP Inspector.
npx @modelcontextprotocol/inspector ./openstack-mcp-serverOn the controller, prefer the wrapper so the Inspector-launched MCP server gets the OpenStack CLI path and authentication environment.
make build
npx @modelcontextprotocol/inspector /home/return/src/openstack-mcp-server/scripts/run-mcp-server.shFrom your laptop, forward the Inspector ports over SSH.
ssh -L 6274:127.0.0.1:6274 -L 6277:127.0.0.1:6277 return@<controller-ip>Open the tokenized Inspector URL from the controller terminal in your laptop
browser, replacing localhost with 127.0.0.1 if needed.
Use the Tools tab to test:
list_instancesget_instancewith{ "name": "test" }list_networkslist_imageslist_flavorsget_agent_memoryplan_instance_operationwith{ "operation": "create", "name": "demo" }summarize_agent_activitywith{ "since_hours": 12, "limit": 20 }record_agent_memorywith{ "default_network": "demo-net", "note": "demo-net is the default network for RCP test instances" }admin_instance_actionwith{ "name": "test", "action": "reboot", "reboot_type": "soft" }create_instancewith{ "name": "demo", "image": "RCP Ubuntu 22.04", "flavor": "m1.small", "network": "demo-net" }delete_instancewith{ "name": "demo", "confirm_name": "demo" }
.
├── cmd/
│ └── openstack-mcp-server/
│ └── main.go
├── internal/
│ ├── openstack/
│ │ ├── flavors.go
│ │ ├── images.go
│ │ ├── instances.go
│ │ └── networks.go
│ └── tools/
│ ├── flavors.go
│ ├── images.go
│ ├── instances.go
│ └── networks.go
├── config/
│ └── openrc.example
├── scripts/
│ ├── run-mcp-server.sh.example
│ ├── install.sh
│ ├── run-inspector.sh
│ └── test.sh
├── go.mod
├── go.sum
├── Makefile
└── README.md
- Go
- OpenStack CLI
- Model Context Protocol Go SDK
MIT License