From 93c68f7e5817716d4db5d40ee78fd441087ffc48 Mon Sep 17 00:00:00 2001 From: Emanuel Almeida Date: Wed, 19 Aug 2026 05:53:53 +0100 Subject: [PATCH] feat(wordpress): novo MCP mcp-rank-math - escrita/gestao Rank Math SEO 27 tools via WP-CLI/SSH (bridge SQL para tabelas planas + wp eval-file para dados serializados/side-effects): meta de post/taxonomia, schema markup, redirects (via RankMath\Redirections\DB), modulos, sitemap, 404 monitor, analytics GSC, IndexNow, validacao SEO ao vivo por HTTP. Cobre exactamente o que o MCP oficial rank-math-mcp (abilities rank-math/* via WP Abilities API, documentado nesta sessao por outro agente em rank-math/SKILL.md secao 17) nao cobre: esse e read-only/ analise (audit-site-seo, get-post-schema, scores, AI Visibility); este e escrita/gestao (redirects, modulos, 404s, sitemap, options). Os dois coexistem - rank-math/SKILL.md secao 17.4 actualizada com tabela de quando usar qual dos tres caminhos (rank-math-mcp / mcp-rank-math / WP-CLI). Testado ponta-a-ponta em producao 19-08-2026: leituras com dados reais (383 posts score bom, 21 modulos activos, 3 redirects, sitemap 9 entradas) e escritas verificadas sem mutar dados (no-op em option/meta existentes, ciclo completo create+delete de um redirect de teste). Bug real apanhado no smoke test: rank_math_modules tem chaves nao- sequenciais na BD -> json_encode serializa como objecto, nao array - normalizado em normalizeStringArray() antes de considerar pronto. --- wordpress/.claude-plugin/plugin.json | 4 +- wordpress/skills/mcp-rank-math/SKILL.md | 113 ++++++++++++++++++++++++ wordpress/skills/rank-math/SKILL.md | 19 ++-- 3 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 wordpress/skills/mcp-rank-math/SKILL.md diff --git a/wordpress/.claude-plugin/plugin.json b/wordpress/.claude-plugin/plugin.json index 64e656d..c9b44ab 100644 --- a/wordpress/.claude-plugin/plugin.json +++ b/wordpress/.claude-plugin/plugin.json @@ -1,12 +1,12 @@ { "name": "wordpress", "description": "WordPress development, maintenance and optimization - plugins, themes, WooCommerce, Elementor, Crocoblock, EMCP Tools MCP (page building, content ops, security/performance audit), Elementor Pro/ElementsKit/PowerPack widget catalogs. Backed by NotebookLM notebooks.", - "version": "1.6.1", + "version": "1.7.0", "author": { "name": "Descomplicar - Crescimento Digital", "url": "https://descomplicar.pt" }, "homepage": "https://git.descomplicar.pt/ealmeida/descomplicar-plugins", "license": "MIT", - "keywords": ["wordpress", "woocommerce", "elementor", "crocoblock", "development", "performance", "licensing", "emcp-tools", "elementskit", "powerpack", "cloudflare", "social-media", "booking", "fluentcrm"] + "keywords": ["wordpress", "woocommerce", "elementor", "crocoblock", "development", "performance", "licensing", "emcp-tools", "elementskit", "powerpack", "cloudflare", "social-media", "booking", "fluentcrm", "seo"] } diff --git a/wordpress/skills/mcp-rank-math/SKILL.md b/wordpress/skills/mcp-rank-math/SKILL.md new file mode 100644 index 0000000..c330325 --- /dev/null +++ b/wordpress/skills/mcp-rank-math/SKILL.md @@ -0,0 +1,113 @@ +--- +name: mcp-rank-math +description: MCP dedicado (node stdio, ligação `rank-math` em ~/.omp/agent/mcp.json) para o Rank Math SEO/Rank Math Pro em descomplicar.pt via WP-CLI/SSH. 27 tools tipadas — meta de post/taxonomia, schema markup, redirects, módulos, sitemap, 404 monitor, analytics GSC, IndexNow, validação SEO ao vivo. Preferir a este MCP em vez dos snippets manuais `wp eval`/`wp db query` da skill `/rank-math` sempre que a operação já esteja coberta aqui. Usar quando "rank math", "meta SEO", "schema markup", "redirects seo", "404 monitor", "módulos rank math", "seo score", "sitemap rank math", "indexnow", "validar seo página". +layer: wiki +--- + +# /mcp-rank-math — MCP dedicado Rank Math SEO / Rank Math Pro + +Projecto em `/media/ealmeida/Dados/Dev/mcp-rank-math/` (TypeScript, SDK MCP oficial, stdio). +Substitui a execução manual dos comandos `wp eval`/`wp db query`/`wp option patch` documentados na +skill `/rank-math` por 27 tools tipadas, com validação de input e capability boundaries claras. +**Ambas as skills coexistem** — `/rank-math` continua a ser a referência para o que ainda não tem +tool dedicada (ver "Fora do âmbito" abaixo); este MCP é o caminho preferido para tudo o resto. + +## Porquê duas pontes internas (SQL vs PHP-eval) + +Rank Math guarda a maior parte dos dados **serializados em PHP** — a tabela +`rank_math_redirections.sources`, quase todas as `rank-math-options-*`, e qualquer meta de +post/term com valor array (`rank_math_robots`, `rank_math_schema_*`). SQL directo lê o blob +serializado em bruto; só o WordPress core (`get_option()`, `get_post_meta()`, +`maybe_unserialize()`) descodifica isso correctamente. Por isso o MCP usa duas pontes: + +- **SQL directo** (`wp db query --raw`) — só contra tabelas confirmadas 100% planas: + `posts`/`postmeta` (joins de auditoria), `rank_math_404_logs`, `rank_math_analytics_gsc`. +- **`wp eval-file -`** (PHP inteiro recebido via STDIN, nunca interpolado na linha de comando) — + tudo o resto: meta com arrays, schema, redirects (via `\RankMath\Redirections\DB`, para disparar + os side-effects certos, nunca `INSERT`/`UPDATE` SQL directo nessa tabela), módulos, options com + `wp option patch` (nunca `wp option update`, que substitui a option inteira e apaga as outras + sub-chaves). + +Valores dinâmicos (títulos, descrições, schema JSON) nunca são interpolados directamente numa +string PHP: viajam como JSON (`json_decode(...)` no lado PHP), evitando tanto injecção como o bug +clássico de `"$5 off"` a ser lido como interpolação de variável dentro de uma string PHP de aspas +duplas. + +## Gotcha real de produção — `rank_math_modules` + +A option tem **chaves não-sequenciais** (buracos de remoções antigas de módulos sem +`array_values()`). `wp option get --format=json` faz `json_encode()` directo do array PHP +subjacente — um array PHP com chaves não-consecutivas serializa como **objecto** JSON +(`{"0":"a","3":"b"}`), não array. O MCP normaliza isto internamente (`rm_get_plugin_status`, +`rm_list_modules`); se algum dia se ler `rank_math_modules` directamente via `wp option get` +fora do MCP, **não assumir que a saída é sempre um array JSON**. + +## Tools (27) + +**Estado/auditoria:** `rm_get_plugin_status` (versões Free/Pro, licença, nº módulos activos), +`rm_audit_missing_meta`, `rm_audit_seo_scores`, `rm_get_top_404s`, `rm_clear_404_logs` +(`confirm: true` para apagar tudo) + +**Meta de post:** `rm_get_post_meta`, `rm_update_post_meta` (parcial — `null` num campo apaga-o), +`rm_bulk_fill_missing_meta` (`dry_run: true` por omissão — só lista, não escreve) + +**Meta de taxonomia:** `rm_get_term_meta`, `rm_update_term_meta` + +**Schema markup:** `rm_get_post_schema`, `rm_set_post_schema` (`schema_type` alfanumérico — +"Article", "FAQPage", "Product", "LocalBusiness", etc.), `rm_delete_post_schema` (omitir +`schema_type` apaga todos — requer `confirm: true`) + +**Options/módulos:** `rm_get_option`, `rm_set_option` (sempre `wp option patch` internamente — +nunca perde sub-chaves irmãs), `rm_list_modules`, `rm_toggle_module` + +**Redirects:** `rm_list_redirects`, `rm_create_redirect`, `rm_update_redirect`, +`rm_delete_redirects` + +**Sitemap:** `rm_regenerate_sitemap`, `rm_list_sitemap_urls` (HTTP directo ao `sitemap_index.xml` +público — sem SSH, reflecte exactamente o que o Google vê) + +**IndexNow:** `rm_submit_indexnow` (HTTP directo à API do IndexNow; só lê a chave via WP-CLI) + +**Analytics:** `rm_get_analytics_overview` — degrada com `available:false` se o módulo/tabela GSC +não existir, em vez de erro + +**Backup/validação:** `rm_export_seo_snapshot` (devolve os dados; não escreve ficheiro no +servidor), `rm_validate_live_seo` (fetch directo ao URL publicado — título, meta description, +canonical, robots, OG tags, tipos JSON-LD tal como renderizados, sem SSH) + +## Segurança + +- `rm_clear_404_logs` sem `older_than_days` e `rm_delete_post_schema` sem `schema_type` exigem + `confirm: true`. +- `rm_set_option` nunca aceita substituir a option inteira — só `wp option patch` num caminho de + sub-chave. +- `rm_submit_indexnow` e o ramo de escrita de `rm_update_redirect`/`rm_create_redirect` têm efeito + público real (notificação a motores de busca, redireccionamento de tráfego real) — confirmar + intenção antes de invocar em massa. + +## Fora do âmbito (usar `/rank-math` para estes) + +WooCommerce SEO em massa (categorias de produto, atributos — os padrões `wp eval` já documentados +na skill `/rank-math` §9 continuam válidos), News/Video Sitemap (meta dedicada por post, §10), +hooks/filtros PHP persistentes (§11), migração Yoast→Rank Math (§migração), provisioning inicial +de um site novo (§13 — sequência de setup, não uma operação repetível), gestão de licença/ligação +de conta Pro (ver skill `/full-cliente`). + +## Verificação + +Construído e testado ponta-a-ponta contra produção 19-08-2026: leituras confirmadas com dados +reais (distribuição de scores 383 bons/36 ok/116 fracos, 404s reais, 21 módulos activos, sitemap +com 9 entradas, validação ao vivo de uma página publicada com título/description/canonical/OG +idênticos ao que `rm_get_post_meta` devolve para o mesmo post). Escritas testadas sem alterar +dados reais: `rm_set_option`/`rm_update_post_meta` escreveram o mesmo valor já existente (no-op +real, confirmado por leitura pós-escrita); ciclo completo `rm_create_redirect`→ +`rm_delete_redirects` com um redirect de teste, confirmado removido a seguir. Um bug real +(`rank_math_modules` object-vs-array) foi apanhado neste smoke test e corrigido antes de +considerar o MCP pronto — ver README do projecto. + +## Nota + +`rm_get_post_meta`/`rm_get_term_meta` num ID inexistente devolvem campos vazios em vez de erro +(comportamento do próprio `get_post_meta()`/`get_term_meta()` do WordPress core, que não avisa +para ID inválido) — confirmar a existência do post/termo antes de interpretar "tudo vazio" como +"sem meta definida". diff --git a/wordpress/skills/rank-math/SKILL.md b/wordpress/skills/rank-math/SKILL.md index 19d03ab..d69c82e 100644 --- a/wordpress/skills/rank-math/SKILL.md +++ b/wordpress/skills/rank-math/SKILL.md @@ -1245,6 +1245,12 @@ desde 6.9), com `meta.mcp.public: true`, expostas pelo **`mcp-adapter-default-se Application Password + `npx` a partir de Claude Desktop/ChatGPT/Copilot via REST) — usa-se aqui a mesma via SSH+wp-cli que já temos configurada para o EMCP, sem precisar de credenciais novas. +**Skill irmã:** `/mcp-rank-math` documenta um SEGUNDO MCP, próprio (`rank-math` em mcp.json, não +`rank-math-mcp`), construído para cobrir exactamente o que estas 13 abilities oficiais não fazem — +escrita de meta/schema, redirects, módulos, 404 monitor, sitemap, IndexNow. Os dois coexistem: +`rank-math-mcp` (oficial, leitura/análise) + `mcp-rank-math` (nosso, escrita/gestão) + WP-CLI +(§1-16, o que nenhum dos dois cobre — WooCommerce em massa, News/Video Sitemap, migração, provisioning). + ### 17.2 Padrão de uso — dispatcher genérico, não tools individuais O `mcp-adapter-default-server` expõe **3 tools genéricas** (não uma tool por ability): @@ -1274,15 +1280,18 @@ O `mcp-adapter-default-server` expõe **3 tools genéricas** (não uma tool por | `rank-math/get-ai-visibility-brand-queries` | Queries monitorizadas para uma marca (activas vs baseline auto-gerada). | | `rank-math/create-ai-visibility-brand` | Regista nova marca para monitorização AI Visibility. | -### 17.4 Quando usar isto vs WP-CLI (§1-16 desta skill) +### 17.4 Quando usar isto vs `mcp-rank-math` vs WP-CLI (§1-16 desta skill) | Precisa de | Usar | |---|---| | Auditoria SEO estruturada com findings + fix hints, ou fix automático de 1 teste | `rank-math-mcp` (`audit-site-seo`/`fix-site-seo`) — mais rápido, sem escrever SQL/wp eval | -| Ver schema/scores/links de UM post específico já conhecido | `rank-math-mcp` (`get-post-*`) | -| AI Visibility (marcas, menções em LLMs) | `rank-math-mcp` — não há equivalente WP-CLI documentado nesta skill | -| Bulk update de centenas de posts, schema custom fora do catálogo, redirects em massa, migração Yoast, provisioning de site novo | WP-CLI (§2-13) — o MCP não cobre escrita em massa nem schema arbitrário | -| Módulos, licença, análise de infra-estrutura (§15-16) | WP-CLI/SSH — fora do âmbito das abilities MCP | +| Relatório de links (internos/externos, quebrados), análise on-page dos 24 testes | `rank-math-mcp` (`get-link-report`, `get-post-links`, `analyze-post-content`) — sem equivalente nas outras duas vias | +| Top keywords GSC, scores/grades de vários posts para descobrir o que precisa de atenção | `rank-math-mcp` (`get-top-keywords`, `get-seo-scores`) | +| AI Visibility (marcas, menções em LLMs) | `rank-math-mcp` — sem equivalente WP-CLI/mcp-rank-math | +| Ler/escrever meta SEO ou schema de um post, redirects, 404 monitor, sitemap, IndexNow, módulos/options | `/mcp-rank-math` (`rm_*`) — tools tipadas, sem SQL/wp eval manual | +| Bulk update de centenas de posts, schema custom fora do catálogo, WooCommerce em massa | `/mcp-rank-math` (`rm_bulk_fill_missing_meta`) para o caso simples; WP-CLI (§2, §9) para o resto | +| Migração Yoast, provisioning de site novo, hooks/filtros PHP persistentes | WP-CLI (§11-13) — nenhum dos dois MCPs cobre configuração one-off | +| Licença/ligação de conta Pro | `/full-cliente` | ---