feat(wordpress): skill mcp-ai-engine — MCP dedicado ao AI Engine (Meow Apps) via WP-CLI/SSH
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
---
|
||||
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_status` em `starter` confirmou `installed: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_limits` em `starter`: 8 leituras reais confirmadas, incluindo `module_addons:true`,
|
||||
`chatbot_discussions_titling:true` (typing dinâmico de booleanos correcto), 2 fornecedores de IA
|
||||
e 1 de embeddings (Pinecone) devolvidos com `has_key:false, key_hint:null` (sem chave configurada
|
||||
no site) e 1 chatbot ("Default") com `instructions` legível e `apiKey` mascarada.
|
||||
- **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 em
|
||||
`ai_envs[0].apikey` no site `ccv` (inactivo, baixo risco) via `wp option patch` fora do MCP;
|
||||
chamada `ai_engine_list_providers` devolveu `has_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 em `starter` —
|
||||
`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 em `starter` — `model` do
|
||||
chatbot `default` (`""`→`"gpt-4o-mini"`→`""`), confirmado por leitura directa fora do MCP que o
|
||||
valor final é byte-a-byte igual ao original e que `instructions` (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.
|
||||
Reference in New Issue
Block a user