--- name: mcp-seriously-simple-podcasting description: MCP dedicado (HTTP StreamableHTTP local, ligação `seriously-simple-podcasting` em ~/.claude.json, porta 3203) para o Seriously Simple Podcasting em emanuelalmeida.pt (produção, 39 episódios reais em 8 shows) — episódios (CPT `podcast`), shows/séries (taxonomia `series`) e definições de show (título, owner, categorias iTunes, explicit/complete). Escritas sempre via bootstrap WordPress (`wp_insert_post`/`wp_update_post`/`wp_insert_term`/`update_option`), nunca SQL directo. Usar quando "episódio podcast", "criar episódio", "show podcast", "definições de show", "categoria itunes", "feed rss emanuelalmeida", "apagar episódio", "estatísticas podcast", ou qualquer gestão de conteúdo de podcast em emanuelalmeida.pt. layer: wiki --- # /mcp-seriously-simple-podcasting — MCP dedicado Seriously Simple Podcasting (emanuelalmeida.pt) Projecto em `/media/ealmeida/Dados/Dev/mcp-seriously-simple-podcasting/` (TypeScript, SDK MCP oficial, StreamableHTTP). O REST API nativo do plugin é escrita-capaz para episódios mas **read-only para definições de show** (`wp/v2/series` só regista `get_callback`, achado confirmado lendo `Rest_Api_Controller::create_api_series_fields()`) — por isso este MCP usa um único mecanismo consistente para tudo (episódios e shows): o bootstrap WordPress completo via `wp eval`, nunca REST nem SQL directo para escritas. **Zona-alvo: emanuelalmeida.pt (produção), 39 episódios reais em 8 shows.** ## Arquitectura — sem tocar no filesystem do servidor Leituras: SQL directo via `$wpdb` (rápido, tipado). Escritas: SEMPRE pelas funções nativas do WordPress (`wp_insert_post`/`wp_update_post`/`wp_delete_post`, `wp_insert_term`/`wp_delete_term`, `wp_set_post_terms`, `update_post_meta`, `update_option`) — nunca INSERT/UPDATE directo, para preservar hooks de feed/permalinks/sanitização nativa. Ambas correm por SSH via `wp eval`, com o corpo PHP + dados de entrada codificados em base64 dentro de uma variável de ambiente remota — **nunca ficheiros escritos/apagados no servidor**, o que evitaria deliberadamente o GATE 5.1 de mutação de infra-estrutura. Ver `src/wp-bridge.ts` (`runPhp()`) — mesmo mecanismo do `mcp-fluent-crm`. ## Tools (14) **Leitura (7):** `ssp_list_episodes` (filtros série/estado/pesquisa), `ssp_get_episode`, `ssp_list_series`, `ssp_get_series_settings` (corrige o bug do REST nativo para explicit/complete), `ssp_get_stats`, `ssp_get_feed_url`, `ssp_get_itunes_categories` (referência estática, sem chamada SSH). **Escrita (7):** `ssp_create_episode`, `ssp_update_episode`, `ssp_delete_episode` (trash por omissão, `force=true` apaga permanentemente), `ssp_set_episode_series`, `ssp_create_series`, `ssp_update_series_settings`, `ssp_delete_series` (destructive — ver guarda abaixo). ## Guardas de segurança - `ssp_update_series_settings`/`ssp_create_series` validam `category`/`category2`/`category3` e `subcategory`/`subcategory2`/`subcategory3` contra a lista oficial Apple Podcasts **antes** de qualquer chamada SSH (rejeita categoria inexistente ou par categoria/subcategoria incoerente com erro accionável). - `ssp_delete_series` recusa remover um show com episódios associados sem `force=true` — **mas atenção:** a contagem usada (`term->count`) só reflecte episódios **publicados**; um show só com episódios em `draft` passa como "vazio" mesmo tendo conteúdo associado. Confirmar sempre com `ssp_list_episodes({series_id, status: 'any'})` antes de forçar a remoção. - `ssp_delete_episode` por omissão move para o lixo (recuperável); `force=true` apaga permanentemente. ## Fora do v1 (decisão deliberada) Gestão da ligação Castos/hosting (não aplicável — desligada neste site), upload directo de ficheiros de áudio (o plugin só aceita URL, sem endpoint de upload próprio — usar Media Library via ferramentas WordPress genéricas e passar o URL resultante), CRUD de tags normais (`post_tag`) — usar ferramentas WordPress genéricas para isso, o CPT `podcast` é standard. ## Credenciais `.env` local (`WP_SSH_HOST=server`, `WP_PATH=/home/ealmeida/emanuelalmeida.pt`), não versionado. Sem tokens/API keys — a autenticação é a própria sessão SSH root já configurada em `~/.ssh/config`. ## Verificação Construído e testado ponta-a-ponta contra a zona real 19-08-2026: todas as 14 tools exercitadas manualmente (incl. guarda de categoria inválida e guarda de show com episódio publicado) + 13/13 evaluations automatizadas (`npm run eval:ci`), que criam e limpam os seus próprios artefactos (`__mcp_eval__`) sem tocar em dados reais. Deploy como processo `hub` persistente (`mcp-seriously-simple-podcasting`, porta 3203, `http://127.0.0.1:3203/mcp`), registado em `~/.claude.json` como `seriously-simple-podcasting`. ## Skills relacionadas - `seriously-simple-podcasting` — conhecimento profundo do plugin: arquitectura CPT/taxonomia, achado central do REST nativo (episódios escrita-capaz, shows read-only), schema de `wp_options` das definições de show (com o gotcha explicit/complete), categorias iTunes, feed RSS, wp-admin — consultar antes de desenhar uma integração ou entender um comportamento que este MCP não cobre.