Dale a tu agente de IA un lector de Twitter: definiciones de herramienta para Claude, ChatGPT y Codex

Actualizado
Definiciones de herramientas listas para copiar con las que Claude, ChatGPT o Codex leen perfiles, posts, respuestas y búsquedas de X sin API key.
En resumen: un agente necesita cuatro cosas para leer X: una URL que pueda construir a partir de un handle o del enlace de una publicación, un cuerpo en JSON o Markdown que pueda leer, un error según el cual pueda ramificar y un límite que pueda ver. Los endpoints
/tools/x/*de UnifAPI dan las cuatro gratis, sin iniciar sesión, sin necesidad de cuenta ni clave de API, con límite por visitante, así que una definición de herramienta es un único GET HTTP. Abajo están las definiciones para el tool use de Anthropic, el function calling de OpenAI y un SKILL.md para Claude Code y Codex, más las tres reglas que necesita el modelo: leerX-RateLimit-Remaining, dormir lo que digaRetry-Aftery pedir Markdown cuando el resultado va directo a la ventana de contexto.
Los modelos ya saben leer X. Pídele a Claude o a ChatGPT qué publicó @NASA esta semana y lo intentarán: una búsqueda web, un fetch de x.com, quizá una URL de Nitter sacada de los datos de entrenamiento. La búsqueda devuelve resúmenes, el fetch devuelve un cascarón de JavaScript y la instancia de Nitter ya no existe. Entonces el modelo adivina o pide disculpas.
El arreglo no es un modelo más listo, es una herramienta con una URL que el modelo pueda construir y un cuerpo que pueda analizar. Este artículo es esa herramienta, en los tres formatos que la gente despliega de verdad.
Los endpoints
Ocho GET, todos bajo https://unifapi.com/tools/x/, todos documentados con una muestra capturada en /llms.txt:
| Endpoint | Parámetros | Devuelve |
|---|---|---|
profile | handle, posts (1–10), cursor | perfil, tasa de engagement, publicaciones recientes |
post | id (id o URL) | una publicación con autor, medios, publicación citada y métricas |
media | handle, cursor | las publicaciones con foto y video de una cuenta |
replies | id, sort=top|recent, cursor | la publicación y sus respuestas públicas |
search | q, cursor | publicaciones recientes; funcionan los operadores de búsqueda de X |
trends | location o woeid | lo que es tendencia ahora |
communities | q, cursor | Comunidades públicas de X sobre un tema |
followers | handle, kind=followers|following | quién sigue a una cuenta, o a quién sigue ella |
Toda lista es { items, hasMore, nextCursor }. Todo error es { error: { type, message } }. Toda respuesta trae X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset; un 429 añade Retry-After. Añade format=md para Markdown.
Tool use de Anthropic
Una sola herramienta con un enum endpoint es más simple para el modelo que ocho herramientas, y los nombres de los parámetros coinciden con los de la API, así que el modelo no puede equivocarse con ellos.
{
"name": "read_x",
"description": "Read public X (Twitter) data with no account: a profile and its recent posts, one post, an account's media, the replies under a post, a search over recent posts (X operators like from:, since:, min_faves:, filter:media work), trends by location, Communities by topic, or an account's followers/following. Free, rate-limited to 20 requests per 10 minutes; search costs 2. Returns JSON. Pass cursor from a previous result to page.",
"input_schema": {
"type": "object",
"properties": {
"endpoint": {
"type": "string",
"enum": [
"profile",
"post",
"media",
"replies",
"search",
"trends",
"communities",
"followers"
]
},
"handle": {
"type": "string",
"description": "X handle or profile URL (profile, media, followers)"
},
"id": { "type": "string", "description": "Post ID or x.com status URL (post, replies)" },
"q": { "type": "string", "description": "Search query or Communities topic" },
"location": {
"type": "string",
"description": "Trends location slug: worldwide, us, uk, japan, india, brazil, korea, germany, spain, mexico"
},
"sort": { "type": "string", "enum": ["top", "recent"] },
"kind": { "type": "string", "enum": ["followers", "following"] },
"cursor": { "type": "string" }
},
"required": ["endpoint"]
}
}
El handler es una línea de fetch:
async function readX(input: { endpoint: string } & Record<string, string | undefined>) {
const { endpoint, ...params } = input;
const qs = new URLSearchParams(Object.entries(params).filter(([, v]) => v) as [string, string][]);
const res = await fetch(`https://unifapi.com/tools/x/${endpoint}?${qs}`, {
headers: { Accept: "application/json" },
});
const body = await res.json();
if (res.status === 429)
return { error: body.error, retryAfterSeconds: Number(res.headers.get("Retry-After")) };
return { ...body, remaining: Number(res.headers.get("X-RateLimit-Remaining")) };
}
Devolver remaining al modelo es deliberado. Si se le dice que le quedan 3 consultas, Claude deja de paginar y responde con lo que tiene en lugar de chocar contra el muro.
Function calling de OpenAI
La misma forma, con el envoltorio de OpenAI:
{
"type": "function",
"function": {
"name": "read_x",
"description": "Read public X (Twitter) data with no account. endpoint=profile|post|media|replies|search|trends|communities|followers. Free, 20 requests per 10 minutes. Returns JSON with { items, hasMore, nextCursor } for lists.",
"parameters": {
"type": "object",
"properties": {
"endpoint": {
"type": "string",
"enum": [
"profile",
"post",
"media",
"replies",
"search",
"trends",
"communities",
"followers"
]
},
"handle": { "type": "string" },
"id": { "type": "string" },
"q": { "type": "string" },
"location": { "type": "string" },
"sort": { "type": "string", "enum": ["top", "recent"] },
"kind": { "type": "string", "enum": ["followers", "following"] },
"cursor": { "type": "string" }
},
"required": ["endpoint"]
}
}
}
Un SKILL.md para Claude Code y Codex
Los agentes de programación no necesitan una definición de herramienta; necesitan que les digan que existe el patrón de URL. Un archivo de skill en el proyecto hace exactamente eso:
---
name: read-x
description: Read public X (Twitter) profiles, posts, replies, search, trends, communities, and followers as JSON or Markdown with no API key, via https://unifapi.com/tools/x/*. Use when a task needs what an account or post says on X.
---
# Reading X
All endpoints are GET https://unifapi.com/tools/x/<endpoint>. No key. Free limit 20 requests
per 10 minutes (search costs 2), printed in X-RateLimit-* headers; on 429 wait Retry-After.
- profile?handle=nasa profile + recent posts (+ posts=1-10, cursor)
- post?id=<id or x.com URL> one post
- media?handle=nasa photo/video posts
- replies?id=<id>&sort=top replies under a post (sort=recent for newest)
- search?q=from:nasa%20filter:media recent posts; X operators work
- trends?location=us trending now
- communities?q=ai X Communities
- followers?handle=nasa&kind=following
Add &format=md for Markdown when the result goes into context. Lists are { items, hasMore,
nextCursor }; pass cursor= to page. Errors are { error: { type, message } }.
Full reference with samples: https://unifapi.com/llms.txt
Con ese archivo presente, "mira qué publicó @NASA esta semana y resume las respuestas a la publicación principal" se convierte en dos curls que el agente escribe por su cuenta.
Tres reglas para el modelo
- Leer el recuento restante antes de paginar.
X-RateLimit-Remainingviene en cada respuesta. Un perfil más sus respuestas más una búsqueda son 4 unidades de 20; un bucle que lo pagina todo son 20 unidades en un minuto. - Dormir lo que diga
Retry-After, nunca reintentar en bucle. El cuerpo del 429 también indica la URL deupgrade; si la tarea es más grande que el plan gratuito, ahí es adonde va, con una clave de workspace y los mismos nombres de campo. - Pedir Markdown cuando el resultado es para leer, JSON cuando es para código.
format=mdrenderiza un perfil y sus publicaciones en unos cientos de tokens sin la sobrecarga de las comillas. El JSON es para cuando el modelo va a filtrar, ordenar o pasar los datos a otra herramienta.
MCP
Si el agente ya habla MCP, la API de X con medición de uso está en el servidor MCP de UnifAPI con las mismas operaciones (perfil, publicación, búsqueda, respuestas, seguidores y más) detrás de una clave de workspace, de pago por uso. Los endpoints HTTP gratuitos de arriba son para cuando todavía no hay clave, o cuando la tarea es un puñado de lecturas que no deberían necesitar una.
Preguntas frecuentes
¿Puede Claude leer Twitter?
Con una herramienta, sí. Claude no puede cargar x.com por sí mismo (la página es un cascarón de JavaScript), pero con la herramienta read_x de arriba lee perfiles, publicaciones, respuestas y resultados de búsqueda en JSON y razona sobre ellos.
¿Puede ChatGPT leer tweets?
La misma respuesta: con la definición de function de arriba, en un GPT personalizado o en un flujo de Assistants. La navegación integrada de ChatGPT no puede renderizar x.com.
¿Esto necesita una clave de API?
No. Los endpoints son gratis, sin clave, sin iniciar sesión y sin necesidad de cuenta, y tienen límite por visitante: 20 consultas cada 10 minutos, y una búsqueda cuenta como dos. Una clave es solo para el acceso sin tope, con medición de uso.
¿Hay un límite en lo que un agente puede hacer con los datos?
Los endpoints leen solo datos públicos. Las cuentas protegidas devuelven su existencia y sus recuentos, nunca sus publicaciones. Usa los datos como permiten los términos de X para el contenido público.