12 KiB
name, description, layer
| name | description | layer |
|---|---|---|
| mcp-complianz | MCP dedicado (node stdio, ligação `complianz` em ~/.omp/agent/mcp.json) para gerir o Complianz GDPR/CMP (Cookie Consent Management) via WP-CLI/SSH — estado/versão, jurisdição e modo de consentimento (opt-in/opt-out por região), configuração principal (`cmplz_options`), banners de cookies (listar/ler/editar texto), cookies e serviços de terceiros detectados pelo scanner. NUNCA expõe pedidos DSAR (PII de titulares de dados). Usar quando "complianz", "cookie consent", "banner de cookies", "GDPR wordpress", "cmplz_options", "cookiebanner", "consenttype opt-in opt-out", "cookie scanner wordpress", "cmplz_dnsmpd". | wiki |
/mcp-complianz — MCP dedicado ao Complianz GDPR/CMP
Projecto em /media/ealmeida/Dados/Dev/mcp-complianz/ (TypeScript, SDK MCP oficial, stdio). Sem
código PHP novo no WordPress — cada tool corre um snippet PHP ESTÁTICO (nunca interpolado com
dados externos) via wp eval sobre o WP-CLI já instalado em server.descomplicar.pt. Todo o
input/output variável viaja em JSON dentro de um envelope base64 por stdin/stdout — nunca
interpolado na linha de comando remota nem no código-fonte PHP.
Não há skill de conhecimento separada para o Complianz — esta skill é a única documentação, incluindo o mapeamento completo de armazenamento (abaixo).
Âmbito
Ler o estado/jurisdição/modo de consentimento, ler e actualizar a configuração principal
(cmplz_options), ler e listar banners de cookies (e editar texto/copy), listar cookies e
serviços de terceiros detectados pelo scanner. Fora do âmbito, deliberadamente: qualquer
registo individual de consentimento de visitante (a tabela cmplz_dnsmpd guarda pedidos DSAR com
nome/email reais de titulares de dados — PII genuína, excluída estruturalmente, nenhum tool deste
MCP a toca, nem sequer agregada); apagar/criar banners; editar cores/CSS/flags do banner (só
texto/copy); scan activo de novos cookies (o Complianz corre isto via cron/admin, não há WP-CLI
para o disparar).
Sites conhecidos
Confirmado por wp plugin list nos 8 sites reais do bundle (19-08-2026): só
starter.descomplicar.pt (staging, v7.5.2) e ccv.descomplicar.pt (v7.5.3.1) têm o Complianz GDPR
activo. Os outros 6 não o têm:
descomplicar.pt(produção): Complianz GDPR NÃO instalado — temreal-cookie-banner(inactive) ewp-consent-api(inactive), nenhum CMP activo neste site.emanuelalmeida.pt: Complianz GDPR não instalado — temcookie-notice(plugin distinto, inactive).care.descomplicar.pt,ecommerce-demo.descomplicar.pt,ecommerce.descomplicar.pt: nenhum plugin de cookies/GDPR detectado.e-commerce.descomplicar.pt: Complianz GDPR não instalado — temcookie-notice(plugin distinto) ACTIVE.
complianz_list_sites devolve a lista completa com notas por site; qualquer tool aceita também um
path absoluto directo para uma instalação futura noutro site. Todos os tools de leitura/escrita
lidam com sites sem Complianz de forma graciosa (complianz_get_jurisdiction devolve
{"active": false}; tools de tabela custom devolvem erro claro "tabela ausente" em vez de crash).
Mapeamento de armazenamento (confirmado por leitura do código-fonte e da base de dados)
| Onde | O quê | Formato | Gotcha |
|---|---|---|---|
Option cmplz_options (wp_options) |
Config principal: jurisdição (regions, other_region_behaviour), modo de consentimento (consent-mode), records_of_consent, datarequest, respect_dnt, cookie_banner_required, enable_cookie_banner, region_redirect, integrações de estatísticas (GA4/GTM/Matomo — só IDs de tracking públicos, sem chaves privadas), textos legais (cookie-statement, privacy-statement) |
Array PHP nativo (confirmado: wp option get cmplz_options sem --format devolve array(...) var_export-style, --format=json produz JSON limpo sem dupla codificação) |
Lido/escrito via get_option()/update_option() no lado PHP (não wp option get/update --format=json directo) para disparar os hooks nativos do plugin (update_option_cmplz_options) |
Tabela custom {$wpdb->prefix}cmplz_cookiebanners |
1 linha por banner (normalmente 1, "Banner A"). ~53 colunas: texto/copy, cores (colorpalette_*), flags inteiras, custom_css |
Colunas text com serialização PHP nativa (não JSON) — cada campo é OU uma string simples (title, accept, message_optin, category_functional, save_preferences, view_preferences) OU um array serializado {text, show} (header, dismiss, category_stats/category_all/category_prefs, functional_text, statistics_text, statistics_text_anonymous, preferences_text, marketing_text) OU cores/settings estruturados (colorpalette_*) |
Ler/escrever via maybe_unserialize()/maybe_serialize() por campo — a forma (string vs array) varia por campo, confirmado empiricamente por leitura directa dos dados em produção/staging |
Tabela custom {$wpdb->prefix}cmplz_cookies |
Cookies/scripts detectados pelo cookie scanner: nome, slug, tipo, retenção, domínio, função/propósito, idioma, ignored/showOnPolicy/deleted |
Colunas simples (int/text), sem serialização | Metadados técnicos do próprio site — sem PII de visitantes |
Tabela custom {$wpdb->prefix}cmplz_services |
Serviços de terceiros detectados: nome, tipo, categoria, thirdParty/sharesData |
Colunas simples | Sem PII |
Tabela custom {$wpdb->prefix}cmplz_dnsmpd |
Pedidos DSAR ("Do Not Sell My Personal Data" / direito ao esquecimento / acesso) — colunas name, email, region de pessoas reais que submeteram um pedido GDPR |
Colunas simples | PII genuína — EXCLUÍDA estruturalmente de qualquer tool deste MCP, mesmo agregada. 0 registos confirmados em ambos os sites testados (19-08-2026), mas a exclusão não depende disso |
Não existe comando WP-CLI custom (wp help complianz/wp help cmplz confirmam "not a registered
command" na v7.5.x) — todo o acesso é via wp eval.
O modo de consentimento (opt-in vs opt-out) não é uma chave directa em cmplz_options — é
computado em runtime por cmplz_get_consenttype_for_region($regiao) a partir da(s) região(ões)
configurada(s) em regions. complianz_get_jurisdiction chama esta função real do plugin (não
reimplementa a lógica), garantindo que o valor devolvido é exactamente o que o plugin usa para
decidir se o banner bloqueia scripts até aceitação.
Tools (10)
| Tool | Read-only | Uso |
|---|---|---|
complianz_list_sites |
sim | Aliases conhecidos, path WP, nota de estado do Complianz por site |
complianz_get_status |
sim | wp plugin list filtrado ao complianz-gdpr — instalado/activo/versão/update pendente |
complianz_get_jurisdiction |
sim | Regiões configuradas, consenttype computado por região (opt-in/opt-out real), flags de política (records_of_consent, datarequest, respect_dnt, cookie_banner_required, etc.) — {"active": false} se inactivo |
complianz_get_options |
sim | cmplz_options completa ou filtrada por keys |
complianz_set_options |
não | Merge de chaves em cmplz_options via update_option() (dispara hooks nativos) |
complianz_list_banners |
sim | Banners configurados: ID, título, se é o banner por omissão, se está desactivado, posição, largura |
complianz_get_banner |
sim | 1 banner completo, todos os campos com maybe_unserialize() aplicado |
complianz_set_banner_text |
não | Actualiza 1 campo de copy (allowlist fixa de 18 campos) — preserva show em campos array, substitui inteiro em campos string |
complianz_list_cookies |
sim | Cookies/scripts detectados pelo scanner (filtros language/ignored) |
complianz_list_services |
sim | Serviços de terceiros detectados pelo scanner (filtro language) |
Segurança
Allowlist rígida: só a option cmplz_options, as 3 tabelas custom não-PII
(cmplz_cookiebanners, cmplz_cookies, cmplz_services) e a lógica de jurisdição do próprio
plugin — nenhum outro dado do WordPress é tocado. A tabela cmplz_dnsmpd (PII de titulares de
dados) está fora do código deste MCP por completo, não apenas filtrada. complianz_set_banner_text
só aceita campos numa allowlist fixa de 18 nomes de coluna (copy/texto), validada tanto no lado
TypeScript (zod enum) como no lado PHP (in_array($field, $allowed, true)) — nunca aceita nome de
coluna arbitrário, o que impede escrever em colorpalette_*/flags/custom_css por esta via. Cada
snippet PHP em wpcli.ts é uma constante estática hardcoded (nunca interpolada com banner_id,
field, text ou chaves de cmplz_options); todo o input variável viaja em JSON dentro de um
envelope base64 por stdin, decodificado remotamente com base64 -d antes de chegar ao wp eval —
nunca na linha de comando. Nenhuma tool deste MCP devolve segredos (as integrações de estatísticas
em cmplz_options guardam apenas IDs de tracking públicos como GA4/GTM, já visíveis no HTML do
site, nunca chaves de API privadas — confirmado por leitura do conteúdo real da option).
Verificação
Construído e testado ponta-a-ponta contra staging e produção real (19-08-2026):
- Build limpo (
npm run build) e smoke test stdio (initialize→notifications/initialized→tools/list) confirmaram handshake MCP correcto e as 10 tools registadas. complianz_get_status/complianz_get_jurisdiction/complianz_get_optionsemstarterdevolveramversion:"7.5.2",update_available:"7.5.3.1",regions_configured:["eu"],consenttype_by_region:{"eu":"optin"}— confirmado idêntico awp plugin list --format=jsonewp option get cmplz_options --format=jsoncorridos directamente por SSH fora do MCP.complianz_get_statusemccvdevolveuversion:"7.5.3.1"(confirmado por SSH directo).complianz_get_status/complianz_get_jurisdiction/complianz_list_bannersemdescomplicar(produção, sem Complianz) confirmaram degradação graciosa:{"installed":false,"active":false},{"active":false}, e erro claro "Tabela de banners ausente" (sem crash), consistente comwp plugin listdirecto não mostrarcomplianz-gdprnesse site.complianz_list_banners/complianz_get_banner/complianz_list_cookies/complianz_list_servicesemstarterdevolveram dados reais (banner "Banner A", posiçãobottom-right, header "Gerir o Consentimento", 16 cookies e 3 serviços empt) confirmados idênticos awp db query SELECT *directo sobrewpbk_cmplz_cookiebanners/wpbk_cmplz_cookies/wpbk_cmplz_services.- Escrita
complianz_set_banner_text(campo string simples):save_preferencesescrito com o valor já-corrente ("Guardar preferências") — leitura directa por SSH antes/depois idêntica. - Escrita
complianz_set_banner_text(campo array{text,show}):headerescrito com o texto já-corrente ("Gerir o Consentimento") — a coluna serializada lida directamente por SSH ficou byte-a-byte idêntica antes/depois (a:2:{s:4:"text";s:21:"Gerir o Consentimento";s:4:"show";i:1;}), confirmando quemaybe_unserialize()/maybe_serialize()preserva a chaveshowsem a tocar. - Escrita
complianz_set_options:respect_dntescrito com o valor já-corrente ("no") —cmplz_optionslida directamente por SSH manteve o mesmo comprimento JSON (1601 bytes) antes/depois, confirmando round-trip sem corrupção. - PII: confirmado por leitura directa da base de dados que
cmplz_dnsmpdtem 0 registos emstartereccv; nenhuma tool deste MCP consulta essa tabela (grep ao código-fonte dewpcli.tsconfirma). Nenhum output de nenhuma tool testada continha dados de visitantes individuais, IPs ou emails de terceiros.
Skills relacionadas
Nenhuma skill de conhecimento separada existe para o Complianz — este documento cobre tudo. Ver
wp-cli para o padrão geral de gestão WordPress via WP-CLI/SSH usado por este MCP.