Skip to main content
Glama
PV-Bhat

GemForge-Gemini-Tools-MCP

gemini_code

Analyze codebases to answer questions about structure, logic, and improvements. Use Repomix and Gemini 2.5 Pro for detailed insights into your code directory or pre-packed files.

Instructions

Analyzes codebases using Repomix and Gemini 2.5 Pro. Answers questions about code structure, logic, and potential improvements.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
codebase_pathNoPath to pre-packed Repomix file
directory_pathNoPath to the code directory
model_idNoOptional model ID override (advanced users only)
questionYesQuestion about the codebase

Implementation Reference

  • Core handler function executing gemini_code tool: handles args validation, packs codebase if directory provided using repomix, selects Gemini model, builds structured request, calls API, formats output, cleans up temp files.
    export async function handleCode(request: any) { // --> ADD THIS LINE <-- console.error('<<<<< RUNNING LATEST handleCode - FIX_ATTEMPT_4 >>>>>'); let tempFilePath: string | null = null; try { // Validate required parameters if (!request.params.arguments || !request.params.arguments.question) { throw new McpError( ErrorCode.InvalidParams, 'question parameter is required' ); } // Extract arguments const args = request.params.arguments as CodeArgs; const { question, directory_path, codebase_path, model_id, repomix_options } = args; // Validate that at least one of directory_path or codebase_path is provided if (!directory_path && !codebase_path) { throw new McpError( ErrorCode.InvalidParams, 'Either directory_path or codebase_path parameter is required' ); } // Determine the analysis path let analysisPath: string; if (codebase_path) { // Use the provided codebase path console.error(`[handleCode] Using provided codebase path: ${codebase_path}`); // Normalize the path for Windows const normalizedPath = path.resolve(codebase_path); console.error(`[handleCode] Normalized codebase path: ${normalizedPath}`); // Check if the file exists try { await fs.access(normalizedPath); console.error(`[handleCode] File exists at: ${normalizedPath}`); analysisPath = normalizedPath; } catch (error) { console.error(`[handleCode] File access error: ${error}`); throw new McpError( ErrorCode.InvalidParams, `Codebase file not found: ${codebase_path} (normalized: ${normalizedPath})` ); } } else { // Pack the directory using Repomix console.error(`[handleCode] Packing directory: ${directory_path}`); if (!directory_path) { throw new McpError( ErrorCode.InvalidParams, 'directory_path is required for packing' ); } // Normalize the directory path for Windows const normalizedDirPath = path.resolve(directory_path); console.error(`[handleCode] Normalized directory path: ${normalizedDirPath}`); // Pack the directory with custom options if provided const packOptions = repomix_options ? { customOptions: repomix_options } : {}; console.error(`[handleCode] Calling packDirectory with${repomix_options ? ' custom options: ' + repomix_options : ''}: ${normalizedDirPath}`); const packResult = await packDirectory(normalizedDirPath, packOptions); console.error(`[handleCode] Pack result: ${JSON.stringify(packResult)}`); if (packResult.error) { console.error(`[handleCode] Pack error: ${packResult.error}`); throw new McpError( ErrorCode.InternalError, `Failed to pack directory: ${packResult.error}` ); } analysisPath = packResult.outputPath; tempFilePath = analysisPath; // Store for cleanup console.error(`[handleCode] Directory packed successfully: ${analysisPath}`); // Verify the file exists try { await fs.access(analysisPath); console.error(`[handleCode] Packed file exists at: ${analysisPath}`); } catch (error) { console.error(`[handleCode] Packed file access error: ${error}`); throw new McpError( ErrorCode.InternalError, `Packed file not found: ${analysisPath}` ); } } // Create a new args object with the updated codebase_path const updatedArgs: CodeArgs = { ...args, codebase_path: analysisPath }; // Select the model using the tool-specific model selector const targetModelId = selectToolModel(TOOL_NAMES.GEM_CODE, updatedArgs); console.error(`[handleCode] Selected model: ${targetModelId}`); // Build the request using the new builder function const internalRequest = await buildCodeRequest(updatedArgs); console.error(`[handleCode] Request built for model: ${targetModelId}`); // Diagnostic: log contents to verify XML is included console.error(`[handleCode] SDK request contents: ${internalRequest.contents.length} entries`); if (internalRequest.contents[0]?.parts) { console.error(`[handleCode] First part length: ${internalRequest.contents[0].parts[0].text.length} chars`); } // Execute the request const { response, rawSdkResponse } = await executeRequest(targetModelId, internalRequest); console.error(`[handleCode] Got response from ${targetModelId}`); // Format the response return formatResponse(response, targetModelId, { operation: TOOL_NAMES.GEM_CODE, customFormat: { question, usedDirectory: !!directory_path, usedCodebasePath: !!codebase_path } }, rawSdkResponse); } catch (error) { console.error('Error in code handler:', error); if (error instanceof McpError) { throw error; } return { content: [ { type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` } ], isError: true }; } finally { // Clean up temporary files if created if (tempFilePath) { try { await cleanupPackedFile(tempFilePath); } catch (cleanupError) { console.error(`[handleCode] Error cleaning up temporary file: ${cleanupError}`); } } } }
  • src/index.ts:212-213 (registration)
    Registers the handleCode function for the 'gemini_code' tool in the MCP tool call switch statement.
    case TOOL_NAMES.GEM_CODE: return await handleCode(request);
  • TypeScript interface defining input arguments for the gemini_code tool.
    export interface CodeArgs extends BaseArgs { /** Question about the codebase */ question: string; /** Path to the code directory */ directory_path?: string; /** Path to pre-packed Repomix file */ codebase_path?: string; /** Custom Repomix command options (for power users) */ repomix_options?: string; }
  • src/index.ts:118-143 (registration)
    Tool specification registration in ListTools handler, including name, description, and input schema for 'gemini_code'.
    { name: TOOL_NAMES.GEM_CODE, description: 'Analyzes codebases using Repomix and Gemini 2.5 Pro. Answers questions about code structure, logic, and potential improvements.', inputSchema: { type: 'object', properties: { question: { type: 'string', description: 'Question about the codebase' }, directory_path: { type: 'string', description: 'Path to the code directory' }, codebase_path: { type: 'string', description: 'Path to pre-packed Repomix file' }, model_id: { type: 'string', description: 'Optional model ID override (advanced users only)' } }, required: ['question'], }, },
  • Constant definition for the gemini_code tool name (TOOL_NAMES.GEM_CODE).
    GEM_CODE: 'gemini_code', // For coding tasks (Gemini 2.5 Pro) GEM_FILEOPS: 'gemini_fileops', // For file operations (Gemini 2.0 Flash-Lite/1.5 Pro)

Other Tools

Related Tools

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/PV-Bhat/GemForge-MCP'

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