Files
Claude Code 4a55d51329 feat(wordpress): EMCP Tools workflow skills + widget catalogs + pending wordpress skills
- emcp-page-building, emcp-content-ops, emcp-site-audit: EMCP Tools MCP
  workflows verified live (atomic/legacy interplay, apply-template overwrite
  risk, create-theme-template goes live immediately, false-positive malware
  pattern in scan-security, change ledger + rollback)
- elementor-pro-widgets: 30+5 native Elementor Pro widgets (curated catalog)
- elementskit-widgets / powerpack-widgets: 42 + 97 third-party widgets,
  widgetType extracted from plugin source (not guessed by convention)
- plugin.json bumped 1.2.0 -> 1.3.0, keywords + description updated
- commits pending wordpress skills already present as untracked files
  (emcp-tools, wordfence, wp-activity-log, seguranca-descomplicar,
  webp-express, wp-fastest-cache, wp-font-perf, wp-meteor,
  wp-activity-log, redis-object-cache, app-for-cloudflare) and pending
  edits (rank-math, wp-cli, wp-content-seo-gate)
2026-08-19 03:44:00 +01:00

43 KiB
Raw Permalink Blame History


name: emcp-tools description: Auditoria e gestão de postura de segurança do EMCP Tools (extensão do WP MCP Adapter da Elementskit — expõe dados Elementor, widgets e ferramentas de operação como MCP tools para agentes de IA). Cobre inventário completo das ~162 abilities registadas por categoria (activas vs desligadas, verificado via wp_get_abilities()), os 9 módulos do plugin (prompts, brand-kits, templates, themer, redirects, agent-skills, cloud, image-optimization, svg-support) e o que cada um expõe, o mecanismo de deny-list incremental versionado (34 migrações), activação granular e segura de uma ferramenta individual (ex: só leitura Rank Math), avaliação de risco por categoria, e arquitectura de registo MCP multi-site. Usar quando "emcp tools", "emcp-tools", "mcp adapter wordpress", "ferramentas mcp elementor", "que tools o agente pode chamar", "activar tool emcp", "desligar tool mcp", "postura default-deny mcp", "agentes de ia no wordpress", "módulos emcp tools", "inventário completo mcp tools", "quantas tools estão activas".

/emcp-tools — Auditoria e Postura de Segurança do EMCP Tools (MCP para Elementor/WP)

Plugin emcp-tools (Mian Shahzad Raza) — extensão do WP MCP Adapter que expõe dados Elementor, widgets, page design tools e um conjunto amplo de operações WordPress como ferramentas MCP chamáveis por agentes de IA. Versão verificada 3.12.1, instalado e activo em emanuelalmeida.pt, descomplicar.pt (public_html) e starter.descomplicar.pt.

Fonte: Hub/04-Stack/02.04-Sistemas/71.Seguranca/CONFIG-Plugins-Referencia.md §10 (EMCP Tools) + BUNDLE-Excelencia-WP.md + verificação SSH ao vivo nesta sessão (16-08-2026) nos três sites do ecossistema.


Arquitectura — como o agente chega às tools deste plugin

O plugin regista um servidor MCP próprio, emcp-tools-server (nome visível "MCP Tools for Elementor Server"), lado a lado com outros servidores do mesmo WP MCP Adapter (elementskit-mcp-server, mcp-adapter-default-server, e nalguns sites fluent-crm). A ligação do agente ao site faz-se por SSH + STDIO, uma entrada por site em ~/.omp/agent/mcp.json:

"emcp-emanuelalmeida": {
  "type": "stdio",
  "command": "ssh",
  "args": ["-T", "-o", "BatchMode=yes", "server",
    "sudo -u ealmeida /usr/local/bin/wp mcp-adapter serve --server=emcp-tools-server --user=ealmeida --path=/home/ealmeida/emanuelalmeida.pt"],
  "timeout": 60000,
  "enabled": true
}

Três instâncias activas no ecossistema, uma ligação MCP por site (cada uma com o seu próprio --path e, portanto, a sua própria config emcp_tools_* independente — não presumir que a postura de um site se aplica a outro, ver §3):

Ligação em mcp.json Site --path
emcp-descomplicar descomplicar.pt /home/ealmeida/public_html
emcp-tools starter.descomplicar.pt /home/ealmeida/starter.descomplicar.pt
emcp-emanuelalmeida emanuelalmeida.pt /home/ealmeida/emanuelalmeida.pt

Comando nativo WP-CLI para inspecção do lado do servidor (sem passar pelo protocolo MCP):

wp mcp-adapter list --path=$PATH --allow-root
wp mcp-adapter list --format=json --path=$PATH --allow-root

⚠️ Achado desta sessão — a coluna Tools de wp mcp-adapter list NÃO é um proxy fiável do nº de ferramentas realmente activas. Verificado ao vivo nos 3 sites (16-08-2026):

Site emcp_tools_disabled_tools (desligadas) wp mcp-adapter list → coluna Tools do emcp-tools-server Activas REAIS (wp_get_abilities(), §7)
descomplicar.pt 78 3 165 (achado crítico — §8.2)
starter.descomplicar.pt 131 3 114
emanuelalmeida.pt 131 115 115

