Post X MCP

Servidor MCP para postar no X (Twitter) com suporte a múltiplas contas

Documentação

mcp-server-x

Um servidor MCP (Model Context Protocol) para X (Twitter). Construído em Rust usando OAuth 1.0a e a API X v2. Suporta múltiplas contas.

Comunica via stdio usando JSON-RPC 2.0.

Ferramentas

FerramentaDescrição
list_accountsLista as contas disponíveis e qual é a padrão
post_tweetPublica um tweet com mídia opcional (até 4 imagens, 1 vídeo ou 1 GIF)
post_threadPublica um thread de até 25 tweets, cada um com mídia opcional
delete_tweetExclui um tweet por ID ou URL
upload_mediaEnvia mídia para anexo posterior (retorna um media_id)
update_profileAtualiza sua bio/descrição, nome de exibição, localização e/ou URL do site (endpoint legado v1.1)
update_profile_bannerAtualiza a imagem de cabeçalho/banner do perfil (endpoint legado v1.1)
search_tweetsPesquisa tweets recentes (últimos 7 dias) com operadores do Twitter
get_timelineObtém sua linha do tempo inicial em ordem cronológica reversa
get_bookmarksObtém seus tweets com marcadores (paginado)
get_meObtém o perfil do usuário autenticado
lookup_userConsulta qualquer usuário por @username ou ID numérico
get_followersLista seus seguidores (paginado)
get_followingLista quem você segue (paginado)
get_all_followersBusca TODOS os seus seguidores em uma única chamada (paginação automática)
get_all_followingBusca TODAS as contas que você segue em uma única chamada (paginação automática)
like_tweetCurte um tweet por ID ou URL
unlike_tweetDescurte um tweet por ID ou URL
retweetRetweeta um tweet por ID ou URL
unretweetDesfaz um retweet por ID ou URL
bookmark_tweetAdiciona um tweet aos marcadores por ID ou URL
unbookmark_tweetRemove um marcador por ID ou URL
get_trendsObtém os assuntos em alta atuais para uma localização WOEID (padrão: mundial)
get_dm_eventsObtém mensagens diretas recentes em todas as conversas
send_dmEnvia uma mensagem direta para uma conversa
follow_userSegue um usuário por username ou ID
unfollow_userDeixa de seguir um usuário por username ou ID

Todas as ferramentas aceitam um parâmetro opcional account para selecionar qual conta X usar. Omita-o para usar a conta padrão.

Início Rápido

1. Compilar

cargo build --release

Produz target/release/mcp-server-x (otimizado com LTO, reduzido).

2. Configurar credenciais

O servidor procura a configuração no primeiro local existente entre:

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

