create_repo
Create or update GitHub repositories using natural language commands to manage project descriptions, topics, and website URLs.
Instructions
Create or update GitHub repositories using natural language commands
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | Natural language command like "Create a repository for my machine learning project with tags python tensorflow" or "Update repository-name description to New description with tags updated ml" |
Implementation Reference
- src/index.ts:175-316 (handler)The core handler function registered for CallToolRequestSchema that implements the 'create_repo' tool logic. It validates input, parses the natural language command, calls GitHub Octokit API to create or update repositories, and formats the response.
this.server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name !== 'create_repo') { throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}` ); } if (!isValidRepoArgs(request.params.arguments)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid command format' ); } try { const parsed = parseCommand(request.params.arguments.command); let response; if (parsed.mode === 'create') { // Generate a repository name based on the description const repoName = parsed.description! .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, ''); // Create the repository response = await this.octokit.rest.repos.createForAuthenticatedUser({ name: repoName, description: parsed.description, homepage: parsed.website, topics: parsed.tags, auto_init: true, }); } else { // Handle different types of updates const [owner, repo] = parsed.name!.split('/'); switch (parsed.mode) { case 'update-description': response = await this.octokit.rest.repos.update({ owner, repo, description: parsed.description, }); break; case 'update-tags': response = await this.octokit.rest.repos.replaceAllTopics({ owner, repo, names: parsed.tags || [], }); break; case 'update-website': response = await this.octokit.rest.repos.update({ owner, repo, homepage: parsed.website, }); break; } } // Format response based on operation type const formatResponse = () => { switch (parsed.mode) { case 'create': { const repo = response.data as { html_url: string; name: string; description: string; topics: string[]; homepage: string | null; }; return { message: 'Repository created successfully', url: repo.html_url, name: repo.name, description: repo.description, topics: repo.topics, homepage: repo.homepage, }; } case 'update-description': { const repo = response.data as { name: string; description: string; }; return { message: 'Repository description updated', name: repo.name, description: repo.description, }; } case 'update-tags': { const topics = response.data as { names: string[]; }; return { message: 'Repository topics updated', topics: topics.names, }; } case 'update-website': { const repo = response.data as { name: string; homepage: string | null; }; return { message: 'Repository website updated', name: repo.name, homepage: repo.homepage, }; } } }; return { content: [ { type: 'text', text: JSON.stringify(formatResponse(), null, 2), }, ], }; } catch (error) { if (error instanceof Error) { return { content: [ { type: 'text', text: `GitHub API error: ${error.message}`, }, ], isError: true, }; } throw error; } }); - src/index.ts:158-171 (schema)The tool schema definition returned by ListToolsRequestSchema handler, specifying name, description, and inputSchema for 'create_repo'.
{ name: 'create_repo', description: 'Create or update GitHub repositories using natural language commands', inputSchema: { type: 'object', properties: { command: { type: 'string', description: 'Natural language command like "Create a repository for my machine learning project with tags python tensorflow" or "Update repository-name description to New description with tags updated ml"' } }, required: ['command'], }, }, - src/index.ts:156-173 (registration)Registration of the ListToolsRequestSchema handler that advertises the 'create_repo' tool.
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: 'create_repo', description: 'Create or update GitHub repositories using natural language commands', inputSchema: { type: 'object', properties: { command: { type: 'string', description: 'Natural language command like "Create a repository for my machine learning project with tags python tensorflow" or "Update repository-name description to New description with tags updated ml"' } }, required: ['command'], }, }, ], })); - src/index.ts:34-96 (helper)Key helper function that parses the natural language 'command' string into a structured ParsedCommand object used by the handler to determine action (create/update) and parameters.
const parseCommand = (command: string): ParsedCommand => { const lowercaseCommand = command.toLowerCase(); // Check for update commands if (lowercaseCommand.includes('update') || lowercaseCommand.includes('change') || lowercaseCommand.includes('set')) { // Extract repository name - common for all update commands const repoMatch = command.match(/(?:update|change|set|modify)\s+(?:the\s+)?(?:repository\s+)?([a-zA-Z0-9-_/]+)/i); if (!repoMatch) { throw new McpError(ErrorCode.InvalidParams, 'Repository name not found in update command'); } const repoName = repoMatch[1]; // Check for description update if (lowercaseCommand.includes('description')) { const descMatch = command.match(/description\s+(?:to|as)\s+["']?([^"']+)["']?/i); if (!descMatch) { throw new McpError(ErrorCode.InvalidParams, 'New description not found in update command'); } return { mode: 'update-description', name: repoName, description: descMatch[1].trim() }; } // Check for tags update if (lowercaseCommand.includes('tags') || lowercaseCommand.includes('topics')) { return { mode: 'update-tags', name: repoName, tags: extractTags(command) }; } // Check for website update if (lowercaseCommand.includes('website') || lowercaseCommand.includes('homepage') || lowercaseCommand.includes('url')) { const website = extractWebsite(command); if (!website) { throw new McpError(ErrorCode.InvalidParams, 'New website URL not found in update command'); } return { mode: 'update-website', name: repoName, website }; } throw new McpError(ErrorCode.InvalidParams, 'Unknown update type. Use "description", "tags", or "website".'); } // This is a create command const descMatch = command.match(/(?:create|make|new)\s+(?:a\s+)?(?:repository\s+)?(?:for|called|named)?\s+([^,\.]+)/i); if (!descMatch) { throw new McpError(ErrorCode.InvalidParams, 'Repository description not found in create command'); } return { mode: 'create', description: descMatch[1].trim(), tags: extractTags(command), website: extractWebsite(command) }; }; - src/index.ts:21-24 (helper)Type guard helper to validate that tool arguments contain a 'command' string.
const isValidRepoArgs = (args: any): args is RepoArgs => typeof args === 'object' && args !== null && typeof args.command === 'string';