Não há correlação directa (menos desligadas em descomplicar.pt devia implicar mais activas, mas mostra o valor mais baixo). A contagem desta coluna parece depender de estado de registo/cache do lado do WP-CLI, não do filtro emcp_tools_disabled_tools aplicado em tempo de pedido MCP. Não usar esta coluna para avaliar postura de segurança — usar sempre o conteúdo real de emcp_tools_disabled_tools (§2) para saber o que está fechado, e o protocolo MCP (tools/list via um cliente MCP ligado, ex. a própria sessão do agente) para saber com exactidão o que está disponível para chamada num momento dado. A 4ª coluna acima é a contagem definitiva, obtida com o método de §7 (wp eval + wp_get_abilities() filtrado, cruzado slug-a-slug contra emcp_tools_disabled_tools) — coincide exactamente com a coluna Tools só em emanuelalmeida.pt; nos outros dois sites a coluna do WP-CLI é enganadora nos dois sentidos (mostra 3 quando o real é 114 e 165).


1. Config verificada (emanuelalmeida.pt, wp_options)

wp option list --search='emcp_tools*' --path=$PATH --allow-root
Opção Valor real Nota
emcp_tools_sandbox_location emcp-sandbox Directório isolado para operações de sandbox
emcp_tools_active_modules ["prompts","brand-kits","templates","themer","redirects","agent-skills","cloud"] (7 de 9 semeados) image-optimization e svg-support estão semeados mas não activos — idêntico nos 3 sites verificados
emcp_tools_disabled_tools array indexado com 131 ferramentas desligadas (formato emcp-tools/<nome-tool>) Ver lista completa §2
emcp_tools_defaults_applied 34 Contador interno de defaults aplicados na instalação
emcp_tools_modules_seeded / emcp_tools_legacy_meta_migrated / emcp_tools_slug_namespace_migrated flags internas de migração Sem acção
emcp_tools_changelog_db_version / emcp_tools_oauth_db_version / emcp_tools_redirects_db_version / emcp_tools_search_index_db_version versões de schema interno Sem acção
emcp_tools_themer_index / emcp_tools_themer_index_healed índice interno do módulo Themer Sem acção

Outros dois sites (descomplicar.pt, starter.descomplicar.pt) partilham o mesmo emcp_tools_active_modules; starter.descomplicar.pt partilha exactamente os mesmos 131 nomes desligados que emanuelalmeida.pt; descomplicar.pt tem apenas 78 desligados (config mais permissiva — verificar antes de assumir postura igual entre sites). Note-se também que templates e agent-skills são módulos Pro (tier() === 'pro') semeados como "activos" em todos os 3 sites por omissão do próprio plugin, mas nenhum destes sites tem licença Pro (emcp_tools_fs()->can_use_premium_code() === false), logo is_available() devolve false e nenhum dos dois módulos corre de facto — ver tabela completa dos 9 módulos em §6, e o achado crítico específico de descomplicar.pt em §8.2 (78 desligados não significa "mais permissivo apenas um pouco" — significa zero tools nativas fechadas).


2. Lista completa das 131 ferramentas desligadas por omissão

Confirmada ao vivo (emanuelalmeida.pt e starter.descomplicar.pt, formato idêntico): array indexado (não associativo) em emcp_tools_disabled_tools, cada entrada emcp-tools/<slug-da-tool>.

wp option get emcp_tools_disabled_tools --format=json --path=$PATH --allow-root

2.1 Ficheiros, sistema e execução remota — risco máximo, nunca activar sem supervisão directa

write-file, edit-file, delete-file, run-wp-cli, dispatch-wp-cli,
get-wp-cli-job, list-wp-cli-jobs

2.2 Base de dados directa

insert-row, update-rows, delete-rows

2.3 Gestão de plugins e temas

install-plugin, activate-plugin, deactivate-plugin, update-plugin, delete-plugin,
install-theme, switch-theme, update-theme, delete-theme

2.4 Utilizadores

create-user, update-user

2.5 Redirecções e migração de site

create-redirect, update-redirect, delete-redirect,
migrate-site, sync-to-live, sync-content-item

2.6 Integrações de terceiros — leitura e escrita (granularidade por par read/write)

acf-write
woo-read, woo-write
metabox-write
essential-addons-read, premium-addons-read, uae-read, uae-write
cf7-write
wpforms-read, wpforms-write
gravityforms-read, gravityforms-write
fluentforms-read, fluentforms-write
ninjaforms-read, ninjaforms-write
formidable-read, formidable-write
metform-read, metform-write
sureforms-read, sureforms-write
forminator-read, forminator-write

2.7 SEO — TODOS os plugins, leitura E escrita fechadas (Rank Math dono único da superfície SEO neste bundle)

slimseo-write
yoast-read, yoast-write
rankmath-read, rankmath-write
aioseo-read, aioseo-write
seopress-read, seopress-write
seoframework-read, seoframework-write
surerank-read, surerank-write

2.8 Temas/frameworks de blocos

theme-write
astra-write
spectra-write
kadence-write, kadence-blocks-write
generatepress-read, generatepress-write
generateblocks-read, generateblocks-write
blocksy-blocks-read, blocksy-blocks-write, blocksy-extensions-read, blocksy-extensions-write

2.9 Elementor avançado (widgets Pro, templates de tema, popups, dynamic tags, CSS/classes globais)

add-pro-widget, create-elementor-theme-template, set-elementor-template-conditions,
list-dynamic-tags, set-dynamic-tag, create-popup, set-popup-settings,
delete-media, add-custom-css,
create-global-class, update-global-class, delete-global-class, reorder-global-classes

