chainguard-mcp-server

ptbhavsar/chainguard-mcp-server

3.2

If you are the rightful owner of chainguard-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

The Chainguard Registry API is a production-ready REST API and FastMCP server designed for interacting with Chainguard's container registry, offering both traditional HTTP endpoints and Model Context Protocol integration for AI assistants.

Tools
6
Resources
0
Prompts
0

Chainguard Registry API

A production-ready REST API and FastMCP server for interacting with Chainguard's container registry. Built with FastAPI and FastMCP, providing both traditional HTTP endpoints and Model Context Protocol integration for AI assistants.

🚀 Features

  • Complete API Coverage: Implements all registry-related endpoints from the Chainguard Registry API
  • Type Safety: Written in Python with comprehensive type definitions using Pydantic
  • Dual Interface: REST API + FastMCP server for AI assistants
  • Authentication: Secure API token handling for Chainguard authentication (pull tokens, OIDC)
  • Rate Limiting: Built-in rate limiting to respect API quotas and prevent abuse
  • Caching: Intelligent response caching with Redis to reduce API calls
  • Error Handling: Proper error handling with meaningful error messages
  • Logging: Structured JSON logging with correlation IDs for debugging and monitoring
  • Testing: Comprehensive unit, integration, and performance tests
  • Documentation: OpenAPI/Swagger specification with interactive docs
  • Container Native: Docker and Kubernetes deployment ready

📦 Installation

# Using pip
pip install chainguard-registry-api

# Using pipenv
pipenv install chainguard-registry-api

# From source
git clone <repository-url>
cd chainguard-registry-api
pip install -e .

🔧 Configuration

The server can be configured using environment variables:

VariableDescriptionDefault
CHAINGUARD_REGISTRY_URLChainguard registry URLhttps://cgr.dev
CHAINGUARD_ORGDefault organizationchainguard
CHAINGUARD_PULL_TOKENYour Chainguard pull token-
API_PORTAPI server port8000
RATE_LIMIT_REQUESTSAPI requests per window100
RATE_LIMIT_WINDOWRate limit window in seconds3600
REDIS_URLRedis cache URLredis://localhost:6379
LOG_LEVELLogging level (debug, info, warn, error)info

🚀 Usage

How MCP Servers Work

MCP servers communicate via stdio (standard input/output) rather than HTTP. They're designed to be used by:

  1. AI assistants (like Claude) that have MCP support built-in
  2. MCP clients that you build yourself
  3. MCP-compatible applications that can spawn and communicate with MCP servers

Starting the Server

# With environment variables
export CHAINGUARD_PULL_TOKEN=your_token_here
export CHAINGUARD_ORG=my-org

# Start REST API server
make dev

# Start MCP server
make mcp

# Or using Python directly
python app/main.py        # REST API
python mcp/server.py      # MCP server

Method 1: Using with Claude Desktop App

  1. Add the server to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
  "mcpServers": {
    "chainguard": {
      "command": "python",
      "args": ["/path/to/chainguard-registry-api/mcp/server.py"],
      "env": {
        "CHAINGUARD_PULL_TOKEN": "your_token_here",
        "CHAINGUARD_ORG": "your-org"
      }
    }
  }
}
  1. Restart Claude Desktop
  2. The Chainguard tools will be available in your conversations

Method 1a: Using with Claude Desktop App (Docker)

If you're running the MCP server in Docker, configure Claude Desktop like this:

{
  "mcpServers": {
    "chainguard": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "CHAINGUARD_PULL_TOKEN=your_token_here",
        "-e", 
        "CHAINGUARD_ORG=your-org",
        "chainguard-registry-api:latest",
        "python",
        "mcp/server.py"
      ]
    }
  }
}

Method 1b: Using with VS Code or Other MCP-Compatible Editors

For VS Code with MCP support extensions, add to your settings:

{
  "mcp.servers": {
    "chainguard": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "CHAINGUARD_PULL_TOKEN=${env:CHAINGUARD_PULL_TOKEN}",
        "-e",
        "CHAINGUARD_ORG=${env:CHAINGUARD_ORG}",
        "-e",
        "LOG_LEVEL=info",
        "chainguard-registry-api:latest",
        "python",
        "mcp/server.py"
      ],
      "env": {
        "DOCKER_HOST": "unix:///var/run/docker.sock"
      }
    }
  }
}

For a development setup with volume mounts:

{
  "mcp.servers": {
    "chainguard": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-v",
        "${workspaceFolder}:/app:ro",
        "-e",
        "CHAINGUARD_PULL_TOKEN=${env:CHAINGUARD_PULL_TOKEN}",
        "-e",
        "LOG_LEVEL=debug",
        "--name",
        "chainguard-mcp-dev",
        "chainguard-registry-api:latest",
        "python",
        "mcp/server.py"
      ]
    }
  }
}

Method 2: Building an MCP Client

Create a client application that spawns the server and communicates with it:

import asyncio
from mcp.client import MCPTestClient

async def main():
    # Create MCP client
    client = MCPTestClient()
    
    try:
        await client.connect()
        
        # List available repositories
        repos = await client.call_tool(
            "list_repositories", 
            organization="chainguard"
        )
        print("Repositories:", repos)
        
        # Get Python repository images
        images = await client.call_tool(
            "get_repository_images",
            repository="python",
            organization="chainguard"
        )
        print("Python images:", images)
        
        # Get manifest for specific image
        manifest = await client.call_tool(
            "get_image_manifest",
            repository="python", 
            tag="latest",
            organization="chainguard"
        )
        print("Manifest:", manifest)
        
        # Search repositories
        search_results = await client.call_tool(
            "search_repositories",
            query="python",
            limit=5
        )
        print("Search results:", search_results)
        
    finally:
        await client.disconnect()

if __name__ == "__main__":
    asyncio.run(main())

Method 3: Direct Testing with MCP Inspector

You can test the server directly using the MCP Inspector tool:

# Install FastMCP with CLI tools
pip install fastmcp[cli]

# Run the inspector with your server
CHAINGUARD_PULL_TOKEN=your_token_here mcp dev mcp/server.py

This will open a web interface where you can:

  • See all available tools and resources
  • Test tool calls interactively
  • View request/response logs
  • Inspect resource content

Method 4: Integration with Other MCP-Compatible Apps

Many applications are adding MCP support. Check the application's documentation for how to configure MCP servers. Generally, you'll need to provide:

  • The command to run: python
  • The path to the server: /path/to/mcp/server.py
  • Environment variables: CHAINGUARD_PULL_TOKEN, CHAINGUARD_ORG

🛠️ Available Tools

list_repositories

List all repositories for an organization.

Parameters:

  • organization (string, optional): Organization name (default: "chainguard")

Example:

list_repositories(organization="chainguard")

get_repository_images

Get available container image tags for a specific repository.

Parameters:

  • repository (string, required): Repository name
  • organization (string, optional): Organization name (default: "chainguard")

Example:

get_repository_images(repository="python", organization="chainguard")

get_image_manifest

Get detailed manifest information for a specific container image.

Parameters:

  • repository (string, required): Repository name
  • tag (string, optional): Image tag (default: "latest")
  • organization (string, optional): Organization name (default: "chainguard")

Example:

get_image_manifest(repository="python", tag="latest", organization="chainguard")

search_repositories

Search for repositories matching a query string.

Parameters:

  • query (string, required): Search query
  • organization (string, optional): Organization name (default: "chainguard")
  • limit (number, optional): Maximum results to return (default: 10)

Example:

search_repositories(query="python", limit=5)

get_popular_repositories

Get a curated list of popular Chainguard repositories.

Parameters:

  • organization (string, optional): Organization name (default: "chainguard")
  • limit (number, optional): Maximum results to return (default: 10)

Example:

get_popular_repositories(limit=10)

get_registry_stats

Get registry statistics and overview information.

Parameters:

  • organization (string, optional): Organization name (default: "chainguard")

Example:

get_registry_stats(organization="chainguard")

📡 Available Resources

chainguard://config

Server configuration and available tools/resources information.

chainguard://health

Health check status and diagnostics for registry connectivity.

chainguard://popular-images

Comprehensive catalog of popular Chainguard images with descriptions.

chainguard://examples

Usage examples and best practices for working with Chainguard images.

📖 REST API Documentation

Once running, visit:

Key REST Endpoints

  • GET /health - Health check
  • GET /api/v1/repositories - List repositories
  • GET /api/v1/repositories/{repo}/images - Get image tags
  • GET /api/v1/repositories/{repo}/images/{tag}/manifest - Get manifest

⚠️ Error Handling

The server handles various error scenarios:

  • 401 Unauthorized: Invalid or missing authentication
  • 403 Forbidden: Insufficient permissions for private repositories
  • 404 Not Found: Repository or image not found
  • 429 Rate Limited: Too many requests - retry after delay
  • 500+ Server Errors: Chainguard API errors

All errors are properly typed and include descriptive messages with correlation IDs for debugging.

🏗️ Development

Setup

# Clone repository
git clone <repository-url>
cd chainguard-registry-api

# Setup development environment
./scripts/setup.sh

# Activate virtual environment
source venv/bin/activate

# Install development dependencies
pip install -r requirements-dev.txt

Running in Development

# Run REST API in development mode
make dev

# Run MCP server in development mode  
make mcp

# Run with auto-reload
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

Testing

# Run all tests
make test

# Run specific test categories
./scripts/run_tests.sh unit
./scripts/run_tests.sh integration
./scripts/run_tests.sh performance

# Run tests with coverage
pytest --cov=app --cov=mcp --cov-report=html

# Test registry connectivity
python scripts/test_registry.py

# Test specific repository
python scripts/test_registry.py python

Code Quality

# Type checking
mypy app/ mcp/

# Linting
flake8 app/ mcp/ tests/

# Formatting
black app/ mcp/ tests/
isort app/ mcp/ tests/

# Check formatting
black --check app/ mcp/ tests/

🚀 Deployment

Docker

# Build and run
make docker

# Or manually
docker build -t chainguard-api .
docker run -p 8000:8000 -e CHAINGUARD_ORG=chainguard chainguard-api

Docker Compose

# Deploy full stack (API + Redis + MCP)
docker-compose up -d

# View logs
docker-compose logs -f

Kubernetes

# Deploy to Kubernetes
kubectl apply -f k8s/

# Check deployment
kubectl get pods
kubectl get services

Production Deployment Script

# Deploy with automated script
./scripts/deploy.sh docker          # Docker deployment
./scripts/deploy.sh compose         # Docker Compose deployment  
./scripts/deploy.sh kubernetes      # Kubernetes deployment
./scripts/deploy.sh status          # Check deployment status

📊 Monitoring

  • Health Checks: /health, /health/ready, /health/live
  • Metrics: Prometheus-compatible metrics (optional)
  • Logging: Structured JSON logging with correlation IDs
  • Rate Limiting: Per-IP request limiting with Redis backend
  • Caching: Redis-based caching with hit/miss metrics

🔒 Security Best Practices

  1. API Token Storage: Never commit pull tokens to version control
  2. HTTPS Only: Always use HTTPS for API communication in production
  3. Token Permissions: Use tokens with minimal required permissions
  4. Rate Limiting: Respect Chainguard's rate limits and implement client-side limiting
  5. Error Messages: Don't expose sensitive information in error responses
  6. Input Validation: All inputs are validated and sanitized
  7. Security Headers: CORS, CSP, and other security headers configured

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes with tests
  4. Run the test suite (make test)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the file for details.

🆘 Support

For issues and questions:

🔗 Related Projects