Skip to content

Latest commit

 

History

History
414 lines (305 loc) · 7.38 KB

File metadata and controls

414 lines (305 loc) · 7.38 KB

Contributing to GitHub MCP Server

Thank you for considering contributing to the GitHub MCP Server! This document provides guidelines and instructions for contributing.

Code of Conduct

Be respectful, inclusive, and professional in all interactions.

Getting Started

Prerequisites

  • Node.js 18+
  • Git
  • GitHub account
  • GitHub Personal Access Token for testing

Setup Development Environment

  1. Fork the repository

  2. Clone your fork:

    git clone https://github.com/your-username/mcp-deployable.git
    cd mcp-deployable
  3. Install dependencies:

    npm install
  4. Set up environment:

    export GITHUB_TOKEN="your_github_token"
  5. Build the project:

    npm run build
  6. Run tests:

    npm test

Development Workflow

Making Changes

  1. Create a new branch:

    git checkout -b feature/your-feature-name
  2. Make your changes following our coding standards

  3. Write or update tests

  4. Ensure all tests pass:

    npm test
  5. Build to verify:

    npm run build
  6. Commit your changes:

    git commit -m "feat: add new feature"

Commit Message Guidelines

We follow Conventional Commits:

  • feat: - New feature
  • fix: - Bug fix
  • docs: - Documentation changes
  • test: - Test changes
  • refactor: - Code refactoring
  • chore: - Maintenance tasks
  • perf: - Performance improvements

Examples:

feat: add support for GitHub Issues
fix: handle rate limit errors correctly
docs: update deployment guide
test: add tests for merge_pr tool

Pull Request Process

  1. Update documentation if needed

  2. Add tests for new features

  3. Ensure all tests pass

  4. Update CHANGELOG.md

  5. Push to your fork:

    git push origin feature/your-feature-name
  6. Create a Pull Request with:

    • Clear title describing the change
    • Detailed description of what and why
    • Link to related issues
    • Screenshots if UI changes

Coding Standards

TypeScript

  • Use strict TypeScript configuration
  • Define types for all parameters and return values
  • Avoid any type unless absolutely necessary
  • Use meaningful variable and function names

Code Style

// Good
async function getPullRequest(params: GetPRParams): Promise<PullRequest> {
  const response = await this.octokit.rest.pulls.get({
    owner: params.owner,
    repo: params.repo,
    pull_number: params.pull_number,
  });
  
  return this.mapPullRequest(response.data);
}

// Bad
async function getPR(p: any): Promise<any> {
  const r = await this.octokit.rest.pulls.get(p);
  return r.data;
}

Validation

All tool inputs must use Zod schemas:

export const NewToolSchema = z.object({
  owner: z.string().min(1, 'Owner is required'),
  repo: z.string().min(1, 'Repository name is required'),
  // ... more fields
});

Error Handling

Always catch and transform errors:

try {
  // operation
} catch (error: any) {
  throw this.handleError(error);
}

Testing

Write tests for new features:

describe('New Tool', () => {
  it('should validate input correctly', () => {
    const validInput = { /* ... */ };
    const result = NewToolSchema.safeParse(validInput);
    expect(result.success).toBe(true);
  });
  
  it('should reject invalid input', () => {
    const invalidInput = { /* ... */ };
    const result = NewToolSchema.safeParse(invalidInput);
    expect(result.success).toBe(false);
  });
});

Adding New Tools

To add a new GitHub operation as a tool:

1. Define Types

Add to src/types/github.ts:

export interface NewToolParams {
  owner: string;
  repo: string;
  // ... parameters
}

export interface NewToolResult {
  // ... result fields
}

2. Create Schema

Add to src/server/schemas/tools.ts:

export const NewToolSchema = z.object({
  owner: z.string().min(1, 'Owner is required'),
  repo: z.string().min(1, 'Repository name is required'),
  // ... more fields
});

export type NewToolInput = z.infer<typeof NewToolSchema>;

3. Implement Method

Add to src/server/tools/github-tools.ts:

async newTool(params: NewToolParams): Promise<NewToolResult> {
  try {
    const response = await this.octokit.rest./* api call */;
    return /* mapped result */;
  } catch (error: any) {
    throw this.handleError(error);
  }
}

4. Register Tool

Add to src/server/index.ts:

// In TOOLS array
{
  name: 'new_tool',
  description: 'Description of what the tool does',
  inputSchema: {
    type: 'object',
    properties: {
      // ... JSON Schema
    },
    required: ['owner', 'repo'],
  },
}

// In CallToolRequestSchema handler
case 'new_tool': {
  const params = NewToolSchema.parse(args);
  result = await githubTools.newTool(params);
  break;
}

5. Add to Worker

Add to src/worker.ts:

// In TOOLS array
{
  name: 'new_tool',
  description: 'Description',
}

// In switch statement
case 'new_tool': {
  const params = NewToolSchema.parse(args);
  result = await githubTools.newTool(params);
  break;
}

6. Write Tests

Add to tests/golden/github-tools.test.ts:

describe('New Tool', () => {
  it('should validate new_tool input', () => {
    const validInput = { /* ... */ };
    const result = NewToolSchema.safeParse(validInput);
    expect(result.success).toBe(true);
  });
  
  // More tests...
});

7. Update Documentation

  • Add example to EXAMPLES.md
  • Update tool list in README.md
  • Add to QUICKSTART.md if relevant

Testing Guidelines

Unit Tests

Test individual components:

npm test

Golden Tests

Test with known-good data:

npm run test:golden

Manual Testing

Test with the example client:

npm run client

Integration Testing

For testing against real GitHub API:

  1. Use a test repository
  2. Create test PRs
  3. Run operations
  4. Verify results
  5. Clean up test data

Documentation

Code Comments

  • Use JSDoc for public APIs
  • Explain complex logic
  • Document assumptions and edge cases
/**
 * Merge a pull request using the specified method
 * @param params - Merge parameters
 * @returns Merge result with SHA and status
 * @throws Error if PR is not mergeable or conflicts exist
 */
async mergePR(params: MergePRParams): Promise<MergeResult> {
  // implementation
}

README Updates

Update documentation when:

  • Adding new features
  • Changing APIs
  • Modifying setup process
  • Adding dependencies

Performance

  • Minimize API calls
  • Use appropriate filters
  • Cache when possible
  • Handle rate limits gracefully

Security

  • Never commit tokens or secrets
  • Validate all inputs
  • Sanitize error messages
  • Use least privilege access
  • Follow GitHub's security best practices

Releasing

Maintainers handle releases:

  1. Update version in package.json
  2. Update CHANGELOG.md
  3. Create git tag
  4. Publish to npm (if applicable)
  5. Create GitHub release

Getting Help

  • Check existing issues and PRs
  • Read documentation thoroughly
  • Ask in GitHub Discussions
  • Be specific about your question

Recognition

Contributors will be:

  • Listed in CHANGELOG.md
  • Mentioned in release notes
  • Added to contributors list

License

By contributing, you agree that your contributions will be licensed under the MIT License.

Thank you for contributing! 🎉