2.10 Snippets PHP — execução de código arbitrário, risco máximo absoluto

add-code-snippet, list-code-snippets,
validate-php-snippet, create-php-snippet, update-php-snippet, get-php-snippet,
list-php-snippets, delete-php-snippet

2.11 Memória do agente

recall, remember, save-session-summary

2.12 Templates PHP de tema

create-theme-php-template, list-theme-php-templates, get-theme-php-template,
update-theme-php-template, delete-theme-php-template

2.13 SEO/A11y automatizados (geração de conteúdo/schema/contraste)

audit-page-seo, extract-keywords-from-content, generate-meta-tags,
generate-schema-markup, set-social-image,
audit-page-a11y, fix-color-contrast, add-alt-text-from-context

2.14 Widgets e blocos custom (criação/edição/eliminação)

list-control-types, validate-widget-spec,
create-custom-widget, update-custom-widget, get-custom-widget, list-custom-widgets,
set-widget-status, delete-custom-widget,
list-block-control-types, validate-block-spec,
create-custom-block, update-custom-block, get-custom-block, list-custom-blocks,
set-block-status, delete-custom-block

3. Como listar ferramentas activas vs desligadas num site

PATH=/home/USER/SITE

# Quantas e quais estão desligadas
wp option get emcp_tools_disabled_tools --format=json --path=$PATH --allow-root

# Módulos activos (nível mais alto — prompts/brand-kits/templates/themer/redirects/agent-skills/cloud/image-optimization/svg-support)
wp option get emcp_tools_active_modules --format=json --path=$PATH --allow-root

# Servidores MCP registados neste site (não usar a coluna Tools como medida de activo — ver aviso acima)
wp mcp-adapter list --path=$PATH --allow-root

Para saber com exactidão quais tools estão disponíveis para chamada num dado momento (a lista real, não a config): ligar via o protocolo MCP (a própria ligação emcp-* em mcp.json) e pedir tools/list — a config emcp_tools_disabled_tools é aplicada como filtro em tempo de pedido pelo plugin, não é reflectida de forma fiável pelo WP-CLI.


4. Activar uma ferramenta específica com segurança (granularidade individual)

O array é indexado (não associativo), por isso wp option patch não serve para remover/adicionar uma entrada isolada — usar wp eval com array_diff/array_values para manter o array limpo e sem duplicados.

Activar (remover do deny-list)

wp eval '
$tool = "emcp-tools/rankmath-read";
$disabled = get_option("emcp_tools_disabled_tools", []);
$before = count($disabled);
$disabled = array_values(array_diff($disabled, [$tool]));
update_option("emcp_tools_disabled_tools", $disabled);
printf("antes=%d depois=%d removida=%s\n", $before, count($disabled), $before !== count($disabled) ? "sim" : "nao (ja estava activa ou nome errado)");
' --allow-root --path=$PATH

Exemplo do pedido típico — activar só leitura Rank Math sem abrir escrita: activar emcp-tools/rankmath-read e deixar emcp-tools/rankmath-write no array (continua desligada). A granularidade é sempre ao nível do slug individual — nunca existe um toggle "Rank Math on/off" only por read/write, exactamente como aparece na lista §2.7.

Reverter (voltar a fechar)

wp eval '
$tool = "emcp-tools/rankmath-read";
$disabled = get_option("emcp_tools_disabled_tools", []);
if (!in_array($tool, $disabled, true)) { $disabled[] = $tool; }
update_option("emcp_tools_disabled_tools", $disabled);
echo count($disabled) . " tools desligadas\n";
' --allow-root --path=$PATH

Verificar sempre depois, de forma independente

wp option get emcp_tools_disabled_tools --format=json --path=$PATH --allow-root | grep -o 'rankmath-read' || echo "confirmado: activa (nao esta no deny-list)"

5. Avaliação de risco por categoria — o que activar e o que nunca activar sem supervisão

Categoria Postura recomendada Justificação
Leitura de design Elementor (o que fica activo por omissão — não está no deny-list) ✅ Seguro por omissão Propósito central do plugin; só leitura/inspecção, sem mutação
SEO leitura isolada (ex.: só rankmath-read) ✅ Seguro activar caso a caso Não muta nada; útil para um agente auditar sem escrever — mas Rank Math continua a ser gerido preferencialmente via /rank-math (WP-CLI directo), não via MCP
SEO escrita (qualquer *-write de SEO) 🔴 Nunca activar sem supervisão Contorna o fluxo de auditoria/rollback do /rank-math; risco de meta/schema incoerente sem revisão humana
Redirecções/migração (create-redirect, migrate-site, sync-to-live) 🔴 Nunca activar sem supervisão Mutação estrutural com impacto em produção e SEO (redirects mal configurados = perda de ranking)
Gestão de plugins/temas (install-plugin, activate-plugin, …) 🔴 Nunca activar sem supervisão Um agente autónomo instalar/remover plugins é a superfície mais perigosa depois de execução de código
Snippets PHP (create-php-snippet, validate-php-snippet, update-php-snippet) 🔴🔴 Nunca activar — risco máximo absoluto Execução de PHP arbitrário persistido no site; equivalente a dar shell ao agente. Único candidato a "nunca, em circunstância nenhuma, sem revisão humana linha a linha antes de guardar"
Ficheiros/sistema (write-file, edit-file, delete-file, run-wp-cli, dispatch-wp-cli) 🔴🔴 Nunca activar — risco máximo Escrita directa no filesystem e execução WP-CLI arbitrária via MCP; contorna toda a auditoria de shell/SSH existente
Base de dados directa (insert-row, update-rows, delete-rows) 🔴🔴 Nunca activar — risco máximo SQL de escrita sem passar por validação da camada WP; risco de corrupção silenciosa
Widgets/blocos custom (create-custom-widget, create-custom-block, …) 🟡 Só com supervisão activa Cria código PHP/JS executado no frontend; menos grave que snippets PHP mas ainda superfície de execução
Utilizadores (create-user, update-user) 🔴 Nunca activar sem supervisão Escalada de privilégios / criação de contas fora do fluxo humano
Memória do agente (recall, remember, save-session-summary) 🟡 Avaliar por site Sem risco de segurança directo, mas cria estado persistente fora do controlo humano — activar só se o workflow do site precisar de continuidade entre sessões MCP
Integrações de terceiros — leitura (woo-read, wpforms-read, …) 🟡 Seguro activar caso a caso, um a um Só expõe dados existentes; activar apenas as integrações realmente instaladas no site, nunca em bloco
Integrações de terceiros — escrita (woo-write, cf7-write, …) 🔴 Nunca activar sem supervisão Mutação em dados de negócio (encomendas, submissões de formulário) sem revisão humana

Regra geral (revista após leitura completa do código-fonte, §6-§8): a concepção do plugin é default-deny bem desenhada — o deny-list incremental descrito em §8.1 fecha metodicamente cada nova categoria de risco assim que é lançada. Mas a postura real, verificada ao vivo, NÃO é uniforme entre os 3 sites: emanuelalmeida.pt e starter.descomplicar.pt reflectem essa concepção (115/162 e 114/160 tools activas, respectivamente, com todas as categorias 🔴/🔴🔴 de facto fechadas); descomplicar.pt diverge de forma crítica — 165/165 tools registadas estão activas, incluindo filesystem, base de dados directa, WP-CLI, PHP snippets e gestão de plugins/utilizadores (ver achado detalhado em §8.2). Qualquer activação deve ser: (1) ao nível de uma única tool, nunca em bloco; (2) reversível e verificada de imediato (§4, com o método correcto de §7/§8.3 — nunca por contagem de arrays); (3) documentada aqui ou em nota do site, para não perder rasto de porque é que uma excepção existe.


6. Módulos — os 9 blocos que a página Modules liga/desliga

Módulo ≠ ferramenta individual: é um interruptor de alto nível (emcp_tools_active_modules) que liga/desliga uma funcionalidade inteira (CPT, hooks de front-end, tab de admin e, nalguns casos, o próprio grupo de MCP tools). Cada módulo estende EMCP_Tools_Module (includes/modules/class-module.php) e expõe tier() (free/pro), default_active() (semeado uma única vez, via EMCP_Tools_Modules_Registry::apply_defaults(), marcador emcp_tools_modules_seeded) e is_available() (gate adicional, ex. licença Pro). Um módulo pro pode estar "activo" no option e mesmo assim não fazer nada — is_available() exige emcp_tools_fs()->can_use_premium_code(); nos 3 sites verificados (build Free, sem licença), templates e agent-skills estão semeados activos mas is_available() devolve false, logo não correm.

Módulo (id) Tier Activo por omissão Disponível nesta sessão (build Free, sem licença) O que liga quando activo+disponível
prompts free sim sim Mostra a tab de admin Prompts (blueprints de prompts prontos a usar para construir páginas; amostras grátis + biblioteca Pro). Não regista MCP tools — é só UI de admin (register() vazio).
brand-kits free sim sim Mostra a tab Brand Kits (kits de cor+tipografia de um clique; kits grátis + biblioteca Pro). Também só UI de admin, sem MCP tools próprias.
cloud free sim sim Arranca EMCP_Tools_Cloud_Connect::init() (fluxo OAuth de ligação à conta EMCP Cloud) e — só quando EMCP_Tools_Cloud::is_connected() for verdadeiro — regista as 7 ferramentas cloud-* (§5 tabela de categorias). Nos 3 sites: módulo activo mas nenhum ligado a uma conta Cloud, logo 0 tools cloud-* registadas.
templates pro sim (seeded) não (sem licença) Quando disponível: mostra a tab Templates (templates de página Elementor prontos a aplicar). Metadata-only (register() vazio) — vive na árvore free só como descrição, a lógica Pro real está fora deste build.
themer free sim sim O módulo mais substancial do bundle free: regista o CPT EMCP_Tools_Themer_CPT, o índice de condições, o controlador de render no front-end, a metabox de admin, blocos Gutenberg dinâmicos, widgets Elementor dinâmicos e templates PHP (Themer PHP, sub-toggle próprio). Desligar este módulo é kill-switch total — pára o CPT, o front-end takeover, a tab, e o registrador de abilities omite as 8 tools *-theme-template*/*-template* (§5).
redirects free sim sim Instala a tabela do Redirect Manager, liga o handler de 301/302 no front-end, o scan de links partidos e as sugestões de redirect ao apagar/renomear uma página. Desligar pára tudo isto e remove as 5 tools *-redirect*/find-broken-links do registo.
agent-skills pro sim (seeded) não (sem licença) Quando disponível: expõe list-skills/get-skill aos agentes ligados + injecta um catálogo ## Skills (~900 tokens) no contexto de discovery. Metadata-only na árvore free.
image-optimization free não (opt-in) depende (precisa de editor de imagem com suporte WebP) Comprime uploads (wp_generate_attachment_metadata) e gera/serve WebP (rewriter de URL); regista resize-media. 5 opções próprias: compress, webp, webp_serve, quality (0-100, default 60), max_dimension, keep_originals. Um optimizador retomável trata a biblioteca já existente a partir do card do módulo.
svg-support free não (opt-in — superfície de segurança) depende (precisa da lib enshrined/svg-sanitize bundled) Permite upload de SVG (mime svg) para quem tiver a capability necessária, corrige wp_check_filetype_and_ext() para REST/sideload, e sanitiza cada SVG (fail-closed: um SVG que não possa ser limpo é rejeitado). Uma opção: admin_only (restringe upload a administradores). Nota: se o Elementor já permitir SVG (como normalmente acontece), este módulo é redundante excepto pela sanitização extra.

7. Inventário verificado das ~162 abilities registadas (build Free, Elementor activo) — por categoria

Correcção a uma hipótese de partida: subtrair ingenuamente 162 − 131 = "~31 activas" está errado — 84 dos 131 slugs em emcp_tools_disabled_tools são nomes de ferramentas Pro (WooCommerce, 6 SEO plugins além do Slim SEO, 5 dos 6 plugins de formulários, frameworks de tema além do Astra, memória do agente, Themer PHP, SEO/A11y automático, Widget/Block Builder — ver lista completa em §2) que nunca chegam a registar-se neste build Free — estão pré-semeados no option para o dia em que o site tiver licença Pro, mas wp_get_abilities() não os devolve porque as classes Pro não existem na árvore free. Contá-los como "desligados" infla artificialmente a contagem de fechadas e desinfla a de activas.

Método de verificação usada (a única fonte fiável — ver aviso sobre wp mcp-adapter list no topo deste documento):

wp eval '
$abilities = wp_get_abilities();
$emcp = array_filter(array_keys($abilities), function($k){ return strpos($k, "emcp-tools/") === 0; });
$disabled = get_option("emcp_tools_disabled_tools", []);
$active = array_diff($emcp, $disabled);
echo "registadas=" . count($emcp) . " desligadas(option)=" . count($disabled) . " activas=" . count($active) . "\n";
' --path=$PATH --allow-root

Resultado real, verificado ao vivo (16-08-2026):

