Skip to main content
Glama

TeamCity MCP Server

A comprehensive Model Context Protocol (MCP) server that exposes JetBrains TeamCity as structured AI-ready resources and tools for LLM agents and IDE plugins.

Quick Start

IDE Integration (Cursor)

The TeamCity MCP server is designed to work seamlessly with AI-powered IDEs like Cursor. Here's how to configure it:

Cursor Configuration

Add this to your Cursor MCP settings:

{
  "mcpServers": {
      "teamcity": {
        "command": "docker",
        "args": [
          "run",
          "--rm",
          "-i",
          "-e",
          "TC_URL",
          "-e",
          "TC_TOKEN",
          "itcaat/teamcity-mcp:latest",
          "--transport",
          "stdio"
        ],
        "env": {
          "TC_URL": "https://your-teamcity-server.com",
          "TC_TOKEN": "your-teamcity-api-token"
        }
      }
    }
}    

Related MCP server: Xcode Diagnostics MCP Plugin

Local Development

1. Build the Server

make build
# This creates ./bin/teamcity-mcp and a symlink ./server

2. Set Environment Variables

# Required
export TC_URL="https://your-teamcity-server.com"

# Optional (enables HMAC authentication)
export SERVER_SECRET="your-hmac-secret-key"

# Authentication
export TC_TOKEN="your-teamcity-api-token"

3. Run the Server

./server
# Server starts on :8123 by default

4. Test the Server

# Health check
curl http://localhost:8123/healthz

# MCP protocol test
curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-hmac-secret-key" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{}}}'

Expected result: Health endpoint should return {"status":"ok"} and MCP endpoint should return initialization response.

Features

  • MCP Protocol Compliance: Full JSON-RPC 2.0 over HTTP/WebSocket support

  • TeamCity Integration: Complete REST API integration with authentication

  • Resource Access: Projects, build types, builds, agents, and artifacts

  • Build Operations: Trigger, cancel, pin builds, set tags, download artifacts, search builds

  • Advanced Search: Comprehensive build search with multiple filters (status, branch, user, dates, tags)

  • Production Ready: Docker, Kubernetes, monitoring, caching, and comprehensive logging

  • Environment-Based Configuration: No config files needed, everything via environment variables

  • AI Time Awareness: Provides real current date/time to prevent AI models from using training data dates

Environment Variables Reference

Required Variables

Variable

Description

Example

TC_URL

TeamCity server URL

https://teamcity.company.com

SERVER_SECRET

HMAC secret for client authentication (optional)

my-secure-secret-123

Authentication Variables

Variable

Description

Example

TC_TOKEN

TeamCity API token

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...

Optional Variables

Variable

Default

Description

Example

LISTEN_ADDR

:8123

Server listen address

:8080 or 0.0.0.0:8123

TC_TIMEOUT

30s

TeamCity API timeout

60s or 2m

TLS_CERT

Path to TLS certificate

/path/to/cert.pem

TLS_KEY

Path to TLS private key

/path/to/key.pem

LOG_LEVEL

info

Log level

debug, info, warn, error

LOG_FORMAT

json

Log format

json or console

CACHE_TTL

10s

Cache TTL for API responses

30s or 1m

Configuration Examples

Development Environment

export TC_URL=http://localhost:8111
export TC_TOKEN=dev-token-123
export SERVER_SECRET=dev-secret
export LOG_LEVEL=debug
export LOG_FORMAT=console
./server

Production Environment

export TC_URL=https://teamcity.company.com
export TC_TOKEN=$TEAMCITY_API_TOKEN
export SERVER_SECRET=$MCP_SERVER_SECRET
export TLS_CERT=/etc/ssl/certs/teamcity-mcp.pem
export TLS_KEY=/etc/ssl/private/teamcity-mcp.key
export LOG_LEVEL=warn
export CACHE_TTL=30s
./server

Docker Deployment

Build and Run

# Build Docker image
make docker

