Skip to main content
Glama

githubSearchRepositories

Search GitHub repositories by keywords or topics to discover open-source projects, using filters like stars, owner, and activity dates to refine results.

Instructions

Search repositories by keywords/topics

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queriesYesResearch queries for githubSearchRepositories (1-3 queries per call for optimal resource management). Review schema before use for optimal results

Implementation Reference

  • Core execution logic for the githubSearchRepositories tool: expands queries for topics/keywords, performs bulk GitHub repository searches via API, processes results, generates pagination and search-specific hints.
    async function searchMultipleGitHubRepos( queries: GitHubReposSearchQuery[], authInfo?: AuthInfo, sessionId?: string ): Promise<CallToolResult> { const expandedQueries = expandQueriesWithBothSearchTypes(queries); return executeBulkOperation( expandedQueries, async (query: GitHubReposSearchQuery, _index: number) => { try { const apiResult = await searchGitHubReposAPI( query, authInfo, sessionId ); const apiError = handleApiError(apiResult, query); if (apiError) return apiError; const repositories = 'data' in apiResult ? apiResult.data.repositories || [] : ([] satisfies SimplifiedRepository[]); const pagination = 'data' in apiResult ? apiResult.data.pagination : undefined; // Generate pagination hints with full context for navigation const paginationHints: string[] = []; if (pagination) { const { currentPage, totalPages, totalMatches, perPage, hasMore } = pagination; const startItem = (currentPage - 1) * perPage + 1; const endItem = Math.min(currentPage * perPage, totalMatches); // Main pagination summary paginationHints.push( `Page ${currentPage}/${totalPages} (showing ${startItem}-${endItem} of ${totalMatches} repos)` ); // Navigation hints if (hasMore) { paginationHints.push(`Next: page=${currentPage + 1}`); } if (currentPage > 1) { paginationHints.push(`Previous: page=${currentPage - 1}`); } if (!hasMore) { paginationHints.push('Final page'); } // Quick navigation hint for multi-page results if (totalPages > 2) { paginationHints.push( `Jump to: page=1 (first) or page=${totalPages} (last)` ); } } // Generate search-type specific hints from metadata const searchHints = generateSearchSpecificHints( query, repositories.length > 0 ); // Use unified pattern: extraHints for pagination and search-specific hints return createSuccessResult( query, { repositories, pagination }, repositories.length > 0, TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES, { extraHints: [...paginationHints, ...(searchHints || [])], } ); } catch (error) { return handleCatchError(error, query); } }, { toolName: TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES, keysPriority: ['repositories', 'pagination', 'error'] satisfies Array< keyof RepoSearchResult >, } ); }
  • Zod schema for input validation of githubSearchRepositories tool queries, supporting bulk queries with keywords/topics search, filters, sorting, and pagination.
    export const GitHubReposSearchQuerySchema = createBulkQuerySchema( TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES, GitHubReposSearchSingleQuerySchema );
  • Registers the githubSearchRepositories tool on the MCP server, specifying name, description, input schema, annotations, and security-wrapped handler function.
    export function registerSearchGitHubReposTool( server: McpServer, callback?: ToolInvocationCallback ) { return server.registerTool( TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES, { description: DESCRIPTIONS[TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES], inputSchema: GitHubReposSearchQuerySchema, annotations: { title: 'GitHub Repository Search', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, }, withSecurityValidation( TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES, async ( args: { queries: GitHubReposSearchQuery[]; }, authInfo, sessionId ): Promise<CallToolResult> => { const queries = args.queries || []; await invokeCallbackSafely( callback, TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES, queries ); return searchMultipleGitHubRepos(queries, authInfo, sessionId); } ) ); }
  • Helper function implementing the GitHub repository search API call using Octokit, query building, result mapping to simplified repositories, pagination calculation, and error handling.
    async function searchGitHubReposAPIInternal( params: GitHubReposSearchQuery, authInfo?: AuthInfo ): Promise< GitHubAPIResponse<{ repositories: SimplifiedRepository[]; pagination?: RepoSearchPagination; }> > { try { const octokit = await getOctokit(authInfo); const query = buildRepoSearchQuery(params); if (!query.trim()) { await logSessionError( TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES, SEARCH_ERRORS.QUERY_EMPTY.code ); return { error: SEARCH_ERRORS.QUERY_EMPTY.message, type: 'http', status: 400, }; } const perPage = Math.min(params.limit || 30, 100); const currentPage = params.page || 1; const searchParams: SearchReposParameters = { q: query, per_page: perPage, page: currentPage, }; if (params.sort && params.sort !== 'best-match') { searchParams.sort = params.sort as SearchReposParameters['sort']; } const result = await octokit.rest.search.repos(searchParams); const repositories = result.data.items.map((repo: RepoSearchResultItem) => { const fullName = repo.full_name; const parts = fullName.split('/'); const owner = parts[0] || ''; const repoName = parts[1] || ''; return { owner, repo: repoName, defaultBranch: repo.default_branch, stars: repo.stargazers_count || 0, description: repo.description ? repo.description.length > 150 ? repo.description.substring(0, 150) + '...' : repo.description : 'No description', url: repo.html_url, createdAt: repo.created_at, updatedAt: repo.updated_at, pushedAt: repo.pushed_at, visibility: repo.visibility, ...(repo.topics && repo.topics.length > 0 && { topics: repo.topics }), ...(repo.forks_count && repo.forks_count > 0 && { forksCount: repo.forks_count, }), ...(repo.open_issues_count && repo.open_issues_count > 0 && { openIssuesCount: repo.open_issues_count, }), }; }); // GitHub caps at 1000 total results const totalMatches = Math.min(result.data.total_count, 1000); const totalPages = Math.min(Math.ceil(totalMatches / perPage), 10); const hasMore = currentPage < totalPages; return { data: { repositories, pagination: { currentPage, totalPages, perPage, totalMatches, hasMore, }, }, status: 200, headers: result.headers, }; } catch (error: unknown) { return handleGitHubAPIError(error); } }
  • Tool configuration entry that defines and exports the registration function for githubSearchRepositories in the ALL_TOOLS array.
    export const GITHUB_SEARCH_REPOSITORIES: ToolConfig = { name: TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES, description: getDescription(TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES), isDefault: true, isLocal: false, type: 'search', fn: registerSearchGitHubReposTool, };

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/bgauryy/octocode-mcp'

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