Motivation
I absolutely love using Cursor IDE for all my development work. As someone who works extensively with GitHub for both personal and professional projects, I wanted to bring GitHub's powerful API capabilities directly into my Cursor workflow. Building an MCP server felt like the perfect way to achieve this while also getting hands-on experience with the MCP protocol. This project lets me access GitHub data and operations right from Cursor's command palette, making my development process much more streamlined.
Implementation
Let's walk through building a GitHub MCP server step by step. We'll create a server that can interact with GitHub's REST API v3 and expose its functionality through MCP tools.
Project Structure
First, let's set up our project structure:
mkdir github-mcp-server
cd github-mcp-server
npm init -y
# Create the basic file structure
mkdir src
touch src/server.ts src/main.ts
Install Dependencies
Add the required dependencies to package.json:
npm install @cursor-io/mcp-server@latest
npm install axios zod dotenv
npm install typescript @types/node --save-dev
Environment Setup
Create a .env
file for GitHub authentication:
GITHUB_TOKEN=your_personal_access_token
Server Implementation
Let's implement the server in src/server.ts
:
import { McpServer } from '@cursor-io/mcp-server';
import { z } from 'zod';
import axios from 'axios';
import dotenv from 'dotenv';
// Load environment variables
dotenv.config();
// Validate environment
const envSchema = z.object({
GITHUB_TOKEN: z.string().min(1),
});
const env = envSchema.parse(process.env);
// Create GitHub API client
const githubClient = axios.create({
baseURL: 'https://api.github.com',
headers: {
Authorization: `Bearer ${env.GITHUB_TOKEN}`,
Accept: 'application/vnd.github.v3+json',
},
});
// Create MCP server instance
export const mcpServer = new McpServer({
name: 'github',
version: '1.0.0',
});
// Add tools
mcpServer.tool({
name: 'list_repos',
description: 'List repositories for the authenticated user',
parameters: z.object({
per_page: z.number().optional().default(30),
page: z.number().optional().default(1),
}),
handler: async (params) => {
const response = await githubClient.get('/user/repos', {
params: {
per_page: params.per_page,
page: params.page,
},
});
return response.data.map((repo: any) => ({
name: repo.name,
full_name: repo.full_name,
description: repo.description,
url: repo.html_url,
}));
},
});
mcpServer.tool({
name: 'create_issue',
description: 'Create a new issue in a repository',
parameters: z.object({
owner: z.string(),
repo: z.string(),
title: z.string(),
body: z.string(),
}),
handler: async (params) => {
const response = await githubClient.post(
`/repos/${params.owner}/${params.repo}/issues`,
{
title: params.title,
body: params.body,
}
);
return {
number: response.data.number,
url: response.data.html_url,
title: response.data.title,
};
},
});
Entry Point
Create the entry point in src/main.ts
:
import { mcpServer } from './server';
async function main() {
await mcpServer.listen();
console.log('GitHub MCP server running...');
}
main().catch(console.error);
Usage
Let's go through how to set up and use the GitHub MCP server with Cursor IDE.
Global Installation
Install the package globally:
npm install -g github-mcp-server
Configure Cursor
Add the GitHub MCP server to your Cursor configuration by editing ~/.cursor/mcp.json
:
{
"servers": [
{
"name": "github",
"command": "github-mcp-server"
}
]
}
Example Prompts
Here are some example prompts you can use in Cursor:
- List your repositories:
List my GitHub repositories and show their descriptions
Response:
Here are your GitHub repositories:
1. my-awesome-project
Description: A collection of useful utilities
URL: https://github.com/username/my-awesome-project
2. personal-website
Description: My personal portfolio website
URL: https://github.com/username/personal-website
- Create an issue:
Create a GitHub issue in my-awesome-project titled "Add authentication feature" with description "Implement OAuth2 authentication flow"
Response:
Created issue #42 in my-awesome-project:
Title: Add authentication feature
URL: https://github.com/username/my-awesome-project/issues/42
- Check repository status:
Show me the status of my latest commits in the main branch
Response:
Latest commit status for main branch:
- SHA: abc123
- Message: "Update README.md"
- Author: username
- Timestamp: 2024-01-09T10:30:00Z
How It Works
Here's a sequence diagram showing how the GitHub MCP server integrates with Cursor IDE:
Rendering diagram...
The diagram shows how user requests flow through the system, from the initial prompt in Cursor IDE through the MCP server and GitHub API, and back to the user with the results.