# Run with environment variables
docker run -p 8123:8123 \
  -e TC_URL=https://teamcity.company.com \
  -e TC_TOKEN=your-token \
  -e SERVER_SECRET=your-secret \
  teamcity-mcp:latest

Docker Compose

# Start with docker-compose
docker-compose up -d

# Check logs
docker-compose logs -f teamcity-mcp

Kubernetes Deployment

Using Helm

# Deploy with Helm
helm install teamcity-mcp ./helm/teamcity-mcp \
  --set teamcity.url=https://teamcity.company.com \
  --set secrets.teamcityToken=your-token \
  --set secrets.serverSecret=your-secret

Manual Kubernetes Deployment

apiVersion: v1
kind: Secret
metadata:
  name: teamcity-mcp-secrets
type: Opaque
stringData:
  teamcity-token: "your-teamcity-token"
  server-secret: "your-server-secret"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: teamcity-mcp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: teamcity-mcp
  template:
    metadata:
      labels:
        app: teamcity-mcp
    spec:
      containers:
      - name: teamcity-mcp
        image: teamcity-mcp:latest
        ports:
        - containerPort: 8123
        env:
        - name: TC_URL
          value: "https://teamcity.company.com"
        - name: TC_TOKEN
          valueFrom:
            secretKeyRef:
              name: teamcity-mcp-secrets
              key: teamcity-token
        - name: SERVER_SECRET
          valueFrom:
            secretKeyRef:
              name: teamcity-mcp-secrets
              key: server-secret

Command Line Options

Flag

Description

Default

--help

Show environment variable help

--version

Show version information

--transport

Transport mode: http or stdio

http

Help and Documentation

# Show environment variable help
./server --help

# Show version
./server --version

# Show command line usage
./server -h

Testing and Verification

Automated Verification

Use the included verification script to test all functionality:

# Run all tests
./scripts/verify.sh

# Available options:
./scripts/verify.sh help     # Show help
./scripts/verify.sh start    # Start server only
./scripts/verify.sh stop     # Stop server only
./scripts/verify.sh clean    # Clean up processes

Manual Testing

# 1. Set environment variables
export TC_URL=http://localhost:8111
export TC_TOKEN=test-token
export SERVER_SECRET=test-secret

# 2. Start server
./server &

# 3. Test health
curl http://localhost:8123/healthz

# 4. Test MCP protocol
curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer test-secret" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{}}}'

# 5. Stop server
pkill -f teamcity-mcp

Development Testing

# Install dependencies
make deps

# Run unit tests
make test

# Run integration tests
make test-integration

# Run load tests
make test-load

# Run linter
make lint

# Format code
make format

# Clean build artifacts
make clean

Available Make Commands

Use make help to see all available commands:

# Basic commands
make build                # Build the binary
make test                 # Run tests
make clean                # Clean build artifacts
make deps                 # Download dependencies
make lint                 # Run linters
make format               # Format code

# Docker commands
make docker               # Build Docker image
make docker-push          # Push Docker image

# Running commands
make run                  # Run the application
make run-stdio            # Run in STDIO mode
make dev                  # Run in development mode with hot reload

# Docker Compose commands
make compose-up           # Start services with Docker Compose
make compose-down         # Stop services
make compose-logs         # Show logs

# Testing commands
make test-integration     # Run integration tests with Docker
make test-load            # Run load tests

# Development tools
make install-tools        # Install development tools

# Release commands
make release-snapshot     # Build snapshot release with GoReleaser
make release-check        # Check GoReleaser configuration

# CI commands
make ci                   # Run CI checks (deps, lint, test, build)
make check                # Run all checks (lint, test, build)

MCP Protocol Testing

Initialize MCP Session

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-03-26",
      "capabilities": {},
      "clientInfo": {
        "name": "test-client",
        "version": "1.0.0"
      }
    }
  }'

List Resources

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "resources/list",
    "params": {}
  }'

List Tools

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/list",
    "params": {}
  }'

Available Tools

The TeamCity MCP server provides 10 powerful tools for managing builds:

1. trigger_build

Trigger a new build in TeamCity.