Site Abilities emcp-tools/* registadas Entradas em emcp_tools_disabled_tools … das quais correspondem a uma ability REALMENTE registada Activas (registada E não desligada)
emanuelalmeida.pt 162 131 47 115
starter.descomplicar.pt 160 131 ~46 114
descomplicar.pt 165 78 0 165 (ver achado crítico, §8)

A tabela abaixo usa emanuelalmeida.pt (162 registadas) como referência — é o site com a config mais representativa da postura default-deny pretendida pelo plugin (starter é quase idêntico; descomplicar.pt diverge de forma crítica, ver §8). Por categoria: ferramentas ACTIVAS (chamáveis agora), DESLIGADAS (bloqueadas pelo deny-list, mas registadas — activáveis via §4), e, quando aplicável, ferramentas do grupo que nem chegam a registar-se neste site (dependem de um plugin/tema de terceiros ausente).

Categoria O que faz Activas Desligadas
Compact tool mode (dispatcher) list-tools/get-tool-schema/call-tool — o modo de despacho compacto (3 ferramentas que expõem indirectamente todas as outras); descrito na arquitectura do servidor MCP no início deste documento. call-tool, get-tool-schema, list-tools —
Elementor — descoberta/query (P0) Fundação de leitura: percorre containers/elementos, resolve schemas de widget/container, lista páginas Elementor e templates disponíveis. find-element, get-container-schema, get-element-settings, get-page-structure, get-widget-schema, list-pages, list-templates, list-widgets —
Elementor — páginas (P1 CRUD) Cria/edita páginas Elementor, exporta o conteúdo de uma página, importa um template para uma página, e ajusta page settings (SEO básico, layout). create-page, delete-page-content, export-page, import-template, update-page-settings —
Elementor — layout/container Manipula a árvore de containers/flexbox/elementos: adicionar, mover, duplicar, remover, reordenar, actualizar propriedades, edição em lote (batch-update). add-container, batch-update, duplicate-element, move-element, remove-element, reorder-elements, set-element-label, update-container, update-element —
Elementor — widgets clássicos (catálogo) Coloca widgets Elementor gratuitos no layout e actualiza as suas definições; add-pro-widget (Elementor Pro) fica desligado por omissão. add-free-widget, update-widget add-pro-widget
Elementor — templates/popups/dynamic tags apply-template/save-as-template activos (aplicar/gravar templates de página); criação de theme templates, popups, dynamic tags e condições de exibição ficam desligados (mutação estrutural). apply-template, save-as-template create-elementor-theme-template, create-popup, list-dynamic-tags, set-dynamic-tag, set-elementor-template-conditions, set-popup-settings
Elementor — configurações globais (cores/tipografia) Lê e actualiza o kit global (cores e tipografia do site) — get-global-settings está agrupado na categoria Query (P0) mas afecta as mesmas definições. get-global-settings, update-global-colors, update-global-typography —
Elementor — build-page composto build-page — ferramenta de alto nível que constrói uma página inteira a partir de uma especificação estruturada (composição de containers+widgets num único pedido). build-page —
Elementor — SVG icons upload-svg-icon — envia um SVG para a biblioteca de ícones Elementor (sanitizado). upload-svg-icon —
Elementor — custom code (CSS/JS/snippets) add-custom-js activo (injecta JS Elementor); add-custom-css, add-code-snippet e list-code-snippets ficam desligados (execução/injecção persistente). add-custom-js add-code-snippet, add-custom-css, list-code-snippets
Elementor 4.0+ — atomic widgets Widgets atómicos do Elementor 4.0+ (heading, paragraph, button, image, svg, youtube, video, divider) e o genérico add-atomic-widget/update-atomic-widget — todos activos. add-atomic-button, add-atomic-divider, add-atomic-heading, add-atomic-image, add-atomic-paragraph, add-atomic-svg, add-atomic-video, add-atomic-widget, add-atomic-youtube, update-atomic-widget —
Elementor 4.0+ — atomic layout (flexbox/div-block) add-div-block, add-flexbox (containers atómicos) e detect-elementor-version (detecta se o site suporta Elementor 4.0+ atomic). add-div-block, add-flexbox, detect-elementor-version —
Elementor 4.0+ — global classes (leitura) list-global-classes — lista as classes CSS globais do Elementor 4.0+. list-global-classes —
Elementor 4.0+ — global classes (escrita) Criar/actualizar/eliminar/reordenar classes globais — todas desligadas por omissão (mutação de CSS partilhado entre todas as páginas). — create-global-class, delete-global-class, reorder-global-classes, update-global-class
Gutenberg (blocos nativos) Conjunto completo de leitura+escrita para blocos Gutenberg nativos (descoberta de blocos/patterns, inserir pattern, CRUD de blocos numa página) — todo activo por omissão (Gutenberg é considerado superfície de baixo risco face ao Elementor neste bundle). add-block, duplicate-block, get-block-schema, get-post-blocks, insert-pattern, list-blocks, list-patterns, move-block, remove-block, update-block —
Page Snapshot get-page-snapshot — digest normalizado de uma página (base para outras ferramentas de leitura); sempre activo. get-page-snapshot —
Transações/rollback (change ledger) get-change/list-changes/rollback-change — ledger de alterações feitas via MCP com possibilidade de reverter; sempre activo (é a rede de segurança das escritas). get-change, list-changes, rollback-change —
Pesquisa de conteúdo (índice léxico) search-content/reindex-search — índice léxico sobre páginas/templates/widgets/globals. reindex-search, search-content —
Content mirror (export/restore git-friendly) export-content/list-content-exports/restore-content — exporta conteúdo de página como ficheiros rastreáveis em git e permite restaurar. export-content, list-content-exports, restore-content —
WordPress — conteúdo (posts/CPT/taxonomias) CRUD completo de posts/CPT (criar, ler, listar, actualizar, eliminar), listar post types/taxonomias, definir termos — activo por omissão. create-post, delete-post, get-post, list-post-types, list-posts, list-taxonomies, set-post-terms, update-post —
WordPress — media library Ler/listar/actualizar/carregar media activos; delete-media desligado (eliminação permanente). get-media, list-media, update-media, upload-media delete-media
WordPress — resize de imagem resize-media só regista quando o módulo Image Optimization está activo (reutiliza o motor de compressão/WebP) — não registado nesta sessão porque o módulo está desligado por omissão. (nenhuma — grupo não registado: resize-media) (n/a — ver nota)
WordPress — settings get-settings/update-settings — leitura e escrita de um conjunto curado de definições do site (não é wp_options livre). get-settings, update-settings —
WordPress — plugins Listar/pesquisar plugins fica activo; instalar/activar/desactivar/actualizar/eliminar plugin ficam desligados (superfície de maior risco depois de execução de código). list-plugins, search-plugins activate-plugin, deactivate-plugin, delete-plugin, install-plugin, update-plugin
WordPress — temas (gestão) Listar/pesquisar temas activo; instalar/mudar/actualizar/eliminar tema desligados. list-themes, search-themes delete-theme, install-theme, switch-theme, update-theme
WordPress — utilizadores Ler/listar utilizadores activo; criar/actualizar utilizador desligados (escalada de privilégios). get-user, list-users create-user, update-user
WordPress — menus de navegação menu-read/menu-write — ambos activos por omissão (menus, itens, theme locations, render). menu-read, menu-write —
Tema activo (framework-agnostic) theme-read activo (get-theme-context, get-mods — identidade do tema, theme_mods); theme-write desligado (set-mods, create-child-theme). theme-read theme-write
Astra (tema) Só regista quando o Astra é o tema activo. astra-read activo (definições Astra Customizer); astra-write desligado. astra-read astra-write
ACF (Advanced Custom Fields) Dispatcher acf-read/acf-write + 15 operações (field groups, post types, taxonomias, options pages) — só regista se ACF (free ou Pro) estiver activo no site; não registado nesta sessão (ACF ausente). (nenhuma — grupo não registado: acf-read, acf-write, create-acf-field-group, create-acf-post-type, create-acf-taxonomy, get-acf-field-group, get-acf-fields, get-acf-post-type, get-acf-taxonomy, list-acf-field-groups, list-acf-options-pages, list-acf-post-types, list-acf-taxonomies, update-acf-field-group, update-acf-fields, update-acf-post-type, update-acf-taxonomy) (n/a — ver nota)
Meta Box Dispatcher metabox-read/metabox-write — só regista se o Meta Box estiver activo; não registado nesta sessão. (nenhuma — grupo não registado: metabox-read, metabox-write) (n/a — ver nota)
Themer (free) — templates de header/footer/single/archive CPT + condições de exibição para header/footer/single/archive/search/404 com qualquer page builder. Todo o grupo activo por omissão: listar/obter/criar/actualizar/eliminar template, listar alvos de condição, definir condições, resolver qual template se aplica a um contexto. create-theme-template, delete-theme-template, get-theme-template, list-condition-targets, list-theme-templates, resolve-template, set-template-conditions, update-theme-template —
Themer PHP templates (toggle próprio) Sub-funcionalidade do Themer para templates PHP brutos, atrás de um toggle independente (EMCP_Tools_Themer_PHP::enabled()) — não activo nesta sessão, por isso as 5 tools não estão sequer registadas. (nenhuma — grupo não registado: create-theme-php-template, delete-theme-php-template, get-theme-php-template, list-theme-php-templates, update-theme-php-template) (n/a — ver nota)
Redirect Manager list-redirects/find-broken-links activos (leitura + scan de links partidos); create/update/delete-redirect desligados (mutação de routing com impacto directo em SEO). find-broken-links, list-redirects create-redirect, delete-redirect, update-redirect
Stock images (busca + sideload + widget) search-images/sideload-image/add-stock-image — pesquisa num provider de stock, descarrega para a Media Library, e coloca como widget de imagem; todo activo (não muta nada fora da Media Library). add-stock-image, search-images, sideload-image —
Performance Analyzer analyze-performance — auditoria de performance só de leitura. analyze-performance —
Security & Malware Scanner scan-security — scanner de malware/postura de segurança, só leitura, sempre activo. scan-security —
Filesystem list-directory/read-file/search-files activos; write-file/edit-file/delete-file desligados (escrita directa no filesystem). list-directory, read-file, search-files delete-file, edit-file, write-file
Base de dados directa describe-table/list-tables/query (SELECT) activos; insert-row/update-rows/delete-rows desligados (escrita SQL directa). describe-table, list-tables, query delete-rows, insert-row, update-rows
WP-CLI (run + jobs) run-wp-cli/dispatch-wp-cli/get-wp-cli-job/list-wp-cli-jobs — todo o grupo desligado por omissão (execução arbitrária de comandos WP-CLI). — dispatch-wp-cli, get-wp-cli-job, list-wp-cli-jobs, run-wp-cli
PHP Snippets (Sandbox) validate/create/update/get/list/delete-php-snippet — todo o grupo desligado por omissão (execução de PHP arbitrário persistido). — create-php-snippet, delete-php-snippet, get-php-snippet, list-php-snippets, update-php-snippet, validate-php-snippet
Sandbox — export/import cloud (bundle) export-sandbox-artifact/import-sandbox-artifact — exporta/importa um artefacto de sandbox (bloco/widget/snippet) como bundle; ambos activos (o bundle em si não executa nada, é só serialização). export-sandbox-artifact, import-sandbox-artifact —
EMCP Cloud (sync remoto) cloud-status/cloud-backup/cloud-list/cloud-pull/cloud-config-sync/cloud-marketplace-list/cloud-marketplace-install — só registam quando o módulo Cloud está activo E o site está ligado a uma conta EMCP Cloud; não registadas nesta sessão porque nenhum dos 3 sites está ligado a uma conta Cloud (ver módulo cloud, §6). (nenhuma — grupo não registado: cloud-backup, cloud-config-sync, cloud-list, cloud-marketplace-install, cloud-marketplace-list, cloud-pull, cloud-status) (n/a — ver nota)

8. Mecanismo do deny-list incremental — e um achado crítico ao vivo em descomplicar.pt

8.1 Como o plugin decide o que fecha por omissão

O deny-list não é estático: includes/admin/class-admin.php, método maybe_apply_default_disabled_tools() (chamado no boot do admin), aplica 34 blocos de migração incremental (DEFAULTS_VERSION = 34, contador emcp_tools_defaults_applied), cada um introduzido numa versão do plugin para fechar uma nova categoria de tool assim que ela é lançada — ex.: v6 fecha escrita de plugins/temas, v9 fecha filesystem, v10 fecha base de dados, v18 fecha WP-CLI, v28 fecha escrita de global classes, v33-34 fecham as tools de migração/sync. A função só adiciona slugs (nunca remove uma escolha do utilizador) e só corre os blocos cujo número é maior que o $applied já gravado:

if ( $applied < N ) { $add = array_merge( $add, /* slugs da versão N */ ); }
// ...
update_option( self::OPTION_DISABLED_TOOLS, array_values( array_unique( array_merge( $existing, $add ) ) ) );
update_option( self::OPTION_DEFAULTS_APPLIED, (string) self::DEFAULTS_VERSION );

