Post X MCP

Servidor MCP para publicar en X (Twitter) con soporte para múltiples cuentas

Documentación

mcp-server-x

Un servidor MCP (Model Context Protocol) para X (Twitter). Construido en Rust usando OAuth 1.0a y la API v2 de X. Soporta múltiples cuentas.

Se comunica a través de stdio usando JSON-RPC 2.0.

Herramientas

HerramientaDescripción
list_accountsLista las cuentas disponibles y cuál es la predeterminada
post_tweetPublica un tweet con medios opcionales (hasta 4 imágenes, 1 video o 1 GIF)
post_threadPublica un hilo de hasta 25 tweets, cada uno con medios opcionales
delete_tweetElimina un tweet por ID o URL
upload_mediaSube medios para adjuntarlos más tarde (devuelve un media_id)
update_profileActualiza tu biografía/descripción, nombre mostrado, ubicación y/o URL del sitio web (endpoint heredado v1.1)
update_profile_bannerActualiza la imagen de cabecera/portada del perfil (endpoint heredado v1.1)
search_tweetsBusca tweets recientes (últimos 7 días) con operadores de Twitter
get_timelineObtén tu cronología de inicio en orden cronológico inverso
get_bookmarksObtén tus tweets marcados (paginados)
get_meObtén el perfil del usuario autenticado
lookup_userBusca cualquier usuario por @nombredeusuario o ID numérico
get_followersLista tus seguidores (paginados)
get_followingLista a quién sigues (paginado)
get_all_followersObtén TODOS tus seguidores en una sola llamada (auto-paginación)
get_all_followingObtén TODAS las cuentas que sigues en una sola llamada (auto-paginación)
like_tweetDa "Me gusta" a un tweet por ID o URL
unlike_tweetQuita "Me gusta" a un tweet por ID o URL
retweetRetuitea un tweet por ID o URL
unretweetDeshace un retweet por ID o URL
bookmark_tweetMarca un tweet por ID o URL
unbookmark_tweetElimina un marcador por ID o URL
get_trendsObtén los temas de tendencia actuales para una ubicación WOEID (predeterminado: mundial)
get_dm_eventsObtén mensajes directos recientes en todas las conversaciones
send_dmEnvía un mensaje directo a una conversación
follow_userSigue a un usuario por nombre de usuario o ID
unfollow_userDeja de seguir a un usuario por nombre de usuario o ID

Todas las herramientas aceptan un parámetro opcional account para seleccionar qué cuenta de X usar. Omítelo para usar la cuenta predeterminada.

Inicio Rápido

1. Compilar

cargo build --release

Produce target/release/mcp-server-x (optimizado con LTO, sin símbolos).

2. Configurar credenciales

El servidor busca la configuración en la primera de estas ubicaciones existentes:

  • $XDG_CONFIG_HOME/mcp-server-x/config.toml
  • ~/.config/mcp-server-x/config.toml
  • $XDG_CONFIG_HOME/mcp-server-post-x/config.toml (heredado)
  • ~/.config/mcp-server-post-x/config.toml (heredado)

También puedes ejecutarlo sin ningún archivo de configuración proporcionando credenciales mediante variables de entorno (ideal para contenedores/CI):

export X_API_KEY=...
export X_API_KEY_SECRET=...
export X_ACCESS_TOKEN=...
export X_ACCESS_TOKEN_SECRET=...
# Optional:
# export X_ACCOUNT_NAME=myaccount

POST_X_* / POST_X_ACCOUNT_NAME todavía se aceptan si las variables X_* no están definidas.

Crea el archivo de configuración (enfoque clásico):

mkdir -p ~/.config/mcp-server-x

Crea ~/.config/mcp-server-x/config.toml:

Cuenta única (no se necesita default_account):

[accounts.myaccount]
api_key = "your-api-key"
api_key_secret = "your-api-key-secret"
access_token = "your-access-token"
access_token_secret = "your-access-token-secret"

Múltiples cuentas:

default_account = "myaccount"

[accounts.myaccount]
api_key = "your-api-key"
api_key_secret = "your-api-key-secret"
access_token = "your-access-token"
access_token_secret = "your-access-token-secret"

[accounts.otheraccount]
api_key = "your-api-key"
api_key_secret = "your-api-key-secret"
access_token = "other-access-token"
access_token_secret = "other-access-token-secret"

Notas:

  • Las claves de cuenta son nombres de usuario de X (ej. [accounts.codechap])
  • Si tienes múltiples cuentas, default_account es obligatorio
  • Si tienes una sola cuenta, default_account es opcional (se detecta automáticamente)
  • Múltiples cuentas pueden compartir el mismo api_key/api_key_secret (misma app de X). Solo los access_token/access_token_secret difieren por cuenta.
  • bookmark_tweet / unbookmark_tweet requieren Contexto de Usuario OAuth 2.0 (bookmark.write). Agrega oauth2_client_id, oauth2_client_secret, oauth2_access_token y oauth2_refresh_token opcionales en la cuenta que necesita marcadores. OAuth 1.0a sigue en uso para todas las demás herramientas. Genera el token de usuario en la Consola de Desarrolladores de X (App → Keys & Tokens → OAuth 2.0 Access Token) con tweet.read, users.read, bookmark.read, bookmark.write y offline.access. Los tokens de acceso duran ~2 horas; el servidor los renueva con oauth2_refresh_token (y escribe los tokens rotados de vuelta en config.toml).

