gemini_generateContent
Generate complete text responses using Google Gemini models. Process single-turn prompts with optional control over token limits, creativity, and safety settings for tailored content creation.
Instructions
Generates non-streaming text content using a specified Google Gemini model. This tool takes a text prompt and returns the complete generated response from the model. It's suitable for single-turn generation tasks where the full response is needed at once. Optional parameters allow control over generation (temperature, max tokens, etc.) and safety settings.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| generationConfig | No | Optional configuration for controlling the generation process. | |
| modelName | No | Optional. The name of the Gemini model to use (e.g., 'gemini-1.5-flash'). If omitted, the server's default model (from GOOGLE_GEMINI_MODEL env var) will be used. | |
| prompt | Yes | Required. The text prompt to send to the Gemini model for content generation. | |
| safetySettings | No | Optional. A list of safety settings to apply, overriding default model safety settings. Each setting specifies a harm category and a blocking threshold. |
Implementation Reference
- The core handler function `processRequest` that executes the `gemini_generate_content` tool logic. It parses arguments, invokes `GeminiService.generateContent` or `generateContentStream`, handles streaming by accumulating chunks, processes function calls from the model, formats responses in MCP content format, and maps errors.const processRequest = async (args: unknown) => { const typedArgs = args as GeminiGenerateContentArgs; logger.debug(`Received ${GEMINI_GENERATE_CONTENT_TOOL_NAME} request:`, { model: typedArgs.modelName, stream: typedArgs.stream, hasFunctionDeclarations: !!typedArgs.functionDeclarations, }); // Avoid logging full prompt potentially try { // Extract arguments - Zod parsing happens automatically via server.tool const { modelName, prompt, stream, functionDeclarations, toolConfig, generationConfig, safetySettings, systemInstruction, cachedContentName, urlContext, modelPreferences, } = typedArgs; // Calculate URL context metrics for model selection let urlCount = 0; let estimatedUrlContentSize = 0; if (urlContext?.urls) { urlCount = urlContext.urls.length; // Estimate content size based on configured limits const maxContentKb = urlContext.fetchOptions?.maxContentKb || 100; estimatedUrlContentSize = urlCount * maxContentKb * 1024; // Convert to bytes } // Prepare parameters object const contentParams: GenerateContentParams & { functionDeclarations?: unknown; toolConfig?: unknown; } = { prompt, modelName, generationConfig, safetySettings: safetySettings?.map((setting) => ({ category: setting.category as HarmCategory, threshold: setting.threshold as HarmBlockThreshold, })), systemInstruction, cachedContentName, urlContext: urlContext?.urls ? { urls: urlContext.urls, fetchOptions: urlContext.fetchOptions, } : undefined, preferQuality: modelPreferences?.preferQuality, preferSpeed: modelPreferences?.preferSpeed, preferCost: modelPreferences?.preferCost, complexityHint: modelPreferences?.complexityHint, taskType: modelPreferences?.taskType, urlCount, estimatedUrlContentSize, }; // Add function-related parameters if provided if (functionDeclarations) { contentParams.functionDeclarations = functionDeclarations; } if (toolConfig) { contentParams.toolConfig = toolConfig; } // Handle streaming vs non-streaming generation if (stream) { // Use streaming generation logger.debug( `Using streaming generation for ${GEMINI_GENERATE_CONTENT_TOOL_NAME}` ); let fullText = ""; // Accumulator for chunks // Call the service's streaming method const sdkStream = serviceInstance.generateContentStream(contentParams); // Iterate over the async generator from the service and collect chunks // The StreamableHTTPServerTransport will handle the actual streaming for HTTP transport for await (const chunkText of sdkStream) { fullText += chunkText; // Append chunk to the accumulator } logger.debug( `Stream collected successfully for ${GEMINI_GENERATE_CONTENT_TOOL_NAME}` ); // Return the complete text in the standard MCP format return { content: [ { type: "text" as const, text: fullText, }, ], }; } else { // Use standard non-streaming generation logger.debug( `Using standard generation for ${GEMINI_GENERATE_CONTENT_TOOL_NAME}` ); const result = await serviceInstance.generateContent(contentParams); // Handle function call responses if function declarations were provided if ( functionDeclarations && typeof result === "object" && result !== null ) { // It's an object response, could be a function call const resultObj = result as FunctionCallResponse; if ( resultObj.functionCall && typeof resultObj.functionCall === "object" ) { // It's a function call request logger.debug( `Function call requested by model: ${resultObj.functionCall.name}` ); // Serialize the function call details into a JSON string const functionCallJson = JSON.stringify(resultObj.functionCall); return { content: [ { type: "text" as const, // Return as text type text: functionCallJson, // Embed JSON string in text field }, ], }; } else if (resultObj.text && typeof resultObj.text === "string") { // It's a regular text response return { content: [ { type: "text" as const, text: resultObj.text, }, ], }; } } // Standard text response if (typeof result === "string") { return { content: [ { type: "text" as const, text: result, }, ], }; } else { // Unexpected response structure from the service logger.error( `Unexpected response structure from generateContent:`, result ); throw new Error( "Invalid response structure received from Gemini service." ); } } } catch (error: unknown) { logger.error( `Error processing ${GEMINI_GENERATE_CONTENT_TOOL_NAME}:`, error ); // Use the central error mapping utility throw mapAnyErrorToMcpError(error, GEMINI_GENERATE_CONTENT_TOOL_NAME); } };
- Zod schema definition for the tool inputs via `GEMINI_GENERATE_CONTENT_PARAMS` and `geminiGenerateContentSchema`, covering model selection, prompt, streaming, function declarations, generation config, safety settings, system instructions, caching, URL context, and model preferences.export const GEMINI_GENERATE_CONTENT_PARAMS = { modelName: ModelNameSchema, prompt: z .string() .min(1) .describe( "Required. The text prompt to send to the Gemini model for content generation." ), stream: z .boolean() .optional() .default(false) .describe( "Optional. Whether to use streaming generation. Note: Due to SDK limitations, the full response is still returned at once." ), functionDeclarations: z .array(FunctionDeclarationSchema) .optional() .describe( "Optional. An array of function declarations (schemas) that the model can choose to call based on the prompt." ), toolConfig: toolConfigSchema, generationConfig: generationConfigSchema, safetySettings: z .array(safetySettingSchema) .optional() .describe( "Optional. A list of safety settings to apply, overriding default model safety settings. Each setting specifies a harm category and a blocking threshold." ), systemInstruction: z .string() .optional() .describe( "Optional. A system instruction to guide the model's behavior. Acts as context for how the model should respond." ), cachedContentName: z .string() .min(1) .optional() .describe( "Optional. Identifier for cached content in format 'cachedContents/...' to use with this request." ), urlContext: urlContextSchema, modelPreferences: ModelPreferencesSchema, }; // Define the complete schema for validation export const geminiGenerateContentSchema = z.object( GEMINI_GENERATE_CONTENT_PARAMS );
- src/tools/geminiGenerateContentConsolidatedTool.ts:231-236 (registration)Direct registration of the tool with the MCP server inside `geminiGenerateContentConsolidatedTool` function using `server.tool(name, description, schema, handler)`.server.tool( GEMINI_GENERATE_CONTENT_TOOL_NAME, GEMINI_GENERATE_CONTENT_TOOL_DESCRIPTION, GEMINI_GENERATE_CONTENT_PARAMS, // Pass the Zod schema object directly processRequest );
- src/tools/registration/registerAllTools.ts:60-64 (registration)Higher-level registration of the consolidated tool function via `ToolRegistry` in the central `registerAllTools` function.registry.registerTool( adaptGeminiServiceTool( geminiGenerateContentConsolidatedTool, "geminiGenerateContentConsolidatedTool" )