
Escuchar este post
Selecciona una voz y genera audio para escuchar este post
Cómo construir un agente ReAct modular que conecte Google Drive y más herramientas usando Model Context Protocol
El Problema
Tu chatbot necesita acceder a Google Drive, Slack, bases de datos... pero cada integración es un dolor de cabeza diferente. MCP (Model Context Protocol) promete estandarizar esto, pero GPT-5-mini no tiene soporte nativo.
La solución: un bridge modular con patrón ReAct.
Arquitectura Minimalista
// La arquitectura en 3 capas Frontend (React) → Backend (Node.js) → MCP Servers ↓ GPT-5-mini API
1. El MCP Server Manager
Primero, necesitas gestionar múltiples servidores MCP dinámicamente:
// mcp-manager.ts class MCPManager { private servers: Map<string, MCPServer> = new Map(); async addServer(name: string, config: ServerConfig) { const server = await createMCPServer(config); this.servers.set(name, server); } async callTool(serverName: string, tool: string, args: any) { const server = this.servers.get(serverName); return await server.callTool(tool, args); } }
2. Conectando Google Drive MCP
Instalación del servidor MCP de Google Drive:
npm install @modelcontextprotocol/server-gdrive
Configuración modular:
// servers/gdrive.ts export const gdriveConfig = { command: 'npx', args: ['@modelcontextprotocol/server-gdrive'], env: { GOOGLE_DRIVE_CLIENT_ID: process.env.GDRIVE_CLIENT_ID, GOOGLE_DRIVE_CLIENT_SECRET: process.env.GDRIVE_SECRET } };
3. El Loop ReAct Simplificado
El corazón del sistema - un loop ReAct que usa GPT-5-mini con custom tools:
// react-agent.ts async function runReActLoop(query: string, mcpManager: MCPManager) { const messages = [{ role: 'system', content: 'You are a ReAct agent. Think step by step.' }]; let maxSteps = 5; while (maxSteps-- > 0) { // Reasoning paso const response = await openai.chat.completions.create({ model: 'gpt-5-mini', messages, tools: getMCPToolsAsOpenAIFunctions(mcpManager), tool_choice: 'auto' }); // Acting paso if (response.choices[0].tool_calls) { const toolCall = response.choices[0].tool_calls[0]; const result = await mcpManager.callTool( toolCall.function.name.split('.')[0], // server name toolCall.function.name.split('.')[1], // tool name JSON.parse(toolCall.function.arguments) ); messages.push({ role: 'tool', content: JSON.stringify(result), tool_call_id: toolCall.id }); } else { // Respuesta final return response.choices[0].message.content; } } }
4. Convertir MCP Tools a OpenAI Functions
GPT-5-mini necesita las herramientas en formato OpenAI:
function getMCPToolsAsOpenAIFunctions(mcpManager: MCPManager) { const tools = []; for (const [serverName, server] of mcpManager.servers) { for (const tool of server.getTools()) { tools.push({ type: 'function', function: { name: `${serverName}.${tool.name}`, description: tool.description, parameters: tool.inputSchema } }); } } return tools; }
5. API Endpoint del Chatbot
// api/chat.ts app.post('/api/chat', async (req, res) => { const { message } = req.body; const response = await runReActLoop(message, mcpManager); res.json({ response }); });
6. Frontend React Minimalista
// ChatInterface.jsx function ChatInterface() { const [messages, setMessages] = useState([]); const sendMessage = async (text) => { const response = await fetch('/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: text }) }); const data = await response.json(); setMessages([...messages, { role: 'user', content: text }, { role: 'assistant', content: data.response } ]); }; // UI components... }
7. Añadiendo Más MCP Servers
La belleza del patrón: añadir nuevas herramientas es trivial:
// servers/slack.ts export const slackConfig = { command: 'npx', args: ['@modelcontextprotocol/server-slack'], env: { SLACK_TOKEN: process.env.SLACK_TOKEN } }; // servers/postgres.ts export const postgresConfig = { command: 'npx', args: ['@modelcontextprotocol/server-postgres'], env: { DATABASE_URL: process.env.DATABASE_URL } };
Registro en el startup:
// startup.ts await mcpManager.addServer('gdrive', gdriveConfig); await mcpManager.addServer('slack', slackConfig); await mcpManager.addServer('postgres', postgresConfig);
Optimizaciones con GPT-5-mini
Parallel Tool Calling
GPT-5-mini puede llamar múltiples herramientas en paralelo:
const response = await openai.chat.completions.create({ model: 'gpt-5-mini', messages, tools, parallel_tool_calls: true // Nueva capacidad de GPT-5 });
Custom Tools para MCP Raw
Usa el nuevo tipo "custom" de GPT-5 para enviar comandos MCP directos:
{ type: 'custom', function: { name: 'mcp_raw', description: 'Send raw MCP protocol messages' } }
Preamble Messages
GPT-5-mini puede informar progreso durante operaciones largas:
tool_choice: 'auto', preamble_messages: true // Mensajes de progreso
Manejo de Errores
try { const result = await mcpManager.callTool(server, tool, args); return { success: true, data: result }; } catch (error) { // GPT-5-mini es mejor manejando errores de herramientas return { success: false, error: error.message, retry_hint: 'Try with different parameters' }; }
Deployment
- Variables de entorno:
OPENAI_API_KEY=sk-... GDRIVE_CLIENT_ID=... GDRIVE_SECRET=...
- Docker Compose para los MCP servers:
services: mcp-gdrive: image: modelcontextprotocol/server-gdrive environment: - GOOGLE_DRIVE_CLIENT_ID mcp-slack: image: modelcontextprotocol/server-slack environment: - SLACK_TOKEN
Conclusión
Este patrón te da:
- Modularidad: Añade/quita MCP servers sin tocar el core
- Simplicidad: El loop ReAct es de ~50 líneas
- Potencia: GPT-5-mini maneja el reasoning, MCP maneja las integraciones
- Escalabilidad: Cada MCP server corre independiente
El futuro de los chatbots no es escribir mil integraciones, es conectar protocolos estándar. MCP + GPT-5-mini es la combinación perfecta para lograrlo.
Checa mi taller para convertirte en Power-User de Claude Code
Abrazo. bliss. 🤓

Mejores Prácticas para Programar con Claude: Guía para Principiantes
Checa este otro Post
