- 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)
43 KiB
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).