Jenkins MCP Server
README.md
# Jenkins MCP Server
A production-ready [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the Jenkins REST API as a rich set of structured tools, with first-class support for the `jenkins-terraform-gcp:1.1` Docker image (Terraform + GCP aware log inspection).
Built with **Python 3.13**, **FastMCP**, **requests** and **python-dotenv**.
## Features
- 64 MCP tools covering jobs, builds, pipelines, nodes, plugins, credentials, users, queue, views, search, system administration, Terraform and GCP.
- Folder, nested-folder, multibranch pipeline and organization-folder support.
- Automatic CSRF crumb handling (Crumb Issuer), with transparent retry on stale crumbs.
- Connection pooling + retry/backoff via a single shared `requests.Session`.
- Structured JSON responses: `{"status": "success", "data": {...}, "message": "..."}` / `{"status": "error", "message": "..."}`.
- Rotating file + console logging.
- Pagination support on list-style tools.
- Docker & docker-compose deployment.
- Optional Jenkins CLI fallback.
## Project Structure
```
jenkins-mcp-gcp/
├── server.py # FastMCP entry point - registers all tools
├── jenkins_client.py # Jenkins REST API client (pooling, retries, crumb)
├── config.py # .env-driven configuration
├── requirements.txt
├── .env.example
├── Dockerfile
├── docker-compose.yml
├── mcp.json # Example MCP client configuration
├── tools/
│ ├── jobs.py # Job management
│ ├── builds.py # Builds, pipeline stages, queue, health report
│ ├── nodes.py # Build agents / nodes
│ ├── plugins.py # Plugin management
│ ├── credentials.py # Credential metadata (no secrets)
│ ├── system.py # Ping, system info, users, views, CLI
│ ├── terraform.py # Terraform-aware tools
│ └── gcp.py # GCP-aware tools
└── utils/
├── logger.py # Logging configuration
├── helpers.py # Response envelope, pagination, decorators
└── terraform_parser.py # Terraform/GCP log-parsing heuristics
```
## Requirements
- Python 3.13+
- A running Jenkins instance (the `jenkins-terraform-gcp:1.1` image at `http://localhost:8090` by default)
- A Jenkins API token (Jenkins → your user → **Configure** → **API Token** → **Add new Token**)
## Installation
### 1. Clone / open the project
```powershell
cd jenkins-mcp
```
### 2. Create a virtual environment
```powershell
python -m venv .venv
.venv\Scripts\Activate.ps1
```
macOS/Linux:
```bash
python3 -m venv .venv
source .venv/bin/activate
```
### 3. Install dependencies
```powershell
pip install -r requirements.txt
```
### 4. Configure environment variables
Copy the example file and fill in your real values - `.env` is git-ignored and never committed:
```powershell
Copy-Item .env.example .env
```
Edit `.env`:
```env
JENKINS_URL=http://localhost:8090
JENKINS_USER=admin
JENKINS_TOKEN=xxxxxxxx
MCP_TRANSPORT=stdio
```
`server.py` (via `config.py`) calls `load_dotenv()` on startup and reads every setting with `os.getenv()`, so the token is picked up automatically from `.env` - you don't need to (and shouldn't) pass `JENKINS_TOKEN` through `mcp.json`, `claude_desktop_config.json`, or any other client configuration file.
## Run the Server
Stdio transport (default - used by Claude Desktop, VS Code, Cursor):
```powershell
python server.py
```
Network transport (used for the Docker deployment or remote clients):
```powershell
$env:MCP_TRANSPORT="streamable-http"; python server.py
```
## Testing
Quick connectivity check once the server is configured:
```powershell
python -c "from jenkins_client import JenkinsClient; import json; print(json.dumps(JenkinsClient().ping(), indent=2))"
```
You can also use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) to interactively call every tool:
```powershell
npx @modelcontextprotocol/inspector python server.py
```
Then call the `ping_jenkins` tool first to validate connectivity/authentication before exercising job/build tools.
## Claude Desktop Configuration
Edit `claude_desktop_config.json` (Claude Desktop → Settings → Developer → Edit Config) and merge in:
```json
{
"mcpServers": {
"jenkins-mcp": {
"command": "C:\\path\\to\\jenkins-mcp\\.venv\\Scripts\\python.exe",
"args": ["C:\\path\\to\\jenkins-mcp\\server.py"],
"env": {
"MCP_TRANSPORT": "stdio"
}
}
}
}
```
> **Security note:** `JENKINS_URL`, `JENKINS_USER` and `JENKINS_TOKEN` are intentionally **not** set here. `server.py` loads them from the `.env` file in the project directory at startup (via `python-dotenv`), so the token never needs to appear in `claude_desktop_config.json`, `mcp.json`, or any other client configuration file that might get committed to source control.
## VS Code MCP Configuration
Create `.vscode/mcp.json` in your workspace (or use the provided `mcp.json` as a template):
```json
{
"servers": {
"jenkins-mcp": {
"type": "stdio",
"command": "${workspaceFolder}/.venv/Scripts/python.exe",
"args": ["${workspaceFolder}/server.py"],
"env": {
"MCP_TRANSPORT": "stdio"
}
}
}
}
```
`JENKINS_URL`, `JENKINS_USER` and `JENKINS_TOKEN` are deliberately omitted from `mcp.json` - they are loaded from your local `.env` file when `server.py` starts, so no credentials ever need to be written to this file (which is safe to commit).
Then run **MCP: List Servers** from the VS Code command palette and start `jenkins-mcp`.
## Cursor MCP Configuration
Add to `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):
```json
{
"mcpServers": {
"jenkins-mcp": {
"command": "python",
"args": ["server.py"],
"cwd": "/absolute/path/to/jenkins-mcp"
}
}
}
```
As long as a `.env` file exists in `cwd`, `server.py` picks up `JENKINS_URL` / `JENKINS_USER` / `JENKINS_TOKEN` automatically - there's no need (and no reason) to duplicate them here.
## Docker Deployment
Build and run with docker-compose (recommended - it also sets up `host.docker.internal` so the container can reach Jenkins running on your Docker Desktop host):
```powershell
docker compose up --build -d
```
The server listens on `http://localhost:8000` using the `streamable-http` transport. Point your MCP client at that URL, or override `JENKINS_URL` in a local `.env` file (docker-compose reads it automatically) if Jenkins is reachable via a different hostname/network.
Build the image manually:
```powershell
docker build -t jenkins-mcp:latest .
docker run --rm -p 8000:8000 --env-file .env --add-host host.docker.internal:host-gateway jenkins-mcp:latest
```
## Configuration Reference (`.env`)
| Variable | Default | Description |
|---|---|---|
| `JENKINS_URL` | `http://localhost:8090` | Base Jenkins URL |
| `JENKINS_USER` | _(empty)_ | Jenkins username |
| `JENKINS_TOKEN` | _(empty)_ | Jenkins API token |
| `JENKINS_VERIFY_SSL` | `true` | Verify TLS certs for `https://` Jenkins |
| `JENKINS_TIMEOUT` | `30` | Request timeout (seconds) |
| `JENKINS_MAX_RETRIES` | `3` | HTTP retry attempts |
| `JENKINS_BACKOFF_FACTOR` | `0.5` | Retry backoff factor |
| `JENKINS_POOL_CONNECTIONS` / `JENKINS_POOL_MAXSIZE` | `10` / `20` | Connection pool sizing |
| `LOG_LEVEL` | `INFO` | Logging level |
| `LOG_FILE` | `logs/jenkins_mcp.log` | Rotating log file path |
| `DEFAULT_PAGE_SIZE` | `50` | Default page size for paginated tools |
| `JENKINS_CLI_JAR` | _(empty)_ | Optional path to `jenkins-cli.jar` |
| `TERRAFORM_STATE_BUCKET` / `GCP_PROJECT` | _(empty)_ | Optional fallback hints for Terraform/GCP tools |
| `MCP_TRANSPORT` | `stdio` | `stdio` \| `streamable-http` \| `sse` |
## Security
- **Never commit secrets.** `JENKINS_TOKEN` (and `JENKINS_USER`) live only in your local `.env` file. `.gitignore` excludes `.env` and `*.env`, and `mcp.json` in this repo intentionally has no credential fields.
- **Use `.env.example` as the template.** It only contains placeholder values and is safe to commit; copy it to `.env` and fill in real values locally (or inject real env vars via your secrets manager / CI in production).
- **Rotate tokens, don't reuse passwords.** Generate a dedicated Jenkins API token (Jenkins → your user → Configure → API Token) instead of using your account password.
- **Nothing sensitive is logged.** `jenkins_client.py` only logs the Jenkins URL and username (never the token), and error messages (e.g. on HTTP 401) reference the *names* of the misconfigured variables, not their values, so credentials never end up in `logs/jenkins_mcp.log` or in tool error responses.
- **Credential tools return metadata only.** `list_credentials_ids` / `get_credential_information` never surface secret values, matching Jenkins' own credential API behavior.
- If a token does leak (e.g. committed by mistake), revoke/regenerate it immediately in Jenkins and scrub it from git history.
## Tool Reference
All tools return `{"status": "success", "data": {...}, "message": "..."}` on success or `{"status": "error", "message": "..."}` on failure.
### General
- `ping_jenkins` - version, URL, authentication status
### Jobs
- `list_jobs`, `get_job`, `create_pipeline_job`, `delete_job`, `enable_job`, `disable_job`, `copy_job`, `search_job`
### Builds
- `trigger_build`, `trigger_build_with_parameters`, `stop_build`, `last_build_status`, `build_console_output`, `build_duration`, `build_artifacts`, `build_changes`, `queue_status`, `search_build`
### Pipeline
- `get_pipeline_stages`, `get_stage_logs`, `replay_pipeline`, `blue_ocean_info`, `pipeline_health_report`
### Nodes
- `list_nodes`, `node_status`, `node_executors`, `online_nodes`, `offline_nodes`
### Plugins
- `installed_plugins`, `plugin_version`, `plugin_updates_available`
### System
- `jenkins_version`, `installed_tools`, `system_information`, `quiet_down_mode`, `cancel_quiet_down`, `run_jenkins_cli_command` (optional)
### Credentials
- `list_credentials_ids`, `get_credential_information` (secret values are never returned)
### Users
- `current_user`, `who_am_i`
### Queue
- `queue_information`, `cancel_queue_item`
### Views
- `list_views`, `view_jobs`
### Terraform Support
- `validate_terraform_pipeline`, `validate_jenkinsfile`, `detect_terraform_version`, `detect_workspace`, `show_tfvars`, `show_backend_configuration`, `show_terraform_plan_log`, `show_apply_log`, `show_destroy_log`, `detect_terraform_errors` (classified into Authentication, Provider, Backend, Syntax, State Lock, Permission, Quota, Networking), `terraform_plan_summary`, `workspace_cleanup`
### GCP Support
- `detect_gcloud_version`, `current_gcp_project`, `service_account`, `enabled_apis`, `terraform_state_bucket`, `gcp_resource_inspector`
> Terraform/GCP tools work by parsing Jenkins console logs and workspace files (Jenkins has no native Terraform/GCP awareness), so they are most accurate immediately after a build has run.
## Security Notes
- Credential tools never return secret values (passwords, private keys, secret text/bytes are stripped from responses).
- CSRF crumbs are obtained automatically and refreshed transparently on rejection.
- Configure `JENKINS_VERIFY_SSL=true` in production and use a scoped Jenkins API token rather than a personal password.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues