- Adicionado estrutura completa do projeto - Configurado MCP server para Premiere Pro - Adicionado documentação e skills - Configurado Gitignore para o projeto
14 KiB
Sim. O ideal é tratar o MCP como um módulo completo de integração com o Premiere, e não como uma única classe responsável por tudo.
O MCP será utilizado para várias finalidades:
- Ler a timeline ativa;
- Ler sequências, faixas e clipes;
- Obter propriedades dos clipes;
- Criar, mover, cortar ou excluir elementos;
- Aplicar alterações na timeline;
- Executar comandos no Premiere;
- Consultar o estado atual do projeto;
- Validar se uma operação foi executada corretamente.
Por isso, uma única classe como ClienteMCP ficaria sobrecarregada rapidamente.
Estrutura recomendada
integracoes/
└── premiere/
├── __init__.py
│
├── cliente_mcp.py
├── sessao_mcp.py
├── erros_mcp.py
│
├── leitura/
│ ├── acesso_a_timeline.py
│ ├── acesso_a_sequencia.py
│ ├── acesso_a_faixas.py
│ └── acesso_a_clipes.py
│
├── escrita/
│ ├── executor_de_comandos.py
│ ├── manipulador_de_clipes.py
│ ├── manipulador_de_timeline.py
│ └── aplicador_de_operacoes.py
│
├── conversores/
│ ├── conversor_de_timeline.py
│ ├── conversor_de_clipes.py
│ └── conversor_de_respostas.py
│
└── contratos/
├── acesso_ao_editor.py
└── executor_do_editor.py
A ideia principal é separar:
Comunicação com o MCP, leitura do Premiere, execução de comandos e conversão dos dados.
1. ClienteMCP
Arquivo:
integracoes/premiere/cliente_mcp.py
Classe:
class ClienteMCP:
"""Responsável pela comunicação técnica com o servidor MCP do Premiere."""
Essa classe deve cuidar somente da comunicação.
Responsabilidades:
- Abrir conexão;
- Encerrar conexão;
- Enviar uma chamada;
- Receber a resposta;
- Controlar timeout;
- Tratar erros de comunicação;
- Registrar logs;
- Identificar falhas de conexão;
- Possivelmente reconectar.
Exemplo conceitual:
class ClienteMCP:
"""Executa chamadas técnicas contra o servidor MCP."""
def conectar(self) -> None:
"""Estabelece a conexão com o MCP."""
def desconectar(self) -> None:
"""Encerra a conexão com o MCP."""
def chamar(self, nome_da_ferramenta: str, argumentos: dict) -> dict:
"""Executa uma ferramenta MCP e retorna sua resposta."""
Ele não deve saber o que é uma timeline, um clipe ou um retake.
Para ele, existe apenas:
chamar ferramenta → receber resposta
2. SessaoMCP
Arquivo:
integracoes/premiere/sessao_mcp.py
Classe:
class SessaoMCP:
"""Controla o estado de uma sessão de comunicação com o Premiere."""
Pode ser útil para armazenar:
- Identificação da sessão;
- Estado da conexão;
- Projeto atual;
- Sequência ativa;
- Última operação executada;
- Ferramentas disponíveis;
- Informações de capacidade do MCP.
Exemplo:
class SessaoMCP:
"""Representa o estado atual da integração com o Premiere."""
def __init__(self):
self.conectado = False
self.projeto_atual = None
self.sequencia_ativa = None
Essa classe não é obrigatória na primeira versão, mas será útil quando a integração crescer.
3. Módulo de leitura
O módulo de leitura seria responsável por transformar comandos técnicos do MCP em operações compreensíveis pelo sistema.
AcessoATimeline
Arquivo:
integracoes/premiere/leitura/acesso_a_timeline.py
Classe:
class AcessoATimeline:
"""Fornece operações de leitura da timeline do Premiere."""
Métodos possíveis:
class AcessoATimeline:
"""Lê a estrutura da timeline ativa."""
def obter_timeline_ativa(self):
"""Retorna os dados da timeline ativa."""
def obter_sequencia_ativa(self):
"""Retorna a sequência atualmente selecionada."""
def obter_faixas(self):
"""Retorna as faixas de vídeo e áudio."""
def obter_clipes(self):
"""Retorna os clipes presentes na timeline."""
def obter_detalhes_do_clipe(self, identificador_do_clipe):
"""Retorna os detalhes de um clipe específico."""
O fluxo seria:
AcessoATimeline
↓
ClienteMCP
↓
MCP do Premiere
O scanner chamaria:
timeline = acesso_a_timeline.obter_timeline_ativa()
E não:
cliente_mcp.chamar("alguma_ferramenta_interna", {...})
Isso é importante porque o restante do sistema não deve conhecer os detalhes do MCP.
Outras classes de leitura
Podemos dividir conforme a complexidade:
leitura/
├── acesso_a_timeline.py
├── acesso_a_sequencia.py
├── acesso_a_faixas.py
├── acesso_a_clipes.py
├── acesso_a_projeto.py
└── acesso_a_itens_de_midia.py
Entretanto, no início, não é necessário criar todas imediatamente.
Podemos começar com:
AcessoAoEditor
e depois dividir quando a classe crescer demais.
4. AcessoAoEditor
Eu recomendaria inicialmente uma classe de fachada chamada AcessoAoEditor.
Arquivo:
integracoes/premiere/acesso_ao_editor.py
Classe:
class AcessoAoEditor:
"""Oferece uma interface simplificada para consultar o Premiere."""
Ela funcionaria como uma porta de entrada para as operações de leitura:
class AcessoAoEditor:
"""Centraliza o acesso estruturado aos dados do Premiere."""
def __init__(self, acesso_a_timeline, acesso_a_clipes):
self.acesso_a_timeline = acesso_a_timeline
self.acesso_a_clipes = acesso_a_clipes
def obter_timeline_ativa(self):
"""Obtém a timeline ativa."""
return self.acesso_a_timeline.obter_timeline_ativa()
def obter_clipes(self):
"""Obtém os clipes da timeline ativa."""
return self.acesso_a_clipes.obter_clipes()
Assim, o scanner dependeria de:
AcessoAoEditor
e não diretamente de:
ClienteMCP
5. Módulo de escrita
A leitura e a escrita devem ser separadas.
integracoes/premiere/
├── leitura/
└── escrita/
Isso evita misturar:
- Consultar dados;
- Alterar dados;
- Executar comandos destrutivos.
ExecutorDeComandos
Arquivo:
integracoes/premiere/escrita/executor_de_comandos.py
Classe:
class ExecutorDeComandos:
"""Executa comandos de alteração no Premiere por meio do MCP."""
Responsabilidades:
- Executar uma operação;
- Enviar parâmetros;
- Receber resultado;
- Identificar falhas;
- Retornar confirmação da operação.
Exemplo:
class ExecutorDeComandos:
"""Executa comandos no editor."""
def executar(self, nome_do_comando: str, argumentos: dict):
"""Executa um comando no Premiere."""
Mas essa classe não deveria decidir qual comando deve ser executado. Ela apenas executa o comando que recebeu.
AplicadorDeOperacoes
Arquivo:
integracoes/premiere/escrita/aplicador_de_operacoes.py
Classe:
class AplicadorDeOperacoes:
"""Aplica operações de edição estruturadas na timeline."""
Essa classe recebe operações já definidas pelo plano de edição:
class AplicadorDeOperacoes:
"""Aplica operações de edição no Premiere."""
def aplicar_corte(self, operacao):
"""Aplica uma operação de corte."""
def mover_clipe(self, operacao):
"""Move um clipe na timeline."""
def excluir_clipe(self, operacao):
"""Exclui um clipe da timeline."""
def aplicar_plano(self, plano):
"""Aplica todas as operações de um plano de edição."""
O fluxo seria:
AplicadorDeOperacoes
↓
ExecutorDeComandos
↓
ClienteMCP
↓
MCP do Premiere
6. ConversorDeTimeline
Arquivo:
integracoes/premiere/conversores/conversor_de_timeline.py
Classe:
class ConversorDeTimeline:
"""Converte os dados brutos do Premiere para o modelo interno do sistema."""
Essa classe é muito importante.
O MCP pode retornar dados em um formato específico, por exemplo:
{
"sequence": {
"name": "Sequência 01",
"timebase": 25
},
"tracks": [],
"clips": []
}
Mas o sistema não deveria depender diretamente desse formato.
O conversor transforma isso em objetos próprios:
class ConversorDeTimeline:
"""Converte uma resposta do Premiere para o domínio interno."""
def converter(self, dados_brutos):
"""Converte os dados brutos em uma timeline do sistema."""
Assim, se futuramente o MCP mudar, somente a integração e os conversores precisarão ser ajustados.
O restante do sistema continua funcionando.
7. Contratos para desacoplar o sistema
O ideal é criar contratos para que o scanner não dependa de uma implementação específica.
AcessoAoEditor
Arquivo:
integracoes/premiere/contratos/acesso_ao_editor.py
Exemplo:
from abc import ABC, abstractmethod
class AcessoAoEditor(ABC):
"""Define as operações de leitura necessárias para acessar um editor."""
@abstractmethod
def obter_timeline_ativa(self):
"""Obtém a timeline ativa do editor."""
raise NotImplementedError
@abstractmethod
def obter_clipes(self):
"""Obtém os clipes da timeline."""
raise NotImplementedError
Depois podemos ter:
AcessoAoEditor
├── AcessoAoPremiere
├── AcessoAoOpenCut
└── AcessoAoEditorSimulado
O último é especialmente útil para testes.
Por exemplo:
class AcessoAoEditorSimulado(AcessoAoEditor):
"""Fornece dados fictícios para testes sem abrir o Premiere."""
8. Como o scanner usaria isso
A classe DescobertaDaTimeline não deveria conhecer MCP.
Ela deveria conhecer apenas uma interface de acesso ao editor.
class DescobertaDaTimeline:
"""Descobre a estrutura da timeline a partir do editor."""
def __init__(self, acesso_ao_editor):
self.acesso_ao_editor = acesso_ao_editor
def executar(self, contexto):
"""Lê a timeline e armazena os dados no contexto."""
timeline = self.acesso_ao_editor.obter_timeline_ativa()
contexto.timeline = timeline
return contexto
O encadeamento seria:
DescobertaDaTimeline
↓
AcessoAoPremiere
↓
AcessoATimeline
↓
ClienteMCP
↓
MCP do Premiere
Ou, usando uma fachada:
DescobertaDaTimeline
↓
AcessoAoEditor
↓
ClienteMCP
↓
MCP do Premiere
9. Arquitetura completa recomendada
projeto/
│
├── scanner/
│ ├── coordenacao/
│ │ ├── analisador_de_timeline.py
│ │ ├── pipeline_do_scanner.py
│ │ └── contexto_de_analise.py
│ │
│ ├── descoberta/
│ │ ├── descoberta_da_timeline.py
│ │ ├── descoberta_de_clipes.py
│ │ └── descoberta_de_arquivos.py
│ │
│ ├── metadados/
│ ├── audio/
│ ├── transcricao/
│ ├── visual/
│ ├── cenas/
│ └── retakes/
│
├── providers/
│ ├── transcricao/
│ ├── analise_visual/
│ ├── deteccao_de_cenas/
│ └── analise_de_audio/
│
├── integracoes/
│ └── premiere/
│ ├── cliente_mcp.py
│ ├── sessao_mcp.py
│ ├── erros_mcp.py
│ │
│ ├── leitura/
│ │ ├── acesso_a_timeline.py
│ │ ├── acesso_a_sequencia.py
│ │ ├── acesso_a_faixas.py
│ │ └── acesso_a_clipes.py
│ │
│ ├── escrita/
│ │ ├── executor_de_comandos.py
│ │ ├── aplicador_de_operacoes.py
│ │ └── manipulador_de_timeline.py
│ │
│ ├── conversores/
│ │ ├── conversor_de_timeline.py
│ │ ├── conversor_de_clipes.py
│ │ └── conversor_de_respostas.py
│ │
│ └── contratos/
│ ├── acesso_ao_editor.py
│ └── executor_do_editor.py
│
├── dominio/
├── configuracao/
├── persistencia/
└── testes/
Minha recomendação prática
Para a primeira versão, não criaria todas as classes imediatamente. Começaria assim:
integracoes/
└── premiere/
├── cliente_mcp.py
├── acesso_ao_editor.py
├── executor_de_comandos.py
├── conversor_de_timeline.py
└── erros_mcp.py
Depois, quando as responsabilidades crescerem:
acesso_ao_editor.py
poderá ser dividido em:
leitura/
├── acesso_a_timeline.py
├── acesso_a_clipes.py
└── acesso_a_projeto.py
E:
executor_de_comandos.py
poderá ser dividido em:
escrita/
├── aplicador_de_operacoes.py
├── manipulador_de_clipes.py
└── manipulador_de_timeline.py
Regra central
A arquitetura deve seguir esta separação:
Scanner
define o que precisa ser analisado
Integração com o Premiere
acessa e altera o editor
Cliente MCP
faz a comunicação técnica
Conversores
transformam dados externos em dados internos
Providers
executam análises usando tecnologias específicas
Motor de decisão
decide o que fazer com os resultados
Aplicador de plano
transforma decisões em operações no editor
Portanto, a resposta direta é:
MCP deve ser um módulo de integração completo, com
ClienteMCPcomo classe de comunicação central, classes especializadas de leitura e escrita, conversores e contratos. Ele não deve ser uma única classe gigante nem ficar misturado dentro do scanner.