Buildkite MCP Server logo

Buildkite MCP Server

by Drew-Goddyn

A microservice for retrieving information from Buildkite via Model Context Protocol (MCP). It allows you to query Buildkite data such as organizations, pipelines, builds, and jobs.

View on GitHub

Last updated: N/A

Buildkite MCP Server

A microservice for retrieving information from Buildkite via Model Context Protocol (MCP).

Setup

  1. Clone this repository
  2. Run npm install
  3. Set the BUILDKITE_ACCESS_TOKEN environment variable
  4. Start the server with node index.js

Using with Cursor (MCP Integration)

To add this server to Cursor, you need to configure it in your ~/.cursor/config/mcp.json file:

{
  "mcpServers": {
    "buildkite": {
      "command": "npx",
      "args": [
        "-y",
        "@drew-goddyn/buildkite-mcp"
      ],
      "env": {
        "BUILDKITE_ACCESS_TOKEN": "your-buildkite-access-token"
      }
    }
  }
}

With this configuration:

  • You don't need to install or run the server manually
  • Cursor will automatically start and stop the server as needed
  • Replace your-buildkite-access-token with your actual Buildkite API token

After updating the configuration, restart Cursor to apply the changes.

MCP Endpoints

List Organizations

POST /mcp_buildkite_list_organizations

Request Body:

{
  "access_token": "optional-if-set-in-env"
}

Response:

[
  {
    "id": "org-id",
    "name": "Organization Name",
    "slug": "organization-slug"
  }
]

List Pipelines

POST /mcp_buildkite_list_pipelines

Request Body:

{
  "organization": "my-org",
  "access_token": "optional-if-set-in-env"
}

Response:

[
  {
    "id": "pipeline-id",
    "name": "Pipeline Name",
    "slug": "pipeline-slug"
  }
]

List Builds

POST /mcp_buildkite_list_builds

Request Body:

{
  "organization": "my-org",
  "pipeline": "my-pipeline",
  "access_token": "optional-if-set-in-env",
  "branch": "main",
  "state": "failed",
  "per_page": 10,
  "page": 1
}

Response:

[
  {
    "id": "build-id",
    "number": 123,
    "state": "failed"
  }
]

Get Build Details

POST /mcp_buildkite_get_build

Request Body:

{
  "organization": "my-org",
  "pipeline": "my-pipeline",
  "build_number": 123,
  "access_token": "optional-if-set-in-env"
}

Response:

{
  "id": "build-id",
  "number": 123,
  "jobs": [
    {
      "id": "job-id",
      "name": "Job Name",
      "state": "failed"
    }
  ]
}

List All Jobs

POST /mcp_buildkite_list_jobs

Request Body:

{
  "organization": "my-org",
  "pipeline": "my-pipeline",
  "build_number": 123,
  "access_token": "optional-if-set-in-env"
}

Response:

[
  {
    "id": "job-id",
    "name": "Job Name",
    "state": "failed"
  }
]

List Failed Jobs

POST /mcp_buildkite_list_failed_jobs

Request Body:

{
  "organization": "my-org",
  "pipeline": "my-pipeline",
  "build_number": 123,
  "access_token": "optional-if-set-in-env"
}

Response:

[
  {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "Test Job",
    "state": "failed",
    "web_url": "https://buildkite.com/my-org/my-pipeline/builds/123#01234567-89ab-cdef-0123-456789abcdef"
  }
]

List Job Spec Failures

POST /mcp_buildkite_list_job_spec_failures

Request Body:

{
  "organization": "my-org",
  "pipeline": "my-pipeline",
  "build_number": 123,
  "job_id": "01234567-89ab-cdef-0123-456789abcdef",
  "access_token": "optional-if-set-in-env"
}

Response:

[
  {
    "type": "RSpec",
    "spec": "./spec/path/to/file_spec.rb:123",
    "message": "Expected result to be X but got Y"
  }
]

Get Job Log

POST /mcp_buildkite_get_job_log

Request Body:

{
  "organization": "my-org",
  "pipeline": "my-pipeline",
  "build_number": 123,
  "job_id": "01234567-89ab-cdef-0123-456789abcdef",
  "access_token": "optional-if-set-in-env",
  "limit": 100  // optional, defaults to all content
}

Response:

{
  "content": "...log content...",
  "size": 12345,
  "format": "raw"
}

List Failed Specs from Build URL

POST /mcp_buildkite_list_failed_specs

Request Body:

{
  "build_url": "https://buildkite.com/my-org/my-pipeline/builds/123",
  "access_token": "optional-if-set-in-env"
}

Response:

{
  "build_url": "https://buildkite.com/my-org/my-pipeline/builds/123",
  "failed_job_count": 2,
  "jobs": [
    {
      "id": "01234567-89ab-cdef-0123-456789abcdef",
      "name": "Test Job 1",
      "web_url": "https://buildkite.com/my-org/my-pipeline/builds/123#01234567-89ab-cdef-0123-456789abcdef",
      "failures": [
        {
          "spec": "./spec/path/to/file_spec.rb:123",
          "message": "Expected result to be X but got Y"
        }
      ]
    },
    {
      "id": "fedcba98-7654-3210-fedc-ba9876543210",
      "name": "Test Job 2",
      "web_url": "https://buildkite.com/my-org/my-pipeline/builds/123#fedcba98-7654-3210-fedc-ba9876543210",
      "failures": []
    }
  ],
  "failures": [
    {
      "job_id": "01234567-89ab-cdef-0123-456789abcdef",
      "job_name": "Test Job 1",
      "job_url": "https://buildkite.com/my-org/my-pipeline/builds/123#01234567-89ab-cdef-0123-456789abcdef",
      "spec": "./spec/path/to/file_spec.rb:123",
      "message": "Expected result to be X but got Y"
    }
  ]
}

Retry Job

POST /mcp_buildkite_retry_job

Request Body:

{
  "organization": "my-org",
  "pipeline": "my-pipeline",
  "build_number": 123,
  "job_id": "01234567-89ab-cdef-0123-456789abcdef",
  "access_token": "optional-if-set-in-env"
}

Response:

{
  "id": "job-id",
  "state": "scheduled"
}

List Pipeline Build Failures

POST /mcp_buildkite_list_pipeline_build_failures

Request Body:

{
  "organization": "my-org",
  "pipeline": "my-pipeline",
  "state": "finished",
  "per_page": 10,
  "page": 1,
  "access_token": "optional-if-set-in-env"
}

Response:

[
  {
    "build_number": 123,
    "build_url": "https://buildkite.com/my-org/my-pipeline/builds/123",
    "failed_jobs": [
      {
        "name": "Test Job",
        "url": "https://buildkite.com/my-org/my-pipeline/builds/123#01234567-89ab-cdef-0123-456789abcdef"
      }
    ]
  }
]

Environment Variables

  • BUILDKITE_ACCESS_TOKEN: Your Buildkite API token with read access
  • PORT: (Optional) Port to run the server on (default: 63330)

Error Handling

The server returns appropriate HTTP status codes and error messages when something goes wrong:

  • 400: Bad Request - Missing or invalid parameters
  • 401: Unauthorized - Invalid or missing access token
  • 404: Not Found - Resource not found
  • 500: Internal Server Error - Server-side error