Asegúralo:

chmod 700 ~/.config/mcp-server-x
chmod 600 ~/.config/mcp-server-x/config.toml

Consulta Obtención de credenciales a continuación para saber cómo obtenerlas.

3. Agregar a tu cliente MCP

Claude Code (~/.claude.json):

{
  "mcpServers": {
    "x": {
      "command": "/path/to/mcp-server-x"
    }
  }
}

Luego pídele a Claude cosas como:

  • "Publica un tweet que diga hola mundo"
  • "Publica un tweet como securechap que diga hola mundo"
  • "Busca tweets sobre Rust"
  • "Muéstrame mi cronología"
  • "Dale Me gusta a este tweet: https://x.com/someone/status/123456"
  • "¿Quiénes son mis seguidores?"
  • "Busca @elonmusk"
  • "Lista mis cuentas"

Referencia de Herramientas

list_accounts

Sin parámetros obligatorios. Devuelve los nombres de cuentas disponibles, cuál es la predeterminada y nombres de usuario en caché.

post_tweet

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
textstringTexto del tweet (máximo 280 caracteres)
mediaarraynoMedios a subir y adjuntar. Cada elemento: { path, alt_text? }. Máximo 4 imágenes, o 1 video, o 1 GIF.
media_idsarraynoIDs de medios previamente subidos para adjuntar (máximo 4). Mutuamente excluyente con media.
reply_tostringnoID del tweet al que responder

post_thread

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
tweetsarrayArray de tweets (máximo 25). Cada uno: { text, media? }

delete_tweet / like_tweet / unlike_tweet / retweet / unretweet / bookmark_tweet / unbookmark_tweet

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
tweet_idstringID del tweet o URL completa del tweet

Todos aceptan URLs como https://x.com/user/status/123456 — el ID se extrae automáticamente.

upload_media

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
pathstringRuta del archivo local. Compatible: jpeg/png/webp (máx. 5MB), gif (máx. 15MB), mp4 (máx. 512MB)
alt_textstringnoTexto alternativo (solo imágenes y GIFs, no video)

Devuelve un media_id para usar con el parámetro media_ids de post_tweet.

update_profile

Actualiza los campos de texto del perfil del usuario autenticado. Debe proporcionarse al menos un campo; solo se cambian los campos que pases, y pasar una cadena vacía borra ese campo.

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
descriptionstringno*Nueva biografía/descripción (máx. 160 caracteres; cadena vacía la borra)
namestringno*Nuevo nombre mostrado (1-50 caracteres)
locationstringno*Nueva ubicación (máx. 30 caracteres; cadena vacía la borra)
urlstringno*Nueva URL del sitio web mostrada en el perfil (máx. 100 caracteres; cadena vacía la borra)

* Se requiere al menos uno de description, name, location o url.

Usa el endpoint heredado POST /1.1/account/update_profile.json (sin equivalente v2). Requiere que la app tenga permiso de Lectura y Escritura; sin él, el endpoint devuelve 403.

update_profile_banner

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
pathstringRuta del archivo local de la imagen de portada (solo JPEG/PNG/WebP, máx. 5MB). X recomienda 1500x500 píxeles.
widthintegernoAncho de la imagen (para recorte)
heightintegernoAlto de la imagen (para recorte)
offset_leftintegernoDesplazamiento izquierdo (píxeles) para inicio del recorte
offset_topintegernoDesplazamiento superior (píxeles) para inicio del recorte

Usa el endpoint heredado POST /1.1/account/update_profile_banner.json (parámetro banner en base64; sin equivalente v2). El éxito devuelve HTTP 200 sin cuerpo.

search_tweets

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
querystringConsulta de búsqueda. Compatible con: from:user, #hashtag, @mention, "exact phrase", -exclude, lang:en
max_resultsintegerno10-100 (predeterminado 10)
sort_orderstringnorecency o relevancy
pagination_tokenstringnoToken de página siguiente de la respuesta anterior

get_trends

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada; determina qué límite de tasa de la app se usa)
woeidintegernoWOEID para la ubicación (predeterminado: 1 = Mundial). Consulta valores comunes en la descripción de la herramienta.

Devuelve nombres de tendencias y volúmenes aproximados de publicaciones.

get_timeline

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
max_resultsintegerno1-100 (predeterminado 20)
excludestringnoreplies, retweets o ambos separados por comas
pagination_tokenstringnoToken de página siguiente

get_bookmarks

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
max_resultsintegerno1-100 (predeterminado 20)
pagination_tokenstringnoToken de página siguiente

