CircleCI

by circleci-public

Recommended SSE
86 stars
1.5k downloads
Not rated
GitHub Website

About

Manage CI/CD pipelines, debug failed builds, and optimize test suites directly from your AI agents - no terminal required. The CircleCI MCP Server is a remote server hosted by CircleCI that connects AI tools and agents

Details

Author
circleci-public
Repository
CircleCI-Public/mcp-server-circleci
GitHub stars
86
Downloads
1,498
License
Other
Transport
SSE
Categories
Developer Tools, Infrastructure, Productivity, Design, AI, Frontend, Project Management, Other, Automation
Tags
#integration

- Analyze git diffs against cursor rules for violations
- Validate and get guidance for your CircleCI configuration
- Download usage data from the CircleCI Usage API
- Identify flaky tests from test execution history
- Find jobs with underused compute resources
- Retrieve build failure logs and job test results
- Get the latest pipeline status for a branch
- List artifacts, followed projects, and component versions
- Rerun workflows from start or from the failed job
- Trigger pipelines and rollback pipelines

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name CircleCI
    Command (node, npx, python, etc.) npx
    Arguments
    • Argument 1 -y
    • Argument 2 @circleci/mcp-server-circleci@latest
    Environment
    • CIRCLECI_TOKEN your-circleci-token
    • CIRCLECI_BASE_URL https://circleci.com
    • MAX_MCP_OUTPUT_LENGTH 50000

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

> Team / centralized deployment: To run one shared remote server for your org (Kubernetes, Docker, etc.) with per-developer or shared CircleCI tokens, see Self-Managed Remote MCP Server.

<details>
<summary><strong>Cursor</strong></summary>

Prerequisites:
- CircleCI Personal API token (learn more)
- NPX: Node.js >= v18 and pnpm
- Docker: Docker

| Mode | When to use | Server setup | Client setup | CircleCI audit trail |
|------|-------------|--------------|--------------|----------------------|
| Per-user tokens (recommended) | Teams with SSO-backed Personal API Tokens | REQUIRE_REQUEST_TOKEN=true, no server PAT | Each dev forwards their PAT | Per developer |
| Shared token (interim) | Quick rollout, single service identity OK | CIRCLECI_TOKEN on server, REQUIRE_REQUEST_TOKEN=false (explicit opt-out) | No auth header needed | Single shared identity |

> Security: Request authentication is on by default in remote mode. The shared-token mode disables it (REQUIRE_REQUEST_TOKEN=false), making every caller able to act as the server's CIRCLECI_TOKEN identity with no credentials — including triggering pipelines with arbitrary config. Only enable it on a network you fully trust, and prefer per-user tokens otherwise. Terminating TLS at an ingress provides encryption, not authentication.
>
> Because that combination is unsafe on a public interface, the server refuses to start when REQUIRE_REQUEST_TOKEN=false is combined with a non-loopback bind address, unless you explicitly accept the risk with MCP_ALLOW_UNAUTHENTICATED_NETWORK_ACCESS=true. The Host/Origin check is not a substitute for authentication — see DNS-rebinding protection below.

Both modes use remote HTTP mode (start=remote). Publish port 8000 (or your chosen port).

Per-user tokens (recommended) — accessed via mcp-remote from localhost:

docker run --rm -p 8000:8000 \
  -e start=remote \
  -e port=8000 \
  -e REQUIRE_REQUEST_TOKEN=true \
  circleci/mcp-server-circleci

Per-user tokens (recommended) — accessed via mcp-remote from a public hostname:

docker run --rm -p 8000:8000 \
  -e start=remote \
  -e port=8000 \
  -e REQUIRE_REQUEST_TOKEN=true \
  -e MCP_ALLOWED_HOSTS=my-mcp.example.com \
  circleci/mcp-server-circleci

Shared token (interim) — accessed via mcp-remote from a public hostname:

Because this mode serves the org's PAT to any caller with no credential, it must be
run only where the published port is unreachable from untrusted networks, and you
must acknowledge that explicitly or the server will refuse to start:

docker run --rm -p 8000:8000 \
  -e start=remote \
  -e port=8000 \
  -e CIRCLECI_TOKEN=your-shared-circleci-pat \
  -e REQUIRE_REQUEST_TOKEN=false \
  -e MCP_ALLOW_UNAUTHENTICATED_NETWORK_ACCESS=true \
  -e MCP_ALLOWED_HOSTS=my-mcp.example.com \
  circleci/mcp-server-circleci

Prefer putting authentication in front of the port instead — an ingress that
requires SSO, mTLS, or an API key — or switch to per-user tokens above.

Environment variables:

| Variable | Description |
|----------|-------------|
| start=remote | Starts the HTTP+SSE MCP server instead of stdio |
| port | Listening port inside the container (default: 8000) |
| REQUIRE_REQUEST_TOKEN | Reject requests without Authorization: Bearer or Circle-Token header. Defaults to required; set REQUIRE_REQUEST_TOKEN=false to allow unauthenticated requests (shared-token mode) |
| CIRCLECI_TOKEN | Shared fallback PAT for all requests when per-user headers are not sent |
| CIRCLECI_BASE_URL | Optional — required for on-prem only (default: https://circleci.com) |
| DISABLE_TELEMETRY=true | Opt out of usage metrics export |
| MCP_ALLOWED_HOSTS | Comma-separated list of additional Host header values to allow (e.g. my-mcp.example.com,my-mcp.example.com:443). Loopback hostnames are always allowed. Required for any non-loopback deployment. |
| MCP_ALLOWED_ORIGINS | Comma-separated list of additional Origin header values to allow (e.g. https://my-app.example.com). Loopback origins are always allowed. Only needed when a browser directly reaches this server (not via mcp-remote). |
| MCP_BIND_HOST | Network interface to bind to (default: 0.0.0.0). Set to 127.0.0.1 to restrict to loopback only (not compatible with Docker -p port mapping). |
| MCP_ALLOW_UNAUTHENTICATED_NETWORK_ACCESS | Required (=true) to start with REQUIRE_REQUEST_TOKEN=false on a non-loopback bind address. Acknowledges that any peer able to reach the port acts as the server's CIRCLECI_TOKEN identity without a credential. Has no effect when request tokens are required. |
| MCP_FILE_OUTPUT_ROOTS | Comma-separated list of additional directories that file-reading/writing tools may use (e.g. /srv/reports,/data/exports). The working directory, home directory and temp directory are always allowed. See the note below. |

> File output locations (applies to both stdio and remote transports): Tools that accept a filesystem path — get_build_failure_logs (outputDir), download_usage_api_data (outputDir) and find_underused_resource_classes (csvFilePath) — may only read and write inside the server's working directory, the user's home directory, and the system temp directory. Within those roots, hidden configuration directories (~/.ssh, ~/.aws, ~/.config, .git, …), node_modules and launch-agent directories are rejected, as are symlinks resolving outside the permitted roots. System directories (/etc, /usr, /bin, /System, /Library, %SystemRoot%, …) are refused unconditionally and cannot be re-enabled. Output files are never written through a symlink.
>
> If your checkout lives outside those roots — /workspace in a container, /srv, /opt, a secondary volume such as /Volumes/work — set MCP_FILE_OUTPUT_ROOTS to that directory, otherwise those paths are rejected. For a stdio server the working directory is usually already the project root, so no configuration is needed. This matters most for the remote transport, where the paths come from network clients rather than the local user.

<a name="dns-rebinding-protection-is-not-authentication"></a>

> DNS-rebinding protection (not authentication): The remote transport validates the Host header on every /mcp request. By default only loopback addresses (localhost, 127.0.0.1, [::1]) are accepted. Public deployments must set MCP_ALLOWED_HOSTS to the hostname clients use, or all /mcp requests will receive 403 Forbidden. The /ping health-check endpoint is not guarded so load-balancer probes continue to work regardless of Host.
>
> The Origin header (sent by browsers) is also validated when present. Non-browser clients such as mcp-remote never send Origin, so they are unaffected by this check.
>
> This check is not an access control and must not be relied on as one. Both headers are chosen by the caller, so any non-browser client — curl, a script, a raw socket — can send an allowed Host and omit Origin to satisfy it. Its only purpose is to stop a browser from being aimed at the server by attacker-controlled DNS, which is the DNS-rebinding threat. Authenticating callers is the job of REQUIRE_REQUEST_TOKEN (or an authenticating proxy in front of the port). Requiring an Origin header would break every legitimate CLI client while stopping no attacker.
>
> Behind a reverse proxy: If your proxy rewrites Host to the backend address (nginx's default), add proxy_set_header Host $host; to pass the original hostname through, then set MCP_ALLOWED_HOSTS to that public hostname. Alternatively, set MCP_ALLOWED_HOSTS to whatever hostname the proxy does forward.

The server accepts per-request tokens via:

- Authorization: Bearer <circleci-pat>
- Circle-Token: <circleci-pat>

If a client sends a header token, it takes precedence over CIRCLECI_TOKEN on the server.

Telemetry metrics recorded during a request are exported using the same token as that request.

Most MCP clients only support local (stdio) processes. Use mcp-remote, a third-party stdio-to-HTTP bridge, to connect them to your remote server.

> URL scheme: Use http://localhost:8000/mcp with --allow-http for local testing. In production, terminate TLS at your ingress/load balancer and use https://your-host/mcp without --allow-http.

> Windows: Avoid spaces around the colon in --header values. Put the full Bearer <token> value in an environment variable.

> Security: Examples use npx for convenience. For production or team rollouts, pin a specific version in your MCP config (for example mcp-remote@0.1.38 instead of mcp-remote). Do not use versions below 0.1.16 (CVE-2025-6514).

Each developer forwards their own CircleCI Personal API Token on every request:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "circleci-token",
      "description": "CircleCI API Token",
      "password": true
    }
  ],
  "mcpServers": {
    "circleci-mcp-server-remote": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "http://localhost:8000/mcp",
        "--allow-http",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer ${input:circleci-token}"
      }
    }
  }
}

Replace http://localhost:8000/mcp with your team's server URL. Cursor and VS Code support ${input:...} prompts; other clients can set AUTH_HEADER directly.

