---
title: "Google ADK"
description: "Crea agentes Gemini ADK para búsqueda de tweets, perfiles, tendencias y escrituras en X revisadas a través de TwexAPI MCP."
---

Crea un agente de Twitter API con Google ADK a través del servidor MCP de TwexAPI. Busca tweets, inspecciona perfiles, lee tendencias y revisa acciones de escritura. Conserva IDs de tweet, cursores y nombres de ruta como JSON durable.

## ¿Por qué usar Google ADK con TwexAPI?

ADK es Gemini-first. TwexAPI aparece como un conjunto de herramientas MCP remoto: `explore` descubre rutas, `twexapi_request` las ejecuta.

| Tarea del agente | Ruta de TwexAPI | Conservar para el siguiente paso |
| --- | --- | --- |
| Buscar tweets | `POST /twitter/advanced_search/page` | Consulta, IDs de tweet, autores, `created_at`, cursor |
| Inspeccionar un perfil | `GET /twitter/{screen_name}/about` | ID de usuario, nombre de usuario, biografía, cantidad de seguidores |
| Leer tendencias | `GET /twitter/global-trending/tweets` | País, tema, filas de tweets |
| Publicar o responder | `POST /twitter/tweets/create` | ID de tweet, ruta, aprobación humana, confirmación de cookie |

Usa ADK cuando el runtime sea Gemini. Usa el [Python SDK](/sdks/python) o [Prefect](/guides/prefect) para trabajos programados que no requieren modelo.

## Requisitos previos

