openstack-mcp
# openstack-mcp
An [MCP](https://modelcontextprotocol.io) server that lets an AI assistant inspect and operate an **OpenStack** cloud — list instances, check quotas, read a stuck VM's console log, and (if you allow it) create and delete servers.
Works with any OpenStack deployment: [CloudPe](https://www.cloudpe.com/), OVHcloud, Infomaniak, university and research clouds, or a local DevStack. Anything `openstacksdk` can reach, this can drive.
**Read-only by default.** Writes require an explicit opt-in, and deletes require a second one. An assistant that can list your project cannot tear it down unless you decided it should be able to.
## Quick start
Install from source (not yet on PyPI):
```bash
pipx install git+https://github.com/abhishekambad-leapswitch/openstack-mcp
```
Point it at a cloud. `openstacksdk` reads standard OpenStack config, so either a `clouds.yaml`:
```yaml
# ~/.config/openstack/clouds.yaml
clouds:
cloudpe:
auth_type: v3applicationcredential
auth:
auth_url: https://<your-region>.cloudpe.com:5000/v3
application_credential_id: <id>
application_credential_secret: <secret>
region_name: RegionOne
```
...or the usual environment variables (`OS_AUTH_URL`, `OS_APPLICATION_CREDENTIAL_ID`, `OS_APPLICATION_CREDENTIAL_SECRET`). **This server never stores or transmits your credentials itself** — it hands off to `openstacksdk`, which resolves them the same way the `openstack` CLI does.
### Claude Code
```bash
claude mcp add openstack --env OS_CLOUD=cloudpe -- openstack-mcp
```
### Claude Desktop / Cursor / any MCP client
```json
{
"mcpServers": {
"openstack": {
"command": "openstack-mcp",
"env": { "OS_CLOUD": "cloudpe" }
}
}
}
```
Then ask things like *"which VMs are down?"*, *"do I have quota for three more m1.large?"*, or *"web-03 won't accept SSH — check its console log."*
To confirm what you've wired up before trusting it, run a dry check — it prints the resolved config and exactly which tools are exposed, without serving or connecting:
```bash
openstack-mcp --check
```
```
openstack-mcp 0.1.0
cloud: cloudpe
mode: read-only
max items per list: 50
12 tools: check_capacity, cloud_info, get_console_output, get_quotas, get_server,
list_flavors, list_images, list_keypairs, list_networks, list_security_groups,
list_servers, list_volumes
```
## The safety model
Most cloud MCP servers hand an assistant the full API and hope for the best. This one is gated, because "delete the test VMs" is a sentence a model can misread.
| Environment variable | Effect |
|---|---|
| *(nothing set)* | **Read-only.** 12 inspection tools. Write tools are not registered at all — the model cannot see or call them. |
| `OPENSTACK_MCP_ALLOW_WRITE=true` | Adds `create_servers` and `power_action` (14 tools). |
| `OPENSTACK_MCP_ALLOW_DELETE=true` | Adds `delete_server` (15 tools). **Requires `ALLOW_WRITE` too** — delete-without-write is treated as a config mistake and ignored. |
| `OPENSTACK_MCP_MAX_ITEMS=50` | Caps how many items any list tool returns. |
| `OPENSTACK_MCP_CLOUD` / `OS_CLOUD` | Which `clouds.yaml` entry to use. |
Two further guardrails:
- **`delete_server` demands confirmation.** You must pass `confirm_name` matching the resolved instance's exact name. Ask it to delete `web-1` when the VM is called `web-01` and it refuses rather than guessing.
- **Tools carry MCP annotations** (`read_only_hint`, `destructive_hint`), so clients that surface risk to the user before running a tool can do so correctly.
Tool gating is enforced at registration, not by asking the model nicely — verified over a real stdio session in the test suite.
## Tools
**Read (always available)**
| Tool | Purpose |
|---|---|
| `cloud_info` | Which cloud, region, and project you're pointed at, and which operations are enabled |
| `list_servers` | Instances with status and IPs; filter by status or name substring |
| `get_server` | Full detail for one instance: flavor, image, key pair, security groups, addresses |
| `list_flavors` | Instance sizes with vCPU, RAM, disk |
| `list_images` | Bootable images |
| `list_networks` | Networks, flagging which are external |
| `list_security_groups` | Security groups and rule counts |
| `list_keypairs` | Registered SSH key pairs |
| `list_volumes` | Block storage volumes and what they're attached to |
| `get_quotas` | Compute quota usage vs limits |
| `check_capacity` | Whether N instances of a flavor fit in remaining quota, and what blocks it if not |
| `get_console_output` | Serial console log — for VMs that boot but are unreachable |
**Write (opt-in)**
| Tool | Purpose |
|---|---|
| `create_servers` | Create one or many instances; `count > 1` names them `<prefix>-01`, `-02`, … |
| `power_action` | start / stop / reboot |
| `delete_server` | Delete one instance, with name confirmation *(needs `ALLOW_DELETE`)* |
### Two design choices worth knowing
**Responses are deliberately small.** `openstacksdk` returns 60+ attributes per server. Feeding all of that to a model is slow, expensive, and buries the useful fields, so every tool returns a trimmed projection — for a server that's id, name, status, and a flattened `{network: [ips]}` map instead of nova's nested address structure.
**`check_capacity` exists so batches fail early.** Asking for eight VMs and discovering the quota ceiling on the fifth leaves a half-built mess. This reports which of instances/vCPUs/RAM binds first, before anything is created. `create_servers` also reports partial failures per instance rather than throwing away what succeeded.
## Development
```bash
git clone https://github.com/abhishekambad-leapswitch/openstack-mcp
cd openstack-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest && ruff check .
```
The suite runs entirely offline against a fake `openstacksdk` connection — no cloud, no credentials, no charges. It covers the tool gating, the trimming, quota arithmetic, partial-failure reporting, and the delete confirmation.
## Provisioning at scale
For standing up fleets declaratively rather than conversationally, see [cloudpe-terraform-bulk-vm](https://github.com/abhishekambad-leapswitch/cloudpe-terraform-bulk-vm) — Terraform for bulk VM creation on the same API.
## License
MIT
TDQS
Scored across 12 tools
Each tool targets a distinct resource or check: servers, flavors, images, networks, security groups, keypairs, volumes, quotas, and console output. Even get_quotas and check_capacity are clearly separated by descriptions: one reports usage, the other tests fit before creation. There is no meaningful overlap or ambiguity.
The vast majority of tools follow a clear list_<resource> or get_<resource> pattern, making the set predictable. The only outlier is cloud_info, which is a noun phrase rather than a verb_noun command, but it does not cause confusion.
Twelve tools is well-scoped for an OpenStack inspection and capacity-planning server. Each tool covers a distinct resource or diagnostic operation, and none feel redundant or unnecessary. The count is appropriate for the apparent purpose.
The set provides solid read-only coverage of compute, storage, network, security, and quota resources, but it has notable dead ends: check_capacity implies instance creation, yet no create_server exists, and security groups only expose rule counts rather than actual rules. For broader OpenStack management workflows, lifecycle operations and deeper network/security-group details are missing.