# Servidor MCP

import { Tabs, TabsList, TabsTrigger, TabsContent } from "zudoku/ui/Tabs.js";

O **MCP Server da Brasil NFe** expõe a API fiscal como ferramentas (tools), recursos (resources) e prompts via [Model Context Protocol](https://modelcontextprotocol.io). Qualquer cliente MCP — Claude Desktop, ChatGPT Apps, Cursor, Windsurf, Copilot, Zed, JetBrains AI, Continue.dev — passa a emitir **NF-e, NFC-e, NFS-e, CT-e, MDF-e e DC-e** por linguagem natural, com a mesma autenticação e os mesmos contratos da REST API.

Esta página é a referência técnica para desenvolvedores. Para a visão geral e configuração visual, veja [/ai/](https://www.brasilnfe.com.br/ai/).

> **Quer ver funcionando antes de integrar?** Abra a [demo interativa](https://api.brasilnfe.com.br/ai/chat) — um chat já conectado ao MCP da Brasil NFe, sem instalar nada.

## Endpoint e discovery

| Recurso | URL |
| --- | --- |
| MCP (JSON-RPC) | `POST https://api.brasilnfe.com.br/services/Mcp` |
| MCP (SSE stream) | `GET https://api.brasilnfe.com.br/services/Mcp` |
| Encerrar sessão | `DELETE https://api.brasilnfe.com.br/services/Mcp` |
| Manifesto MCP | `GET https://api.brasilnfe.com.br/.well-known/mcp` |
| Info / status | `GET https://api.brasilnfe.com.br/services/Mcp/info` |

**Transport:** Streamable HTTP. **Spec:** `2025-11-25` (versão atual; o `initialize` negocia fallback para `2025-06-18`, `2025-03-26` e `2024-11-05`).

## Autenticação

O servidor usa o **mesmo token de empresa** da API REST. Envie em um destes dois cabeçalhos:

```bash
Authorization: Bearer SEU_TOKEN
# ou
Token: SEU_TOKEN
```

O token identifica a empresa: o servidor resolve automaticamente CNPJ, regime tributário, certificado digital e estado de contingência em cada chamada. Cada token tem rate-limit isolado (default **60 req/min**).

## Cabeçalhos de sessão e protocolo

| Cabeçalho | Direção | Uso |
| --- | --- | --- |
| `Mcp-Session-Id` | resp / req | Devolvido no `initialize`, deve ser reenviado em chamadas subsequentes |
| `MCP-Protocol-Version` | resp | Versão negociada da spec |
| `X-Request-Id` | resp | ID único de cada chamada (auditoria) |
| `X-RateLimit-Limit` / `Remaining` / `Reset` | resp | Telemetria do rate-limit |
| `Retry-After` | resp (429) | Segundos para retry quando excede rate-limit |

## Métodos JSON-RPC suportados

| Método | Função |
| --- | --- |
| `initialize` | Abre a sessão e negocia versão + capabilities. |
| `notifications/initialized` | Confirma o fim do handshake (notificação). |
| `ping` | Health-check da sessão. |
| `tools/list` · `tools/call` | Lista e executa tools. |
| `resources/list` · `resources/templates/list` · `resources/read` | Lista e lê resources. |
| `prompts/list` · `prompts/get` | Lista e expande prompts. |
| `tasks/list` · `tasks/get` · `tasks/result` · `tasks/cancel` | Execução assíncrona de tools longas (ver *Operações longas: tasks e progress*). |
| `completion/complete` | Autocomplete de argumentos (aceito; retorna vazio nesta versão). |
| `logging/setLevel` | Ajuste de nível de log (aceito, no-op). |

As capabilities anunciadas no `initialize` são `tools`, `resources`, `prompts`, `logging`, `completions` e `tasks`. **Batch JSON-RPC não é suportado** (removido na spec `2025-06-18`): envie uma requisição por vez — um array retorna `-32600`.

## Configuração nos clientes MCP

<Tabs defaultValue="claude">
  <TabsList>
    <TabsTrigger value="claude">Claude Desktop</TabsTrigger>
    <TabsTrigger value="cursor">Cursor</TabsTrigger>
    <TabsTrigger value="windsurf">Windsurf</TabsTrigger>
    <TabsTrigger value="vscode">VS Code Copilot</TabsTrigger>
  </TabsList>

  <TabsContent value="claude">

Edite `claude_desktop_config.json` (no macOS: `~/Library/Application Support/Claude/`, no Windows: `%APPDATA%\Claude\`).

```json
{
  "mcpServers": {
    "brasilnfe": {
      "url": "https://api.brasilnfe.com.br/services/Mcp",
      "headers": {
        "Authorization": "Bearer SEU_TOKEN"
      }
    }
  }
}
```

Reinicie o Claude Desktop. As 34 tools aparecem no menu de ferramentas.

  </TabsContent>

  <TabsContent value="cursor">

Crie ou edite `.cursor/mcp.json` no seu projeto (ou em `~/.cursor/mcp.json` para uso global):

```json
{
  "mcpServers": {
    "brasilnfe": {
      "url": "https://api.brasilnfe.com.br/services/Mcp",
      "headers": {
        "Authorization": "Bearer SEU_TOKEN"
      }
    }
  }
}
```

  </TabsContent>

  <TabsContent value="windsurf">

Em `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "brasilnfe": {
      "serverUrl": "https://api.brasilnfe.com.br/services/Mcp",
      "headers": {
        "Authorization": "Bearer SEU_TOKEN"
      }
    }
  }
}
```

  </TabsContent>

  <TabsContent value="vscode">

Em `.vscode/mcp.json` (Copilot Chat com MCP habilitado):

```json
{
  "servers": {
    "brasilnfe": {
      "type": "http",
      "url": "https://api.brasilnfe.com.br/services/Mcp",
      "headers": {
        "Authorization": "Bearer SEU_TOKEN"
      }
    }
  }
}
```

  </TabsContent>
</Tabs>

## Catálogo de tools

São **34 tools** organizadas em 8 categorias. Cada uma tem `inputSchema`/`outputSchema` JSON (gerados a partir dos contratos C# da API) e anotações que orientam o cliente MCP.

### Anotações de comportamento

| Hint | Significado |
| --- | --- |
| `readOnlyHint` | A tool não muda estado. Cliente pode chamar sem confirmação. |
| `destructiveHint` | Operação irreversível (cancelamento, inutilização). Cliente deve pedir confirmação obrigatória. |
| `idempotentHint` | Múltiplas chamadas com mesmo input produzem mesmo resultado. |
| `openWorldHint` | Resultado depende de sistemas externos (SEFAZ). |

### NF-e / NFC-e

| Tool | Descrição |
| --- | --- |
| `nfe_emitir` | Emite NF-e (modelo 55) ou NFC-e (modelo 65). |
| `nfe_emitir_complementar` | NF-e complementar (finalidade=2) referenciando nota original. |
| `nfe_previsualizar` | Pré-visualização do DANFE em PDF, sem enviar à SEFAZ. |

### NFS-e

| Tool | Descrição |
| --- | --- |
| `nfse_emitir` | Emite NFS-e via Portal Nacional ou prefeitura específica. |
| `nfse_consultar` | Consulta status e dados de NFS-e por número, série e ambiente. |

### CT-e · MDF-e · DC-e · NF-EnerCom

| Tool | Descrição |
| --- | --- |
| `cte_emitir` | Emite Conhecimento de Transporte Eletrônico. |
| `cte_desacordo` | Registra desacordo do tomador (evento tipo 4). Prazo: 45 dias. |
| `mdfe_emitir` | Emite MDF-e agrupando vários CT-e/NF-e. |
| `mdfe_encerrar` | Encerra MDF-e autorizado (evento tipo 3). |
| `dce_emitir` | Emite DC-e (Declaração de Conteúdo) para PF/MEI. |
| `nfenercom_gerar_arquivo` | Gera arquivo NF-EnerCom (pré-requisito). |
| `nfenercom_emitir` | Emite NF-EnerCom (Energia Comercializada). |

### Eventos fiscais

| Tool | Descrição |
| --- | --- |
| `evento_cancelar` | Cancela NF-e, NFC-e, NFS-e, CT-e, MDF-e ou DC-e. **Destructive.** |
| `evento_carta_correcao` | CC-e em NF-e ou CT-e (evento tipo 2). Limite: 20 por nota. |
| `evento_manifestar` | Manifestação do destinatário (ciência, confirmação, desconhecimento, não realizada). |
| `evento_inutilizar` | Inutiliza faixa de numeração não utilizada. **Destructive, irreversível.** |

### Consultas SEFAZ e cadastros

| Tool | Descrição |
| --- | --- |
| `sefaz_status` | Status do serviço de autorização da SEFAZ por UF e ambiente. |
| `cadastro_consultar` | Consulta dados cadastrais na SEFAZ por CPF/CNPJ/IE e UF. |
| `cliente_consultar` | Pesquisa unificada de cliente/fornecedor no cadastro local; faz fallback para BrasilAPI (Receita Federal) quando o termo é um CNPJ válido. Suporta paginação. |
| `produto_consultar` | Pesquisa produto no cadastro por código, NCM, GTIN/EAN ou descrição. Suporta paginação. |
| `tributacao_consultar` | Lista regras de tributação da empresa (CFOP, CSTs, alíquotas ICMS/PIS/COFINS/IPI/IBS/CBS). Suporta paginação. |
| `nota_listar` | Lista NF-e/NFC-e/NFS-e emitidas ou recebidas em um intervalo. |
| `imposto_calcular` | Simula ICMS, PIS, COFINS, IPI, ST sem emitir nota. |

### Cadastros

| Tool | Descrição |
| --- | --- |
| `cliente_criar` | Cadastra novo cliente (destinatário/fornecedor/transportadora). Recusa duplicata por `CpfCnpj`. |
| `cliente_editar` | Atualiza cliente existente. Exige `Id`; envie payload completo (campos omitidos são zerados). |
| `produto_criar` | Cadastra novo produto. NCM aceito com 7 ou 8 dígitos (zero-pad automático); EAN/GTIN validado por dígito verificador. |
| `produto_editar` | Atualiza produto existente. Exige `Id`; envie payload completo. |
| `tributacao_criar` | Cadastra regra de tributação (CFOP + CSTs + alíquotas). `CstIbsCbs` obrigatório (Reforma Tributária). |
| `tributacao_editar` | Atualiza regra de tributação existente. Exige `Id`; envie payload completo. |

### Arquivos · Downloads

| Tool | Descrição |
| --- | --- |
| `arquivo_baixar` | XML ou PDF/DANFE de uma nota por chave. Retorna em base64. |
| `arquivo_baixar_evento` | Arquivo de evento por chave + sequencial. |
| `arquivo_baixar_periodo` | Exporta XMLs/PDFs de um período em ZIP base64 (long-running). |

### Auxiliares

| Tool | Descrição |
| --- | --- |
| `fci_gerar` | Gera FCI (Ficha de Conteúdo de Importação). |
| `health` | Health-check da API. |

## Resources

Resources são leituras estáveis identificadas por URI no esquema `brasilnfe://`. O agente lê resources antes de tomar decisões (ex: confirmar emitente antes de emitir).

| URI | Conteúdo |
| --- | --- |
| `brasilnfe://empresa/atual` | Snapshot da empresa do token (razão social, CNPJ, IE, regime, contingência). |
| `brasilnfe://nfe/{chave}/xml` | XML autorizado de uma NF-e/NFC-e emitida. |
| `brasilnfe://nfe/{chave}/danfe` | DANFE em PDF. |
| `brasilnfe://nfe-entrada/{chave}/xml` | XML de NF-e recebida (entrada). |
| `brasilnfe://nfe-entrada/{chave}/danfe` | DANFE de NF-e recebida. |
| `brasilnfe://evento/{chave}/{tipoArquivo}` | XML (1) ou PDF (2) de evento (CC-e, cancelamento, manifestação). |

Os resources com placeholders (`{chave}`, `{tipoArquivo}`) são listados em `resources/templates/list`.

## Prompts prontos

São 5 fluxos guiados (templates de mensagem) que o cliente MCP exibe como ações de um clique. Cada um valida regras fiscais antes de chamar a tool correspondente.

| Prompt | Argumentos | O que faz |
| --- | --- | --- |
| `emitir_nfe_simples` | `cnpjCliente*`, `descricaoProduto*`, `valor*`, `ambiente`, `naturezaOperacao` | Guia o agente a emitir NF-e modelo 55, lendo `empresa/atual` e validando SEFAZ antes. |
| `cancelar_nota` | `chave`, `numeroNFSe`, `justificativa*` | Valida prazo legal e tamanho da justificativa antes de chamar `evento_cancelar`. |
| `diagnostico_emissao` | `uf` | Verifica empresa, SEFAZ e contingência. Conclui com PRONTO ou ATENÇÃO. |
| `relatorio_periodo` | `dataInicio*`, `dataFim*`, `modeloDocumento` | Lista notas, agrupa por status, identifica top 5 destinatários. |
| `carta_correcao` | `chave*`, `correcao*` | Valida o que pode ser corrigido (não permite valores, datas, partes, série). |

## Exemplo end-to-end

### 1. Initialize

```bash
curl -X POST "https://api.brasilnfe.com.br/services/Mcp" \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-11-25",
      "capabilities": {},
      "clientInfo": { "name": "meu-app", "version": "1.0" }
    }
  }'
```

A resposta inclui `serverInfo`, `capabilities` e `instructions`. **Anote o `Mcp-Session-Id`** dos response headers — ele é obrigatório nas próximas chamadas.

### 2. Listar tools

```bash
curl -X POST "https://api.brasilnfe.com.br/services/Mcp" \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Mcp-Session-Id: SESSAO_DEVOLVIDA" \
  -H "Content-Type: application/json" \
  -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'
```

### 3. Chamar tool

```bash
curl -X POST "https://api.brasilnfe.com.br/services/Mcp" \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Mcp-Session-Id: SESSAO_DEVOLVIDA" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "sefaz_status",
      "arguments": { "Uf": "SP", "TipoAmbiente": 2 }
    }
  }'
```

### 4. Ler resource

```bash
curl -X POST "https://api.brasilnfe.com.br/services/Mcp" \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Mcp-Session-Id: SESSAO_DEVOLVIDA" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 4,
    "method": "resources/read",
    "params": { "uri": "brasilnfe://empresa/atual" }
  }'
```

## Códigos de erro JSON-RPC

| Código | Significado |
| --- | --- |
| `-32700` | Parse error (JSON inválido) |
| `-32600` | Invalid Request (formato JSON-RPC inválido, batch ou corpo vazio) |
| `-32601` | Method not found |
| `-32602` | Invalid params (parâmetro obrigatório ausente, URI mal formada, etc.) |
| `-32603` | Internal error |
| `-32001` | Auth required (token ausente) |
| `-32002` | Auth invalid (token não identifica a empresa) |
| `-32003` | Rate limited (com `data.retryAfterSeconds`) |

Os códigos `-32004` (session required) e `-32005` (session expired) são reservados para erros de sessão.

## Operações longas: tasks e progress

Tools longas (anotadas como `LongRunning`, ex: `arquivo_baixar_periodo`) podem ser executadas de duas formas.

### Progress por SSE

Envie `_meta.progressToken` no `tools/call` e mantenha aberto um `GET /services/Mcp` com o mesmo `Mcp-Session-Id`. O servidor emite `notifications/progress` a cada 5 segundos até a tool concluir.

### Execução assíncrona (tasks)

Para não bloquear a chamada, inclua um objeto `task` no `params` do `tools/call`. O servidor registra a operação em background e devolve **imediatamente** um descritor de task; o resultado é buscado depois.

- Só tools `LongRunning` aceitam `task`. Em qualquer outra, o campo retorna erro (`taskSupport=forbidden`).
- TTL default **600s**, máximo **3600s** (`task.ttl` em ms). Até **50 tasks** simultâneas por empresa.
- Status possíveis: `working`, `input_required`, `completed`, `failed`, `cancelled`. Enquanto não-terminal, o descritor traz `pollInterval` (ms).
- Mudanças de status também são empurradas por SSE via `notifications/tasks/status`.

| Método | Função |
| --- | --- |
| `tasks/get` | Status atual da task (não bloqueia). |
| `tasks/result` | Faz long-poll (até 90s) e devolve o resultado da tool quando a task fica terminal. |
| `tasks/list` | Lista as tasks da empresa autenticada. |
| `tasks/cancel` | Cancela uma task ainda em execução. |

```json
// tools/call assíncrono: inclua "task" no params
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "arquivo_baixar_periodo",
    "arguments": { "DataInicio": "2026-01-01", "DataFim": "2026-01-31" },
    "task": { "ttl": 900000 }
  }
}
```

A resposta traz `result.task` com `taskId` e `status: "working"`. Para colher o resultado:

```json
{ "jsonrpc": "2.0", "id": 6, "method": "tasks/result", "params": { "taskId": "SEU_TASK_ID" } }
```

## Auditoria

Cada `tools/call`, `resources/read` e `prompts/get` registra: timestamp UTC, request id, sessão, empresa, método, tool/resource/prompt, latência em ms, sucesso/erro. Os logs ficam acessíveis pelo painel da Brasil NFe.

## Boas práticas para produção

1. **Sempre leia `brasilnfe://empresa/atual` antes da primeira emissão** da sessão para confirmar emitente e regime.
2. **Use o prompt `diagnostico_emissao` antes de operações em massa** — ele valida SEFAZ e contingência.
3. **Default para `tipoAmbiente: 2` (homologação)** em qualquer integração nova; promova para produção (`1`) deliberadamente.
4. **Ajuste o rate-limit no app.config** (`Mcp:RateLimit:RequestsPerMinute`) conforme volume.
5. **Mantenha o log de auditoria do MCP integrado ao seu SIEM** — todo `tools/call` é rastreável por `requestId` + `sessionId`.
6. **Encerre sessões ociosas com `DELETE /services/Mcp`** + `Mcp-Session-Id` para liberar recursos.
