UNPKG

jaegis-github-mcp-server

Version:

GitHub MCP Server - AI-powered Model Context Protocol server with JAEGIS AI documentation intelligence, natural language workflows, and 45+ comprehensive GitHub tools

1,082 lines (1,070 loc) • 297 kB
#!/usr/bin/env node "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js"); const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); const types_js_1 = require("@modelcontextprotocol/sdk/types.js"); const rest_1 = require("@octokit/rest"); const dotenv = __importStar(require("dotenv")); const fs = __importStar(require("fs")); const path = __importStar(require("path")); // Command line argument parsing const args = process.argv.slice(2); const hasListTools = args.includes('--list-tools'); const hasToolsJson = args.includes('--tools-json'); const hasHelp = args.includes('--help') || args.includes('-h'); const formatTable = args.includes('--format=table'); // Security: Credential sanitization function sanitizeCredential(value) { if (!value || value.length < 8) return '****'; return `${value.substring(0, 4)}****...****${value.substring(value.length - 4)}`; } function sanitizeEnvVars(env) { const sensitiveKeys = ['TOKEN', 'KEY', 'SECRET', 'PASSWORD', 'API_']; const sanitized = { ...env }; Object.keys(sanitized).forEach(key => { if (sensitiveKeys.some(sensitive => key.toUpperCase().includes(sensitive))) { sanitized[key] = sanitizeCredential(sanitized[key]); } }); return sanitized; } // Helper function to get package directory function getPackageDirectory() { // Try to find package.json starting from current file location let currentDir = __dirname; while (currentDir !== path.dirname(currentDir)) { const packageJsonPath = path.join(currentDir, 'package.json'); if (fs.existsSync(packageJsonPath)) { try { const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); if (packageJson.name === 'github-mcp-server') { return currentDir; } } catch (error) { // Continue searching } } currentDir = path.dirname(currentDir); } // Fallback to current working directory return process.cwd(); } // Load environment variables from multiple locations function loadEnvironmentVariables() { const packageDir = getPackageDirectory(); const envPaths = [ // Package directory (when installed as npm package) path.join(packageDir, '.env'), // Current working directory (when run from project) path.join(process.cwd(), '.env'), // User home directory path.join(process.env.HOME || process.env.USERPROFILE || '', '.mcp', '.env'), ]; for (const envPath of envPaths) { if (fs.existsSync(envPath)) { dotenv.config({ path: envPath }); console.log(`Loaded environment variables from: ${envPath}`); break; } } // Also try default dotenv loading dotenv.config(); } // Load environment variables loadEnvironmentVariables(); // Helper function to normalize paths for GitHub API (always uses forward slashes) function normalizeGitHubPath(filePath) { return filePath.replace(/\\/g, '/'); } function showHelp() { console.log(` GitHub MCP Server v3.1.0 - AI-powered GitHub automation with 45+ tools USAGE: github-mcp-server [OPTIONS] OPTIONS: --list-tools List all available tools with descriptions --tools-json Output complete MCP tools schema as JSON --format=table Use table format for tool listings (default: JSON) --help, -h Show this help message ENVIRONMENT VARIABLES: GITHUB_TOKEN GitHub personal access token (required) Format: ghp_* or github_pat_* Generate at: https://github.com/settings/tokens GITHUB_USERNAME GitHub username (required) GITHUB_EMAIL GitHub email (optional) EXAMPLES: # List all tools in table format github-mcp-server --list-tools --format=table # Get tools schema for MCP client integration github-mcp-server --tools-json # Start the MCP server (default) github-mcp-server QUICK SETUP: 1. Generate GitHub token: https://github.com/settings/tokens 2. Set environment variables: export GITHUB_TOKEN=ghp_your_token_here export GITHUB_USERNAME=your_username 3. Run: github-mcp-server For detailed documentation, see: README.md `); } function getToolsInfo() { return [ // Core GitHub Tools { name: 'create_repository', category: 'Repository Management', description: 'Create a new GitHub repository with optional configuration', requiredParams: ['name'], optionalParams: ['description', 'private', 'auto_init', 'gitignore_template'], inputSchema: { type: 'object', properties: { name: { type: 'string' } } } }, { name: 'get_repository', category: 'Repository Management', description: 'Get detailed information about a repository', requiredParams: ['owner', 'repo'], optionalParams: ['account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, { name: 'list_repositories', category: 'Repository Management', description: 'List repositories for a user or organization', requiredParams: [], optionalParams: ['username', 'type', 'sort', 'per_page'], inputSchema: { type: 'object', properties: {} } }, { name: 'update_repository', category: 'Repository Management', description: 'Update repository settings and configuration', requiredParams: ['owner', 'repo'], optionalParams: ['name', 'description', 'private', 'has_issues', 'has_projects'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, { name: 'delete_repository', category: 'Repository Management', description: 'Delete a repository (irreversible action)', requiredParams: ['owner', 'repo'], optionalParams: ['account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, // File Operations { name: 'create_file', category: 'File Operations', description: 'Create a new file in a repository', requiredParams: ['owner', 'repo', 'path', 'content', 'message'], optionalParams: ['branch', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, path: { type: 'string' } } } }, { name: 'get_file', category: 'File Operations', description: 'Get file content and metadata from repository', requiredParams: ['owner', 'repo', 'path'], optionalParams: ['ref', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, path: { type: 'string' } } } }, { name: 'update_file', category: 'File Operations', description: 'Update existing file content in repository', requiredParams: ['owner', 'repo', 'path', 'content', 'message', 'sha'], optionalParams: ['branch', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, path: { type: 'string' } } } }, { name: 'delete_file', category: 'File Operations', description: 'Delete a file from repository', requiredParams: ['owner', 'repo', 'path', 'message', 'sha'], optionalParams: ['branch', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, path: { type: 'string' } } } }, // Branch Management { name: 'create_branch', category: 'Branch Management', description: 'Create a new branch from existing branch or commit', requiredParams: ['owner', 'repo', 'branch_name', 'from_branch'], optionalParams: ['account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, branch_name: { type: 'string' } } } }, { name: 'list_branches', category: 'Branch Management', description: 'List all branches in a repository', requiredParams: ['owner', 'repo'], optionalParams: ['account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, { name: 'delete_branch', category: 'Branch Management', description: 'Delete a branch from repository', requiredParams: ['owner', 'repo', 'branch_name'], optionalParams: ['account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, branch_name: { type: 'string' } } } }, // Pull Requests { name: 'create_pull_request', category: 'Pull Requests', description: 'Create a new pull request between branches', requiredParams: ['owner', 'repo', 'title', 'head', 'base'], optionalParams: ['body', 'draft', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, title: { type: 'string' } } } }, { name: 'list_pull_requests', category: 'Pull Requests', description: 'List pull requests with filtering options', requiredParams: ['owner', 'repo'], optionalParams: ['state', 'head', 'base', 'sort', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, { name: 'merge_pull_request', category: 'Pull Requests', description: 'Merge a pull request using specified strategy', requiredParams: ['owner', 'repo', 'pull_number'], optionalParams: ['commit_title', 'commit_message', 'merge_method', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, pull_number: { type: 'number' } } } }, // Issues { name: 'create_issue', category: 'Issues', description: 'Create a new issue with title and description', requiredParams: ['owner', 'repo', 'title'], optionalParams: ['body', 'assignees', 'labels', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, title: { type: 'string' } } } }, { name: 'list_issues', category: 'Issues', description: 'List issues with filtering and sorting options', requiredParams: ['owner', 'repo'], optionalParams: ['state', 'labels', 'sort', 'direction', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, { name: 'update_issue', category: 'Issues', description: 'Update issue title, body, state, or labels', requiredParams: ['owner', 'repo', 'issue_number'], optionalParams: ['title', 'body', 'state', 'labels', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, issue_number: { type: 'number' } } } }, // Advanced Repository Management (8 tools) { name: 'reorganize_repository', category: 'Advanced Repository Management', description: 'Smart repository restructuring with file organization', requiredParams: ['owner', 'repo', 'reorganization_plan'], optionalParams: ['commit_message', 'create_backup_branch', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, { name: 'bulk_upload_with_structure', category: 'Advanced Repository Management', description: 'Upload multiple files maintaining directory structure', requiredParams: ['owner', 'repo', 'files'], optionalParams: ['base_path', 'commit_message', 'branch', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, files: { type: 'array' } } } }, { name: 'smart_bulk_upload', category: 'Advanced Repository Management', description: 'Intelligent bulk upload with file filtering and optimization', requiredParams: ['owner', 'repo', 'files'], optionalParams: ['filters', 'optimization_rules', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, files: { type: 'array' } } } }, { name: 'batch_file_operations', category: 'Advanced Repository Management', description: 'Coordinated multi-file operations in single transaction', requiredParams: ['owner', 'repo', 'operations'], optionalParams: ['commit_message', 'branch', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, operations: { type: 'array' } } } }, { name: 'sync_local_to_remote', category: 'Advanced Repository Management', description: 'Bidirectional synchronization between local and remote', requiredParams: ['owner', 'repo', 'local_path'], optionalParams: ['sync_direction', 'exclude_patterns', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' }, local_path: { type: 'string' } } } }, { name: 'merge_repositories', category: 'Advanced Repository Management', description: 'Multi-repository consolidation with history preservation', requiredParams: ['target_owner', 'target_repo', 'source_repositories'], optionalParams: ['merge_strategy', 'preserve_history', 'account'], inputSchema: { type: 'object', properties: { target_owner: { type: 'string' }, target_repo: { type: 'string' } } } }, { name: 'clone_and_modify', category: 'Advanced Repository Management', description: 'Template-based repository creation with modifications', requiredParams: ['template_owner', 'template_repo', 'new_owner', 'new_repo'], optionalParams: ['modifications', 'account'], inputSchema: { type: 'object', properties: { template_owner: { type: 'string' }, template_repo: { type: 'string' } } } }, { name: 'cross_account_transfer', category: 'Advanced Repository Management', description: 'Cross-account repository transfers with permission management', requiredParams: ['source_account', 'target_account', 'source_owner', 'source_repo', 'target_owner', 'target_repo'], optionalParams: ['transfer_settings', 'preserve_settings'], inputSchema: { type: 'object', properties: { source_account: { type: 'string' }, target_account: { type: 'string' } } } }, // JAEGIS AI Documentation Intelligence (5 tools) { name: 'analyze_documentation_quality', category: 'JAEGIS AI Documentation Intelligence', description: 'AI-powered documentation analysis with quality scoring and improvements', requiredParams: ['owner', 'repo'], optionalParams: ['analysis_scope', 'quality_standards', 'generate_improvements', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, { name: 'track_development_velocity', category: 'JAEGIS AI Documentation Intelligence', description: 'Development velocity tracking with AI vs Human metrics and insights', requiredParams: ['owner', 'repo'], optionalParams: ['time_period', 'include_ai_metrics', 'generate_report', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, { name: 'monitor_repository_intelligence', category: 'JAEGIS AI Documentation Intelligence', description: 'AI-powered repository monitoring with intelligent insights', requiredParams: ['owner', 'repo'], optionalParams: ['monitoring_scope', 'alert_thresholds', 'generate_insights', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, { name: 'analyze_dependencies_intelligence', category: 'JAEGIS AI Documentation Intelligence', description: 'Smart dependency analysis with security and modernization insights', requiredParams: ['owner', 'repo'], optionalParams: ['analysis_depth', 'include_security_scan', 'modernization_recommendations', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, { name: 'generate_mermaid_diagrams', category: 'JAEGIS AI Documentation Intelligence', description: 'AI-powered Mermaid diagram generation with code-synchronized updates', requiredParams: ['owner', 'repo'], optionalParams: ['diagram_types', 'auto_update', 'embed_in_readme', 'account'], inputSchema: { type: 'object', properties: { owner: { type: 'string' }, repo: { type: 'string' } } } }, // Natural Language Workflows { name: 'execute_workflow', category: 'Natural Language Workflows', description: 'Execute complex multi-step workflows using natural language commands', requiredParams: ['workflow_description'], optionalParams: ['context', 'dry_run', 'account'], inputSchema: { type: 'object', properties: { workflow_description: { type: 'string' } } } } ]; } function displayToolsTable(tools) { console.log('\nšŸ“Š GitHub MCP Server - Tool Inventory\n'); console.log('ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”'); console.log('│ Tool Name │ Category │ Required │ Optional │'); console.log('ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤'); tools.forEach(tool => { const name = tool.name.padEnd(35); const category = tool.category.padEnd(32); const required = tool.requiredParams.length.toString().padEnd(8); const optional = tool.optionalParams.length.toString().padEnd(8); console.log(`│ ${name} │ ${category} │ ${required} │ ${optional} │`); }); console.log('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜'); // Summary by category const categories = tools.reduce((acc, tool) => { acc[tool.category] = (acc[tool.category] || 0) + 1; return acc; }, {}); console.log('\nšŸ“‹ Tool Summary by Category:'); Object.entries(categories).forEach(([category, count]) => { console.log(` • ${category}: ${count} tools`); }); console.log(`\nšŸŽÆ Total: ${tools.length} tools available\n`); } function displayToolsJson(tools, includeSchema = false) { const output = { server: 'github-mcp-server', version: '3.1.0', totalTools: tools.length, categories: tools.reduce((acc, tool) => { acc[tool.category] = (acc[tool.category] || 0) + 1; return acc; }, {}), tools: tools.map(tool => ({ name: tool.name, category: tool.category, description: tool.description, parameters: { required: tool.requiredParams, optional: tool.optionalParams, total: tool.requiredParams.length + tool.optionalParams.length }, ...(includeSchema && { inputSchema: tool.inputSchema }) })) }; console.log(JSON.stringify(output, null, 2)); } // Handle command line arguments before server initialization if (hasHelp) { showHelp(); process.exit(0); } if (hasListTools || hasToolsJson) { const tools = getToolsInfo(); if (hasToolsJson) { displayToolsJson(tools, true); } else if (formatTable) { displayToolsTable(tools); } else { displayToolsJson(tools, false); } process.exit(0); } class GitHubMCPServer { server; octokit; config; octokitInstances = {}; constructor() { this.config = this.loadConfig(); this.validateConfiguration(); this.initializeOctokitInstances(); // Maintain backward compatibility with single token this.octokit = this.getOctokit(); this.server = new index_js_1.Server({ name: 'github-mcp-server', version: '3.1.0', }, { capabilities: { tools: {}, }, }); this.setupToolHandlers(); this.setupErrorHandling(); } loadConfig() { // Get package directory for portable configuration loading const packageDir = getPackageDirectory(); // Try to load from JSON file first - check multiple locations const configPaths = [ // Package directory (when installed as npm package) path.join(packageDir, 'config.json'), path.join(packageDir, 'github-config.json'), // Current working directory (when run from project) path.join(process.cwd(), 'config.json'), path.join(process.cwd(), 'github-config.json'), // User home directory path.join(process.env.HOME || process.env.USERPROFILE || '', '.mcp', 'github-config.json'), // System-wide configuration path.join(process.env.HOME || process.env.USERPROFILE || '', '.config', 'github-mcp-server', 'config.json'), ]; for (const configPath of configPaths) { if (fs.existsSync(configPath)) { try { const configData = JSON.parse(fs.readFileSync(configPath, 'utf8')); console.log(`Loaded configuration from: ${configPath}`); return { ...configData, token: configData.token || process.env.GITHUB_TOKEN, username: configData.username || process.env.GITHUB_USERNAME }; } catch (error) { console.warn(`Failed to load config from ${configPath}:`, error); } } } console.log('No configuration file found, using environment variables'); // Fallback to environment variables const token = process.env.GITHUB_TOKEN; const username = process.env.GITHUB_USERNAME; if (!token) { const packageDir = getPackageDirectory(); throw new Error(`GitHub token is required. Please either: 1. Set GITHUB_TOKEN environment variable 2. Create a .env file in: ${packageDir} or ${process.cwd()} 3. Create a config.json file in one of these locations: - ${packageDir} - ${process.cwd()} - ${path.join(process.env.HOME || process.env.USERPROFILE || '', '.mcp')} - ${path.join(process.env.HOME || process.env.USERPROFILE || '', '.config', 'github-mcp-server')} See the setup guide for detailed instructions.`); } if (!username) { throw new Error(`GitHub username is required. Please either: 1. Set GITHUB_USERNAME environment variable 2. Add username to your .env or config.json file See the setup guide for detailed instructions.`); } return { token, username, accounts: { [username]: { username, token, email: process.env.GITHUB_EMAIL || `${username}@example.com`, default: true } }, currentAccount: username }; } initializeOctokitInstances() { if (this.config.accounts) { for (const [accountName, account] of Object.entries(this.config.accounts)) { this.octokitInstances[accountName] = new rest_1.Octokit({ auth: account.token, }); } } } getOctokit(account) { if (this.config.accounts && account) { return this.octokitInstances[account] || this.octokitInstances[Object.keys(this.octokitInstances)[0]]; } if (this.config.accounts && this.config.currentAccount) { return this.octokitInstances[this.config.currentAccount] || this.octokitInstances[Object.keys(this.octokitInstances)[0]]; } // Fallback to single instance if (!this.octokit) { this.octokit = new rest_1.Octokit({ auth: this.config.token }); } return this.octokit; } getAccountInfo(account) { if (!this.config.accounts) return null; const accountName = account || this.config.currentAccount || Object.keys(this.config.accounts)[0]; return this.config.accounts[accountName] || null; } setupErrorHandling() { this.server.onerror = (error) => { console.error('[MCP Error]', error); }; process.on('SIGINT', async () => { await this.server.close(); process.exit(0); }); } setupToolHandlers() { this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => { return { tools: [ // Account Management Tools { name: 'switch_account', description: 'Switch to a different GitHub account', inputSchema: { type: 'object', properties: { account: { type: 'string', description: 'Account name to switch to' } }, required: ['account'] } }, { name: 'list_accounts', description: 'List all configured GitHub accounts', inputSchema: { type: 'object', properties: {} } }, // Repository Management Tools { name: 'list_repositories', description: 'List repositories for the authenticated user', inputSchema: { type: 'object', properties: { account: { type: 'string', description: 'Account to use (optional)' }, type: { type: 'string', enum: ['all', 'owner', 'public', 'private', 'member'], description: 'Type of repositories to list', default: 'all' }, sort: { type: 'string', enum: ['created', 'updated', 'pushed', 'full_name'], description: 'Sort repositories by', default: 'updated' }, per_page: { type: 'number', description: 'Number of repositories per page (max 100)', default: 30, maximum: 100 } } } }, { name: 'get_repository', description: 'Get information about a specific repository', inputSchema: { type: 'object', properties: { account: { type: 'string', description: 'Account to use (optional)' }, owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' } }, required: ['owner', 'repo'] } }, { name: 'create_repository', description: 'Create a new repository', inputSchema: { type: 'object', properties: { account: { type: 'string', description: 'Account to use (optional)' }, name: { type: 'string', description: 'Repository name' }, description: { type: 'string', description: 'Repository description' }, private: { type: 'boolean', description: 'Whether the repository is private', default: false }, auto_init: { type: 'boolean', description: 'Whether to initialize with README', default: true } }, required: ['name'] } }, { name: 'get_user_info', description: 'Get information about the authenticated user', inputSchema: { type: 'object', properties: {} } }, { name: 'list_issues', description: 'List issues for a repository', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, state: { type: 'string', enum: ['open', 'closed', 'all'], description: 'Issue state', default: 'open' } }, required: ['owner', 'repo'] } }, { name: 'create_issue', description: 'Create a new issue in a repository', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, title: { type: 'string', description: 'Issue title' }, body: { type: 'string', description: 'Issue body/description' } }, required: ['owner', 'repo', 'title'] } }, { name: 'get_file_content', description: 'Get the content of a file from a repository', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, path: { type: 'string', description: 'File path in the repository' }, ref: { type: 'string', description: 'Branch, tag, or commit SHA', default: 'main' } }, required: ['owner', 'repo', 'path'] } }, // File Management Tools { name: 'upload_file', description: 'Create or upload a new file to a repository', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, path: { type: 'string', description: 'File path in the repository' }, content: { type: 'string', description: 'File content' }, message: { type: 'string', description: 'Commit message' }, branch: { type: 'string', description: 'Branch name', default: 'main' }, encoding: { type: 'string', description: 'Content encoding', default: 'utf-8' } }, required: ['owner', 'repo', 'path', 'content', 'message'] } }, { name: 'update_file', description: 'Update existing file content in a repository', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, path: { type: 'string', description: 'File path in the repository' }, content: { type: 'string', description: 'New file content' }, message: { type: 'string', description: 'Commit message' }, branch: { type: 'string', description: 'Branch name', default: 'main' }, sha: { type: 'string', description: 'Current file SHA (required for updates)' } }, required: ['owner', 'repo', 'path', 'content', 'message', 'sha'] } }, { name: 'delete_file', description: 'Delete a file from a repository', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, path: { type: 'string', description: 'File path in the repository' }, message: { type: 'string', description: 'Commit message' }, branch: { type: 'string', description: 'Branch name', default: 'main' }, sha: { type: 'string', description: 'Current file SHA (required for deletion)' } }, required: ['owner', 'repo', 'path', 'message', 'sha'] } }, { name: 'create_directory', description: 'Create a new directory by adding a placeholder file', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, path: { type: 'string', description: 'Directory path' }, message: { type: 'string', description: 'Commit message' }, branch: { type: 'string', description: 'Branch name', default: 'main' } }, required: ['owner', 'repo', 'path', 'message'] } }, // Branch Operations { name: 'create_branch', description: 'Create a new branch from an existing branch', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, branch_name: { type: 'string', description: 'Name of the new branch' }, from_branch: { type: 'string', description: 'Source branch to create from', default: 'main' } }, required: ['owner', 'repo', 'branch_name'] } }, { name: 'list_branches', description: 'List all branches in a repository', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, protected: { type: 'boolean', description: 'Filter by protection status' } }, required: ['owner', 'repo'] } }, { name: 'merge_branch', description: 'Merge one branch into another', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, base: { type: 'string', description: 'Target branch (merge into)' }, head: { type: 'string', description: 'Source branch (merge from)' }, commit_message: { type: 'string', description: 'Merge commit message' } }, required: ['owner', 'repo', 'base', 'head'] } }, { name: 'delete_branch', description: 'Delete a branch from the repository', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, branch: { type: 'string', description: 'Branch name to delete' } }, required: ['owner', 'repo', 'branch'] } }, // Commit Operations { name: 'get_commit_history', description: 'Get commit history for a repository or specific branch', inputSchema: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner username' }, repo: { type: 'string', description: 'Repository name' }, sha: { type: 'string', description: 'Branch name or commit SHA'