# 03 — Camada MCP (`server.py`) — 62 ferramentas `server.py` (3824 linhas) é a camada de transporte. Não tem lógica de timeline — mapeia nome → handler e delega ao Engine. O dispatch é um dicionário `TOOL_HANDLERS` (padrão de despacho, sem cadeias gigantes de if/elif). ## Helpers centrais (use-os, não reinvente) | Helper | Linha | Função | |--------|------:|--------| | `_check_json_depth()` | 83 | Rejeita payloads além de 50 níveis | | `_validate_filepath()` | 103 | Sandbox de entrada | | `_validate_output_path()` | 149 | Sandbox de saída | | `_format_clip_table()` | 245 | Renderização de tabela | | `_markdown_table()` | 259 | Renderização de tabela markdown | | `_parse_project()` | 319 | Parseia FCPXML → `(tree, timeline, project)`; quase todos os handlers começam aqui | | `_resolve_io_paths()` | 357 | Validação de caminho de entrada/saída | | `_setup_modifier()` | 390 | Prepara modifier com validação | | `_setup_generator()` | 414 | Prepara generator com validação | | `_parse_timestamp_parts()` | 433 | Parse de timestamps (min:seg, H:MM:SS, SMPTE) | | `_detect_flash_frames/gaps/duplicate_groups()` | 1667+ | Detectores de QC | ## As 62 ferramentas por categoria ### Timeline & análise (Projeto) `list_projects`, `analyze_timeline`, `list_clips`, `list_markers`, `list_connected_clips`, `list_compound_clips`, `list_library_clips`, `list_roles`, `list_keywords`, `list_effects`. ### QC e detecção `find_short_cuts`, `find_long_clips`, `analyze_pacing`, `detect_flash_frames`, `detect_duplicates`, `detect_gaps`, `validate_timeline`, `detect_silence_candidates`, `detect_media_silence`, `remove_silence_candidates`, `remove_media_silence`, `detect_beats`. ### Edição `add_marker`, `batch_add_markers`, `trim_clip`, `reorder_clips`, `add_transition`, `change_speed`, `delete_clips`, `split_clip`, `insert_clip`, `fix_flash_frames`, `rapid_trim`, `fill_gaps`, `add_audio`, `create_compound_clip`, `flatten_compound_clip`. ### Geração `auto_rough_cut`, `generate_montage`, `generate_ab_roll`, `list_templates`, `apply_template`. ### Beats / markers importados `import_beat_markers`, `snap_to_beats`, `import_srt_markers`, `import_transcript_markers`. ### Roles `assign_role`, `filter_by_role`, `export_role_stems`. ### Transcrição & edição por transcrição `transcribe_media`, `edit_by_transcript`, `remove_filler_words`. ### Diferenciação `diff_timelines`. ### Export / relink `export_edl`, `export_csv`, `export_resolve_xml`, `export_fcp7_xml`, `relink_media`. ### Reformat `reformat_timeline`. ### Live (macOS) `push_to_fcp`, `list_fcp_libraries`. --- ## Padrão de handler (a forma de fazer) ```python async def handle_(arguments: dict): tree, timeline, project = _parse_project(arguments) # 1. parseia # ...opera com o Engine (parser/writer/rough_cut/export)... return _text_result(text) # 2. devolve ``` Regras: - Todo handler valida caminho com `_validate_filepath`/`_validate_output_path`. - Saídas sempre com sufixo `_modified`, `_chapters`, etc. — original nunca é tocado. - Cada handler tem o seu `async def handle_(arguments: dict)`. - Sempre retornam via `_text_result(text)` (envolve o texto em `TextContent` MCP). ## Para adicionar uma ferramenta nova 1. Escrever a função no módulo do Engine (`fcpxml/…`) + testes. 2. Criar `handle_` em `server.py` seguindo o padrão acima. 3. Registrar no dicionário `TOOL_HANDLERS`. 4. Rodar `./Engine/run_after_fix.sh`.