Files
claude-plugins/wordpress/skills/mcp-happyfiles/SKILL.md
T
Emanuel Almeida 87e4290283 docs: skill mcp-happyfiles — MCP HappyFiles Pro (pastas media library)
Documenta a taxonomia happyfiles_category (hierárquica, attachments), o
gotcha include_children=true por omissão no WP_Query (corrigido no MCP),
query_var=false na taxonomia (wp post list --happyfiles_category não
funciona), e confirma no código-fonte que apagar pasta nunca apaga
ficheiros. 9 tools, verificação ponta-a-ponta contra descomplicar.pt
(produção) e starter.descomplicar.pt documentada.
2026-08-19 06:33:26 +01:00

8.0 KiB

name, description, layer
name description layer
mcp-happyfiles MCP dedicado multi-site (node stdio, ligação `happyfiles` em ~/.omp/agent/mcp.json) para gerir as pastas da media library organizadas pelo HappyFiles Pro em qualquer site do bundle Descomplicar® onde o plugin esteja activo — listar pastas com contagem e hierarquia, criar/renomear/apagar pastas, listar ficheiros de uma pasta ou sem pasta, mover ficheiros entre pastas. Apagar uma pasta NUNCA apaga ficheiros. Site é um parâmetro em cada tool, não uma ligação fixa. Usar quando "happyfiles mcp", "pastas media library", "organizar biblioteca de media", "mover ficheiros de pasta wordpress", "criar pasta happyfiles", "apagar pasta happyfiles", "ficheiros sem pasta", "uncategorized happyfiles". wiki

/mcp-happyfiles — MCP dedicado multi-site ao HappyFiles Pro

Projecto em /media/ealmeida/Dados/Dev/mcp-happyfiles/ (TypeScript, SDK MCP oficial, stdio). Sem código PHP novo no WordPress — cada tool corre wp eval via ssh server sobre a API nativa de taxonomias do WordPress (get_terms, wp_insert_term, wp_update_term, wp_delete_term, wp_set_object_terms, wp_delete_object_term_relationships), nunca SQL directo. site é um parâmetro em cada tool, não uma ligação fixa por site.

Arquitectura de dados (confirmada no código-fonte do plugin em 19-08-2026)

O HappyFiles Pro não tem tabelas próprias para pastas de media library. Cada "pasta" é um termo da taxonomia custom happyfiles_category (constante HAPPYFILES_TAXONOMY), registada só para o post type attachment, hierárquica (usa parent/term_id nativos do WordPress). Cada ficheiro (attachment) pertence a uma pasta através de uma relação normal wp_term_relationships — exactamente como categorias/tags em posts.

  • Contagem de ficheiros por pasta = WP_Term->count, mantida automaticamente pelo WordPress via _update_generic_term_count (callback registado pelo próprio plugin) sempre que wp_set_object_terms/wp_delete_term corre. Nunca precisa de ser recalculada manualmente.
  • Metadados extra por pasta (termmeta, opcionais): happyfiles_position (inteiro, ordenação manual na UI) e happyfiles_folder_color (cor custom). Ambos ausentes por omissão.
  • "Sem pasta" (Uncategorized) não é um termo real — é tax_query com operator => NOT EXISTS sobre happyfiles_category. O próprio Data::get_folders() do plugin usa a convenção term_id = -1 para esta pseudo-pasta e -2 para "Todos os ficheiros"; este MCP replica a mesma convenção internamente (folderId: -1 nas tools de listagem de ficheiros).
  • Gotcha WP_Query confirmado ao vivo: tax_query por omissão tem include_children => true (taxonomia hierárquica) — listar ficheiros de uma pasta-pai sem include_children: false devolve também os ficheiros de todas as subpastas (reproduzido: pasta "Clientes" mostrava 120 ficheiros em vez dos 7 directamente associados). Este MCP força sempre include_children => false, replicando o mesmo padrão que o próprio Actions::delete_folder() do plugin usa para não apagar relações de subpastas por engano.
  • query_var da taxonomia é false (public => false na chamada register_taxonomy, confirmado via get_taxonomy('happyfiles_category')->query_var) — wp post list --happyfiles_category=X não funciona, nem via WP-CLI nem em pedidos normais; o próprio plugin nunca depende disto, constrói sempre tax_query explícito em PHP. Por isso este MCP também nunca usa esse atalho.
  • Apagar pasta nunca apaga ficheiros: Actions::delete_folder() (e o wp_delete_term() nativo que ele chama) só remove a linha da taxonomia e as relações wp_term_relationships — os posts attachment continuam a existir, só passam a "Sem pasta". Confirmado no código-fonte (includes/actions.php) e testado ao vivo neste MCP (ver secção Verificação).
  • Uma pasta por ficheiro por omissão: wp_set_object_terms($id, [$folderId], $taxonomy, false) com append=false substitui a pasta anterior — é o comportamento por omissão do HappyFiles Pro (happyfiles_multiple_folders = false). Este MCP replica exactamente essa semântica em happyfiles_move_files.

