Skip to main content
Glama
eubrunodiego

flat-mcp

by eubrunodiego
README.md
# flat-mcp — edite suas partituras do Flat.io pelo Claude

[![Licença: MIT](https://img.shields.io/badge/licen%C3%A7a-MIT-green.svg)](LICENSE)

Criado por **[@eubrunodiego](https://github.com/eubrunodiego)** · 2026-10-27

Servidor MCP local que conecta o Claude (app desktop) diretamente à
[REST API do Flat.io](https://flat.io/developers/docs/api/) usando **a sua conta**,
por meio de um token pessoal. Com ele, o Claude consegue listar, ler, **editar**,
restaurar, exportar e criar partituras.

## Por que não usar o conector oficial do Flat?

O Flat oferece um servidor MCP oficial (`https://mcp.flat.io/mcp`), mas ele
**só lê e cria** partituras — não edita as existentes — e exige assinatura
Flat Power. Esta integração fala direto com a REST API, onde editar é possível.

## Como a edição funciona

A API do Flat não altera notas "no lugar": cada edição grava uma **nova revisão**
da partitura (`POST /scores/{id}/revisions`). O fluxo de cada ferramenta de edição é:

1. baixa a última revisão em MusicXML;
2. aplica a alteração (troca de compassos ou substituição exata de texto);
3. valida o XML — se ficar inválido, **nada é gravado**;
4. grava a nova revisão com uma descrição do que mudou.

Nada é apagado. Para desfazer, peça ao Claude para restaurar uma revisão anterior.

> **Atenção:** a documentação do Flat avisa que a última revisão pode não refletir
> alterações muito recentes feitas no editor web (ele consolida revisões a cada
> ~100 modificações). Antes de editar pela API, feche a partitura no navegador
> ou salve uma revisão manualmente, para não sobrescrever trabalho recente.

---

## 1. Gere seu token pessoal

1. Acesse <https://flat.io/developers/apps> e crie um app (ex.: "Claude").
2. No menu lateral, abra **REST API → Personal tokens**.
3. Dê um nome ao token e marque os escopos:
   `scores`, `collections` e `account.public_profile`.
4. Copie o token e guarde-o — ele dá acesso total às suas partituras.

## 2. Instale

### 2.1 Instale o uv

O [uv](https://docs.astral.sh/uv/) instala o Python e as dependências sozinho.

```bash
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
```

```powershell
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

Anote o caminho completo do executável, que será usado no passo 3:

```bash
which uv          # macOS/Linux — ex.: /Users/voce/.local/bin/uv
```

```powershell
where.exe uv      # Windows — ex.: C:\Users\voce\.local\bin\uv.exe
```

### 2.2 Baixe este repositório

Coloque-o num local fixo (não mova a pasta depois de configurar):

```bash
git clone https://github.com/eubrunodiego/flat-mcp.git ~/flat-mcp
```

Sem git, use **Code → Download ZIP** no GitHub e descompacte em `~/flat-mcp`.

### 2.3 Teste a conexão

```bash
cd ~/flat-mcp
FLAT_ACCESS_TOKEN=cole-seu-token-aqui uv run python -c "from flat_mcp import FlatClient; print(FlatClient().me()['username'])"
```

Se aparecer seu nome de usuário do Flat, está tudo certo.

<details><summary>Sem uv (pip)</summary>

```bash
cd ~/flat-mcp
python3 -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install .
```
No passo 3, use como `command` o caminho completo de `.venv/bin/flat-mcp`
(Windows: `.venv\Scripts\flat-mcp.exe`) e deixe `args` vazio.
</details>

## 3. Conecte ao Claude

### 3.1 Claude desktop (macOS e Windows)

1. No app Claude, abra **Configurações → Desenvolvedor → Editar configuração**.
   Isso abre o arquivo `claude_desktop_config.json`:
   - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
   - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
2. Acrescente a chave `mcpServers` **no nível de cima** do arquivo, ao lado das
   chaves que já existem (não dentro de `preferences`). Lembre da vírgula depois
   do bloco anterior:

```json
{
  "preferences": { "...": "o que já existia no seu arquivo" },
  "mcpServers": {
    "flat": {
      "command": "/CAMINHO/COMPLETO/DO/uv",
      "args": ["--directory", "/CAMINHO/COMPLETO/flat-mcp", "run", "flat-mcp"],
      "env": {
        "FLAT_ACCESS_TOKEN": "cole-seu-token-aqui",
        "FLAT_EXPORT_DIR": "/CAMINHO/onde/salvar/exportacoes"
      }
    }
  }
}
```

   - `command`: o caminho completo do `uv` anotado no passo 2.1. Use o caminho
     completo — o app nem sempre enxerga o PATH do terminal.
   - `--directory`: o caminho completo da pasta deste repositório.
   - No Windows, escreva as barras dobradas: `"C:\\Users\\voce\\flat-mcp"`.
   - `FLAT_EXPORT_DIR` é opcional (padrão: pasta Downloads).
3. Confira se o JSON é válido:

```bash
python3 -m json.tool "$HOME/Library/Application Support/Claude/claude_desktop_config.json" > /dev/null && echo "JSON OK"
```

4. Feche o Claude **por completo** (⌘Q no macOS; no Windows, saia pelo ícone da
   bandeja) e abra de novo. As ferramentas `flat_*` aparecem no menu de
   ferramentas da conversa. Peça "teste a conexão com o Flat" para confirmar.

### 3.2 Claude Code (terminal)

```bash
claude mcp add flat --scope user \
  --env FLAT_ACCESS_TOKEN=cole-seu-token-aqui \
  -- uv --directory ~/flat-mcp run flat-mcp
```

Confira com `claude mcp list`. Dentro do Claude Code, `/mcp` mostra o status.

### 3.3 Resolução de problemas

Os registros do servidor ficam em:
- macOS: `~/Library/Logs/Claude/mcp-server-flat.log`
- Windows: `%APPDATA%\Claude\logs\mcp-server-flat.log`

| Mensagem no log | Causa e solução |
|---|---|
| `Failed to spawn process: No such file or directory` | O `uv` não foi encontrado. Instale-o (2.1) e use o caminho completo em `command`. |
| `401 Unauthorized` | Token errado, expirado ou sem os escopos do passo 1. |
| Servidor não aparece | JSON inválido ou `mcpServers` dentro de outra chave. Rode a validação do passo 3. |
| `No such file or directory` com o caminho do projeto | O caminho em `--directory` está errado ou a pasta foi movida. |

## 4. Use

Exemplos de pedidos:

- "Liste minhas partituras do Flat modificadas recentemente."
- "Na partitura *Ave Maria*, mostre os compassos 9 a 16 do Contralto."
- "No compasso 12 do Soprano, troque o Fá por Sol e mantenha o ritmo. Mostre o dry-run antes de gravar."
- "Corrija o título para 'Ave Maria (Schubert)' e o compositor para 'F. Schubert'."
- "Desfaça a última edição da partitura X."
- "Exporte a partitura X em PDF e em MusicXML."

## Ferramentas

| Ferramenta | O que faz |
|---|---|
| `flat_whoami` | Testa a conexão e mostra a conta |
| `flat_list_scores` / `flat_find_score` | Lista ou procura partituras (paginado) |
| `flat_list_collections` | Lista as coleções (pastas) |
| `flat_score_overview` | Metadados + partes, nº de compassos, armadura e compasso |
| `flat_get_measures` | MusicXML de um trecho de compassos |
| `flat_get_musicxml` | MusicXML bruto, paginado |
| `flat_list_revisions` | Histórico de revisões |
| **`flat_replace_measures`** | Troca compassos inteiros de uma parte → nova revisão |
| **`flat_edit_musicxml`** | Substituições exatas de texto (com contagem obrigatória) → nova revisão |
| **`flat_upload_revision`** | Substitui a partitura inteira por um MusicXML/MXL/MIDI |
| **`flat_restore_revision`** | Desfaz: copia uma revisão antiga para uma nova |
| `flat_update_metadata` | Título, subtítulo, compositor, letrista, arranjador, descrição, privacidade |
| `flat_create_score` / `flat_fork_score` | Cria nova partitura (privada por padrão) ou duplica uma |
| `flat_export` | Salva em PDF, PNG, MusicXML, MXL, MIDI, MP3, WAV |

`flat_replace_measures` e `flat_edit_musicxml` aceitam `dry_run=true`, que confere
o resultado sem gravar.

## Usar como biblioteca Python

```python
from flat_mcp import FlatClient
from flat_mcp import musicxml as mx

flat = FlatClient()  # lê FLAT_ACCESS_TOKEN
scores, _ = flat.list_scores()
sid = scores[0]["id"]

xml = flat.get_musicxml(sid)
print(mx.summarize(xml))
novo = mx.apply_text_edits(xml, [{"find": "<work-title>Rascunho</work-title>",
                                   "replace": "<work-title>Versão final</work-title>"}])
flat.create_revision(sid, novo, description="Título final")
```

## Segurança

- O token fica apenas no seu computador (variável de ambiente). Não o coloque em
  repositórios. Para revogá-lo, apague-o em <https://flat.io/developers/apps>.
- Partituras criadas são **privadas** por padrão; tornar pública exige que você peça.
- Os escopos `scores`/`collections` permitem apagar partituras pela API, mas este
  servidor **não expõe nenhuma ferramenta de exclusão**.

## Testes

```bash
uv run --extra dev pytest -q
```

Os testes usam uma API do Flat simulada em memória — não tocam na sua conta.

## Limitações

- Edição por compasso suporta MusicXML `score-partwise` (o formato que o Flat exporta).
- Exportações pesadas (MP3/WAV/PDF de partituras longas) podem demorar; o tempo limite é 60 s.
- Limites de requisição da API: veja <https://flat.io/developers/docs/api/rate-limits>.

## Créditos e licença

Desenvolvido por **[@eubrunodiego](https://github.com/eubrunodiego)** em 2026-10-27.

Distribuído sob a [licença MIT](LICENSE). Você pode usar, modificar e
redistribuir, desde que mantenha o aviso de copyright.

Este projeto não é afiliado ao Flat.io (Tutteo Ltd). "Flat" é marca de seus
respectivos donos.

TDQS

B3.2/5.0

Scored across 16 tools

Disambiguation4/5

The four write paths (flat_upload_revision, flat_replace_measures, flat_edit_musicxml, flat_restore_revision) all produce new revisions but operate at clearly different granularities (whole score, measure range, exact text substitution, revert), and the descriptions spell this out. The only mild overlaps are flat_get_measures vs flat_get_musicxml and flat_score_overview vs flat_get_musicxml, which are differentiated by range/pagination.

Naming Consistency4/5

Almost every tool follows a flat_verb_noun pattern in snake_case (flat_create_score, flat_list_scores, flat_replace_measures), which is highly predictable. The lone deviation is flat_score_overview being noun-first, plus flat_whoami which lacks a noun but is a recognizable idiom.

Tool Count4/5

16 tools is slightly on the heavy side but each maps to a plausible, non-redundant operation in a music-score editing lifecycle (read, edit, history, export, account). Nothing feels padded, though the set could be tightened by merging the two MusicXML getters.

Completeness4/5

Create, read (overview, measures, raw XML), update (metadata, measures, text, whole-score), fork, revision history/restore, and multi-format export are all covered, so most workflows reach no dead end. The notable gap is deletion/trashing of scores (the 'trash' collection is listed but no tool moves a score there) and collaboration management.

Maintenance

ActivityMaintained
ResponsivenessNo issues