Você também pode executar sem nenhum arquivo de configuração fornecendo credenciais por meio de variáveis de ambiente (ótimo para contêineres/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 ainda são aceitos se as variáveis X_* não estiverem definidas.

Crie o arquivo de configuração (abordagem clássica):

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

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

Conta única (sem default_account necessário):

[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últiplas contas:

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"

Observações:

  • As chaves das contas são usernames do X (ex.: [accounts.codechap])
  • Se você tiver múltiplas contas, default_account é obrigatório
  • Se você tiver uma conta, default_account é opcional (detecção automática)
  • Múltiplas contas podem compartilhar o mesmo api_key/api_key_secret (mesmo app X). Apenas o access_token/access_token_secret difere por conta.
  • bookmark_tweet / unbookmark_tweet exigem OAuth 2.0 User Context (bookmark.write). Adicione oauth2_client_id, oauth2_client_secret, oauth2_access_token e oauth2_refresh_token opcionais na conta que precisa de marcadores. OAuth 1.0a permanece em uso para todas as outras ferramentas. Gere o token de usuário no Console de Desenvolvedor do X (App → Keys & Tokens → OAuth 2.0 Access Token) com tweet.read, users.read, bookmark.read, bookmark.write e offline.access. Os tokens de acesso duram cerca de 2 horas; o servidor os renova com oauth2_refresh_token (e grava os tokens rotacionados de volta em config.toml).

Proteja-o:

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

Veja Obtendo credenciais abaixo para saber como obtê-las.

3. Adicionar ao seu cliente MCP

Claude Code (~/.claude.json):

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

Depois, peça coisas como:

  • "Publique um tweet dizendo olá mundo"
  • "Publique um tweet como securechap dizendo olá mundo"
  • "Pesquise tweets sobre Rust"
  • "Mostre minha linha do tempo"
  • "Curta este tweet: https://x.com/someone/status/123456"
  • "Quem são meus seguidores?"
  • "Consulte @elonmusk"
  • "Liste minhas contas"

Referência de Ferramentas

list_accounts

Sem parâmetros obrigatórios. Retorna os nomes das contas disponíveis, qual é a padrão e usernames em cache.

post_tweet

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
textstringsimTexto do tweet (máx. 280 caracteres)
mediaarraynãoMídia para enviar e anexar. Cada item: { path, alt_text? }. Máx. 4 imagens, ou 1 vídeo, ou 1 GIF.
media_idsarraynãoIDs de mídia pré-enviados para anexar (máx. 4). Mutuamente exclusivo com media.
reply_tostringnãoID do tweet para responder

post_thread

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
tweetsarraysimArray de tweets (máx. 25). Cada um: { text, media? }

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

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
tweet_idstringsimID do tweet ou URL completa do tweet

Todos aceitam URLs como https://x.com/user/status/123456 — o ID é extraído automaticamente.

upload_media

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
pathstringsimCaminho do arquivo local. Suportados: jpeg/png/webp (máx. 5MB), gif (máx. 15MB), mp4 (máx. 512MB)
alt_textstringnãoTexto alternativo (apenas imagens e GIFs, não vídeo)

Retorna um media_id para usar com o parâmetro media_ids de post_tweet.

update_profile

Atualiza os campos de texto do perfil do usuário autenticado. Pelo menos um campo deve ser fornecido; apenas os campos passados são alterados, e passar uma string vazia limpa esse campo.

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
descriptionstringnão*Nova bio/descrição (máx. 160 caracteres; string vazia limpa)
namestringnão*Novo nome de exibição (1-50 caracteres)
locationstringnão*Nova localização (máx. 30 caracteres; string vazia limpa)
urlstringnão*Nova URL do site exibida no perfil (máx. 100 caracteres; string vazia limpa)

* Pelo menos um de description, name, location ou url é obrigatório.

Usa o endpoint legado POST /1.1/account/update_profile.json (sem equivalente v2). Exige que o app tenha permissão Read and Write; sem ela, o endpoint retorna 403.

update_profile_banner

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
pathstringsimCaminho do arquivo local da imagem do banner (apenas JPEG/PNG/WebP, máx. 5MB). O X recomenda 1500x500 pixels.
widthinteironãoLargura da imagem (para recorte)
heightinteironãoAltura da imagem (para recorte)
offset_leftinteironãoDeslocamento esquerdo (pixels) para início do recorte
offset_topinteironãoDeslocamento superior (pixels) para início do recorte

Usa o endpoint legado POST /1.1/account/update_profile_banner.json (parâmetro banner em base64; sem equivalente v2). Sucesso retorna HTTP 200 sem corpo.

search_tweets

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
querystringsimConsulta de pesquisa. Suporta: from:user, #hashtag, @mention, "exact phrase", -exclude, lang:en
max_resultsinteironão10-100 (padrão 10)
sort_orderstringnãorecency ou relevancy
pagination_tokenstringnãoToken da próxima página da resposta anterior

get_trends

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão; determina qual limite de taxa do app é usado)
woeidinteironãoWOEID da localização (padrão: 1 = Mundial). Veja valores comuns na descrição da ferramenta.

Retorna nomes dos assuntos em alta e volumes aproximados de postagens.

get_timeline

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
max_resultsinteironão1-100 (padrão 20)
excludestringnãoreplies, retweets ou ambos separados por vírgula
pagination_tokenstringnãoToken da próxima página

get_bookmarks

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
max_resultsinteironão1-100 (padrão 20)
pagination_tokenstringnãoToken da próxima página

lookup_user / follow_user / unfollow_user

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
userstringsimUsername (com ou sem @) ou ID numérico do usuário

get_followers / get_following

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
max_resultsinteironão1-100 (padrão 20)
pagination_tokenstringnãoToken da próxima página

get_all_followers / get_all_following

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
max_usersinteironãoLimite de segurança (padrão 5000, máx. 10000). Evita respostas enormes para contas com muitos seguidores.

Pagina automaticamente pelos resultados (100 por página) com atraso de 200ms entre páginas. Para contas com dezenas de milhares de seguidores, prefira as ferramentas paginadas get_followers / get_following.

get_dm_events

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
max_resultsinteironão1-100 (padrão 20)
pagination_tokenstringnãoToken da próxima página

send_dm

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)
conversation_idstringsimID da conversa de DM (obter de get_dm_events)
textstringsimTexto da mensagem