Parameters:

  • buildTypeId (required): Build configuration ID

  • branchName (optional): Branch name to build

  • properties (optional): Build properties object

Example:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 4,
    "method": "tools/call",
    "params": {
      "name": "trigger_build",
      "arguments": {
        "buildTypeId": "YourProject_BuildConfiguration",
        "branchName": "main",
        "properties": {
          "env.DEPLOY_ENV": "staging"
        }
      }
    }
  }'

2. cancel_build

Cancel a running build.

Parameters:

  • buildId (required): Build ID to cancel

  • comment (optional): Cancellation comment

Example:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 5,
    "method": "tools/call",
    "params": {
      "name": "cancel_build",
      "arguments": {
        "buildId": "12345",
        "comment": "Cancelled due to urgent hotfix"
      }
    }
  }'

3. pin_build

Pin or unpin a build to prevent it from being cleaned up.

Parameters:

  • buildId (required): Build ID to pin/unpin

  • pin (required): true to pin, false to unpin

  • comment (optional): Pin comment

Example:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 6,
    "method": "tools/call",
    "params": {
      "name": "pin_build",
      "arguments": {
        "buildId": "12345",
        "pin": true,
        "comment": "Release candidate build"
      }
    }
  }'

4. set_build_tag

Add or remove tags from a build.

Parameters:

  • buildId (required): Build ID

  • tags (optional): Array of tags to add

  • removeTags (optional): Array of tags to remove

Example:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 7,
    "method": "tools/call",
    "params": {
      "name": "set_build_tag",
      "arguments": {
        "buildId": "12345",
        "tags": ["release", "v1.2.3"],
        "removeTags": ["beta"]
      }
    }
  }'

5. download_artifact

Download build artifacts.

Parameters:

  • buildId (required): Build ID

  • artifactPath (required): Path to the artifact

Example:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 8,
    "method": "tools/call",
    "params": {
      "name": "download_artifact",
      "arguments": {
        "buildId": "12345",
        "artifactPath": "dist/app.zip"
      }
    }
  }'

6. search_builds

Search for builds with comprehensive filtering options.

Parameters (all optional):

  • buildTypeId: Filter by build configuration ID

  • status: Filter by build status (SUCCESS, FAILURE, ERROR, UNKNOWN)

  • state: Filter by build state (queued, running, finished)

  • branch: Filter by branch name

  • agent: Filter by agent name

  • user: Filter by user who triggered the build

  • sinceBuild: Search builds since this build ID

  • sinceDate: Search builds since this date (YYYYMMDDTHHMMSS+HHMM)

  • untilDate: Search builds until this date (YYYYMMDDTHHMMSS+HHMM)

  • tags: Array of tags to filter by

  • personal: Include personal builds (boolean)

  • pinned: Filter by pinned status (boolean)

  • count: Maximum number of builds to return (1-1000, default: 100)

Examples:

Search for failed builds:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 9,
    "method": "tools/call",
    "params": {
      "name": "search_builds",
      "arguments": {
        "status": "FAILURE",
        "count": 10
      }
    }
  }'

Search for recent builds on main branch:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 10,
    "method": "tools/call",
    "params": {
      "name": "search_builds",
      "arguments": {
        "branch": "main",
        "state": "finished",
        "count": 20
      }
    }
  }'

Search for builds with specific tags:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 11,
    "method": "tools/call",
    "params": {
      "name": "search_builds",
      "arguments": {
        "tags": ["release", "production"],
        "pinned": true
      }
    }
  }'

7. fetch_build_log

Fetch the build log for a specific build with filtering options to handle large logs.

Parameters:

  • buildId (required): Build ID to fetch log for

  • plain (optional): Return log as plain text (default: true)

  • archived (optional): Return log as zip archive (default: false)

  • dateFormat (optional): Custom timestamp format (Java SimpleDateFormat)

  • maxLines (optional): Maximum number of lines to return (applied after filtering)

  • filterPattern (optional): Regex pattern to filter log lines

  • severity (optional): Filter by severity level: "error", "warning", or "info"

  • tailLines (optional): Return only the last N lines (applied after filtering)

