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)
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions the tool analyzes codebases and answers questions, but lacks details on permissions, rate limits, response format, or error handling. For a tool with 4 parameters and no output schema, this is a significant gap in transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded, consisting of two clear sentences that directly state the tool's function. There's no wasted verbiage, and it efficiently communicates the core purpose. However, it could be slightly more structured by explicitly mentioning key parameters or use cases.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (4 parameters, no output schema, no annotations), the description is incomplete. It doesn't explain the relationship between codebase_path and directory_path, what kind of questions are supported, or what the output looks like. For a code analysis tool with multiple input options, more context is needed to guide effective usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description doesn't explicitly discuss parameters, but schema description coverage is 100%, providing clear documentation for all 4 parameters. The description implies the tool answers questions about codebases, which aligns with the 'question' parameter. However, it doesn't add meaningful context beyond what the schema already covers, such as how codebase_path and directory_path interact.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Analyzes codebases using Repomix and Gemini 2.5 Pro. Answers questions about code structure, logic, and potential improvements.' It specifies the action (analyzes/answers), resource (codebases), and technology used (Repomix and Gemini 2.5 Pro). However, it doesn't explicitly differentiate from sibling tools like gemini_fileops, gemini_reason, or gemini_search, which likely have related but distinct functions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It mentions analyzing codebases and answering questions, but doesn't specify use cases, prerequisites, or exclusions. Without context, it's unclear how this differs from sibling tools, leaving the agent to guess based on tool names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

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