CP

circleci-public/mcp-server-circleci

Developer tools
94 stars 63 forks Quality 81 Trend 29NOASSERTION

@circleci/mcp-server-circleci is no longer receiving feature work. Use CircleCI's or the instead — see the . This repository will be archived.

Overview

@circleci/mcp-server-circleci is no longer receiving feature work. Use CircleCI's or the instead — see the . This repository will be archived.

README

[!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.

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

Model Context Protocol (MCP) is a new, standardized protocol for managing context between large language models (LLMs) and external systems. In this repository, we provide an MCP Server for CircleCI.

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 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

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

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 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:

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.

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
  • Circle-Token:

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, 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 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 [email protected] instead of mcp-remote). Do not use versions below 0.1.16 (CVE-2025-6514).

Client configuration: per-user tokens

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.

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:

{
  "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):

#!/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:

{
  "mcpServers": {
    "circleci-remote-mcp-server": {
      "command": "/full/path/to/circleci-remote-mcp.sh"
    }
  }
}

Claude Code

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.

3. Verify the deployment

# 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

Tool Details

Troubleshooting

Telemetry

The server supports OpenTelemetry metrics for tracking tool usage. Metrics are exported unless you set DISABLE_TELEMETRY=true. On remote deployments, metrics use the same token as the request (per-user PAT or shared server PAT).

Metric Description
circleci.mcp.tool.invocations Tool invocation count
circleci.mcp.tool.duration_ms Execution time in ms
circleci.mcp.tool.errors Error count

Development

Getting Started

  1. Clone the repository:

    git clone https://github.com/CircleCI-Public/mcp-server-circleci.git
    cd mcp-server-circleci
    
  2. Install dependencies:

    pnpm install
    
  3. Build the project:

    pnpm build
    

Building Docker Container

You can build the Docker container locally using:

docker build -t circleci:mcp-server-circleci .

This will create a Docker image tagged as circleci:mcp-server-circleci that you can use with any MCP client.

Local stdio mode (single developer, token on the client):

docker run --rm -i \
  -e CIRCLECI_TOKEN=your-circleci-token \
  -e CIRCLECI_BASE_URL=https://circleci.com \
  circleci/mcp-server-circleci

Remote mode (centralized server for a team): see Self-Managed Remote MCP Server.

Development with MCP Inspector

The easiest way to iterate on the MCP Server is using the MCP inspector. You can learn more about the MCP inspector at https://modelcontextprotocol.io/docs/tools/inspector

  1. Start the development server:

    pnpm watch # Keep this running in one terminal
    
  2. In a separate terminal, launch the inspector:

    pnpm inspector
    
  3. Configure the environment:

    • Add your CIRCLECI_TOKEN to the Environment Variables section in the inspector UI
    • The token needs read access to your CircleCI projects
    • Optionally set your CircleCI Base URL (defaults to https://circleci.com)

Testing

  • Run the test suite:

    pnpm test
    
  • Run tests in watch mode during development:

    pnpm test:watch
    

For more detailed contribution guidelines, see CONTRIBUTING.md

View the full README on GitHub

Install

npx -y @circleci/mcp-server-circleci@latest
New to MCP? Start with the mcpskill.org guide →

Configuration

{ "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" } } } }