Examples:

Fetch only errors (limited to 50 lines):

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 12,
    "method": "tools/call",
    "params": {
      "name": "fetch_build_log",
      "arguments": {
        "buildId": "12345",
        "severity": "error",
        "maxLines": 50
      }
    }
  }'

Fetch lines matching a pattern:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 13,
    "method": "tools/call",
    "params": {
      "name": "fetch_build_log",
      "arguments": {
        "buildId": "12345",
        "filterPattern": "test.*failed",
        "maxLines": 100
      }
    }
  }'

Fetch last 200 lines:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 14,
    "method": "tools/call",
    "params": {
      "name": "fetch_build_log",
      "arguments": {
        "buildId": "12345",
        "tailLines": 200
      }
    }
  }'

Fetch archived build log:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 15,
    "method": "tools/call",
    "params": {
      "name": "fetch_build_log",
      "arguments": {
        "buildId": "12345",
        "archived": true
      }
    }
  }'

8. search_build_configurations

Search for build configurations with comprehensive filtering options including basic filters, parameters, steps, and VCS roots.

Parameters (all optional):

Basic filters:

  • projectId: Filter by project ID

  • name: Search by configuration name (partial matching)

  • enabled: Filter by enabled status (boolean)

  • paused: Filter by paused status (boolean)

  • template: Filter templates (true) or regular configurations (false) (boolean)

  • count: Maximum number of configurations to return (1-1000, default: 100)

Advanced filters:

  • parameterName: Search by parameter name (partial matching)

  • parameterValue: Search by parameter value (partial matching)

  • stepType: Search by build step type (e.g., 'gradle', 'docker', 'powershell')

  • stepName: Search by build step name (partial matching)

  • vcsType: Search by VCS type (e.g., 'git', 'subversion')

  • includeDetails: Include detailed information (parameters, steps, VCS) in results (boolean, default: false)

Examples:

Basic search by name:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 15,
    "method": "tools/call",
    "params": {
      "name": "search_build_configurations",
      "arguments": {
        "name": "Test",
        "enabled": true
      }
    }
  }'

Search with parameter filter:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 16,
    "method": "tools/call",
    "params": {
      "name": "search_build_configurations",
      "arguments": {
        "parameterName": "env.DEPLOY_TARGET",
        "parameterValue": "production",
        "includeDetails": true
      }
    }
  }'

Search for Gradle configurations:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 17,
    "method": "tools/call",
    "params": {
      "name": "search_build_configurations",
      "arguments": {
        "stepType": "gradle",
        "projectId": "MyProject",
        "includeDetails": true
      }
    }
  }'

Search for Git-based configurations:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 18,
    "method": "tools/call",
    "params": {
      "name": "search_build_configurations",
      "arguments": {
        "vcsType": "git",
        "stepName": "Deploy"
      }
    }
  }'

9. get_current_time

Get the current server date and time to ensure AI models use real current time instead of training data dates.

Parameters:

  • format (optional): Date format (rfc3339, date, timestamp, or custom Go format)

  • timezone (optional): Timezone (e.g., 'UTC', 'Local', 'America/New_York')

Example:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 19,
    "method": "tools/call",
    "params": {
      "name": "get_current_time",
      "arguments": {
        "format": "rfc3339",
        "timezone": "UTC"
      }
    }
  }'

10. get_test_results

Get test results for a specific build with optional filtering by test status.

Parameters:

  • buildId (required): Build ID to get test results for

  • status (optional): Filter by test status: SUCCESS, FAILURE, UNKNOWN, IGNORED

  • includeDetails (optional): Include test details like stack traces (default: false)

  • count (optional): Maximum number of tests to return (default: 100, max: 1000)

Examples:

Get all test results for a build:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 20,
    "method": "tools/call",
    "params": {
      "name": "get_test_results",
      "arguments": {
        "buildId": "12345"
      }
    }
  }'