lookup_user / follow_user / unfollow_user

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
userstringNombre de usuario (con o sin @) o ID numérico de usuario

get_followers / get_following

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
max_resultsintegerno1-100 (predeterminado 20)
pagination_tokenstringnoToken de página siguiente

get_all_followers / get_all_following

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
max_usersintegernoLímite de seguridad (predeterminado 5000, máximo 10000). Evita respuestas enormes para cuentas con muchos seguidores.

Auto-pagina a través de los resultados (100 por página) con un retraso de 200ms entre páginas. Para cuentas con decenas de miles de seguidores, prefiere las herramientas paginadas get_followers / get_following.

get_dm_events

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
max_resultsintegerno1-100 (predeterminado 20)
pagination_tokenstringnoToken de página siguiente

send_dm

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)
conversation_idstringID de la conversación de DM (obtener de get_dm_events)
textstringTexto del mensaje

get_me

ParámetroTipoObligatorioDescripción
accountstringnoCuenta a usar (omitir para la predeterminada)

Devuelve tu ID de usuario, nombre mostrado y @nombredeusuario.

Agregar Cuentas Adicionales

Para agregar otra cuenta de X a una app existente (sin una cuenta de desarrollador separada), usa el script de autorización OAuth incluido:

export X_API_KEY="your-app-api-key"
export X_API_KEY_SECRET="your-app-api-key-secret"
./oauth-authorize.sh

Importante: El script ya no contiene credenciales codificadas. Debes proporcionar las Consumer Keys de tu propia app mediante las dos variables de entorno mostradas arriba. Esto ejecuta el flujo OAuth 1.0a de 3 patas basado en PIN:

  1. Abre una URL donde la nueva cuenta autoriza tu aplicación
  2. Pegas el PIN de vuelta en la terminal
  3. Genera el bloque de configuración [accounts.username] para añadir a tu config.toml

Todas las cuentas que autorices comparten la misma App de X (y sus límites de tasa + facturación). Este es el patrón normal para uso multi-cuenta.

Obtención de Credenciales

  1. Ve a developer.x.com y regístrate para obtener una cuenta de desarrollador
  2. Crea un Proyecto y una App en la Consola de Desarrollador
  3. En la configuración de tu App, configura Autenticación de usuario:
    • Permisos de la App: Lectura y escritura (y Mensajes Directos si quieres soporte de DM)
    • Tipo: Aplicación Web, Aplicación Automatizada o Bot
    • URL de callback: https://example.com (no se usa, pero es obligatoria)
    • URL del sitio web: cualquier URL válida
  4. Ve a Claves y tokens y genera:
    • Clave de API y Secreto de Clave de API (bajo Claves de Consumidor)
    • Token de Acceso y Secreto de Token de Acceso (bajo Tokens de Autenticación)
  5. Copia los cuatro valores en tu config.toml bajo [accounts.yourusername]

El servidor valida las credenciales al inicio. Si recibes errores 401 persistentes, regenera tus tokens en developer.x.com.

Desarrollo

cargo build              # debug build
cargo run                # run in dev mode
RUST_LOG=debug cargo run # debug logging (credentials are redacted)

cargo test               # run unit tests
cargo clippy -- -D warnings   # strict lint check (must pass)
cargo build --release    # optimized binary

Detalles Técnicos

  • Autenticación: OAuth 1.0a con firmas HMAC-SHA1 (RFC 5849, codificación porcentual RFC 3986)
  • Multi-cuenta: Múltiples cuentas de X por instancia del servidor, seleccionables por llamada de herramienta
  • API de Tweets: X API v2 (api.x.com/2/)
  • Subida de medios: Subida fragmentada v1.1 (upload.twitter.com/1.1/media/upload.json) — flujo INIT/APPEND/FINALIZE/STATUS para video/GIF, multipart simple para imágenes
  • Límites de medios: JPEG/PNG/WebP hasta 5MB, GIF hasta 15MB, MP4 hasta 512MB
  • Validación de medios: Máximo 4 imágenes O 1 video O 1 GIF por tweet (sin mezclar)
  • Publicación de hilos: Retraso de 500ms entre tweets, encadenados vía in_reply_to_tweet_id
  • Lógica de reintentos: Reintento automático con retroceso exponencial en errores 503
  • Límites de tasa: Las respuestas 429 incluyen la marca de tiempo de reinicio en el mensaje de error (sin reintento automático — el llamador decide)
  • Seguridad: get_all_followers / get_all_following están limitados a 10k usuarios por defecto para evitar destruir las ventanas de contexto de LLM
  • Edición de Rust: 2021 (amplia compatibilidad)

Estructura del Proyecto

src/
  main.rs    — entry point, config loading, tracing, stdio transport
  server.rs  — MCP tool handlers, response formatting, multi-account routing
  api.rs     — X API client: OAuth signing, tweet/media/user/DM endpoints
  params.rs  — tool parameter types (serde + JSON Schema)