When the server has CIRCLECI_TOKEN set and is started with REQUIRE_REQUEST_TOKEN=false (request auth is on by default and must be explicitly disabled, and a non-loopback bind additionally requires MCP_ALLOW_UNAUTHENTICATED_NETWORK_ACCESS=true), clients do not need to send a token:

{
  "mcpServers": {
    "circleci-mcp-server-remote": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "http://localhost:8000/mcp",
        "--allow-http"
      ]
    }
  }
}

```bash

config_helper

Validate and get guidance for your CircleCI configuration.

download_usage_api_data

Download usage data from the CircleCI Usage API for a given organization, allowing flexible date input.

find_flaky_tests

Identify flaky tests by analyzing test execution history in your CircleCI project.

find_underused_resource_classes

Find jobs with underused compute resources by analyzing CircleCI usage data.

get_build_failure_logs

Retrieve detailed failure logs from CircleCI builds.

get_job_test_results

Retrieve test metadata and results for CircleCI jobs.

get_latest_pipeline_status

Get the status of the latest pipeline for a branch.

list_artifacts

List artifacts produced by a CircleCI job.

list_component_versions

List all versions for a CircleCI component in an environment.

list_followed_projects

List all CircleCI projects you're following.

rerun_workflow

Rerun a workflow from start or from the failed job.

run_pipeline

Trigger a pipeline to run.

run_rollback_pipeline

Trigger a rollback for a CircleCI project.

| Tool | Description |
|------|-------------|
| config_helper | Validate and get guidance for your CircleCI configuration |
| download_usage_api_data | Download usage data from the CircleCI Usage API |
| find_flaky_tests | Identify flaky tests by analyzing test execution history |
| find_underused_resource_classes | Find jobs with underused compute resources |
| get_build_failure_logs | Retrieve detailed failure logs from CircleCI builds |
| get_job_test_results | Retrieve test metadata and results for CircleCI jobs |
| get_latest_pipeline_status | Get the status of the latest pipeline for a branch |
| list_artifacts | List artifacts produced by a CircleCI job |
| list_component_versions | List all versions for a CircleCI component |
| list_followed_projects | List all CircleCI projects you're following |
| rerun_workflow | Rerun a workflow from start or from the failed job |
| run_pipeline | Trigger a pipeline to run |
| run_rollback_pipeline | Trigger a rollback for a project |

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "circleci": {
            "env": {
                "CIRCLECI_TOKEN": "your-circleci-token",
                "CIRCLECI_BASE_URL": "https://circleci.com",
                "MAX_MCP_OUTPUT_LENGTH": "50000"
            },
            "args": [
                "-y",
                "@circleci/mcp-server-circleci@latest"
            ],
            "command": "npx"
        }
    }
}

Linux

{
    "env": {
        "CIRCLECI_TOKEN": "your-circleci-token",
        "CIRCLECI_BASE_URL": "https://circleci.com",
        "MAX_MCP_OUTPUT_LENGTH": "50000"
    },
    "args": [
        "-y",
        "@circleci/mcp-server-circleci@latest"
    ],
    "command": "npx"
}

Macos

{
    "env": {
        "CIRCLECI_TOKEN": "your-circleci-token",
        "CIRCLECI_BASE_URL": "https://circleci.com",
        "MAX_MCP_OUTPUT_LENGTH": "50000"
    },
    "args": [
        "-y",
        "@circleci/mcp-server-circleci@latest"
    ],
    "command": "npx"
}

Windows

{
    "env": {
        "CIRCLECI_TOKEN": "your-circleci-token",
        "CIRCLECI_BASE_URL": "https://circleci.com",
        "MAX_MCP_OUTPUT_LENGTH": "50000"
    },
    "args": [
        "/c",
        "npx",
        "-y",
        "@circleci/mcp-server-circleci@latest"
    ],
    "command": "cmd"
}
> [!IMPORTANT] > **This package is deprecated. Please migrate.** > > `@circleci/mcp-server-circleci` is no longer receiving feature work. Use CircleCI's **hosted MCP server** or the **CircleCI CLI MCP** instead — see the **[CircleCI MCP overview](https://circleci.com/docs/guides/toolkit/circleci-mcp-overview/)**. > > This repository will be archived. Existing versions remain installable from npm, but running an unmaintained server that holds a CircleCI Personal API Token is not recommended. > > If you are running the **self-managed remote transport** (`start=remote`), migrate first: the hosted server is its direct replacement and removes the need to operate a network-facing service that brokers your org's token. # CircleCI MCP Server [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/CircleCI-Public/mcp-server-circleci/blob/main/LICENSE) [![CircleCI](https://dl.circleci.com/status-badge/img/gh/CircleCI-Public/mcp-server-circleci/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/CircleCI-Public/mcp-server-circleci/tree/main) [![npm](https://img.shields.io/npm/v/@circleci/mcp-server-circleci?logo=npm)](https://www.npmjs.com/package/@circleci/mcp-server-circleci) Model Context Protocol (MCP) is a [new, standardized protocol](https://modelcontextprotocol.io/introduction) for managing context between large language models (LLMs) and external systems. In this repository, we provide an MCP Server for [CircleCI](https://circleci.com). Use Cursor, Windsurf, Copilot, Claude, or any MCP-compatible client to interact with CircleCI using natural language — without leaving your IDE. ## Tools | Tool | Description | |------|-------------| | [`config_helper`](#config_helper) | Validate and get guidance for your CircleCI configuration | | [`download_usage_api_data`](#download_usage_api_data) | Download usage data from the CircleCI Usage API | | [`find_flaky_tests`](#find_flaky_tests) | Identify flaky tests by analyzing test execution history | | [`find_underused_resource_classes`](#find_underused_resource_classes) | Find jobs with underused compute resources | | [`get_build_failure_logs`](#get_build_failure_logs) | Retrieve detailed failure logs from CircleCI builds | | [`get_job_test_results`](#get_job_test_results) | Retrieve test metadata and results for CircleCI jobs | | [`get_latest_pipeline_status`](#get_latest_pipeline_status) | Get the status of the latest pipeline for a branch | | [`list_artifacts`](#list_artifacts) | List artifacts produced by a CircleCI job | | [`list_component_versions`](#list_component_versions) | List all versions for a CircleCI component | | [`list_followed_projects`](#list_followed_projects) | List all CircleCI projects you're following | | [`rerun_workflow`](#rerun_workflow) | Rerun a workflow from start or from the failed job | | [`run_pipeline`](#run_pipeline) | Trigger a pipeline to run | | [`run_rollback_pipeline`](#run_rollback_pipeline) | Trigger a rollback for a project | ## Installation > **Team / centralized deployment:** To run one shared remote server for your org (Kubernetes, Docker, etc.) with per-developer or shared CircleCI tokens, see [Self-Managed Remote MCP Server](#self-managed-remote-mcp-server). <details> <summary><strong>Cursor</strong></summary> **Prerequisites:** - [CircleCI Personal API token](https://app.circleci.com/settings/user/tokens) ([learn more](https://circleci.com/docs/managing-api-tokens/)) - NPX: [Node.js >= v18](https://nodejs.org/) and [pnpm](https://pnpm.io/installation) - Docker: [Docker](https://docs.docker.com/get-docker/) #### Using NPX in a local MCP Server Add the following to your Cursor MCP config: ```json { "mcpServers": { "circleci-mcp-server": { "command": "npx", "args": ["-y", "@circleci/mcp-server-circleci@latest"], "env": { "CIRCLECI_TOKEN": "your-circleci-token", "CIRCLECI_BASE_URL": "https://circleci.com", "MAX_MCP_OUTPUT_LENGTH": "50000" } } } } ``` > `CIRCLECI_BASE_URL` is optional — required for on-prem customers only. > `MAX_MCP_OUTPUT_LENGTH` is optional — maximum output length for MCP responses (default: 50000). #### Using Docker in a local MCP Server Add the following to your Cursor MCP config: ```json { "mcpServers": { "circleci-mcp-server": { "command": "docker", "args": [ "run", "--rm", "-i", "-e", "CIRCLECI_TOKEN", "-e", "CIRCLECI_BASE_URL", "-e", "MAX_MCP_OUTPUT_LENGTH", "circleci/mcp-server-circleci" ], "env": { "CIRCLECI_TOKEN": "your-circleci-token", "CIRCLECI_BASE_URL": "https://circleci.com", "MAX_MCP_OUTPUT_LENGTH": "50000" } } } } ``` #### Using a Self-Managed Remote MCP Server See [Self-Managed Remote MCP Server](#self-managed-remote-mcp-server). Use the [per-user client configuration](#client-configuration-per-user-tokens) and add it to your Cursor MCP config (`Cursor Settings → MCP`). </details> <details> <summary><strong>VS Code</strong></summary> **Prerequisites:** - [CircleCI Personal API token](https://app.circleci.com/settings/user/tokens) ([learn more](https://circleci.com/docs/managing-api-tokens/)) - NPX: [Node.js >= v18](https://nodejs.org/) and [pnpm](https://pnpm.io/installation) - Docker: [Docker](https://docs.docker.com/get-docker/) #### Using NPX in a local MCP Server Add the following to `.vscode/mcp.json` in your project: ```json { "inputs": [ { "type": "promptString", "id": "circleci-token", "description": "CircleCI API Token", "password": true }, { "type": "promptString", "id": "circleci-base-url", "description": "CircleCI Base URL", "default": "https://circleci.com" } ], "servers": { "circleci-mcp-server": { "type": "stdio", "command": "npx", "args": ["-y", "@circleci/mcp-server-circleci@latest"], "env": { "CIRCLECI_TOKEN": "${input:circleci-token}", "CIRCLECI_BASE_URL": "${input:circleci-base-url}" } } } } ``` > 💡 Inputs are prompted on first server start, then stored securely by VS Code. #### Using Docker in a local MCP Server Add the following to `.vscode/mcp.json` in your project: ```json { "inputs": [ { "type": "promptString", "id": "circleci-token", "description": "CircleCI API Token", "password": true }, { "type": "promptString", "id": "circleci-base-url", "description": "CircleCI Base URL", "default": "https://circleci.com" } ], "servers": { "circleci-mcp-server": { "type": "stdio", "command": "docker", "args": [ "run", "--rm", "-i", "-e", "CIRCLECI_TOKEN", "-e", "CIRCLECI_BASE_URL", "circleci/mcp-server-circleci" ], "env": { "CIRCLECI_TOKEN": "${input:circleci-token}", "CIRCLECI_BASE_URL": "${input:circleci-base-url}" } } } } ``` #### Using a Self-Managed Remote MCP Server See [Self-Managed Remote MCP Server](#self-managed-remote-mcp-server). Use the [per-user client configuration](#client-configuration-per-user-tokens) in `.vscode/mcp.json`. </details> <details> <summary><strong>Claude Desktop</strong></summary> **Prerequisites:** - [CircleCI Personal API token](https://app.circleci.com/settings/user/tokens) ([learn more](https://circleci.com/docs/managing-api-tokens/)) - NPX: [Node.js >= v18](https://nodejs.org/) and [pnpm](https://pnpm.io/installation) - Docker: [Docker](https://docs.docker.com/get-docker/) #### Using NPX in a local MCP Server Add the following to your `claude_desktop_config.json`: ```json { "mcpServers": { "circleci-mcp-server": { "command": "npx", "args": ["-y", "@circleci/mcp-server-circleci@latest"], "env": { "CIRCLECI_TOKEN": "your-circleci-token", "CIRCLECI_BASE_URL": "https://circleci.com", "MAX_MCP_OUTPUT_LENGTH": "50000" } } } } ``` #### Using Docker in a local MCP Server Add the following to your `claude_desktop_config.json`: ```json { "mcpServers": { "circleci-mcp-server": { "command": "docker", "args": [ "run", "--rm", "-i", "-e", "CIRCLECI_TOKEN", "-e", "CIRCLECI_BASE_URL", "-e", "MAX_MCP_OUTPUT_LENGTH", "circleci/mcp-server-circleci" ], "env": { "CIRCLECI_TOKEN": "your-circleci-token", "CIRCLECI_BASE_URL": "https://circleci.com", "MAX_MCP_OUTPUT_LENGTH": "50000" } } } } ``` #### Using a Self-Managed Remote MCP Server See [Self-Managed Remote MCP Server](#self-managed-remote-mcp-server). Create a wrapper script as shown in [Claude Desktop and CLI clients](#claude-desktop-and-cli-clients), then point your `claude_desktop_config.json` at it. To find or create your config file, open Claude Desktop settings, click **Developer** in the left sidebar, then click **Edit Config**. The config file is located at: - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` - Windows: `%APPDATA%\Claude\claude_desktop_config.json` For more information: https://modelcontextprotocol.io/quickstart/user </details> <details> <summary><strong>Claude Code</strong></summary> **Prerequisites:** - [CircleCI Personal API token](https://app.circleci.com/settings/user/tokens) ([learn more](https://circleci.com/docs/managing-api-tokens/)) - NPX: [Node.js >= v18](https://nodejs.org/) and [pnpm](https://pnpm.io/installation) - Docker: [Docker](https://docs.docker.com/get-docker/) #### Using NPX in a local MCP Server ```bash claude mcp add circleci-mcp-server -e CIRCLECI_TOKEN=your-circleci-token -- npx -y @circleci/mcp-server-circleci@latest ``` #### Using Docker in a local MCP Server ```bash claude mcp add circleci-mcp-server -e CIRCLECI_TOKEN=your-circleci-token -e CIRCLECI_BASE_URL=https://circleci.com -- docker run --rm -i -e CIRCLECI_TOKEN -e CIRCLECI_BASE_URL circleci/mcp-server-circleci ``` #### Using a Self-Managed Remote MCP Server See [Self-Managed Remote MCP Server](#self-managed-remote-mcp-server) and the [Claude Code](#claude-code) client setup there. </details> <details> <summary><strong>Windsurf</strong></summary> **Prerequisites:** - [CircleCI Personal API token](https://app.circleci.com/settings/user/tokens) ([learn more](https://circleci.com/docs/managing-api-tokens/)) - NPX: [Node.js >= v18](https://nodejs.org/) and [pnpm](https://pnpm.io/installation) - Docker: [Docker](https://docs.docker.com/get-docker/) #### Using NPX in a local MCP Server Add the following to your Windsurf `mcp_config.json`: ```json { "mcpServers": { "circleci-mcp-server": { "command": "npx", "args": ["-y", "@circleci/mcp-server-circleci@latest"], "env": { "CIRCLECI_TOKEN": "your-circleci-token", "CIRCLECI_BASE_URL": "https://circleci.com", "MAX_MCP_OUTPUT_LENGTH": "50000" } } } } ``` #### Using Docker in a local MCP Server Add the following to your Windsurf `mcp_config.json`: ```json { "mcpServers": { "circleci-mcp-server": { "command": "docker", "args": [ "run", "--rm", "-i", "-e", "CIRCLECI_TOKEN", "-e", "CIRCLECI_BASE_URL", "-e", "MAX_MCP_OUTPUT_LENGTH", "circleci/mcp-server-circleci" ], "env": { "CIRCLECI_TOKEN": "your-circleci-token", "CIRCLECI_BASE_URL": "https://circleci.com", "MAX_MCP_OUTPUT_LENGTH": "50000" } } } } ``` #### Using a Self-Managed Remote MCP Server See [Self-Managed Remote MCP Server](#self-managed-remote-mcp-server). Use the [per-user client configuration](#client-configuration-per-user-tokens) in your Windsurf `mcp_config.json`. For more information: https://docs.windsurf.com/windsurf/mcp </details> <details> <summary><strong>Amazon Q Developer CLI</strong></summary> **Prerequisites:** - [CircleCI Personal API token](https://app.circleci.com/settings/user/tokens) ([learn more](https://circleci.com/docs/managing-api-tokens/)) - NPX: [Node.js >= v18](https://nodejs.org/) and [pnpm](https://pnpm.io/installation) MCP client configuration in Amazon Q Developer is stored in JSON format in a file named `mcp.json`. Two levels of configuration are supported: - **Global:** `~/.aws/amazonq/mcp.json` — applies to all workspaces - **Workspace:** `.amazonq/mcp.json` — specific to the current workspace If both files exist, their contents are merged. In case of conflict, the workspace config takes precedence. #### Using NPX in a local MCP Server Edit `~/.aws/amazonq/mcp.json` or create `.amazonq/mcp.json` with the following: ```json { "mcpServers": { "circleci-local": { "command": "npx", "args": [ "-y", "@circleci/mcp-server-circleci@latest" ], "env": { "CIRCLECI_TOKEN": "YOUR_CIRCLECI_TOKEN", "CIRCLECI_BASE_URL": "https://circleci.com", "MAX_MCP_OUTPUT_LENGTH": "50000" }, "timeout": 60000 } } } ``` #### Using a Self-Managed Remote MCP Server See [Self-Managed Remote MCP Server](#self-managed-remote-mcp-server). Use a wrapper script as shown in [Claude Desktop and CLI clients](#claude-desktop-and-cli-clients), then register it with `q mcp add`. </details> <details> <summary><strong>Amazon Q Developer in the IDE</strong></summary> **Prerequisites:** - [CircleCI Personal API token](https://app.circleci.com/settings/user/tokens) ([learn more](https://circleci.com/docs/managing-api-tokens/)) - NPX: [Node.js >= v18](https://nodejs.org/) and [pnpm](https://pnpm.io/installation) #### Using NPX in a local MCP Server Edit `~/.aws/amazonq/mcp.json` or create `.amazonq/mcp.json` with the following: ```json { "mcpServers": { "circleci-local": { "command": "npx", "args": [ "-y", "@circleci/mcp-server-circleci@latest" ], "env": { "CIRCLECI_TOKEN": "YOUR_CIRCLECI_TOKEN", "CIRCLECI_BASE_URL": "https://circleci.com", "MAX_MCP_OUTPUT_LENGTH": "50000" }, "timeout": 60000 } } } ``` #### Using a Self-Managed Remote MCP Server See [Self-Managed Remote MCP Server](#self-managed-remote-mcp-server). Use a wrapper script as shown in [Claude Desktop and CLI clients](#claude-desktop-and-cli-clients), then add it via the MCP configuration UI: 1. [Access the MCP configuration UI](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/mcp-ide.html#mcp-ide-configuration-access-ui) 2. Choose the **+** symbol 3. Select scope: **global** or **local** 4. Enter a name (e.g. `circleci-remote-mcp`) 5. Select transport protocol: **stdio** 6. Enter the command path to your script 7. Click **Save** </details> <details> <summary><strong>Smithery</strong></summary> To install CircleCI MCP Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@CircleCI-Public/mcp-server-circleci): ```bash npx -y @smithery/cli install @CircleCI-Public/mcp-server-circleci --client claude ``` </details> ## Self-Managed Remote MCP Server Run the MCP server centrally (for example on Kubernetes or Docker) so your team shares one deployment. Choose how developers authenticate: ### Choose a deployment mode | Mode | When to use | Server setup | Client setup | CircleCI audit trail | |------|-------------|--------------|--------------|----------------------| | **Per-user tokens** (recommended) | Teams with SSO-backed Personal API Tokens | `REQUIRE_REQUEST_TOKEN=true`, no server PAT | Each dev forwards their PAT | Per developer | | **Shared token** (interim) | Quick rollout, single service identity OK | `CIRCLECI_TOKEN` on server, `REQUIRE_REQUEST_TOKEN=false` (explicit opt-out) | No auth header needed | Single shared identity | > **Security:** Request authentication is **on by default** in remote mode. The shared-token mode disables it (`REQUIRE_REQUEST_TOKEN=false`), making every caller able to act as the server's `CIRCLECI_TOKEN` identity with no credentials — including triggering pipelines with arbitrary config. Only enable it on a network you fully trust, and prefer per-user tokens otherwise. Terminating TLS at an ingress provides encryption, not authentication. > > Because that combination is unsafe on a public interface, the server **refuses to start** when `REQUIRE_REQUEST_TOKEN=false` is combined with a non-loopback bind address, unless you explicitly accept the risk with `MCP_ALLOW_UNAUTHENTICATED_NETWORK_ACCESS=true`. The `Host`/`Origin` check is *not* a substitute for authentication — see [DNS-rebinding protection](#dns-rebinding-protection-is-not-authentication) below. ### 1. Deploy the server Both modes use remote HTTP mode (`start=remote`). Publish port `8000` (or your chosen port). **Per-user tokens (recommended) — accessed via `mcp-remote` from localhost:** ```bash docker run --rm -p 8000:8000 \ -e start=remote \ -e port=8000 \ -e REQUIRE_REQUEST_TOKEN=true \ circleci/mcp-server-circleci ``` **Per-user tokens (recommended) — accessed via `mcp-remote` from a public hostname:** ```bash docker run --rm -p 8000:8000 \ -e start=remote \ -e port=8000 \ -e REQUIRE_REQUEST_TOKEN=true \ -e MCP_ALLOWED_HOSTS=my-mcp.example.com \ circleci/mcp-server-circleci ``` **Shared token (interim) — accessed via `mcp-remote` from a public hostname:** Because this mode serves the org's PAT to any caller with no credential, it must be run only where the published port is unreachable from untrusted networks, and you must acknowledge that explicitly or the server will refuse to start: ```bash docker run --rm -p 8000:8000 \ -e start=remote \ -e port=8000 \ -e CIRCLECI_TOKEN=your-shared-circleci-pat \ -e REQUIRE_REQUEST_TOKEN=false \ -e MCP_ALLOW_UNAUTHENTICATED_NETWORK_ACCESS=true \ -e MCP_ALLOWED_HOSTS=my-mcp.example.com \ circleci/mcp-server-circleci ``` Prefer putting authentication in front of the port instead — an ingress that requires SSO, mTLS, or an API key — or switch to per-user tokens above. **Environment variables:** | Variable | Description | |----------|-------------| | `start=remote` | Starts the HTTP+SSE MCP server instead of stdio | | `port` | Listening port inside the container (default: `8000`) | | `REQUIRE_REQUEST_TOKEN` | Reject requests without `Authorization: Bearer` or `Circle-Token` header. Defaults to required; set `REQUIRE_REQUEST_TOKEN=false` to allow unauthenticated requests (shared-token mode) | | `CIRCLECI_TOKEN` | Shared fallback PAT for all requests when per-user headers are not sent | | `CIRCLECI_BASE_URL` | Optional — required for on-prem only (default: `https://circleci.com`) | | `DISABLE_TELEMETRY=true` | Opt out of usage metrics export | | `MCP_ALLOWED_HOSTS` | Comma-separated list of additional `Host` header values to allow (e.g. `my-mcp.example.com,my-mcp.example.com:443`). Loopback hostnames are always allowed. Required for any non-loopback deployment. | | `MCP_ALLOWED_ORIGINS` | Comma-separated list of additional `Origin` header values to allow (e.g. `https://my-app.example.com`). Loopback origins are always allowed. Only needed when a browser directly reaches this server (not via `mcp-remote`). | | `MCP_BIND_HOST` | Network interface to bind to (default: `0.0.0.0`). Set to `127.0.0.1` to restrict to loopback only (not compatible with Docker `-p` port mapping). | | `MCP_ALLOW_UNAUTHENTICATED_NETWORK_ACCESS` | Required (`=true`) to start with `REQUIRE_REQUEST_TOKEN=false` on a non-loopback bind address. Acknowledges that any peer able to reach the port acts as the server's `CIRCLECI_TOKEN` identity without a credential. Has no effect when request tokens are required. | | `MCP_FILE_OUTPUT_ROOTS` | Comma-separated list of additional directories that file-reading/writing tools may use (e.g. `/srv/reports,/data/exports`). The working directory, home directory and temp directory are always allowed. See the note below. | > **File output locations (applies to both stdio and remote transports):** Tools that accept a filesystem path — `get_build_failure_logs` (`outputDir`), `download_usage_api_data` (`outputDir`) and `find_underused_resource_classes` (`csvFilePath`) — may only read and write inside the server's working directory, the user's home directory, and the system temp directory. Within those roots, hidden configuration directories (`~/.ssh`, `~/.aws`, `~/.config`, `.git`, …), `node_modules` and launch-agent directories are rejected, as are symlinks resolving outside the permitted roots. System directories (`/etc`, `/usr`, `/bin`, `/System`, `/Library`, `%SystemRoot%`, …) are refused unconditionally and cannot be re-enabled. Output files are never written through a symlink. > > If your checkout lives outside those roots — `/workspace` in a container, `/srv`, `/opt`, a secondary volume such as `/Volumes/work` — set `MCP_FILE_OUTPUT_ROOTS` to that directory, otherwise those paths are rejected. For a stdio server the working directory is usually already the project root, so no configuration is needed. This matters most for the remote transport, where the paths come from network clients rather than the local user. <a name="dns-rebinding-protection-is-not-authentication"></a> > **DNS-rebinding protection (not authentication):** The remote transport validates the `Host` header on every `/mcp` request. By default only loopback addresses (`localhost`, `127.0.0.1`, `[::1]`) are accepted. **Public deployments must set `MCP_ALLOWED_HOSTS`** to the hostname clients use, or all `/mcp` requests will receive `403 Forbidden`. The `/ping` health-check endpoint is not guarded so load-balancer probes continue to work regardless of `Host`. > > The `Origin` header (sent by browsers) is also validated when present. Non-browser clients such as `mcp-remote` never send `Origin`, so they are unaffected by this check. > > **This check is not an access control and must not be relied on as one.** Both headers are chosen by the caller, so any non-browser client — curl, a script, a raw socket — can send an allowed `Host` and omit `Origin` to satisfy it. Its only purpose is to stop a *browser* from being aimed at the server by attacker-controlled DNS, which is the DNS-rebinding threat. Authenticating callers is the job of `REQUIRE_REQUEST_TOKEN` (or an authenticating proxy in front of the port). Requiring an `Origin` header would break every legitimate CLI client while stopping no attacker. > > **Behind a reverse proxy:** If your proxy rewrites `Host` to the backend address (nginx's default), add `proxy_set_header Host $host;` to pass the original hostname through, then set `MCP_ALLOWED_HOSTS` to that public hostname. Alternatively, set `MCP_ALLOWED_HOSTS` to whatever hostname the proxy does forward. The server accepts per-request tokens via: - `Authorization: Bearer <circleci-pat>` - `Circle-Token: <circleci-pat>` If a client sends a header token, it takes precedence over `CIRCLECI_TOKEN` on the server. Telemetry metrics recorded during a request are exported using the same token as that request. ### 2. Configure clients Most MCP clients only support local (stdio) processes. Use [`mcp-remote`](https://www.npmjs.com/package/mcp-remote), a third-party stdio-to-HTTP bridge, to connect them to your remote server. > **URL scheme:** Use `http://localhost:8000/mcp` with `--allow-http` for local testing. In production, terminate TLS at your ingress/load balancer and use `https://your-host/mcp` without `--allow-http`. > **Windows:** Avoid spaces around the colon in `--header` values. Put the full `Bearer <token>` value in an environment variable. > **Security:** Examples use `npx` for convenience. For production or team rollouts, pin a specific version in your MCP config (for example `mcp-remote@0.1.38` instead of `mcp-remote`). Do not use versions below `0.1.16` ([CVE-2025-6514](https://www.npmjs.com/package/mcp-remote)). #### Client configuration: per-user tokens Each developer forwards their own CircleCI Personal API Token on every request: ```json { "inputs": [ { "type": "promptString", "id": "circleci-token", "description": "CircleCI API Token", "password": true } ], "mcpServers": { "circleci-mcp-server-remote": { "command": "npx", "args": [ "-y", "mcp-remote", "http://localhost:8000/mcp", "--allow-http", "--header", "Authorization:${AUTH_HEADER}" ], "env": { "AUTH_HEADER": "Bearer ${input:circleci-token}" } } } } ``` Replace `http://localhost:8000/mcp` with your team's server URL. Cursor and VS Code support `${input:...}` prompts; other clients can set `AUTH_HEADER` directly. #### Client configuration: shared token When the server has `CIRCLECI_TOKEN` set and is started with `REQUIRE_REQUEST_TOKEN=false` (request auth is on by default and must be explicitly disabled, and a non-loopback bind additionally requires `MCP_ALLOW_UNAUTHENTICATED_NETWORK_ACCESS=true`), clients do not need to send a token: ```json { "mcpServers": { "circleci-mcp-server-remote": { "command": "npx", "args": [ "-y", "mcp-remote", "http://localhost:8000/mcp", "--allow-http" ] } } } ``` #### Claude Desktop and CLI clients Create a wrapper script (e.g. `circleci-remote-mcp.sh`): ```bash #!/bin/bash export AUTH_HEADER="Bearer your-circleci-token" npx mcp-remote http://localhost:8000/mcp --allow-http --header "Authorization:${AUTH_HEADER}" ``` Make it executable (`chmod +x circleci-remote-mcp.sh`), then reference it from your MCP config: ```json { "mcpServers": { "circleci-remote-mcp-server": { "command": "/full/path/to/circleci-remote-mcp.sh" } } } ``` #### Claude Code ```bash claude mcp add circleci-mcp-server \ -e AUTH_HEADER="Bearer your-circleci-token" \ -- npx mcp-remote http://localhost:8000/mcp --allow-http --header "Authorization:${AUTH_HEADER}" ``` Omit `--header` and `AUTH_HEADER` when using a [shared-token server](#1-deploy-the-server). ### 3. Verify the deployment ```bash # Health check (no auth required) curl http://localhost:8000/ping # Should return 401 when REQUIRE_REQUEST_TOKEN=true and no token is sent curl -s -o /dev/null -w "%{http_code}\n" -X POST http://localhost:8000/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' # Should return 200 with a valid Bearer token and MCP Accept headers curl -s -o /dev/null -w "%{http_code}\n" -X POST http://localhost:8000/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer your-circleci-pat" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' ``` ## Demo <details> <summary><strong>Watch it in action</strong></summary>
No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.