12 KiB
name: mcp-ai-engine
description: MCP dedicado (node stdio, ligação ai-engine em ~/.omp/agent/mcp.json) para gerir o AI Engine (Meow Apps, slug ai-engine) multi-site (bundle Descomplicar) via WP-CLI/SSH — estado/versão, fornecedores de IA e de embeddings/vector DB configurados (chave API SEMPRE mascarada), modelos/ambientes por omissão por tipo de tarefa, módulos/feature-toggles, chatbots/assistentes configurados, estatísticas de uso agregadas (tokens/custos por modelo/mês/dia, sem PII), add-ons, limites de utilização. Escrita: activar/desactivar um módulo, actualizar modelo/instruções de um chatbot. Usar quando "ai engine", "mwai", "meow apps", "chatbot wordpress", "mwai_options", "mwai_chatbots", "chave API openai wordpress", "fornecedor de IA configurado", "estatísticas de uso IA wordpress", "assistente de IA wordpress".
layer: wiki
/mcp-ai-engine — MCP dedicado ao AI Engine (Meow Apps)
Projecto em /media/ealmeida/Dados/Dev/mcp-ai-engine/ (TypeScript, SDK MCP oficial, stdio). Cada
tool executa wp option get/patch via WP-CLI já instalado em server.descomplicar.pt. Escritas
viajam em base64 por stdin (base64 -d | wp option patch update ...), nunca interpoladas na linha
de comando remota.
Não há skill de conhecimento separada para o AI Engine — esta skill é a única documentação, incluindo o mapeamento completo de armazenamento (abaixo).
Âmbito
Estado/configuração/estatísticas do plugin: fornecedores de IA e as suas capacidades, chatbots
configurados, módulos activos, defaults por tipo de tarefa, uso agregado (tokens/custos),
add-ons, limites. Nunca chaves API em claro. Fora do âmbito (excluído estruturalmente, não
por falta de tempo): histórico de conversas/discussões de visitantes (tabela wp_mwai_chats —
PII, e nem sequer existe ainda nos sites verificados porque o módulo chatbot_discussions está
desligado em todos), ficheiros enviados (wp_mwai_files), tarefas agendadas (wp_mwai_tasks),
qualquer escrita em apikey/apiKey (por desenho — ver Segurança).
Sites conhecidos
Confirmado por wp plugin list --format=csv em todos os 8 sites reais do bundle (19-08-2026):
| Site | Estado AI Engine | Notas |
|---|---|---|
starter (starter.descomplicar.pt) |
ACTIVO, 3.7.1 | Chatbot "Default" (botId: default) configurado, providers OpenAI + Claude registados sem chave API. Site principal de teste deste MCP. |
ccv (ccv.descomplicar.pt) |
Instalado, inactivo, 3.7.1 | Config (mwai_options/mwai_chatbots) persiste na BD mesmo com o plugin desactivado — continua legível/editável via WP-CLI. |
ecommerce-demo (ecommerce-demo.descomplicar.pt) |
Instalado, inactivo, 3.7.1 | Sem chatbots configurados (mwai_chatbots nunca chegou a ser gravada). |
ecommerce (ecommerce.descomplicar.pt) |
Instalado, inactivo, 3.7.1 | — |
descomplicar (produção) |
NÃO instalado | Apesar de referido como "activo" num briefing anterior — confirmado por leitura directa wp plugin list que NÃO está no site. |
emanuelalmeida, care, e-commerce |
NÃO instalado | — |
ai_engine_list_sites devolve esta lista com as notas; qualquer tool aceita também um path
absoluto directo para uma instalação futura noutro site.
Mapeamento de armazenamento (confirmado por leitura do código-fonte do plugin)
O AI Engine guarda arrays PHP nativos (não strings com JSON lá dentro) em 2 options —
confirmado ao vivo com wp eval "echo gettype(get_option('mwai_options'));" → array. Por isso
--format=json é seguro tanto para leitura como para escrita (ao contrário do WP Fastest Cache ou
do TablePress, que serializam JSON como string plana — ver mcp-wpfc/mcp-tablepress).
| Option | Conteúdo | Formato |
|---|---|---|
mwai_options (classes/core.php, $option_name) |
Config principal: ai_envs (fornecedores de IA), embeddings_envs (fornecedores de embeddings/vector DB), module_*/workspace_*/chatbot_*/speech_*/mcp_* (feature toggles), ai_*_default_env/ai_*_default_model (defaults por tipo de tarefa: texto, fast, visão, imagens, áudio, JSON, embeddings), ai_usage/ai_usage_daily (estatísticas de uso agregadas), addons, limits/default_limits, chatbot_defaults, logs_path, etc. |
Array PHP nativo |
mwai_chatbots ($chatbots_option_name) |
Array de chatbots/assistentes: botId, name, model, instructions (prompt de sistema), temperature, maxMessages, maxTokens, apiKey (override opcional por chatbot), tema/UI, functions, mcpServers, crossSite. |
Array PHP nativo |
mwai_themes ($themes_option_name) |
Temas visuais custom do widget de chat. Vazio/false em todos os sites verificados — fora do âmbito deste MCP (não é config de IA). |
Array PHP nativo (ou false quando nunca gravada) |
Gotcha confirmado ao vivo: a option mwai_options lida por wp option get inclui campos que
o próprio plugin trata como "dinâmicos" no seu código (populate_dynamic_options() em
core.php:1404, chamado só pelo acessor interno get_all_options(), nunca pelo WordPress core
get_option()) — nomeadamente addons (com enabled calculado) e ai_engines (catálogo enorme
e estático de modelos por fornecedor). Na prática estes campos já estão persistidos na BD em
todos os sites verificados, porque o painel admin (React) faz round-trip do objecto completo que
recebe via REST (que já vem enriquecido) de volta para update_option() na gravação. Ou seja: não
é um artefacto deste MCP, é o estado real da BD — ai_engine_list_addons lê exactamente isso.
Para não agravar este "bloat" nem arriscar persistir uma cópia desactualizada do catálogo ai_engines
(que é grande e evolui com cada release do plugin), nenhuma tool de escrita deste MCP relê e
regrava a option inteira — todas usam wp option patch update <option> <key-path...>, que
grava só o caminho aninhado pedido dentro do array já existente na BD.
Não existe comando WP-CLI custom (wp help mwai/wp help ai-engine confirmam "not a registered
command" na v3.7.1) — todo o acesso é via wp option get/patch.
Tools (12)
| Tool | Read-only | Uso |
|---|---|---|
ai_engine_list_sites |
sim | Aliases conhecidos, path WP, nota de estado do AI Engine |
ai_engine_get_status |
sim | Instalado/activo/versão — wp plugin list filtrado a ai-engine |
ai_engine_list_providers |
sim | ai_envs (OpenAI, Claude, Azure, Google, OpenRouter, Replicate, Mistral, etc.) — chave API mascarada |
ai_engine_list_embeddings_providers |
sim | embeddings_envs (Internal/WordPress DB, OpenAI Vector Store, Pinecone, etc.) — chave API mascarada |
ai_engine_get_defaults |
sim | Modelo/ambiente por omissão por tipo de tarefa (texto, fast, visão, imagens, áudio, JSON, embeddings) |
ai_engine_list_modules |
sim | Todas as chaves booleanas de mwai_options (descoberta dinâmica — module_*, workspace_*, chatbot_*, speech_*, mcp_*, flags soltas) |
ai_engine_list_chatbots |
sim | Chatbots/assistentes configurados (nome, modelo, instruções, limites) — apiKey mascarada |
ai_engine_get_usage |
sim | ai_usage/ai_usage_daily — tokens/custos agregados por modelo/mês/dia, sem PII |
ai_engine_list_addons |
sim | Add-ons oficiais do AI Engine e se estão enabled |
ai_engine_get_limits |
sim | Quotas de créditos/queries por período (visitantes/utilizadores/sistema) |
ai_engine_set_module |
não | Activa/desactiva 1 chave booleana já existente em mwai_options (valida dinamicamente que existe e é booleana antes de escrever) |
ai_engine_set_chatbot_field |
não | Actualiza model ou instructions de 1 chatbot (por botId) — allowlist rígida de 2 campos, nunca apiKey/functions/mcpServers |
Segurança
Chaves API nunca em claro, em nenhuma tool, em nenhuma circunstância. ai_envs[].apikey,
embeddings_envs[].apikey e mwai_chatbots[].apiKey são sempre destruturados fora do objecto
devolvido e substituídos por { has_key: boolean, key_hint: string | null } (src/mask.ts) —
key_hint mostra só os últimos 4 caracteres prefixados de asteriscos (***abcd), ou máscara total
se a chave tiver ≤4 caracteres. Nenhuma tool de escrita toca em apikey/apiKey — ai_engine_set_module
só aceita chaves já-booleanas de mwai_options (rejeita ai_envs/embeddings_envs/qualquer chave
não-booleana), ai_engine_set_chatbot_field só aceita field ∈ {model, instructions} (enum zod,
rejeitado no schema antes mesmo de chegar ao handler).
Escritas usam wp option patch update <option> <key-path...> com o valor em base64 sobre stdin
(nunca interpolado no comando SSH remoto). Gotcha herdado do mcp-gtranslate: update_option()
devolve false tanto em falha real como quando o valor gravado já é igual ao actual, e o WP-CLI
nem sempre reporta esse caso como sucesso — em caso de exit code != 0, patchKey relê o valor no
caminho pedido e só propaga o erro se continuar diferente do pretendido.
Sem histórico de conversas de visitantes acessível por este MCP — a tabela wp_mwai_chats
(módulo chatbot_discussions) não é lida por nenhuma tool, mesmo que venha a ser activada no
futuro; é uma exclusão estrutural, não uma limitação de dados actualmente vazios.
Verificação
Construído e testado ponta-a-ponta (19-08-2026):
- Build TypeScript limpo (
npm run build), smoke test stdio (initialize+tools/list→ 12 tools). ai_engine_get_statusemstarterconfirmouinstalled:true, active:true, version:"3.7.1".ai_engine_list_providers/ai_engine_list_embeddings_providers/ai_engine_list_chatbots/ai_engine_list_modules/ai_engine_get_defaults/ai_engine_get_usage/ai_engine_list_addons/ai_engine_get_limitsemstarter: 8 leituras reais confirmadas, incluindomodule_addons:true,chatbot_discussions_titling:true(typing dinâmico de booleanos correcto), 2 fornecedores de IA e 1 de embeddings (Pinecone) devolvidos comhas_key:false, key_hint:null(sem chave configurada no site) e 1 chatbot ("Default") cominstructionslegível eapiKeymascarada.- Verificação de mascaramento com chave real (não apenas ausência de chave): gravada
temporariamente uma chave de teste falsa (
sk-TEST-FAKE-...abcdEND) directamente emai_envs[0].apikeyno siteccv(inactivo, baixo risco) viawp option patchfora do MCP; chamadaai_engine_list_providersdevolveuhas_key:true, key_hint:"***dEND"— a chave completa nunca apareceu em nenhum campo da resposta JSON-RPC. Valor restaurado a""de imediato e confirmado por leitura directa idêntico ao original. - Também testado directamente
maskSecret()isolado (chave longa →***+ últimos 4 chars; chave curta ≤4 chars → máscara total; vazio/null/undefined→has_key:false). - Escrita
ai_engine_set_module: round-trip idempotente emstarter—module_statistics(false→true→false), confirmado por leitura directa fora do MCP antes/ depois idêntico ao valor original. - Escrita
ai_engine_set_chatbot_field: round-trip idempotente emstarter—modeldo chatbotdefault(""→"gpt-4o-mini"→""), confirmado por leitura directa fora do MCP que o valor final é byte-a-byte igual ao original e queinstructions(campo não tocado) permaneceu inalterado.
Skills relacionadas
Nenhuma skill de conhecimento separada existe para o AI Engine — este documento cobre tudo. Ver
wp-cli para o padrão geral de gestão WordPress via WP-CLI/SSH usado por este MCP, e
mcp-gtranslate/mcp-tablepress para o padrão de wp option patch com arrays nativos vs. options
JSON-em-string.