{"id":1537,"date":"2026-09-11T01:04:33","date_gmt":"2026-09-11T04:04:33","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/?p=1537"},"modified":"2026-09-11T01:13:12","modified_gmt":"2026-09-11T04:13:12","slug":"mcp-wp-go-wordpress-por-mcp-sem-ssh","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/en\/2026\/09\/mcp-wp-go-wordpress-por-mcp-sem-ssh\/","title":{"rendered":"mcp-wp-go: WordPress via MCP without SSH"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/09\/mcp-wp-go-wordpress-rest.webp\" alt=\"Mascote LinuxPro gerenciando WordPress por MCP em uma esta\u00e7\u00e3o com telas de API e upload de m\u00eddia\" width=\"1486\" height=\"856\" \/><\/p>\n<p>Editar um WordPress por automa\u00e7\u00e3o costuma virar uma escolha ruim entre credenciais de SSH, comandos fr\u00e1geis e APIs gen\u00e9ricas demais. O <a href=\"https:\/\/github.com\/jniltinho\/mcp-wp-go\" target=\"_blank\" rel=\"noopener\">mcp-wp-go<\/a> \u00e9 um servidor MCP escrito em Go que usa a REST API nativa do WordPress para criar, editar, publicar, despublicar, validar posts e administrar m\u00eddias \u2014 sem executar shell remoto no servidor. A ideia \u00e9 dar a agentes de IA uma interface controlada para operar conte\u00fado, mantendo permiss\u00f5es, hooks e cache do pr\u00f3prio WordPress no caminho.<\/p>\n<h2>O problema: automa\u00e7\u00e3o editorial n\u00e3o deve depender de SSH<\/h2>\n<p>SSH e WP-CLI continuam excelentes para manuten\u00e7\u00e3o do host, mas n\u00e3o s\u00e3o a melhor fronteira para uma tarefa editorial rotineira. Um agente que precisa somente criar um rascunho, subir uma imagem ou conferir se uma URL est\u00e1 p\u00fablica n\u00e3o deve receber acesso irrestrito ao sistema operacional. A REST API do WordPress j\u00e1 oferece autentica\u00e7\u00e3o, capacidades por usu\u00e1rio e endpoints para posts, m\u00eddia, categorias e tags.<\/p>\n<p>O mcp-wp-go conecta essa API ao <em>Model Context Protocol<\/em> (MCP). Na pr\u00e1tica, o cliente MCP conversa pelo <code>stdio<\/code> com o bin\u00e1rio local; o bin\u00e1rio conversa com <strong>um \u00fanico WordPress configurado<\/strong> via HTTPS. A URL do site n\u00e3o \u00e9 aceita como argumento de ferramenta, evitando que uma chamada seja redirecionada para outro destino.<\/p>\n<h2>Como a arquitetura funciona<\/h2>\n<ul>\n<li><strong>Cliente MCP:<\/strong> Codex, Claude Code ou outro cliente chama ferramentas tipadas.<\/li>\n<li><strong>mcp-wp-go:<\/strong> processo local em Go; <code>stdout<\/code> fica reservado ao protocolo e logs v\u00e3o para <code>stderr<\/code>.<\/li>\n<li><strong>WordPress REST API:<\/strong> recebe chamadas autenticadas por uma senha de aplicativo, n\u00e3o pela senha do servidor.<\/li>\n<li><strong>WordPress:<\/strong> aplica permiss\u00f5es do usu\u00e1rio, hooks e integra\u00e7\u00e3o de cache da pr\u00f3pria instala\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>Esse desenho n\u00e3o substitui o controle de acesso do WordPress: ele o torna a camada central. Crie uma senha de aplicativo exclusiva para a automa\u00e7\u00e3o, use um usu\u00e1rio com o menor conjunto de capacidades que resolva o trabalho e revogue a senha caso ela seja exposta. Nunca coloque a senha em Git, README, logs ou no arquivo de configura\u00e7\u00e3o versionado do cliente MCP.<\/p>\n<h2>O que o mcp-wp-go faz<\/h2>\n<p>O projeto organiza as ferramentas em quatro grupos:<\/p>\n<ul>\n<li><strong>Posts:<\/strong> listar, ler HTML edit\u00e1vel, criar rascunhos, atualizar conte\u00fado, publicar, despublicar e enviar para a lixeira.<\/li>\n<li><strong>M\u00eddias:<\/strong> listar, obter metadados, fazer upload de GIF, JPEG, PNG ou WebP, atualizar texto alternativo\/legenda e excluir.<\/li>\n<li><strong>Capas:<\/strong> enviar uma imagem, coloc\u00e1-la como primeiro elemento do corpo e usar a URL relativa retornada pelo pr\u00f3prio site. A ferramenta n\u00e3o define imagem destacada, evitando duplica\u00e7\u00e3o em temas que a renderizam separadamente.<\/li>\n<li><strong>Valida\u00e7\u00e3o:<\/strong> consultar categorias e tags, testar a autentica\u00e7\u00e3o e verificar se um post est\u00e1 publicado e se seu permalink responde HTTP 2xx.<\/li>\n<\/ul>\n<p>Nas vers\u00f5es recentes, <code>wordpress_get_post<\/code> tamb\u00e9m devolve <code>featured_media<\/code>. Isso permite a uma rotina de QA confirmar que a capa ficou no corpo e n\u00e3o foi marcada, sem querer, como imagem destacada.<\/p>\n<h2>Instala\u00e7\u00e3o no Linux<\/h2>\n<p>O projeto exige Go 1.27 ou mais recente para compilar. Clone o reposit\u00f3rio, execute os testes, gere o bin\u00e1rio e instale-o no diret\u00f3rio local padr\u00e3o do usu\u00e1rio. A configura\u00e7\u00e3o sens\u00edvel fica fora do clone:<\/p>\n<pre><code class=\"language-bash\">git clone https:\/\/github.com\/jniltinho\/mcp-wp-go.git\ncd mcp-wp-go\nmake check\nmake build\n\n# Instala o bin\u00e1rio para o usu\u00e1rio atual.\ninstall -D -m 0755 dist\/mcp-wp-go \"$HOME\/.local\/bin\/mcp-wp-go\"\n\n# Cria uma configura\u00e7\u00e3o privada fora do reposit\u00f3rio.\ninstall -d -m 700 \"$HOME\/.config\"\ninstall -m 600 .env.example \"$HOME\/.config\/mcp-wp-go.env\"\n$EDITOR \"$HOME\/.config\/mcp-wp-go.env\"\n\ncommand -v mcp-wp-go<\/code><\/pre>\n<p>O artefato de compila\u00e7\u00e3o fica em <code>dist\/mcp-wp-go<\/code>, mas o caminho est\u00e1vel usado pelo cliente \u00e9 <code>~\/.local\/bin\/mcp-wp-go<\/code>. Assim, o clone pode ficar em qualquer diret\u00f3rio e ser atualizado ou removido sem quebrar a configura\u00e7\u00e3o MCP. Se <code>~\/.local\/bin<\/code> ainda n\u00e3o estiver no <code>PATH<\/code> da sess\u00e3o, use o caminho absoluto no cliente ou adicione-o \u00e0 configura\u00e7\u00e3o do shell. O carregador de ambiente entende linhas simples <code>CHAVE=VALOR<\/code>; ele n\u00e3o executa expans\u00e3o de shell nem comandos escondidos.<\/p>\n<pre><code class=\"language-bash\">WP_BASE_URL=https:\/\/wp.exemplo.com\nWP_USERNAME=editor-automacao\nWP_APP_PASSWORD=senha-de-aplicativo-do-wordpress\nWP_TIMEOUT=30s\nWP_MAX_UPLOAD_BYTES=26214400\n# Recomendado: limita quais diret\u00f3rios locais podem ser lidos para upload.\nWP_UPLOAD_ROOT=\/srv\/capas<\/code><\/pre>\n<p><strong>N\u00e3o<\/strong> use a senha de root, a senha normal da conta WordPress ou credenciais do banco de dados. A senha de aplicativo \u00e9 espec\u00edfica para essa integra\u00e7\u00e3o e pode ser revogada independentemente.<\/p>\n<h2>Registrar no cliente MCP<\/h2>\n<p>Guarde a configura\u00e7\u00e3o sens\u00edvel fora do reposit\u00f3rio e aponte o cliente para caminhos absolutos:<\/p>\n<pre><code class=\"language-json\">{\n  \"mcpServers\": {\n    \"wordpress_go\": {\n      \"type\": \"stdio\",\n      \"command\": \"\/home\/operador\/.local\/bin\/mcp-wp-go\",\n      \"args\": [\"--env-file\", \"\/home\/operador\/.config\/mcp-wp-go.env\"]\n    }\n  }\n}<\/code><\/pre>\n<p>Depois de recarregar o cliente, chame <code>wordpress_site_health<\/code>. A resposta identifica o usu\u00e1rio autenticado, mas n\u00e3o exp\u00f5e a senha. Esse \u00e9 o primeiro teste antes de qualquer mudan\u00e7a editorial.<\/p>\n<h2>Fluxo seguro: rascunho, capa, publica\u00e7\u00e3o e checagem<\/h2>\n<p>Um fluxo editorial previs\u00edvel come\u00e7a com rascunho. Primeiro, use <code>wordpress_list_categories<\/code> e <code>wordpress_list_tags<\/code> para reaproveitar taxonomias existentes; depois crie o post em <code>draft<\/code>. A cria\u00e7\u00e3o fecha coment\u00e1rios automaticamente.<\/p>\n<pre><code class=\"language-json\">{\n  \"title\": \"Novo guia t\u00e9cnico\",\n  \"content\": \"&lt;p&gt;Introdu\u00e7\u00e3o do artigo.&lt;\/p&gt;\",\n  \"status\": \"draft\",\n  \"categories\": [46],\n  \"tags\": [311, 31]\n}<\/code><\/pre>\n<p>Em seguida, use <code>wordpress_set_post_cover<\/code> com uma imagem local WebP e um <code>alt_text<\/code> descritivo. A ferramenta aceita apenas imagens regulares permitidas, confere tipo e extens\u00e3o, respeita o limite configurado e pode restringir a leitura a <code>WP_UPLOAD_ROOT<\/code>.<\/p>\n<p>A publica\u00e7\u00e3o e a despublica\u00e7\u00e3o foram separadas da edi\u00e7\u00e3o comum. As ferramentas <code>wordpress_publish_posts<\/code> e <code>wordpress_unpublish_posts<\/code> aceitam de um a cem IDs \u00fanicos, mas exigem confirma\u00e7\u00e3o expl\u00edcita:<\/p>\n<pre><code class=\"language-json\">{ \"ids\": [123, 124], \"confirm\": true }<\/code><\/pre>\n<p>Opera\u00e7\u00f5es em lote n\u00e3o s\u00e3o transacionais: se um ID falhar, os demais podem j\u00e1 ter sido processados. Por isso a resposta lista o resultado de cada post. Antes de publicar em massa, valide a sele\u00e7\u00e3o com <code>wordpress_get_post<\/code> ou <code>wordpress_list_posts<\/code>.<\/p>\n<p>Por fim, <code>wordpress_check_post_live<\/code> confirma duas coisas: o status do post \u00e9 <code>publish<\/code> e o permalink p\u00fablico retorna HTTP 2xx. Para uma capa, confira tamb\u00e9m <code>featured_media<\/code>, a primeira imagem do HTML e o resultado visual no navegador. Automa\u00e7\u00e3o diminui trabalho repetitivo; ela n\u00e3o elimina revis\u00e3o editorial.<\/p>\n<h2>Prote\u00e7\u00f5es contra erros comuns<\/h2>\n<ul>\n<li>Excluir post ou m\u00eddia requer <code>confirm: true<\/code>; o padr\u00e3o \u00e9 mover para a lixeira. Exclus\u00e3o definitiva requer <code>permanent: true<\/code>.<\/li>\n<li>Editar post n\u00e3o altera slug, data ou status. As mudan\u00e7as de status t\u00eam ferramentas pr\u00f3prias e confirma\u00e7\u00e3o obrigat\u00f3ria.<\/li>\n<li>Upload n\u00e3o aceita arquivos arbitr\u00e1rios: GIF, JPEG, PNG e WebP passam por valida\u00e7\u00e3o de extens\u00e3o, assinatura e tamanho.<\/li>\n<li>O cliente HTTP limita redirects e n\u00e3o aceita que um redirecionamento saia do host WordPress configurado.<\/li>\n<li>A checagem p\u00fablica rejeita permalinks fora do host configurado, reduzindo o risco de usar uma URL devolvida pela API para fazer requisi\u00e7\u00f5es externas.<\/li>\n<\/ul>\n<p>H\u00e1 uma diferen\u00e7a importante entre reduzir o acesso ao host e resolver toda a seguran\u00e7a de conte\u00fado. Um agente ainda pode escrever um texto ruim, apagar um post se receber confirma\u00e7\u00e3o ou reproduzir uma instru\u00e7\u00e3o maliciosa de uma fonte. Trabalhe com rascunhos, fa\u00e7a revis\u00e3o humana antes de altera\u00e7\u00f5es destrutivas e mantenha backups e hist\u00f3rico de revis\u00f5es do WordPress.<\/p>\n<h2>Go, testes e releases<\/h2>\n<p>O projeto usa a SDK oficial do MCP para Go e mant\u00e9m <code>main.go<\/code> na raiz do reposit\u00f3rio. O <code>Makefile<\/code> oferece <code>make fmt<\/code>, <code>make vet<\/code>, <code>make test<\/code> e <code>make check<\/code>. Os testes cobrem, entre outros pontos, fechamento de coment\u00e1rios na cria\u00e7\u00e3o, URL relativa de capa, valida\u00e7\u00e3o de <code>featured_media<\/code> e mudan\u00e7a de status sem alterar outros campos.<\/p>\n<p>As tags acionam GitHub Actions. A release <strong>v0.2.0<\/strong> publica pacotes para Linux amd64, macOS arm64 e Windows amd64, com notas de vers\u00e3o revisadas. Isso facilita testar o mesmo servidor MCP em esta\u00e7\u00f5es de trabalho e servidores sem exigir que cada operador compile Go localmente.<\/p>\n<h2>Onde esse projeto se encaixa<\/h2>\n<p>O mcp-wp-go \u00e9 uma pe\u00e7a de automa\u00e7\u00e3o editorial, n\u00e3o uma substitui\u00e7\u00e3o para observabilidade, backup ou hardening do WordPress. Ele combina bem com uma rotina que gera imagens, pesquisa fontes, redige rascunhos e valida links; para conte\u00fado t\u00e9cnico, \u00e9 \u00fatil aplicar a mesma disciplina de mudan\u00e7a que j\u00e1 usamos em infraestrutura. Quem mant\u00e9m agentes e ferramentas tamb\u00e9m pode aproveitar o guia de <a href=\"\/2026\/09\/openobserve-ubuntu-servidor-dedicado-s3-gcs-minio\/\">OpenObserve no Ubuntu<\/a> para centralizar logs e investigar falhas de integra\u00e7\u00e3o.<\/p>\n<p>O projeto \u00e9 aberto e recebe contribui\u00e7\u00f5es no <a href=\"https:\/\/github.com\/jniltinho\/mcp-wp-go\" target=\"_blank\" rel=\"noopener\">GitHub<\/a>. Antes de usar em produ\u00e7\u00e3o, leia o README, ajuste as permiss\u00f5es do usu\u00e1rio WordPress e teste em um ambiente n\u00e3o cr\u00edtico.<\/p>\n<p><strong>Fontes:<\/strong> <a href=\"https:\/\/github.com\/jniltinho\/mcp-wp-go\" target=\"_blank\" rel=\"noopener\">reposit\u00f3rio e README do mcp-wp-go<\/a> \u00b7 <a href=\"https:\/\/github.com\/jniltinho\/mcp-wp-go\/releases\/tag\/v0.2.0\" target=\"_blank\" rel=\"noopener\">release v0.2.0<\/a> \u00b7 <a href=\"https:\/\/github.com\/modelcontextprotocol\/go-sdk\" target=\"_blank\" rel=\"noopener\">SDK oficial MCP para Go<\/a> \u00b7 <a href=\"https:\/\/developer.wordpress.org\/rest-api\/\" target=\"_blank\" rel=\"noopener\">WordPress REST API<\/a> \u00b7 <a href=\"https:\/\/developer.wordpress.org\/advanced-administration\/security\/application-passwords\/\" target=\"_blank\" rel=\"noopener\">WordPress Application Passwords<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Editing WordPress through automation often becomes a poor choice between SSH credentials, fragile commands and overly generic APIs. The mcp-wp-go is an MCP server written in Go that uses the native WordPress REST API to create, edit, publish, unpublish, validate posts and administer media \u2014 without executing remote shell on the server. A \u2026 <a title=\"mcp-wp-go: WordPress via MCP without SSH\" class=\"read-more\" href=\"https:\/\/www.linuxpro.com.br\/en\/2026\/09\/mcp-wp-go-wordpress-por-mcp-sem-ssh\/\" aria-label=\"Read more about mcp-wp-go: WordPress por MCP sem SSH\">Read more<\/a><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[45,46],"tags":[424,122,31,311],"class_list":["post-1537","post","type-post","status-publish","format-standard","hentry","category-desenv","category-devops","tag-api","tag-automacao","tag-golang","tag-mcp"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/1537","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/comments?post=1537"}],"version-history":[{"count":3,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/1537\/revisions"}],"predecessor-version":[{"id":1541,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/1537\/revisions\/1541"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/media?parent=1537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/categories?post=1537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/tags?post=1537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}