Google Gen AI JavaScript SDK for building applications powered by Gemini with content generation, image/video generation, function calling, caching, and real-time live sessions
The MCP (Model Context Protocol) integration allows you to convert MCP clients and tools into Gemini-compatible tools for extended functionality and interoperability.
Convert MCP clients or tools to Gemini CallableTool interface.
/**
* Convert MCP clients/tools to Gemini tools
* @param mcpClientOrTools - MCP client or tools array
* @param config - Tool configuration
* @returns Promise resolving to callable tool
*/
function mcpToTool(
mcpClientOrTools: McpClient | McpTool[],
config?: CallableToolConfig
): Promise<CallableTool>;
interface CallableToolConfig {
/** Tool display name */
displayName?: string;
/** Tool description */
description?: string;
/** Additional configuration */
[key: string]: unknown;
}Usage Examples:
import { GoogleGenAI, mcpToTool } from '@google/genai';
import { McpClient } from '@modelcontextprotocol/sdk';
const client = new GoogleGenAI({ apiKey: 'YOUR_API_KEY' });
// Connect to MCP server
const mcpClient = new McpClient({
serverUrl: 'http://localhost:3000'
});
await mcpClient.connect();
// Convert MCP client to Gemini tool
const mcpTool = await mcpToTool(mcpClient, {
displayName: 'External MCP Tools',
description: 'Tools provided by MCP server'
});
// Use in generation with automatic function calling
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: 'Use the available tools to complete this task',
config: {
tools: [mcpTool],
automaticFunctionCalling: {
maximumRemoteCalls: 10
}
}
});
console.log('Response:', response.text);
// Close MCP connection
await mcpClient.disconnect();MCP client interface (from @modelcontextprotocol/sdk).
interface McpClient {
/** Connect to MCP server */
connect(): Promise<void>;
/** Disconnect from MCP server */
disconnect(): Promise<void>;
/** List available tools */
listTools(): Promise<McpTool[]>;
/** Call a tool */
callTool(name: string, args: Record<string, unknown>): Promise<unknown>;
}MCP tool definition.
interface McpTool {
/** Tool name */
name: string;
/** Tool description */
description?: string;
/** Input schema */
inputSchema?: {
type: string;
properties?: Record<string, unknown>;
required?: string[];
};
}Gemini callable tool interface.
interface CallableTool {
/** Get tool declaration */
tool(): Promise<Tool>;
/** Execute function calls */
callTool(functionCalls: FunctionCall[]): Promise<Part[]>;
}import { GoogleGenAI, mcpToTool } from '@google/genai';
import { McpClient } from '@modelcontextprotocol/sdk';
const client = new GoogleGenAI({ apiKey: 'YOUR_API_KEY' });
// Create and connect MCP client
const mcpClient = new McpClient({
serverUrl: 'http://localhost:3000',
apiKey: 'MCP_SERVER_KEY'
});
await mcpClient.connect();
console.log('Connected to MCP server');
// List available tools
const tools = await mcpClient.listTools();
console.log('Available MCP tools:');
tools.forEach(tool => {
console.log(` - ${tool.name}: ${tool.description}`);
});
// Convert to Gemini tool
const geminiTool = await mcpToTool(mcpClient);
// Use in generation
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: 'Search for information about AI',
config: {
tools: [geminiTool]
}
});
// Handle function calls manually
if (response.functionCalls) {
console.log('MCP tools were called:', response.functionCalls);
}
// Cleanup
await mcpClient.disconnect();import { McpTool } from '@modelcontextprotocol/sdk';
// Define specific MCP tools
const mcpTools: McpTool[] = [
{
name: 'search_database',
description: 'Search the database',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string' },
limit: { type: 'number' }
},
required: ['query']
}
},
{
name: 'get_weather',
description: 'Get weather information',
inputSchema: {
type: 'object',
properties: {
location: { type: 'string' }
},
required: ['location']
}
}
];
// Convert tools (not client)
const geminiTool = await mcpToTool(mcpTools, {
displayName: 'Database and Weather Tools'
});
// Use in generation
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: 'Search the database for AI papers and check weather in San Francisco',
config: {
tools: [geminiTool],
automaticFunctionCalling: {
maximumRemoteCalls: 5
}
}
});
console.log('Response:', response.text);// Connect MCP client
const mcpClient = new McpClient({
serverUrl: 'http://localhost:3000'
});
await mcpClient.connect();
// Convert to tool
const mcpTool = await mcpToTool(mcpClient);
// Stream with MCP tools
const stream = await client.models.generateContentStream({
model: 'gemini-2.0-flash',
contents: 'Use the tools to gather information',
config: {
tools: [mcpTool]
}
});
for await (const chunk of stream) {
if (chunk.text) {
process.stdout.write(chunk.text);
}
// Check for function calls
if (chunk.functionCalls) {
console.log('\nMCP tools invoked:', chunk.functionCalls);
}
}
await mcpClient.disconnect();// Setup MCP
const mcpClient = new McpClient({
serverUrl: 'http://localhost:3000'
});
await mcpClient.connect();
const mcpTool = await mcpToTool(mcpClient);
// Create chat with MCP tools
const chat = client.chats.create({
model: 'gemini-2.0-flash',
config: {
tools: [mcpTool],
systemInstruction: 'You are a helpful assistant with access to external tools.'
}
});
// Multi-turn conversation with MCP
const r1 = await chat.sendMessage({
message: 'Search for recent AI developments'
});
console.log('Assistant:', r1.text);
const r2 = await chat.sendMessage({
message: 'Get more details about the first result'
});
console.log('Assistant:', r2.text);
// Cleanup
await mcpClient.disconnect();// Connect to multiple MCP servers
const mcpClient1 = new McpClient({
serverUrl: 'http://localhost:3000'
});
const mcpClient2 = new McpClient({
serverUrl: 'http://localhost:4000'
});
await Promise.all([
mcpClient1.connect(),
mcpClient2.connect()
]);
// Convert each to tool
const [tool1, tool2] = await Promise.all([
mcpToTool(mcpClient1, { displayName: 'Database Tools' }),
mcpToTool(mcpClient2, { displayName: 'API Tools' })
]);
// Use both in generation
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: 'Use both database and API tools to gather information',
config: {
tools: [tool1, tool2],
automaticFunctionCalling: {
maximumRemoteCalls: 10
}
}
});
console.log('Response:', response.text);
// Cleanup
await Promise.all([
mcpClient1.disconnect(),
mcpClient2.disconnect()
]);import { CallableTool, Tool, FunctionCall, Part } from '@google/genai';
import { McpClient } from '@modelcontextprotocol/sdk';
// Custom wrapper for MCP client
class CustomMcpTool implements CallableTool {
constructor(private mcpClient: McpClient) {}
async tool(): Promise<Tool> {
// Get tools from MCP server
const mcpTools = await this.mcpClient.listTools();
// Convert to Gemini format
const functionDeclarations = mcpTools.map(mcpTool => ({
name: mcpTool.name,
description: mcpTool.description,
parametersJsonSchema: mcpTool.inputSchema
}));
return {
functionDeclarations
};
}
async callTool(functionCalls: FunctionCall[]): Promise<Part[]> {
const results: Part[] = [];
for (const fc of functionCalls) {
try {
console.log(`Calling MCP tool: ${fc.name}`);
// Call MCP server
const result = await this.mcpClient.callTool(fc.name!, fc.args || {});
results.push({
functionResponse: {
name: fc.name,
response: { result },
id: fc.id
}
});
} catch (error) {
console.error(`MCP tool error: ${fc.name}`, error);
results.push({
functionResponse: {
name: fc.name,
response: {
error: error.message
},
id: fc.id
}
});
}
}
return results;
}
}
// Use custom wrapper
const mcpClient = new McpClient({ serverUrl: 'http://localhost:3000' });
await mcpClient.connect();
const customTool = new CustomMcpTool(mcpClient);
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: 'Use the tools',
config: {
tools: [customTool],
automaticFunctionCalling: {
maximumRemoteCalls: 5
}
}
});// MCP connection with error handling
async function connectMcpWithRetry(
config: { serverUrl: string },
maxRetries: number = 3
): Promise<McpClient> {
const mcpClient = new McpClient(config);
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
await mcpClient.connect();
console.log('Connected to MCP server');
return mcpClient;
} catch (error) {
console.error(`Connection attempt ${attempt} failed:`, error);
if (attempt === maxRetries) {
throw new Error('Failed to connect to MCP server after retries');
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
throw new Error('Unexpected error');
}
// Use with error handling
try {
const mcpClient = await connectMcpWithRetry({
serverUrl: 'http://localhost:3000'
});
const mcpTool = await mcpToTool(mcpClient);
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: 'Use the MCP tools',
config: {
tools: [mcpTool]
}
});
console.log('Response:', response.text);
await mcpClient.disconnect();
} catch (error) {
console.error('MCP error:', error);
}// Discover and document MCP tools
async function discoverMcpTools(mcpClient: McpClient): Promise<void> {
await mcpClient.connect();
const tools = await mcpClient.listTools();
console.log(`Discovered ${tools.length} MCP tools:\n`);
tools.forEach((tool, index) => {
console.log(`${index + 1}. ${tool.name}`);
console.log(` Description: ${tool.description || 'N/A'}`);
if (tool.inputSchema?.properties) {
console.log(' Parameters:');
Object.entries(tool.inputSchema.properties).forEach(([name, schema]: [string, any]) => {
const required = tool.inputSchema?.required?.includes(name) ? '(required)' : '(optional)';
console.log(` - ${name}: ${schema.type} ${required}`);
if (schema.description) {
console.log(` ${schema.description}`);
}
});
}
console.log('');
});
await mcpClient.disconnect();
}
// Discover tools
const mcpClient = new McpClient({
serverUrl: 'http://localhost:3000'
});
await discoverMcpTools(mcpClient);import { FunctionCallingConfigMode } from '@google/genai';
// Connect MCP
const mcpClient = new McpClient({
serverUrl: 'http://localhost:3000'
});
await mcpClient.connect();
const mcpTool = await mcpToTool(mcpClient);
// Force model to use MCP tools
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: 'Get information',
config: {
tools: [mcpTool],
toolConfig: {
functionCallingConfig: {
mode: FunctionCallingConfigMode.ANY // Must call at least one tool
}
}
}
});
console.log('Response:', response.text);
await mcpClient.disconnect();// Monitor MCP server health
class McpHealthMonitor {
private mcpClient: McpClient;
private isHealthy: boolean = false;
constructor(serverUrl: string) {
this.mcpClient = new McpClient({ serverUrl });
}
async check(): Promise<boolean> {
try {
await this.mcpClient.connect();
// Try to list tools as health check
const tools = await this.mcpClient.listTools();
this.isHealthy = tools.length >= 0;
await this.mcpClient.disconnect();
return this.isHealthy;
} catch (error) {
console.error('MCP health check failed:', error);
this.isHealthy = false;
return false;
}
}
async waitUntilHealthy(timeoutMs: number = 30000): Promise<void> {
const startTime = Date.now();
while (Date.now() - startTime < timeoutMs) {
const healthy = await this.check();
if (healthy) {
console.log('MCP server is healthy');
return;
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
throw new Error('MCP server health check timeout');
}
isServerHealthy(): boolean {
return this.isHealthy;
}
}
// Use health monitor
const monitor = new McpHealthMonitor('http://localhost:3000');
await monitor.waitUntilHealthy();
if (monitor.isServerHealthy()) {
// Proceed with MCP integration
const mcpClient = new McpClient({
serverUrl: 'http://localhost:3000'
});
await mcpClient.connect();
const mcpTool = await mcpToTool(mcpClient);
// Use tool...
await mcpClient.disconnect();
}import { Type } from '@google/genai';
// Define native Gemini tool
const nativeTool = {
functionDeclarations: [{
name: 'calculate',
description: 'Perform calculation',
parameters: {
type: Type.OBJECT,
properties: {
expression: { type: Type.STRING }
}
}
}]
};
// Setup MCP tool
const mcpClient = new McpClient({
serverUrl: 'http://localhost:3000'
});
await mcpClient.connect();
const mcpTool = await mcpToTool(mcpClient);
// Use both together
const response = await client.models.generateContent({
model: 'gemini-2.0-flash',
contents: 'Calculate 2+2 and search for information',
config: {
tools: [nativeTool, mcpTool],
automaticFunctionCalling: {
maximumRemoteCalls: 10
}
}
});
console.log('Response:', response.text);
await mcpClient.disconnect();Install with Tessl CLI
npx tessl i tessl/npm-google--genai