Get only failed tests with details:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 21,
    "method": "tools/call",
    "params": {
      "name": "get_test_results",
      "arguments": {
        "buildId": "12345",
        "status": "FAILURE",
        "includeDetails": true
      }
    }
  }'

Get successful tests with limited count:

curl -X POST http://localhost:8123/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret" \
  -d '{
    "jsonrpc": "2.0",
    "id": 22,
    "method": "tools/call",
    "params": {
      "name": "get_test_results",
      "arguments": {
        "buildId": "12345",
        "status": "SUCCESS",
        "count": 50
      }
    }
  }'

Local Binary Configuration

If you prefer to use the local binary instead of Docker:

{
  "teamcity": {
    "command": "/path/to/teamcity-mcp",
    "args": ["--transport", "stdio"],
    "env": {
      "TC_URL": "https://your-teamcity-server.com",
      "TC_TOKEN": "your-teamcity-api-token"
    }
  }
}

Usage in Cursor

Once configured, you can use natural language commands like:

  • "Search for failed builds in the last week"

  • "Trigger a build for the main branch"

  • "Show me recent builds for project X"

  • "Pin the latest successful build"

  • "Cancel the running build 12345"

  • "Add a release tag to build 12345"

  • "Fetch the build log for build 12345"

  • "Get the archived log for the latest build"

  • "Find all build configurations with 'Test' in the name"

  • "Search for enabled configurations in MyProject"

  • "Show me all build configuration templates"

  • "Find configurations that use Gradle build steps"

  • "Search for configurations with DEPLOY_TARGET parameter set to production"

  • "Show me all configurations using Git VCS"

  • "Find Docker-based build configurations"

  • "Search for configurations with specific parameter names"

  • "What's the current date and time?"

  • "Get current time in UTC"

  • "Show me today's date"

  • "Get test results for build 12345"

  • "Show me failed tests for the latest build"

  • "Get test results with details for build 12345"

  • "Show me all passing tests for this build"

  • "What tests failed in build 12345?"

The AI will automatically use the appropriate TeamCity tools to fulfill your requests.

Available Resources

The server exposes TeamCity data as MCP resources:

  • teamcity://projects - List all projects

  • teamcity://buildTypes - List all build configurations

  • teamcity://builds - List recent builds

  • teamcity://agents - List build agents

  • teamcity://runtime - Current server date, time, and runtime information

Troubleshooting

Common Issues

  1. Missing required environment variables

    Error: TC_URL environment variable is required

    Solution: Set all required environment variables

  2. Authentication failures

    Error: TC_TOKEN environment variable is required

    Solution: Set TC_TOKEN with your TeamCity API token

  3. Invalid timeout format

    Error: invalid TC_TIMEOUT format

    Solution: Use valid duration format like 30s, 1m, 2h

  4. Port already in use

    Error: listen tcp :8123: bind: address already in use

    Solution: Set LISTEN_ADDR to a different port or stop the conflicting service

Debug Mode

Enable debug logging:

export LOG_LEVEL=debug
export LOG_FORMAT=console
./server

Health Check

The server provides a health endpoint:

curl http://localhost:8123/healthz
# Expected: {"service":"teamcity-mcp","status":"ok","timestamp":"..."}

Metrics

Prometheus metrics are available:

curl http://localhost:8123/metrics

TeamCity Integration Testing

Verify TeamCity connectivity:

# Check TeamCity server accessibility
curl -H "Authorization: Bearer your-token" \
  http://your-teamcity-url/app/rest/projects

# Verify authentication
curl -H "Authorization: Bearer your-token" \
  http://your-teamcity-url/app/rest/server

Protocol Reference

See Protocol.md for detailed MCP protocol implementation and TeamCity API mapping.

License

MIT License - see LICENSE for details.

-
security - not tested
A
license - permissive license
-
quality - not tested

Resources

Looking for Admin?

Admins can modify the Dockerfile, update the server description, and track usage metrics. If you are the server author, to access the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/itcaat/teamcity-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server