Skip to main content
Glama

get-repo-context

Retrieve all files from a GitHub repository to provide context for AI models, with options to filter by file extensions and exclude specific paths.

Instructions

Get all files from a GitHub repository to use as context

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ownerYesGitHub repository owner/organization name
repoYesGitHub repository name
maxFilesNoMaximum number of files to include (default: 50)
fileExtensionsNoFile extensions to include (e.g., ['js', 'ts', 'md'])
excludePathsNoPaths to exclude (e.g., ['node_modules', 'dist'])

Implementation Reference

  • The main execution handler for the 'get-repo-context' tool. It fetches all files recursively from the GitHub repository, applies filters based on maxFiles, fileExtensions, and excludePaths, retrieves content for selected files, and returns formatted markdown text blocks.
    async ({ owner, repo, maxFiles = 50, fileExtensions = [], excludePaths = ['node_modules', 'dist', 'build'] }) => { try { console.error(`Fetching files from ${owner}/${repo}...`); const allFiles = await getAllFiles(owner, repo); console.error(`Found ${allFiles.length} total files in the repository`); let filteredFiles = allFiles.filter(file => { if (excludePaths.some(excludePath => file.path.includes(excludePath))) { return false; } if (fileExtensions.length > 0) { const extension = file.path.split('.').pop() || ''; return fileExtensions.includes(extension); } return true; }); filteredFiles = filteredFiles.slice(0, maxFiles); console.error(`Selected ${filteredFiles.length} files after filtering`); const fileContents: { path: string; content: string | null }[] = []; for (const file of filteredFiles) { if (file.type === 'file') { const content = await getFileContent(owner, repo, file.path); fileContents.push({ path: file.path, content }); } } const formattedContent = fileContents .filter(file => file.content !== null) .map(file => `File: ${file.path}\n\n\`\`\`\n${file.content}\n\`\`\`\n\n`) .join('---\n\n'); return { content: [ { type: "text", text: `Repository Context for ${owner}/${repo}:\n\n${formattedContent}`, }, ], }; } catch (error) { console.error("Error fetching repository context:", error); return { content: [ { type: "text", text: `Error fetching repository context: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } },
  • Input schema defined using Zod for the tool parameters: owner (string), repo (string), maxFiles (number, optional), fileExtensions (array of strings, optional), excludePaths (array of strings, optional).
    { owner: z.string().describe("GitHub repository owner/organization name"), repo: z.string().describe("GitHub repository name"), maxFiles: z.number().optional().describe("Maximum number of files to include (default: 50)"), fileExtensions: z.array(z.string()).optional().describe("File extensions to include (e.g., ['js', 'ts', 'md'])"), excludePaths: z.array(z.string()).optional().describe("Paths to exclude (e.g., ['node_modules', 'dist'])"), },
  • src/index.ts:84-153 (registration)
    Registration of the 'get-repo-context' tool using server.tool(), including name, description, input schema, and handler function.
    server.tool( "get-repo-context", "Get all files from a GitHub repository to use as context", { owner: z.string().describe("GitHub repository owner/organization name"), repo: z.string().describe("GitHub repository name"), maxFiles: z.number().optional().describe("Maximum number of files to include (default: 50)"), fileExtensions: z.array(z.string()).optional().describe("File extensions to include (e.g., ['js', 'ts', 'md'])"), excludePaths: z.array(z.string()).optional().describe("Paths to exclude (e.g., ['node_modules', 'dist'])"), }, async ({ owner, repo, maxFiles = 50, fileExtensions = [], excludePaths = ['node_modules', 'dist', 'build'] }) => { try { console.error(`Fetching files from ${owner}/${repo}...`); const allFiles = await getAllFiles(owner, repo); console.error(`Found ${allFiles.length} total files in the repository`); let filteredFiles = allFiles.filter(file => { if (excludePaths.some(excludePath => file.path.includes(excludePath))) { return false; } if (fileExtensions.length > 0) { const extension = file.path.split('.').pop() || ''; return fileExtensions.includes(extension); } return true; }); filteredFiles = filteredFiles.slice(0, maxFiles); console.error(`Selected ${filteredFiles.length} files after filtering`); const fileContents: { path: string; content: string | null }[] = []; for (const file of filteredFiles) { if (file.type === 'file') { const content = await getFileContent(owner, repo, file.path); fileContents.push({ path: file.path, content }); } } const formattedContent = fileContents .filter(file => file.content !== null) .map(file => `File: ${file.path}\n\n\`\`\`\n${file.content}\n\`\`\`\n\n`) .join('---\n\n'); return { content: [ { type: "text", text: `Repository Context for ${owner}/${repo}:\n\n${formattedContent}`, }, ], }; } catch (error) { console.error("Error fetching repository context:", error); return { content: [ { type: "text", text: `Error fetching repository context: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } }, );
  • Helper function getAllFiles() that recursively lists all files in the repository by traversing directories using GitHub API.
    async function getAllFiles(owner: string, repo: string, path: string = ""): Promise<{ path: string, type: string }[]> { const contents = await getRepoContents(owner, repo, path); let allFiles: { path: string, type: string }[] = []; for (const item of contents) { if (item.type === 'file') { allFiles.push({ path: item.path, type: 'file' }); } else if (item.type === 'dir') { const subFiles = await getAllFiles(owner, repo, item.path); allFiles = [...allFiles, ...subFiles]; } } return allFiles; }
  • Helper function getRepoContents() that fetches contents of a specific path in the repo using Octokit.
    async function getRepoContents(owner: string, repo: string, path: string = ""): Promise<any[]> { try { const response = await octokit.repos.getContent({ owner, repo, path, }); if (Array.isArray(response.data)) { return response.data; } else if (response.data && 'type' in response.data) { return [response.data]; } return []; } catch (error) { console.error(`Error getting repo contents for ${owner}/${repo}/${path}:`, error); return []; } }
  • Helper function getFileContent() that retrieves the base64-decoded content of a specific file.
    async function getFileContent(owner: string, repo: string, path: string): Promise<string | null> { try { const response = await octokit.repos.getContent({ owner, repo, path, }); if ('content' in response.data && 'encoding' in response.data) { if (response.data.encoding === 'base64') { return Buffer.from(response.data.content, 'base64').toString('utf-8'); } } return null; } catch (error) { console.error(`Error getting file content for ${owner}/${repo}/${path}:`, error); return null; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/shanksxz/gh-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server