get_me

ParâmetroTipoObrigatórioDescrição
accountstringnãoConta a usar (omitir para a padrão)

Retorna seu ID de usuário, nome de exibição e @username.

Adicionando Contas Adicionais

Para adicionar outra conta X a um app existente (sem uma conta de desenvolvedor separada), use o script de autorização OAuth incluído:

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

Importante: O script não contém mais nenhuma credencial codificada. Você deve fornecer as Consumer Keys do seu próprio app por meio das duas variáveis de ambiente mostradas acima. Este fluxo executa o fluxo OAuth 1.0a baseado em PIN de 3 etapas:

  1. Abre uma URL onde a nova conta autoriza seu aplicativo
  2. Você cola o PIN de volta no terminal
  3. Ele gera o bloco de configuração [accounts.username] para adicionar ao seu config.toml

Todas as contas que você autoriza compartilham o mesmo App X (e seus limites de taxa + cobrança). Este é o padrão normal para uso com múltiplas contas.

Obtendo Credenciais

  1. Acesse developer.x.com e cadastre-se para uma conta de desenvolvedor
  2. Crie um Projeto e um App no Console do Desenvolvedor
  3. Nas configurações do seu App, configure a Autenticação de usuário:
    • Permissões do app: Leitura e escrita (e Mensagens diretas se você quiser suporte a DM)
    • Tipo: Web App, App Automatizado ou Bot
    • URL de callback: https://example.com (não usada, mas obrigatória)
    • URL do site: qualquer URL válida
  4. Vá para Chaves e tokens e gere:
    • API Key e API Key Secret (em Consumer Keys)
    • Access Token e Access Token Secret (em Authentication Tokens)
  5. Copie todos os quatro valores para o seu config.toml em [accounts.yourusername]

O servidor valida as credenciais na inicialização. Se você receber erros 401 persistentes, regenere seus tokens em developer.x.com.

Desenvolvimento

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

Detalhes Técnicos

  • Autenticação: OAuth 1.0a com assinaturas HMAC-SHA1 (RFC 5849, codificação percentual RFC 3986)
  • Multi-contas: Várias contas X por instância do servidor, selecionáveis por chamada de ferramenta
  • API de Tweets: X API v2 (api.x.com/2/)
  • Upload de mídia: upload em partes v1.1 (upload.twitter.com/1.1/media/upload.json) — fluxo INIT/APPEND/FINALIZE/STATUS para vídeo/GIF, multipart simples para imagens
  • Limites de mídia: JPEG/PNG/WebP até 5MB, GIF até 15MB, MP4 até 512MB
  • Validação de mídia: Máximo de 4 imagens OU 1 vídeo OU 1 GIF por tweet (sem mistura)
  • Postagem em thread: atraso de 500ms entre tweets, encadeados via in_reply_to_tweet_id
  • Lógica de repetição: repetição automática com backoff exponencial em erros 503
  • Limites de taxa: respostas 429 incluem timestamp de redefinição na mensagem de erro (sem repetição automática — quem chama decide)
  • Segurança: get_all_followers / get_all_following são limitados a 10 mil usuários por padrão para evitar destruir janelas de contexto de LLM
  • Edição Rust: 2021 (ampla compatibilidade)

Estrutura do Projeto

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)