Buildkite MCP Server
by Drew-Goddyn
README.md
# 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:
```json
{
"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:**
```json
{
"access_token": "optional-if-set-in-env"
}
```
**Response:**
```json
[
{
"id": "org-id",
"name": "Organization Name",
"slug": "organization-slug"
}
]
```
### List Pipelines
```
POST /mcp_buildkite_list_pipelines
```
**Request Body:**
```json
{
"organization": "my-org",
"access_token": "optional-if-set-in-env"
}
```
**Response:**
```json
[
{
"id": "pipeline-id",
"name": "Pipeline Name",
"slug": "pipeline-slug"
}
]
```
### List Builds
```
POST /mcp_buildkite_list_builds
```
**Request Body:**
```json
{
"organization": "my-org",
"pipeline": "my-pipeline",
"access_token": "optional-if-set-in-env",
"branch": "main",
"state": "failed",
"per_page": 10,
"page": 1
}
```
**Response:**
```json
[
{
"id": "build-id",
"number": 123,
"state": "failed"
}
]
```
### Get Build Details
```
POST /mcp_buildkite_get_build
```
**Request Body:**
```json
{
"organization": "my-org",
"pipeline": "my-pipeline",
"build_number": 123,
"access_token": "optional-if-set-in-env"
}
```
**Response:**
```json
{
"id": "build-id",
"number": 123,
"jobs": [
{
"id": "job-id",
"name": "Job Name",
"state": "failed"
}
]
}
```
### List All Jobs
```
POST /mcp_buildkite_list_jobs
```
**Request Body:**
```json
{
"organization": "my-org",
"pipeline": "my-pipeline",
"build_number": 123,
"access_token": "optional-if-set-in-env"
}
```
**Response:**
```json
[
{
"id": "job-id",
"name": "Job Name",
"state": "failed"
}
]
```
### List Failed Jobs
```
POST /mcp_buildkite_list_failed_jobs
```
**Request Body:**
```json
{
"organization": "my-org",
"pipeline": "my-pipeline",
"build_number": 123,
"access_token": "optional-if-set-in-env"
}
```
**Response:**
```json
[
{
"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:**
```json
{
"organization": "my-org",
"pipeline": "my-pipeline",
"build_number": 123,
"job_id": "01234567-89ab-cdef-0123-456789abcdef",
"access_token": "optional-if-set-in-env"
}
```
**Response:**
```json
[
{
"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:**
```json
{
"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:**
```json
{
"content": "...log content...",
"size": 12345,
"format": "raw"
}
```
### List Failed Specs from Build URL
```
POST /mcp_buildkite_list_failed_specs
```
**Request Body:**
```json
{
"build_url": "https://buildkite.com/my-org/my-pipeline/builds/123",
"access_token": "optional-if-set-in-env"
}
```
**Response:**
```json
{
"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:**
```json
{
"organization": "my-org",
"pipeline": "my-pipeline",
"build_number": 123,
"job_id": "01234567-89ab-cdef-0123-456789abcdef",
"access_token": "optional-if-set-in-env"
}
```
**Response:**
```json
{
"id": "job-id",
"state": "scheduled"
}
```
### List Pipeline Build Failures
```
POST /mcp_buildkite_list_pipeline_build_failures
```
**Request Body:**
```json
{
"organization": "my-org",
"pipeline": "my-pipeline",
"state": "finished",
"per_page": 10,
"page": 1,
"access_token": "optional-if-set-in-env"
}
```
**Response:**
```json
[
{
"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 This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues