Skip to main content
Glama
pdogra1299
by pdogra1299

search_code

Find code snippets across Bitbucket repositories using context-aware search patterns. Filter by workspace, repository, file type, or specific code contexts like assignments, declarations, or usages.

Instructions

Search for code across Bitbucket repositories with enhanced context-aware search patterns (currently only supported for Bitbucket Server)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
file_patternNoFile path pattern to filter results (e.g., "*.java", "src/**/*.ts") (optional)
include_patternsNoAdditional custom search patterns to include (e.g., ["variable =", ".variable"]) (optional)
limitNoMaximum number of results to return (default: 25)
repositoryNoRepository slug to search in (optional, searches all repos if not specified)
search_contextNoContext to search for: assignment (term=value), declaration (defining term), usage (calling/accessing term), exact (quoted match), or any (all patterns)
search_queryYesThe search term or phrase to look for in code (e.g., "variable")
startNoStart index for pagination (default: 0)
workspaceYesBitbucket workspace/project key (e.g., "PROJ")

Implementation Reference

  • Main handler function executing the search_code tool: parses args, builds contextual search query, calls Bitbucket Server search API, formats and returns results.
    async handleSearchCode(args: any) {
      try {
        const { 
          workspace, 
          repository, 
          search_query, 
          search_context = 'any',
          file_pattern, 
          include_patterns = [],
          limit = 25, 
          start = 0 
        } = args;
    
        if (!workspace || !search_query) {
          throw new Error('Workspace and search_query are required');
        }
    
        // Only works for Bitbucket Server currently
        if (!this.apiClient.getIsServer()) {
          throw new Error('Code search is currently only supported for Bitbucket Server');
        }
    
        // Build the enhanced query string
        let query = `project:${workspace}`;
        if (repository) {
          query += ` repo:${repository}`;
        }
        if (file_pattern) {
          query += ` path:${file_pattern}`;
        }
        
        // Build smart search patterns
        const smartQuery = buildSmartQuery(search_query, search_context, include_patterns);
        query += ` ${smartQuery}`;
    
        // Prepare the request payload
        const payload: BitbucketServerSearchRequest = {
          query: query.trim(),
          entities: { 
            code: {
              start: start,
              limit: limit
            }
          }
        };
    
        // Make the API request (no query params needed, pagination is in payload)
        const response = await this.apiClient.makeRequest<BitbucketServerSearchResult>(
          'post',
          `/rest/search/latest/search?avatarSize=64`,
          payload
        );
    
        const searchResult = response;
    
        // Use simplified formatter for cleaner output
        const simplifiedOutput = formatCodeSearchOutput(searchResult);
    
        // Prepare pagination info
        const hasMore = searchResult.code?.isLastPage === false;
        const nextStart = hasMore ? (searchResult.code?.nextStart || start + limit) : undefined;
        const totalCount = searchResult.code?.count || 0;
    
        // Build a concise response with search context info
        let resultText = `Code search results for "${search_query}"`;
        if (search_context !== 'any') {
          resultText += ` (context: ${search_context})`;
        }
        resultText += ` in ${workspace}`;
        if (repository) {
          resultText += `/${repository}`;
        }
        
        // Show the actual search query used
        resultText += `\n\nSearch query: ${query.trim()}`;
        resultText += `\n\n${simplifiedOutput}`;
        
        if (totalCount > 0) {
          resultText += `\n\nTotal matches: ${totalCount}`;
          if (hasMore) {
            resultText += ` (showing ${start + 1}-${start + (searchResult.code?.values?.length || 0)})`;
          }
        }
    
        return {
          content: [{
            type: 'text',
            text: resultText
          }]
        };
      } catch (error: any) {
        const errorMessage = error.response?.data?.errors?.[0]?.message || error.message;
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              error: `Failed to search code: ${errorMessage}`,
              details: error.response?.data
            }, null, 2)
          }],
          isError: true
        };
      }
    }
  • Tool schema definition including input schema with properties, descriptions, enums, and required fields.
    {
      name: 'search_code',
      description: 'Search for code across Bitbucket repositories with enhanced context-aware search patterns (currently only supported for Bitbucket Server)',
      inputSchema: {
        type: 'object',
        properties: {
          workspace: {
            type: 'string',
            description: 'Bitbucket workspace/project key (e.g., "PROJ")',
          },
          repository: {
            type: 'string',
            description: 'Repository slug to search in (optional, searches all repos if not specified)',
          },
          search_query: {
            type: 'string',
            description: 'The search term or phrase to look for in code (e.g., "variable")',
          },
          search_context: {
            type: 'string',
            enum: ['assignment', 'declaration', 'usage', 'exact', 'any'],
            description: 'Context to search for: assignment (term=value), declaration (defining term), usage (calling/accessing term), exact (quoted match), or any (all patterns)',
          },
          file_pattern: {
            type: 'string',
            description: 'File path pattern to filter results (e.g., "*.java", "src/**/*.ts") (optional)',
          },
          include_patterns: {
            type: 'array',
            items: { type: 'string' },
            description: 'Additional custom search patterns to include (e.g., ["variable =", ".variable"]) (optional)',
          },
          limit: {
            type: 'number',
            description: 'Maximum number of results to return (default: 25)',
          },
          start: {
            type: 'number',
            description: 'Start index for pagination (default: 0)',
          },
        },
        required: ['workspace', 'search_query'],
      },
    },
  • src/index.ts:140-141 (registration)
    Registration of the search_code tool in the main request handler switch statement, delegating to SearchHandlers.handleSearchCode.
    case 'search_code':
      return this.searchHandlers.handleSearchCode(request.params.arguments);
  • Type guard function for validating search_code tool arguments.
    export const isSearchCodeArgs = (
      args: any
    ): args is {
      workspace: string;
      repository?: string;
      search_query: string;
      file_pattern?: string;
      limit?: number;
      start?: number;
    } =>
      typeof args === 'object' &&
      args !== null &&
      typeof args.workspace === 'string' &&
      typeof args.search_query === 'string' &&
      (args.repository === undefined || typeof args.repository === 'string') &&
      (args.file_pattern === undefined || typeof args.file_pattern === 'string') &&
      (args.limit === undefined || typeof args.limit === 'number') &&
      (args.start === undefined || typeof args.start === 'number');
  • Helper function to build contextual search query patterns based on search term and context (e.g., assignment, declaration). Used by the handler.
    function buildSmartQuery(
      searchTerm: string, 
      searchContext: string = 'any',
      includePatterns: string[] = []
    ): string {
      const contextPatterns = buildContextualPatterns(searchTerm);
      
      let patterns: string[] = [];
      
      // Add patterns based on context
      if (searchContext in contextPatterns) {
        patterns = [...contextPatterns[searchContext as keyof SearchContext]];
      } else {
        patterns = [...contextPatterns.any];
      }
      
      // Add user-provided patterns
      if (includePatterns && includePatterns.length > 0) {
        patterns = [...patterns, ...includePatterns];
      }
      
      // Remove duplicates and join with OR
      const uniquePatterns = [...new Set(patterns)];
      
      // If only one pattern, return it without parentheses
      if (uniquePatterns.length === 1) {
        return uniquePatterns[0];
      }
      
      // Wrap each pattern in quotes for safety and join with OR
      const quotedPatterns = uniquePatterns.map(pattern => `"${pattern}"`);
      return `(${quotedPatterns.join(' OR ')})`;
    }

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/pdogra1299/bitbucket-mcp-server'

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