Martes, 8 de septiembre de 2026  ·  LATAM / Español
Intermedio 45 min en total 5 pasos

Cómo conectar Claude con Gmail paso a paso

Integra Claude con Gmail vía API para leer, resumir y redactar correos automáticamente con Python.

Imagen de portada editorial · Cómo conectar Claude con Gmail paso a paso · Educación · Claude Builders
Requisitos
  • Cuenta de Google con Gmail activo
  • Cuenta en console.anthropic.com con API key
  • Python 3.10+ instalado
  • Conocimientos básicos de terminal y pip
Lo que vas a aprender
  • Configurar credenciales OAuth de la API de Gmail
  • Autenticarte y leer correos desde Python
  • Enviar los correos a Claude para resumirlos o clasificarlos
  • Redactar respuestas automáticas con Claude y crear borradores en Gmail
PASO 1 · ~10 min

Crear credenciales OAuth en Google Cloud

Claude no habla con Gmail directamente: necesitas la API de Gmail de Google como puente. Entra en console.cloud.google.com, crea un proyecto nuevo (por ejemplo 'claude-gmail') y en 'APIs y servicios' habilita la Gmail API. Luego ve a 'Pantalla de consentimiento OAuth', elige tipo 'Externo' y añade tu propia cuenta de Google como usuario de prueba; así evitas el proceso de verificación de Google mientras desarrollas. Después, en 'Credenciales', crea un 'ID de cliente de OAuth' de tipo 'Aplicación de escritorio' y descarga el archivo JSON. Renómbralo a credentials.json y guárdalo en la carpeta de tu proyecto. Este archivo contiene el client_id y client_secret que autorizan tu script a acceder a tu buzón, siempre bajo tu consentimiento explícito. No es una integración nativa de Anthropic, sino la vía estándar y segura para conectar cualquier app con Gmail.

bash
# Estructura de tu proyecto
# proyecto/
# ├── credentials.json   <- descargado de Google Cloud
# ├── gmail_claude.py
# └── requirements.txt
ConsejoAñade credentials.json y token.json a tu .gitignore desde el primer momento: son secretos que dan acceso a tu correo.
Error comúnSi olvidas añadir tu cuenta como 'usuario de prueba' en la pantalla de consentimiento, Google bloqueará el login con un error 403 access_denied.
PASO 2 · ~5 min

Instalar dependencias de Python

Necesitas dos bloques de librerías: las oficiales de Google para autenticarte y consumir la Gmail API, y el SDK de Anthropic para hablar con Claude. Créate un entorno virtual para no ensuciar tu Python global (buena práctica tanto si estás en España como en LATAM con conexiones variables, porque fija versiones reproducibles). Instala todo con pip. El paquete google-auth-oauthlib gestiona el flujo OAuth que abre el navegador para pedirte permiso; google-api-python-client construye el cliente de Gmail; y anthropic es el cliente oficial para la API de Claude. Con estas cuatro dependencias tienes todo lo necesario para el resto del tutorial.

bash
python -m venv venv
source venv/bin/activate   # En Windows: venv\Scripts\activate

pip install google-auth google-auth-oauthlib \
            google-api-python-client anthropic
ConsejoGuarda las versiones con 'pip freeze > requirements.txt' para reinstalar el entorno idéntico en otra máquina.
PASO 3 · ~8 min

Autenticarte y leer tus últimos correos

El primer arranque abrirá tu navegador para que autorices el acceso; a partir de ahí se guarda un token.json y no tendrás que volver a loguearte. Usamos el scope 'gmail.modify' porque más adelante crearemos borradores; si solo quisieras leer, bastaría 'gmail.readonly'. La función list_messages recupera los IDs de los correos más recientes y get_message extrae asunto y cuerpo en texto plano. Fíjate en que decodificamos el body en base64url, que es como Gmail devuelve el contenido. Este es el material que luego pasaremos a Claude.

python
import os, base64
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

SCOPES = ['https://www.googleapis.com/auth/gmail.modify']

def get_service():
    creds = None
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        with open('token.json', 'w') as f:
            f.write(creds.to_json())
    return build('gmail', 'v1', credentials=creds)

def leer_correos(service, n=5):
    res = service.users().messages().list(userId='me', maxResults=n, q='is:unread').execute()
    correos = []
    for m in res.get('messages', []):
        msg = service.users().messages().get(userId='me', id=m['id']).execute()
        headers = {h['name']: h['value'] for h in msg['payload']['headers']}
        body = extraer_cuerpo(msg['payload'])
        correos.append({'id': m['id'], 'asunto': headers.get('Subject',''),
                        'de': headers.get('From',''), 'cuerpo': body})
    return correos

