asbjborg/github-milestones-mcp-server
If you are the rightful owner of github-milestones-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.
This project is a dedicated MCP server for managing GitHub milestones, filling the gap left by the official GitHub MCP server.
list_milestones
List milestones for a repository.
get_milestone
Get details of a specific milestone.
create_milestone
Create a new milestone.
update_milestone
Update an existing milestone.
delete_milestone
Delete a milestone.
GitHub Milestones MCP Server
MCP server for GitHub Milestones API - filling the gap in the official GitHub MCP server
šÆ Project Purpose
The official GitHub MCP Server provides excellent tools for issues, pull requests, and files, but completely lacks milestone support. This standalone MCP server fills that gap by providing full milestone management capabilities through the Model Context Protocol (MCP).
Why This Exists
The Problem:
- GitHub's official MCP server omits milestone endpoints
- No clean way to manage project milestones through Cursor/MCP
The Solution:
- Dedicated MCP server focused solely on GitHub Milestones API
- Proper milestone semantics (due dates, progress tracking, etc.)
- Composable with the existing GitHub MCP server
- Clean separation of concerns
š Features
Core Milestone Operations
- ā List Milestones - Get all milestones for a repository
- ā Get Milestone - Fetch specific milestone details
- ā Create Milestone - Create new milestones with due dates
- ā Update Milestone - Modify existing milestones
- ā Delete Milestone - Remove milestones
MCP Integration
- ā Full MCP Protocol Support - Works with any MCP-compatible client
- ā Type-Safe Schemas - Zod validation for all inputs
- ā Proper Error Handling - Meaningful error messages
- ā Composable Design - Works alongside other MCP servers
šļø Architecture
Project Structure
src/
āāā index.ts # Main MCP server entry point
āāā github-client.ts # GitHub API client (Octokit wrapper)
āāā schemas.ts # Zod schemas for input validation
āāā types.ts # TypeScript type definitions (to be created)
Docker/
āāā Dockerfile # Multi-stage build for optimized production image
āāā docker-compose.yml # Container orchestration
āāā .dockerignore # Build context optimization
Key Design Decisions
- Multi-stage Docker Build - Optimized production image with minimal attack surface
- Octokit for API Access - Robust, well-maintained GitHub API client
- Zod for Validation - Runtime type safety and clear error messages
- MCP SDK - Official Model Context Protocol implementation
- TypeScript - Type safety and better developer experience
- ESM Modules - Modern JavaScript module system
- Security-first Containerization - Non-root user, minimal dependencies in production
š ļø Implementation Roadmap
Phase 1: Core Functionality ā
- Basic project structure
- MCP server setup with proper tool registration
- GitHub client with authentication
- All 5 milestone operations (CRUD + list)
- Input validation with Zod schemas
Phase 2: Enhanced Features (Next Steps)
- Add milestone progress calculations
- Support for milestone descriptions with markdown
- Bulk operations (e.g., close multiple milestones)
- Integration with GitHub Projects API
- Better error responses with actionable suggestions
Phase 3: Production Ready
- Multi-stage Docker build - Optimized production images
- Security hardening - Non-root container user, minimal attack surface
- Comprehensive error handling and retry logic
- Logging and observability
- Performance optimizations (caching, rate limiting)
- Documentation and examples
š³ Docker Optimizations
This project uses a multi-stage Docker build for production-ready containerization:
Build Stages
-
Builder Stage (
node:18-alpine AS builder
)- Installs all dependencies (including dev dependencies)
- Compiles TypeScript to JavaScript
- Prepares the application for production
-
Production Stage (
node:18-alpine AS production
)- Installs only production dependencies (
--omit=dev
) - Copies built application from builder stage
- Creates non-root user for security
- Results in minimal, secure final image
- Installs only production dependencies (
Benefits
- Smaller Image Size - Production stage excludes dev dependencies and source code
- Enhanced Security - Non-root user execution, minimal attack surface
- Faster Deployments - Optimized layers and reduced image size
- Build Consistency - Reproducible builds across environments
š” Having Docker/MCP setup issues? See our troubleshooting guide for solutions to common environment variable problems.
š§ Development Setup
Prerequisites
- Node.js 18+ OR Docker
- GitHub Personal Access Token with
repo
scope - TypeScript knowledge (for development)
Option 1: Docker Setup (Recommended)
# Clone the repository
git clone https://github.com/asbjborg/github-milestones-mcp-server.git
cd github-milestones-mcp-server
# Set up environment
export GITHUB_TOKEN="your_github_token_here"
# Build with optimized multi-stage Docker build
npm run docker:build
# Run the containerized server
npm run docker:run
# Or use docker-compose for easier management
docker-compose up -d
Option 2: Local Node.js Setup
# Clone the repository
git clone https://github.com/asbjborg/github-milestones-mcp-server.git
cd github-milestones-mcp-server
# Install dependencies
npm install
# Set up environment
export GITHUB_TOKEN="your_github_token_here"
# or
export GITHUB_PERSONAL_ACCESS_TOKEN="your_github_token_here"
# Build the project
npm run build
# Run in development mode
npm run dev
Testing the Server
# Docker
npm run docker:run
# Local Node.js
npm run start
# The server runs on stdio - test with MCP client tools
# or integrate with Cursor MCP configuration
š MCP Configuration
Docker Setup (Recommended)
Add to your ~/.cursor/mcp.json
:
{
"mcpServers": {
"github-milestones": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--init",
"--stop-timeout=5",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"github-milestones-mcp-server:latest"
]
}
}
}
Docker Args Explained:
--init
- Ensures proper signal handling and zombie process reaping--stop-timeout=5
- Sets 5-second timeout for graceful container shutdown-e GITHUB_PERSONAL_ACCESS_TOKEN
- Passes your GitHub token from environment
šØ Troubleshooting MCP Docker Setup
Having issues with "authorization denied" or Docker environment variables?
The official Cursor/GitHub MCP documentation has known issues with Docker environment variable handling. The problem is mixing Cursor's MCP env
section (JSON) with Docker's -e
flags, causing shell substitution like ${GITHUB_TOKEN}
to become literal strings instead of resolving to actual token values.
Key insight: Use -e VARNAME
(without values) to pass environment variables from your host, avoiding JSON substitution issues entirely.
š For detailed troubleshooting and step-by-step fixes, see:
How to Actually Setup GitHub MCP Server with Docker in Cursor (The Working Guide)
Local Node.js Setup
{
"mcpServers": {
"github-milestones": {
"command": "node",
"args": ["/path/to/github-milestones-mcp-server/dist/index.js"],
"env": {
"GITHUB_TOKEN": "your_token_here"
}
}
}
}
š Usage Examples
With Cursor Agent
Once configured, you can ask Cursor:
- "List all open milestones in this repository"
- "Create a milestone for Q1 2025 with due date March 31st"
- "Update milestone 5 to be closed"
- "Show me details of milestone 3"
Programmatic Usage
// The server exposes these MCP tools:
await callTool('list_milestones', {
owner: 'your-username',
repo: 'your-project',
state: 'open'
});
await callTool('create_milestone', {
owner: 'your-username',
repo: 'your-project',
title: 'Q1 2025 Release',
description: 'First quarter feature release',
due_on: '2025-03-31T23:59:59Z'
});
š¤ Integration Patterns
With Existing GitHub MCP Server
This server is designed to complement, not replace, the official GitHub MCP server:
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--init",
"--stop-timeout=5",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"-e",
"GITHUB_TOOLSETS=issues,pull_requests,repos",
"ghcr.io/github/github-mcp-server:latest"
]
},
"github-milestones": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--init",
"--stop-timeout=5",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"github-milestones-mcp-server:latest"
]
}
}
}
Now you have:
- Full GitHub functionality (issues, PRs, files) from the official server
- Complete milestone management from this dedicated server
š API Reference
Tool: list_milestones
List milestones for a repository.
Parameters:
owner
(string, required) - Repository ownerrepo
(string, required) - Repository namestate
(enum, optional) - Filter by state: 'open', 'closed', 'all'sort
(enum, optional) - Sort by: 'due_on', 'completeness'direction
(enum, optional) - Sort direction: 'asc', 'desc'per_page
(number, optional) - Results per page (1-100)page
(number, optional) - Page number
Tool: get_milestone
Get details of a specific milestone.
Parameters:
owner
(string, required) - Repository ownerrepo
(string, required) - Repository namemilestone_number
(number, required) - Milestone number
Tool: create_milestone
Create a new milestone.
Parameters:
owner
(string, required) - Repository ownerrepo
(string, required) - Repository nametitle
(string, required) - Milestone titledescription
(string, optional) - Milestone descriptiondue_on
(string, optional) - Due date (ISO 8601 format)state
(enum, optional) - Initial state: 'open', 'closed'
Tool: update_milestone
Update an existing milestone.
Parameters:
owner
(string, required) - Repository ownerrepo
(string, required) - Repository namemilestone_number
(number, required) - Milestone to updatetitle
(string, optional) - New titledescription
(string, optional) - New descriptiondue_on
(string, optional) - New due datestate
(enum, optional) - New state
Tool: delete_milestone
Delete a milestone.
Parameters:
owner
(string, required) - Repository ownerrepo
(string, required) - Repository namemilestone_number
(number, required) - Milestone to delete
š Security Considerations
- GitHub Token - Requires repo scope, store securely
- Input Validation - All inputs validated with Zod schemas
- Error Handling - No sensitive data leaked in error messages
- Rate Limiting - Inherits GitHub API rate limits (5000/hour)
š¤ Contributing
This project follows standard contribution practices:
- Issues - Use GitHub issues for bug reports and feature requests
- Pull Requests - Follow conventional commit format
- Code Style - ESLint configuration provided
- Testing - Add tests for new features
š License
MIT License - see file.
šāāļø Support
- GitHub Issues - Bug reports and feature requests
- Documentation - This README and inline code comments
- Community - Share improvements and use cases
š§ AI Development Notes
This section is for AI assistants continuing development
Current Implementation Status
- ā MCP Server Framework - Fully functional with proper tool registration
- ā GitHub Integration - Octokit client with authentication
- ā All CRUD Operations - Complete milestone management
- ā Type Safety - Zod schemas and TypeScript types
Next Development Priorities
- Error Handling - Improve error messages and recovery
- Testing - Add unit and integration tests
- Performance - Add caching and rate limit handling
- Documentation - Add more usage examples
Code Quality Guidelines
- Follow existing TypeScript patterns
- Maintain MCP protocol compliance
- Keep error messages user-friendly
- Use descriptive variable names
- Add JSDoc comments for public APIs
Known Issues to Address
- Rate limiting not implemented
- No retry logic for failed requests
- Error responses could be more actionable
- Missing integration tests
This project is ready for active development and production use!