diff --git a/wordpress/.claude-plugin/plugin.json b/wordpress/.claude-plugin/plugin.json index 89e1778..6f7fcca 100644 --- a/wordpress/.claude-plugin/plugin.json +++ b/wordpress/.claude-plugin/plugin.json @@ -8,5 +8,5 @@ }, "homepage": "https://git.descomplicar.pt/ealmeida/descomplicar-plugins", "license": "MIT", - "keywords": ["wordpress", "woocommerce", "elementor", "crocoblock", "development", "performance", "licensing", "emcp-tools", "elementskit", "powerpack"] + "keywords": ["wordpress", "woocommerce", "elementor", "crocoblock", "development", "performance", "licensing", "emcp-tools", "elementskit", "powerpack", "cloudflare"] } diff --git a/wordpress/skills/mcp-cloudflare-app/SKILL.md b/wordpress/skills/mcp-cloudflare-app/SKILL.md new file mode 100644 index 0000000..f9d7f4b --- /dev/null +++ b/wordpress/skills/mcp-cloudflare-app/SKILL.md @@ -0,0 +1,90 @@ +--- +name: mcp-cloudflare-app +description: MCP dedicado (HTTP StreamableHTTP local, ligação `cloudflare-app` em ~/.claude.json, porta 3201) para a zona Cloudflare gerida pelo plugin App for Cloudflare® (`app-for-cf`) em descomplicar.pt — definições de zona SSL/TLS/Speed/Caching/Network/Scrape Shield, Bot Management + Super Bot Fight Mode, WAF via Managed Ruleset, HSTS, Certificate Transparency, Leaked Credential Checks, purge de cache. Fala directamente com a Cloudflare API v4, sem passar pelo EMCP Tools nem pelo WordPress em runtime. Usar quando "waf cloudflare vazio", "bot management ai", "purge cache cloudflare", "hsts cloudflare", "managed ruleset", "is_robots_txt_managed", "certificate transparency cloudflare", "leaked credential checks", ou qualquer alteração de definição de zona Cloudflare via MCP em vez de curl manual. +layer: wiki +--- + +# /mcp-cloudflare-app — MCP dedicado à zona Cloudflare (App for Cloudflare®) + +Projecto em `/media/ealmeida/Dados/Dev/mcp-cloudflare-app/` (TypeScript, SDK MCP oficial, +StreamableHTTP). Não é uma extensão do EMCP Tools nem fala com o WordPress em runtime — o plugin +App for Cloudflare® não expõe REST próprio (confirmado por leitura completa do código-fonte, ver +skill `app-for-cloudflare`). Toda a configuração de zona vive na Cloudflare API v4, não em +`wp_options`; este MCP fala directamente com essa API usando um token extraído uma vez de +`wp_options.app_for_cf.cloudflareAuth.token` e guardado em `.env` local (não em cada chamada). + +**Relação com a skill `app-for-cloudflare`:** essa skill é a fonte de conhecimento (mapeamento +completo plugin↔Cloudflare API, gotchas, scopes de token, as ~52 definições de zona). Esta skill é +o "como executar" — qual tool chamar para cada operação. Consultar `app-for-cloudflare` para +entender uma definição; usar as tools abaixo para lê-la/escrevê-la. + +## Âmbito + +Zona actual configurada: **descomplicar.pt**. Para gerir outra zona do bundle, extrair +`cloudflareAuth.token`/`cfZoneId` de `wp_options.app_for_cf` desse site (SQL read-only, ver +"Credenciais" abaixo) e actualizar o `.env` do MCP — não há multi-zona numa única ligação. + +Não cobre: R2 media storage, Zero Trust Access, Page/Cache Rules, Firewall Rules custom, DMARC, +Web Analytics, ferramentas de diagnóstico (request trace/IP/domain/WHOIS) — todas Pro-only na UI do +plugin ou fora do âmbito "definições de zona + segurança + purge" decidido na criação do MCP +(19-08-2026). Gerir manualmente via dashboard Cloudflare ou via curl directo (ver skill +`app-for-cloudflare` §10/§2 para os endpoints). + +## Tools (14) + +| Tool | Read-only | Uso | +|---|---|---| +| `cf_list_zone_settings` | sim | Lê todas as definições de zona em bloco | +| `cf_get_zone_setting` | sim | Lê uma definição por id (ex. `rocket_loader`, `cache_level`) | +| `cf_update_zone_setting` | não | Escreve uma definição por id — bloqueia ids de bot_management/`waf` com redirect accionável para a tool certa | +| `cf_get_bot_management` | sim | Lê Bot Management/SBFM completo (inclui campos fora da UI do plugin: `ai_bots_protection`, `is_robots_txt_managed`), sinaliza risco GEO | +| `cf_update_bot_management` | não | Escreve Bot Management/SBFM — merge parcial (lê, aplica só os campos dados, PUT completo; remove `using_latest_model` do payload automaticamente) | +| `cf_get_waf_status` | sim | Verifica se a fase `http_request_firewall_managed` tem regras `execute` reais (o toggle legado `waf` não garante protecção) | +| `cf_deploy_managed_ruleset` | não | Implanta o Cloudflare Managed Free Ruleset na fase managed — disponível em qualquer plano | +| `cf_get_hsts_settings` / `cf_update_hsts_settings` | sim/não | HSTS (`security_header`) | +| `cf_get_certificate_transparency` / `cf_update_certificate_transparency` | sim/não | Alertas CT (`ct/alerting`) | +| `cf_get_leaked_cred_checks` / `cf_update_leaked_cred_checks` | sim/não | Leaked Credential Checks | +| `cf_purge_cache` | não | Purga tudo (omitir `files`) ou até 30 URLs específicos | + +Padrão Descomplicar® para Bot Management (GEO-crítico — ver skill `app-for-cloudflare` §5a): +`cf_update_bot_management` com `{"ai_bots_protection":"disabled","content_bots_protection":"disabled","crawler_protection":"disabled","ai_training":"disabled","ai_search":"disabled","ai_user":"disabled","fight_mode":false,"is_robots_txt_managed":false}` +— nunca aceitar o "good" que o próprio plugin recomenda para `ai_bots_protection`/`crawler_protection` +(`block`/`enabled`), é o oposto da decisão Descomplicar. + +## Segurança + +Escritas em `bot_management` fazem sempre GET→merge→PUT (nunca um PUT parcial cego — a Cloudflare +substitui o objecto inteiro). `cf_update_zone_setting` recusa explicitamente ids que pertencem ao +endpoint `bot_management` (`waf`, `bot_fight_mode`, `ai_bots_protection`, `crawler_protection`, +`bot_likely_automated`, `bot_definitely_automated`, `bot_verified_bots`, +`bot_static_resource_protection`, `bot_optimize_wordpress`, `bot_enable_js`) e devolve `isError` +com a tool certa a usar, em vez de deixar a Cloudflare rejeitar com `10405 Method not allowed`. + +## Credenciais + +`.env` local (`CLOUDFLARE_API_TOKEN`, `CLOUDFLARE_ZONE_ID`, `CLOUDFLARE_ACCOUNT_ID`, +`CLOUDFLARE_ZONE_NAME`), não versionado. Reextrair para outro site via SQL read-only (mais rápido +que SSH+WP-CLI se já houver uma ligação EMCP a esse site): + +```sql +SELECT option_value FROM _options WHERE option_name = 'app_for_cf'; +``` + +O valor é um array PHP serializado — extrair `cloudflareAuth.token` e `cfZoneId`. Confirmar o +prefixo real da tabela primeiro (`SHOW TABLES LIKE '%options%'`; em descomplicar.pt é `wpah_`, não +`wp_`). + +## Verificação + +Construído e testado ponta-a-ponta contra a zona real `descomplicar.pt` 19-08-2026: 12/12 +evaluations (`npm run eval:ci`), incluindo leitura real que confirmou dois achados de produção +ainda por corrigir — WAF Managed Ruleset vazio (zero regras `execute`) e HSTS desligado. Bot +Management já correcto (sem risco GEO). Deploy como processo `hub` persistente (`mcp-cloudflare-app`, +porta 3201, `http://127.0.0.1:3201/mcp`), registado em `~/.claude.json` como `cloudflare-app`. + +## Skills relacionadas + +- `app-for-cloudflare` — mapeamento completo plugin↔Cloudflare API v4, gotchas, scopes de token, + as ~52 definições de zona, EasyConfig, WAF, Bot Management, HSTS, o modelo `wp_options.app_for_cf`. +- `wordfence` — se a decisão for usar Wordfence em vez do WAF Cloudflare como camada primária, é essa + a skill certa para regras/bloqueios ao nível da aplicação (este MCP só cobre o WAF de edge).