def extraer_cuerpo(payload):
    if 'parts' in payload:
        for p in payload['parts']:
            if p['mimeType'] == 'text/plain' and p['body'].get('data'):
                return base64.urlsafe_b64decode(p['body']['data']).decode('utf-8', 'ignore')
    data = payload['body'].get('data')
    return base64.urlsafe_b64decode(data).decode('utf-8','ignore') if data else ''
ConsejoEl parámetro q acepta la misma sintaxis de búsqueda de Gmail: 'is:unread from:jefe@empresa.com' filtra justo lo que te interesa.
Error comúnSi borras el scope o lo cambias, elimina token.json antes de reejecutar; si no, seguirás usando el permiso antiguo y verás errores de scope insuficiente.
PASO 4 · ~7 min

Enviar correos a Claude para resumirlos

Ahora conectamos con la API de Claude. Instancia el cliente con tu API key (mejor desde una variable de entorno que hardcodeada) y usa el modelo claude-opus-4-8. Pasamos cada correo dentro del prompt pidiendo un resumen breve y una etiqueta de prioridad. Claude devuelve texto estructurado que puedes parsear o mostrar directamente. Mantén los cuerpos por debajo de unos miles de caracteres si procesas muchos correos, para controlar coste y latencia; puedes truncar con cuerpo[:4000]. Este patrón —leer de una fuente externa, procesar con Claude, actuar— es la base de cualquier agente útil.

python
import anthropic

client = anthropic.Anthropic(api_key=os.environ['ANTHROPIC_API_KEY'])

def resumir_con_claude(correo):
    prompt = f"""Resume este correo en 2 frases y asígnale una prioridad (ALTA/MEDIA/BAJA).

De: {correo['de']}
Asunto: {correo['asunto']}
Cuerpo:
{correo['cuerpo'][:4000]}

Responde en formato:
Prioridad: <nivel>
Resumen: <texto>"""
    resp = client.messages.create(
        model='claude-opus-4-8',
        max_tokens=300,
        messages=[{'role': 'user', 'content': prompt}]
    )
    return resp.content[0].text

service = get_service()
for c in leer_correos(service, n=5):
    print(f"\n=== {c['asunto']} ===")
    print(resumir_con_claude(c))
ConsejoExporta la clave con 'export ANTHROPIC_API_KEY=sk-ant-...' en tu terminal (o en un archivo .env) para no exponerla en el código.
Error comúnNo pegues el correo entero sin límite: cuerpos de newsletters con HTML pueden disparar los tokens y el coste sin aportar nada al resumen.
PASO 5 · ~5 min

Redactar respuestas y crear borradores

El último paso cierra el círculo: pedimos a Claude que redacte una respuesta y la guardamos como borrador en Gmail para que tú la revises antes de enviar. Crear un borrador (en lugar de enviar directamente) es la opción responsable: mantienes el control humano sobre lo que sale de tu cuenta. Construimos un mensaje MIME con el destinatario y el asunto, lo codificamos en base64url y lo subimos con drafts().create. Ábrelo en Gmail, ajusta lo que quieras y envía. Con esto tienes un asistente de correo funcional de punta a punta.

python
from email.mime.text import MIMEText

def redactar_respuesta(correo):
    prompt = f"""Redacta una respuesta profesional y cordial en español a este correo.
Asunto: {correo['asunto']}
Contenido: {correo['cuerpo'][:3000]}
Devuelve solo el cuerpo de la respuesta."""
    resp = client.messages.create(model='claude-opus-4-8', max_tokens=600,
        messages=[{'role':'user','content':prompt}])
    return resp.content[0].text

def crear_borrador(service, correo, texto):
    mime = MIMEText(texto)
    mime['To'] = correo['de']
    mime['Subject'] = 'Re: ' + correo['asunto']
    raw = base64.urlsafe_b64encode(mime.as_bytes()).decode()
    borrador = service.users().drafts().create(
        userId='me', body={'message': {'raw': raw}}).execute()
    return borrador['id']

for c in leer_correos(service, n=3):
    respuesta = redactar_respuesta(c)
    bid = crear_borrador(service, c, respuesta)
    print(f"Borrador creado ({bid}) para: {c['asunto']}")
ConsejoPara responder dentro del mismo hilo, añade el header 'In-Reply-To' con el Message-ID original y pasa 'threadId' en el body del draft.
Error comúnEvita usar drafts().send() automáticamente en producción sin revisión humana: un resumen mal interpretado podría enviar información incorrecta a un cliente.
Resultado

Has construido un puente funcional entre Gmail y Claude: tu script lee correos no leídos, los resume y prioriza con claude-opus-4-8, y genera borradores de respuesta listos para revisar. Este flujo lectura-procesamiento-acción es exactamente el patrón que sostiene los agentes reales, y dominarlo te prepara para dar el salto hacia agentes e integraciones con MCP, donde estas conexiones se orquestan de forma estandarizada y escalable.

PRÓXIMOS PASOS