- Python 3.10 o posterior
- Una [API key de TwexAPI](https://twexapi.io/dashboard)
- Una API key de Google AI
- Una cookie de Twitter o `auth_token` para acciones de escritura — consulta

Las lecturas públicas de X no requieren credenciales de X Developer. Autentícate con TwexAPI.

## Instalación

```bash
python -m pip install "google-adk>=1.0" python-dotenv
```

```txt .env
TWEXAPI_API_KEY=YOUR_API_KEY
GOOGLE_API_KEY=...
```

## Conectar TwexAPI MCP

```python
import os

from google.adk.tools.mcp_tool import McpToolset, StreamableHTTPConnectionParams

twexapi_toolset = McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://api.twexapi.io/mcp",
        headers={"x-api-key": os.environ["TWEXAPI_API_KEY"]},
    )
)
```

Las solicitudes MCP no autenticadas devuelven `401`. Envía `x-api-key` en la primera solicitud.

## Ejemplo completo

```python
import asyncio
import os
from pathlib import Path
from typing import Literal

from dotenv import load_dotenv
from google.adk.agents import LlmAgent
from google.adk.runners import InMemoryRunner
from google.adk.tools.mcp_tool import McpToolset, StreamableHTTPConnectionParams
from google.genai import types
from pydantic import BaseModel


class TweetRow(BaseModel):
    tweet_id: str
    text: str
    author_username: str | None = None
    created_at: str | None = None


class TweetSearchHandoff(BaseModel):
    query: str
    route_used: str
    tweets: list[TweetRow]
    has_more: bool
    next_cursor: str | None = None
    stop_reason: Literal[
        "complete",
        "requested_limit",
        "cursor_stalled",
        "page_cap",
    ]


async def main() -> None:
    load_dotenv()

    twexapi_toolset = McpToolset(
        connection_params=StreamableHTTPConnectionParams(
            url="https://api.twexapi.io/mcp",
            headers={"x-api-key": os.environ["TWEXAPI_API_KEY"]},
        )
    )

    agent = LlmAgent(
        model="gemini-2.5-flash",
        name="twexapi_agent",
        instruction=(
            "Use TwexAPI for Twitter API requests. Call explore before twexapi_request. "
            "Preserve exact IDs and cursors. Never invent missing tweet fields. "
            "Ask for confirmation before read_only: false actions. "
            "Return only valid JSON for TweetSearchHandoff."
        ),
        tools=[twexapi_toolset],
    )

    runner = InMemoryRunner(agent=agent, app_name="twexapi_app")
    session = await runner.session_service.create_session(
        app_name="twexapi_app",
        user_id="user-1",
    )

    response_parts: list[str] = []
    async for event in runner.run_async(
        user_id="user-1",
        session_id=session.id,
        new_message=types.Content(
            role="user",
            parts=[
                types.Part(
                    text=(
                        "Search 25 recent tweets about Google ADK MCP. "
                        "Return query, route_used, tweet rows, has_more, "
                        "next_cursor, and stop_reason as JSON."
                    )
                )
            ],
        ),
    ):
        if event.content and event.content.parts:
            response_parts.extend(
                part.text for part in event.content.parts if part.text
            )

    handoff = TweetSearchHandoff.model_validate_json("".join(response_parts))
    Path("twexapi-adk-handoff.json").write_text(
        handoff.model_dump_json(indent=2),
        encoding="utf-8",
    )
    await twexapi_toolset.close()


asyncio.run(main())
```

Si el modelo envuelve el JSON en fences de Markdown, elimínalos antes de `model_validate_json`. Persiste el archivo fuera de la sesión ADK.

## Conservar el contrato de respuesta MCP

Reutiliza la misma consulta y filtros en cada página. Trata cada cursor como opaco.

Detén la paginación cuando se alcance el total solicitado, `has_more` sea false, `next_cursor` se repita o se alcance el límite de páginas.

## Mantener una entrega de agente reanudable

<CardGroup cols={2}>
  <Card title="Páginas de tweets" icon="message-square">
    Almacena `tweet_id`, `text`, `author_username`, `created_at`, `has_more`, `next_cursor` y la consulta original.
  </Card>
  <Card title="Filas de perfil" icon="user-round">
    Almacena `user_id`, `username`, `name`, `description` y cantidades de seguidores.
  </Card>
  <Card title="Filas de tendencias" icon="radio">
    Almacena país, tema, etiqueta de contenido e IDs de tweet.
  </Card>
  <Card title="Acciones de escritura" icon="send">
    Almacena ruta, texto de vista previa y aprobación. Mantén las cookies en un almacén de secretos. Consulta.
  </Card>
</CardGroup>

Consulta [Agent MCP Handoff](/mcp/agent-handoff).

## Construir manejo de errores

| Estado | Significado | Decisión del agente |
| --- | --- | --- |
| `400` | Ruta o parámetros inválidos | Corrige la solicitud antes de reintentar |
| `401` | API key faltante o inválida | Detente y reemplaza la credencial |
| `403` | Acceso denegado o créditos | Pausa escrituras; verifica [Get Balance](/api-reference/balance-endpoints/get-balance-api-balance-get) |
| `429` | Límite de tasa alcanzado | Espera y luego reanuda el mismo cursor |
| `5xx` | Fallo temporal del servidor | Aplica backoff acotado a lecturas seguras |

Consulta [Error Handling](/guides/error-handling) y [Rate Limits](/guides/rate-limits).

## Configuración multiagente

Dale herramientas de TwexAPI solo al recolector. Mantén agentes de análisis y escritura sin herramientas para que las aprobaciones de escritura sigan siendo explícitas.

```python
researcher = LlmAgent(
    model="gemini-2.5-flash",
    name="researcher",
    instruction="Collect X/Twitter data through TwexAPI MCP and return compact JSON.",
    tools=[twexapi_toolset],
)

analyst = LlmAgent(
    model="gemini-2.5-flash",
    name="analyst",
    instruction="Analyze structured tweet rows. Do not call external tools.",
)
```

## Headers dinámicos y filtrado de herramientas

Usa headers dinámicos cuando una app ADK sirva múltiples cuentas de TwexAPI.

```python
def get_headers(context):
    return {"x-api-key": context.state["twexapi_api_key"]}


twexapi_toolset = McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://api.twexapi.io/mcp",
    ),
    header_provider=get_headers,
)
```

Expone solo descubrimiento a agentes de planificación:

```python
planning_toolset = McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://api.twexapi.io/mcp",
        headers={"x-api-key": os.environ["TWEXAPI_API_KEY"]},
    ),
    tool_filter=["explore"],
)
```

## Versiones de paquetes

| Paquete | Rango compatible |
| --- | --- |
| Python | `>=3.10` |
| `google-adk` | `>=1.0` |
| `pydantic` | `>=2.7` |

## Próximos pasos

- [MCP Tools](/mcp/tools)
- [Agent MCP Handoff](/mcp/agent-handoff)
-
- [Python SDK](/sdks/python)
- [Advanced Twitter Search](/api-reference/search-endpoints/get-data-page-twitter-advanced-search-page-post)