Sites conhecidos

Chamar happyfiles_list_sites para a lista actual. Confirmados HappyFiles Pro 1.8.3 activo ao vivo em 19-08-2026: descomplicar (produção, /home/ealmeida/public_html — 66 pastas reais em uso, 1218 attachments, 893 sem pasta), emanuelalmeida (emanuelalmeida.pt), starter (starter.descomplicar.pt). Também aceita um path absoluto directamente (/home/ealmeida/<site>) para sites fora desta lista, sem exigir rebuild do MCP.

Tools (9)

Tool Read-only Uso
happyfiles_list_sites sim Aliases conhecidos, path WP, nota de estado
happyfiles_get_status sim Plugin instalado/activo + versão
happyfiles_list_folders sim Todas as pastas: id, nome, slug, parent, count, position, color, mais all_files_count/uncategorized_count
happyfiles_create_folder não Nova pasta, parentId opcional para subpasta
happyfiles_rename_folder não Novo nome + slug recalculado
happyfiles_delete_folder não Nunca apaga ficheiros. deleteSubfolders:true apaga em cascata; por omissão as subpastas sobem para o pai (comportamento nativo wp_delete_term)
happyfiles_list_files_in_folder sim Ficheiros directamente numa pasta (não inclui subpastas), paginado
happyfiles_list_uncategorized_files sim Ficheiros sem nenhuma pasta atribuída, paginado
happyfiles_move_files não 1+ ficheiros para uma pasta (substitui a pasta anterior) ou folderId: null para desassociar (Sem pasta)

Todas as tools exigem site como primeiro parâmetro.

Segurança

Nenhuma escrita usa SQL directo nem classes internas do plugin (não são autoload-seguras fora do wp-admin) — só as funções nativas de taxonomia do WordPress, as mesmas que os handlers AJAX do próprio HappyFiles Pro chamam (includes/actions.php, includes/ajax.php), pelo que os hooks (created_term, edited_term, delete_term, set_object_terms) disparam sempre. O corpo PHP corrido por wp eval é sempre um template estático sem texto do utilizador interpolado; nomes de pasta e IDs de ficheiros viajam em JSON codificado em base64 pelo STDIN do processo remoto (php://stdin dentro do PHP, stream_get_contents(STDIN)), nunca na linha de comando — evita por completo ter de escapar aspas/unicode num nome de pasta para a shell remota.

Verificação

Construído e testado ponta-a-ponta contra produção e staging em 19-08-2026:

  • Leituras cruzadas independentes (descomplicar, produção): happyfiles_list_folders devolveu 66 pastas, all_files_count: 1218 e uncategorized_count: 893 — confirmados byte-a-byte via wp eval/wp post list --format=count directos fora do MCP. happyfiles_list_files_in_folder na pasta "Clientes" (id 42) devolveu total: 7 depois de corrigido o gotcha include_children (tinha devolvido 120 antes da correcção); confirmado via wp post term list <id> happyfiles_category em vários ficheiros individuais devolvidos.
  • Ciclo de escrita completo em starter (site vazio de pastas, 7 attachments — sandbox seguro): happyfiles_create_folder → happyfiles_rename_folder → happyfiles_move_files (ficheiro 19 para a pasta nova, confirmado via wp post term list directo) → happyfiles_list_files_in_folder (1 item) / happyfiles_list_uncategorized_files (6 itens, confirmado) → happyfiles_move_files de volta a null (confirmado wp post term list vazio de novo) → happyfiles_delete_folder → estado final confirmado idêntico ao inicial (wp term list vazio, wp post list --format=count ainda 7, wp post get 19 com o título original intacto).

Skills relacionadas

Nenhuma skill de conhecimento dedicada ao HappyFiles Pro existe neste bundle — esta skill é a única documentação (arquitectura de dados + tools). Ver wp-cli para o padrão geral de gestão via WP-CLI no servidor CWP.