# G-ART — Engine Overview Este documento descreve a arquitetura interna do **G-ART / fcp-mcp-server** (repositório `G-ART`), uma aplicação **MCP (Model Context Protocol) server em Python** que lê, analisa e reescreve arquivos **FCPXML** do Final Cut Pro — a ponte entre o Final Cut Pro e IA. Diferente do CommandPost (automação de GUI via Lua/Hammerspoon), este projeto opera **fora** do Final Cut Pro: você exporta o XML, o servidor processa o documento como dados estruturados e devolve um XML modificado para importação. Nada é patcheado, nenhuma API privada é usada. Toda a análise foi feita a partir do código-fonte em `server.py` e `fcpxml/`. > **Guia rápido:** [01 Arquitetura](docs/01_ARCHITECTURE.md) · > [02 Módulos](docs/02_MODULES.md) · [03 Server/Tools](docs/03_SERVER_TOOLS.md) · > [04 Testes & Workflow](docs/04_TESTS_AND_WORKFLOW.md) · > [05 Experiências](docs/05_EXPERIENCIAS.md) · [06 Boas Práticas](docs/06_BOAS_PRATICAS.md) --- ## 1. O que o programa faz 1. **Um motor de parse/serialização FCPXML** — transforma timelines do Final Cut Pro (XML v1.8–v1.14, flat `.fcpxml` e bundles `.fcpxmld`) em objetos Python, e reescreve de volta sem perda de sidecars (object tracking, Cinematic). 2. **Uma camada MCP de 62 ferramentas** — expõe análise, edição em lote, QC, geração, exportação cross-NLE, inteligência de mídia (silêncio/beats) e edição baseada em transcrição, tudo acessível por um cliente MCP (Claude). 3. **Modo Live (macOS)** — faz *push* de um FCPXML direto para o Final Cut Pro em execução via Apple events oficiais (Open Document), sem re-importação manual. Leitura de bibliotecas abertas via dicionário AppleScript read-only. --- ## 2. Pilha tecnológica | Camada | Tecnologia | |--------|-----------| | Linguagem | **Python 3.10+** (~7.1k linhas em `server.py` + `fcpxml/`) | | Protocolo MCP | **mcp** (`mcp` SDK), servidor por stdio | | Parsing XML | **defusedxml** em todos os 4 entry points + `lxml`/`ElementTree` | | Tempo racional | frações `numerador/denominador` no formato `"600/2400s"` | | Análise de mídia | **ffmpeg** `silencedetect` (opcional) e **librosa** (extra `[intelligence]`) | | Transcrição | **Whisper** local (extra `[transcribe]`) | | Controle Live | **osascript** / Apple events para o bundle `com.apple.FinalCut` | | Validação | **xmllint** contra os DTDs oficiais do bundle do Final Cut Pro | | Licença | MIT | --- ## 3. Estrutura geral do repositório ``` G-ART/ ├── server.py # MCP server — 62 tools, prompts, resources, dispatch ├── fcpxml/ # "Engine" — biblioteca Python de núcleo │ ├── models.py # TimeValue, Timecode, Clip, Timeline, enums, QC models │ ├── parser.py # FCPXML → objetos Python (spine, connected clips, roles) │ ├── writer.py # Modifica e grava FCPXML (markers, trim, gaps, speed) │ ├── rough_cut.py # Gera timelines novas (rough cuts, montages, A/B) │ ├── diff.py # Motor de comparação de timelines │ ├── export.py # Export DaVinci Resolve v1.9 + FCP7 XMEML v5 │ ├── media_intel.py # Detecção real de silêncio (ffmpeg) e beats (librosa) │ ├── transcribe.py # Transcrição Whisper local + edição por transcrição │ ├── templates.py # Templates de timeline (intro/outro, lower thirds) │ ├── live.py # Modo Live — push_to_fcp / list_fcp_libraries │ ├── safe_xml.py # Wrappers defusedxml + serialize_xml() │ └── dtd.py # Validação contra DTDs oficiais da Apple ├── Engine/ # Esta documentação da arquitetura ├── admin/ # Scripts de manutenção (graphify.sh, graphify.md) ├── docs/ # WORKFLOWS, CAPABILITY-AUDIT, specs ├── examples/ # Fixture de teste (sample.fcpxml) ├── tests/ # 1032 testes / 24 suítes └── tools/ # Pacote Python (__init__) ``` --- ## 4. O "Engine": a biblioteca `fcpxml/` É o núcleo desacoplado do MCP. Não conhece o protocolo MCP nem os argumentos das ferramentas — trabalha apenas com objetos Python e XML. `server.py` atua como *camada de transporte/adaptação* que chama este núcleo. ### 4.1 Fundamentos de tempo — `models.TimeValue` Toda hora é uma fração racional, nunca float. Isso elimina erro de arredondamento em trim/split/speed em qualquer frame rate: ```python TimeValue(600, 2400) # "600/2400s" == 0.25s ``` - Comparações por **multiplicação cruzada** (`a/b < c/d` → `a*d < c*b`), permanecendo sempre em inteiros. - Denominadores normalizados para positivos na construção — o sinal vive no numerador. - Soma/subtração compartilham um único caminho `_binop()` (fast-path de mesmo denominador + alinhamento por LCM). ### 4.2 Modelos principais — `models.py` | Classe | Função | |--------|--------| | `TimeValue`, `Timecode` | Tempo racional e formatação/parse de timecode | | `Clip`, `VideoClip`, `AudioClip` | Clips da timeline (offset, start, duration, markers) | | `ConnectedClip` | Clips com atributo `lane` (acima/abaixo da espinha) | | `CompoundClip` | Clips compostos | | `Timeline`, `Project` | Contêineres de espinha + connected clips | | `Marker`, `MarkerType`, `MarkerColor` | Marcadores; `INCOMPLETE` é canônico, `TODO` é alias | | `SilenceCandidate`, `FlashFrame`, `GapInfo`, `DuplicateGroup` | Resultados de QC | | `ValidationIssue`, `ValidationResult` | Resultados de validação | | `SegmentSpec`, `PacingConfig`, `MontageConfig` | Parâmetros de geração | **Single source of truth**: `MarkerType` enum é dono da serialização — `from_string()` para entrada, `from_xml_element()` para parse, `xml_attrs` para escrita. `from_xml_element` faz match estrito do atributo `completed` (`'0'`/`'1'` apenas), rejeitando valores com padding de espaço. ### 4.3 Subsistemas | Subsistema | Módulo | Função | |-----------|--------|--------| | Parser | `parser.py` | FCPXML → objetos Python: espinha, connected clips, secondary storylines, roles | | Modifier | `writer.FCPXMLModifier` | Edição index-based (clips/resources/formats dicts) do documento existente | | Writer | `writer.FCPXMLWriter` | Gera FCPXML novo a partir de objetos Python | | Rough cut | `rough_cut.py` | Gera timelines (rough cuts, montages, A/B roll) | | Diff | `diff.py` | Compara timelines — detecta added/removed/moved/trimmed | | Export | `export.py` | DaVinci Resolve v1.9 + FCP7 XMEML v5 | | Media intel | `media_intel.py` | Detecção real de silêncio (ffmpeg) e beats (librosa, lazy) | | Transcript | `transcribe.py` | Whisper local + edição por transcrição | | Templates | `templates.py` | Estruturas pré-prontas (intro/outro, lower thirds, music video) | | Live | `live.py` | push_to_fcp (Apple event) e list_fcp_libraries (AppleScript) | | Segurança XML | `safe_xml.py` | Wrappers defusedxml centralizados + `serialize_xml()` | | DTD | `dtd.py` | Valida output contra DTDs oficiais no bundle do FCP | --- ## 5. A camada MCP — `server.py` ### 5.1 Padrão de dispatch Não há cadeias gigantes de `if/elif`. Um dicionário mapeia nome → handler assíncrono: ```python TOOL_HANDLERS = { "analyze_timeline": handle_analyze_timeline, "list_clips": handle_list_clips, # ... 62 tools } ``` Cada ferramenta tem seu `async def handle_(arguments: dict)`. Todas retornam via `_text_result(text)`, que envolve strings no `TextContent` MCP. ### 5.2 Helpers centrais | Helper | Linha | Função | |--------|-------|--------| | `_parse_project()` | `server.py:319` | Parseia FCPXML → `(tree, timeline, project)`; a maioria dos handlers começa aqui | | `_resolve_io_paths()` | `server.py:357` | Consolida validação de caminho de entrada/saída | | `_setup_modifier()` / `_setup_generator()` | `server.py:390` / `:414` | Preparam modifier/generator com validação | | `_format_clip_table()` / `_markdown_table()` | `server.py:245` / `:259` | Renderização de tabelas | | `_parse_timestamp_parts()` | `server.py:433` | Parse de timestamps (min:seg, H:MM:SS, SMPTE) | | `_detect_flash_frames()` / `_detect_gaps()` / `_detect_duplicate_groups()` | `server.py:1667+` | Detectores de QC | | `_validate_filepath()` / `_validate_output_path()` | `server.py:103` / `:149` | Sandbox de I/O | | `_check_json_depth()` | `server.py:83` | Rejeita payloads aninhados além de 50 níveis | ### 5.3 Modo Live — `fcpxml/live.py` Rode apenas as superfícies sancionadas da Apple — sem patch de binário, sem APIs privadas, sem acessibilidade: - **push_to_fcp** — import FCPXML via Apple event *Open Document*. Injeta um `` no documento (local da biblioteca, copy/link assets, suprimir avisos). Requer um caminho `.fcpbundle` para *zero-click* de verdade; sem ele, o FCP abre um modal "Open Library" que bloqueia até resposta humana. - **list_fcp_libraries** — enumera bibliotecas → eventos → projetos via o dicionário AppleScript read-only (suite `com.apple.FinalCut.library.inspection`). **A assimetria estrutural**: import é scriptable, mas a Apple não oferece export programático — para puxar a timeline atual de volta, você ainda roda `File > Export XML`. O modo Live *empurra*; round-trips voltam pelas ferramentas XML. --- ## 6. Fluxo de um pedido ``` Cliente MCP (Claude) │ JSON-RPC (stdio) ▼ server.py ── dispatcher (TOOL_HANDLERS) │ ├── handle_* (valida caminho, _parse_project, opera) │ ├── fcpxml/parser.py (XML → objetos) ├── fcpxml/writer.py (edita / grava) ├── fcpxml/rough_cut.py (gera novas timelines) ├── fcpxml/export.py (cross-NLE) │ ▼ output_.fcpxml (original nunca é sobrescrito) │ ▼ Final Cut Pro: File → Import → XML (ou push_to_fcp, sem cliques) ``` --- ## 7. Validação padrão pós-correção (é obrigatório) Regra do padrão do sistema: **sempre após concluir qualquer correção de código, o sistema é automaticamente executado/validado.** O gatilho é o script `[Engine/run_after_fix.sh](run_after_fix.sh)`. Toda vez que você terminar uma correção, acione-o: ```bash ./Engine/run_after_fix.sh ``` Ele roda (a partir de qualquer diretório) e falha (`set -e`) se algo não passar: 1. **`uv run ruff check . --exclude docs/`** — lint com zero erros. 2. **`uv run pytest tests/ -v`** — toda a suíte de testes passa. Se falhar, corrija antes de prosseguir. Esta validação é o mesmo critério já descrito em `CLAUDE.md` (Pre-Commit) — a diferença é que agora há um comando único padronizado que garante a execução automática do sistema após cada correção, sem depender de lembrar dos dois comandos no pre-commit. --- ## 8. Como navegar a documentação > Esta pasta `Engine/` é o **hub da documentação**. Comece por aqui. ### Documentação padrão (leia nesta ordem) - [docs/01_ARCHITECTURE.md](docs/01_ARCHITECTURE.md) — como o sistema é dividido (camadas: admin → server → fcpxml/) e como se conectam. **Leia antes de qualquer mudança.** - [docs/02_MODULES.md](docs/02_MODULES.md) — guia módulo a módulo do `fcpxml/` (responsabilidade, tamanho, APIs públicas). - [docs/03_SERVER_TOOLS.md](docs/03_SERVER_TOOLS.md) — a camada MCP `server.py`, 62 ferramentas, helpers e o padrão de handler. - [docs/04_TESTS_AND_WORKFLOW.md](docs/04_TESTS_AND_WORKFLOW.md) — suíte de testes, fluxo de trabalho (lint + pytest), execução e estado atual do sistema. - [docs/05_EXPERIENCIAS.md](docs/05_EXPERIENCIAS.md) — **memória de projeto**: registro cumulativo de problemas estruturais, erros recorrentes e decisões. **Atualize sempre que um problema for detectado/corrigido.** - [docs/06_BOAS_PRATICAS.md](docs/06_BOAS_PRATICAS.md) — **boas práticas de programação** a aplicar em toda alteração/correção; inclui checklist final. ### Outros documentos - [../CLAUDE.md](../CLAUDE.md) — visão geral, key patterns, execução e pre-commit. - [../docs/CAPABILITY-AUDIT-2026-06.md](../docs/CAPABILITY-AUDIT-2026-06.md) — auditoria do ecossistema e roadmap dual-mode (XML + Live). - [../docs/WORKFLOWS.md](../docs/WORKFLOWS.md) — 8 receitas de workflow de produção. - [../docs/specs/](../docs/specs/) — schemas de tools, estrutura FCPXML, pseudocódigo do writer, algoritmo de rough cut, implementação do server, roadmap, modelos. - [../admin/graphify.md](../admin/graphify.md) — pipeline de graphify do código.