Consequência arquitectural importante: um site cujo emcp_tools_defaults_applied já esteja em 34 nunca mais recebe fecho automático de tools novas, mesmo que o plugin lance uma v35 no futuro — nesse cenário a nova categoria nasceria activa nesse site até alguém a fechar à mão. E mais relevante ainda para o presente: se o valor de emcp_tools_disabled_tools for alterado manualmente (via wp eval/array_diff, como o método §4 deste documento ensina, ou por qualquer outro caminho) removendo entradas em massa, o contador de versão não volta atrás — o site fica com um deny-list mais pequeno do que o "de fábrica" para essa versão, sem qualquer aviso.

8.2 🔴 Achado crítico verificado ao vivo (16-08-2026) — descomplicar.pt

Ao aplicar o método de verificação do §7 aos 3 sites, descomplicar.pt destacou-se: active=165 = registered=165 — zero ferramentas efectivamente fechadas, apesar de emcp_tools_disabled_tools ter 78 entradas. Inspeccionando essas 78 entradas (wp option get emcp_tools_disabled_tools --format=json --path=/home/ealmeida/public_html): são exclusivamente slugs de integrações de terceiros que não estão instaladas neste site (WooCommerce, Essential/Premium Addons, UAE, os 6 plugins de formulários, os 7 plugins de SEO, Astra/Spectra/Kadence/GeneratePress/Blocksy, recall/remember/save-session-summary, os 4 achados SEO/A11y automáticos, e os 16 slugs do Widget/Block Builder Pro) — nenhuma das categorias nativas mais perigosas (filesystem, base de dados, WP-CLI, PHP snippets, gestão de plugins/temas, gestão de utilizadores) aparece nessa lista. Confirmado directamente, ferramenta a ferramenta:

Tool Registada em descomplicar.pt? Está no deny-list? Chamável agora via MCP?
emcp-tools/write-file sim não 🔴 SIM
emcp-tools/edit-file sim não 🔴 SIM
emcp-tools/delete-file sim não 🔴 SIM
emcp-tools/run-wp-cli sim não 🔴 SIM
emcp-tools/dispatch-wp-cli sim não 🔴 SIM
emcp-tools/insert-row sim não 🔴 SIM
emcp-tools/update-rows sim não 🔴 SIM
emcp-tools/delete-rows sim não 🔴 SIM
emcp-tools/create-php-snippet sim não 🔴 SIM
emcp-tools/update-php-snippet sim não 🔴 SIM
emcp-tools/install-plugin sim não 🔴 SIM
emcp-tools/activate-plugin sim não 🔴 SIM
emcp-tools/create-user sim não 🔴 SIM
emcp-tools/update-user sim não 🔴 SIM

Todas as 34 versões de migração já correram (emcp_tools_defaults_applied = 34, igual aos outros 2 sites), o que exclui "instalação nunca migrada" como explicação — a hipótese mais provável, dado o padrão exacto de remoção (sobrevivem só integrações de terceiros; desaparecem só as categorias nativas de risco máximo/alto de §5), é que o array foi reescrito manualmente nalgum momento — por exemplo com uma variante do próprio comando de §4 aplicada de forma demasiado ampla (ex.: array_diff contra uma lista de slugs "de terceiros" em vez de um único slug) — sem que a subtracção tenha sido revertida depois.

Isto não foi corrigido nesta tarefa (o âmbito desta expansão de skill é só leitura — ver constraints). Requer decisão humana urgente: ou (a) confirmar que a abertura destas 14+ tools nativas em descomplicar.pt foi intencional e está devidamente supervisionada, ou (b) alinhar descomplicar.pt com o deny-list dos outros 2 sites, repondo pelo menos as categorias 🔴🔴 de §5 (filesystem, base de dados, WP-CLI, snippets PHP) com o padrão do método §4, aplicado entrada a entrada.

8.3 Regra de verificação a aplicar sempre, daqui em diante

Nunca confiar na contagem de entradas em emcp_tools_disabled_tools isoladamente — nem para avaliar "quão fechado" está um site (v. descomplicar.pt, 78 entradas e 0 tools realmente fechadas), nem para o inverso (a lista de 131 em emanuelalmeida.pt/starter também tem 84 entradas "mortas" que nunca vão fechar nada neste build). O único método correcto é o wp eval + wp_get_abilities() do §7, comparado slug a slug contra emcp_tools_disabled_tools — nunca o tamanho dos arrays, nunca a coluna Tools de wp mcp-adapter list (ver aviso na arquitectura, que mostra 3 para descomplicar.pt quando o valor real é 165).


Fonte

Hub/04-Stack/02.04-Sistemas/71.Seguranca/CONFIG-Plugins-Referencia.md §10 (EMCP Tools, mapeado 16-08-2026) + BUNDLE-Excelencia-WP.md (contexto do bundle e registo dos 3 sites) + verificação SSH ao vivo nesta tarefa (wp option list/get, wp plugin get, wp mcp-adapter list, ~/.omp/agent/mcp.json) em descomplicar.pt, starter.descomplicar.pt e emanuelalmeida.pt + leitura completa do código-fonte do plugin (build Free emcp-tools 3.12.1) em emanuelalmeida.pt: todos os ficheiros em includes/abilities/ (46 classes de abilities + integrações forms/seo), includes/modules/ (9 módulos + sub-módulos Image Optimization e SVG Support), includes/admin/class-admin.php (catálogo de tools, maybe_apply_default_disabled_tools(), as 34 versões do deny-list incremental), includes/modules/class-modules-registry.php + class-module.php (ciclo de vida dos módulos), includes/class-migration.php (migração elementor-mcp → emcp-tools), emcp-tools.php (bootstrap, guarda Free⇄Pro) — e verificação ao vivo via wp eval + wp_get_abilities() filtrado a emcp-tools/* cruzado slug-a-slug contra emcp_tools_disabled_tools, nos 3 sites (método completo em §7).