get-repositories
Retrieve Azure DevOps project repositories with optional links to manage codebase access across multiple organizations.
Instructions
Get repositories from Azure DevOps project
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| includeLinks | No | Include repository links in response |
Implementation Reference
- src/handlers/tool-handlers.ts:915-940 (handler)Executes the get-repositories tool by calling the Azure DevOps Git repositories API endpoint '/git/repositories', processes the response to extract key repository information, and formats it as MCP content.private async getRepositories(args: any): Promise<any> { try { const result = await this.makeApiRequest('/git/repositories?api-version=7.1'); const repositories = result.value.map((repo: any) => ({ id: repo.id, name: repo.name, url: repo.webUrl, defaultBranch: repo.defaultBranch, size: repo.size, ...(args.includeLinks && { links: repo._links }) })); return { content: [{ type: 'text', text: JSON.stringify({ count: repositories.length, repositories }, null, 2), }], }; } catch (error) { throw new Error(`Failed to get repositories: ${error instanceof Error ? error.message : 'Unknown error'}`); } }
- src/index.ts:229-241 (registration)Registers the 'get-repositories' tool in the MCP server's listTools response, providing the tool name, description, and input schema.{ name: 'get-repositories', description: 'Get repositories from Azure DevOps project', inputSchema: { type: 'object', properties: { includeLinks: { type: 'boolean', description: 'Include repository links in response', }, }, }, },
- src/handlers/tool-handlers.ts:41-42 (handler)Switch case in handleToolCall method that dispatches tool calls named 'get-repositories' to the getRepositories handler method.case 'get-repositories': return await this.getRepositories(args || {});
- src/handlers/tool-handlers.ts:71-131 (helper)Helper method used by getRepositories to make authenticated API requests to Azure DevOps.private async makeApiRequest(endpoint: string, method: string = 'GET', body?: any): Promise<any> { if (!this.currentConfig) { throw new Error('No configuration available'); } const { organizationUrl, pat, project } = this.currentConfig; const baseUrl = `${organizationUrl}/${project}/_apis`; const requestUrl = `${baseUrl}${endpoint}`; return new Promise((resolve, reject) => { const urlParts = new url.URL(requestUrl); const postData = body ? JSON.stringify(body) : undefined; const options = { hostname: urlParts.hostname, port: urlParts.port || 443, path: urlParts.pathname + urlParts.search, method, headers: { 'Authorization': `Basic ${Buffer.from(`:${pat}`).toString('base64')}`, 'Content-Type': method === 'PATCH' && endpoint.includes('/wit/workitems/') ? 'application/json-patch+json' : 'application/json', 'Accept': 'application/json', // For preview APIs, we need to properly handle the API version in the URL, not headers ...(postData && { 'Content-Length': Buffer.byteLength(postData) }), }, }; const req = https.request(options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { try { if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) { const result = data ? JSON.parse(data) : {}; resolve(result); } else { reject(new Error(`HTTP ${res.statusCode}: ${data}`)); } } catch (error) { reject(new Error(`Failed to parse response: ${error}`)); } }); }); req.on('error', (error) => { reject(new Error(`Request failed: ${error.message}`)); }); if (postData) { req.write(postData); } req.end(); }); }