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
| Name | Required | Description | Default |
|---|---|---|---|
| file_pattern | No | File path pattern to filter results (e.g., "*.java", "src/**/*.ts") (optional) | |
| include_patterns | No | Additional custom search patterns to include (e.g., ["variable =", ".variable"]) (optional) | |
| limit | No | Maximum number of results to return (default: 25) | |
| repository | No | Repository slug to search in (optional, searches all repos if not specified) | |
| search_context | No | Context to search for: assignment (term=value), declaration (defining term), usage (calling/accessing term), exact (quoted match), or any (all patterns) | |
| search_query | Yes | The search term or phrase to look for in code (e.g., "variable") | |
| start | No | Start index for pagination (default: 0) | |
| workspace | Yes | Bitbucket workspace/project key (e.g., "PROJ") |
Implementation Reference
- src/handlers/search-handlers.ts:96-199 (handler)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 }; } }
- src/tools/definitions.ts:618-661 (schema)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);
- src/types/guards.ts:313-331 (schema)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 ')})`; }