# spinnaker-mcp

![spinnaker-mcp, painted on the bow of a ship's hull, with the tagline: Drive Spinnaker pipelines from your AI agent](<https://geiserx.github.io/spinnaker-mcp/images/banner.svg>)

[![Docker Pulls](<https://img.shields.io/docker/pulls/drumsergio/spinnaker-mcp?style=flat-square&amp;logo=docker>)](<https://hub.docker.com/r/drumsergio/spinnaker-mcp>) [![GitHub Stars](<https://img.shields.io/github/stars/GeiserX/spinnaker-mcp?style=flat-square&amp;logo=github>)](<https://github.com/GeiserX/spinnaker-mcp/stargazers>) [![Release](<https://img.shields.io/github/v/release/GeiserX/spinnaker-mcp?style=flat-square>)](<https://github.com/GeiserX/spinnaker-mcp/releases>) [![License: GPL-3.0-or-later](<https://img.shields.io/github/license/GeiserX/spinnaker-mcp?style=flat-square>)](<https://github.com/GeiserX/spinnaker-mcp/blob/main/LICENSE>)

---

**spinnaker-mcp** connects Claude, Cursor or any other MCP client to a [Spinnaker](<https://spinnaker.io/>) instance through its Gate API. Ask in plain words which executions of an application failed today and at which stage, what a stage returned, or what changed in a pipeline since its last revision; if you allow it, the assistant can also trigger, pause, resume or cancel the pipeline. Without it, the same answers mean opening each execution and stage in Deck, Spinnaker's UI, one at a time. It is one Go binary with 38 tools, 10 resources and 5 prompts, and by default it registers only the 27 tools that read. Start with [Getting started](<https://geiserx.github.io/spinnaker-mcp/getting-started/index.md>), then [Usage](<https://geiserx.github.io/spinnaker-mcp/usage/index.md>) for everything the assistant can read and do.

- **[Getting started](<https://geiserx.github.io/spinnaker-mcp/getting-started/index.md>)**

  ---

  npm, Docker, Helm or a local build, and what each needs from your Gate.
- **[Connect your client](<https://geiserx.github.io/spinnaker-mcp/getting-started/#claude-code-claude-desktop-configuration>)**

  ---

  The `mcpServers` block for Claude Code, Claude Desktop and Cursor, with your Gate URL and token.
- **[Usage](<https://geiserx.github.io/spinnaker-mcp/usage/index.md>)**

  ---

  The 38 tools, which of them change Spinnaker, the 10 resources and the 5 prompts.
- **[Configuration](<https://geiserx.github.io/spinnaker-mcp/configuration/index.md>)**

  ---

  Every environment variable with its default, the toolsets, and the HTTP endpoints.

## What the assistant sees

![MCP Inspector connected to spinnaker-mcp started with TOOLSETS=readonly: the tool list holds only read tools, and search\_executions is selected with its application, trigger type, status and time-range arguments](<https://geiserx.github.io/spinnaker-mcp/images/screenshots/tools-readonly.png>)

By default the client is offered 27 tools and none of them can change Spinnaker. The resources give it the applications and accounts to start from (`spinnaker://applications`, `spinnaker://application/{name}/executions`), and the tools go deeper: an execution's stages and outputs, a cluster's server groups, an instance's console output. The full list is on [Usage](<https://geiserx.github.io/spinnaker-mcp/usage/index.md>).

![MCP Inspector, Prompts tab: the five spinnaker-mcp prompts, with incident-response selected and its application and execution\_id arguments](<https://geiserx.github.io/spinnaker-mcp/images/screenshots/prompts.png>)

The five prompts are ready-made requests a client can offer as commands: review a pipeline before it runs, investigate a failed execution, audit a pipeline, summarise an application's infrastructure, and plan a rollback.

## Read versus act

- 27 tools only read. `evaluate_expression` sends a SpEL expression to Gate in a POST and changes nothing; it is marked read-only too.
- 11 tools change Spinnaker: `trigger_pipeline`, `judge_stage`, `save_pipeline`, `update_pipeline`, `delete_pipeline`, `cancel_execution`, `pause_execution`, `resume_execution`, `restart_stage`, `save_strategy` and `delete_strategy`. All but pause and resume are marked destructive, so a client that reads MCP tool annotations can ask before them.
- With no `TOOLSETS` only the 27 are registered. `TOOLSETS=all` adds the 11; groups such as `pipelines,executions` pick tools by area instead. See [Toolsets](<https://geiserx.github.io/spinnaker-mcp/configuration/#toolsets>).
- The resources and prompts are always registered. Resources only read; a prompt returns text and calls nothing by itself.

## How it runs

```
flowchart LR
    C[MCP client<br/>Claude Code, Claude Desktop, Cursor]
    S[spinnaker-mcp<br/>one Go binary]
    G[Spinnaker Gate<br/>port 8084]
    SP[Spinnaker services]
    C <-->|MCP over stdio,<br/>or HTTP on /mcp| S
    S <-->|HTTP, token, basic auth,<br/>session cookie or x509 client cert| G
    G <--> SP
```

- Over stdio the client starts the binary itself. `npx -y spinnaker-mcp` downloads the binary for your platform and runs it that way, and the Docker image defaults to stdio too.
- Over HTTP the binary serves `/mcp`, `/healthz` and `/readyz` on `127.0.0.1:8085`. The Helm chart runs it this way in a pod. See [HTTP transport](<https://geiserx.github.io/spinnaker-mcp/configuration/#http-transport>).
- Every call runs as the Gate identity you configure: a bearer token first, then basic auth, then the session cookie `spinnaker-mcp login` stores for a Gate behind SSO, with an x509 client certificate on top when configured. Spinnaker's own access rules apply to that identity.
- Binaries for Linux, macOS and Windows on amd64 and arm64, the npm package `spinnaker-mcp`, the Docker image `drumsergio/spinnaker-mcp` and a Helm chart in the repository, all at one version. Install paths are on [Getting started](<https://geiserx.github.io/spinnaker-mcp/getting-started/index.md>).

## What it does not do

- It has no user accounts. Over HTTP every `/mcp` request needs the one bearer token in `MCP_AUTH_TOKEN` (required whenever it listens beyond `127.0.0.1`, and by the Helm chart), and whoever holds that token acts with the Gate credentials the server holds.
- It does not add permissions. It can do what its Gate identity can do in Spinnaker, and nothing more.
- It does not cover all of Gate. The 38 tools are the pipeline, execution, strategy and infrastructure calls; what comes next is on the [roadmap](<https://github.com/GeiserX/spinnaker-mcp/blob/main/ROADMAP.md>).
- It stores nothing. There is no database and no cache; every tool reads Gate when it is called.

## Getting help

- `/readyz` answers 503 with `"gate_reachable": false`: the server cannot reach `GATE_URL`. A 200 only proves Gate answered; a wrong token still passes it. See [HTTP transport](<https://geiserx.github.io/spinnaker-mcp/configuration/#http-transport>).
- The server exits at start with `Invalid toolsets`: `all`, `readonly` or `mutating` was combined with another value. See [Toolsets](<https://geiserx.github.io/spinnaker-mcp/configuration/#toolsets>).
- Something else: open an [issue](<https://github.com/GeiserX/spinnaker-mcp/issues>) with the server's log lines. A security problem goes through the [security policy](<https://github.com/GeiserX/spinnaker-mcp/blob/main/SECURITY.md>), never a public issue.
- Running the tests and trying the server in MCP Inspector: [Development](<https://geiserx.github.io/spinnaker-mcp/development/index.md>). The other MCP servers in the family and where this one is listed: [Related projects](<https://geiserx.github.io/spinnaker-mcp/related/index.md>).

## License

spinnaker-mcp is released under the [GPL-3.0-or-later](<https://github.com/GeiserX/spinnaker-mcp/blob/main/LICENSE>) license. It is built on [mcp-go](<https://github.com/mark3labs/mcp-go>).
