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