Skip to main content
Glama
JoseTorquato

fiscal-mcp

by JoseTorquato

fiscal-mcp

Documento fiscal brasileiro como ferramenta de agente. Valide NF-e e NFS-e antes de transmitir — sem certificado, sem cadastro, sem enviar nada para lugar nenhum.

MIT Python 3.11+ 289 testes

pip install "fiscal-mcp[xsd]"
fiscal-mcp validar nota.xml
  [erro] ibs-cclasstrib-prefixo-cst
      cClassTrib não corresponde ao CST do item
      item 2: imposto/IBSCBS/cClassTrib = '000123' não começa por
              imposto/IBSCBS/CST = '200'
      → Os três primeiros dígitos do cClassTrib são o CST do item. Este é o erro
        mais comum ao ligar o módulo de IBS/CBS num ERP.

  [erro] schema-elemento-fora-de-ordem
      cEAN apareceu onde o leiaute espera xProd
      item 1, linha 62 do XML
      → O schema da NF-e exige a sequência exata do leiaute — trocar a ordem
        reprova mesmo com todos os campos presentes.

  2 erro(s), 0 aviso(s)

Três camadas, num laudo só: schema XSD oficial, regras fiscais e chave de acesso. Tudo local — o processo não abre socket, e há teste que prova.


Por que existe

Rejeição da SEFAZ chega tarde, custa uma transmissão e vem com mensagem críptica. Boa parte dos motivos é aritmética simples ou campo fora de formato — coisa que dá para pegar antes de enviar, na sua própria máquina.

E agora tem prazo: desde 3 de agosto de 2026, documentos fiscais do regime regular precisam trazer os campos de IBS e CBS, e notas sem eles podem ser rejeitadas (CGIBS).

Enquanto isso, um agente de IA consegue mexer no seu Notion e no seu GitHub, mas não sabe ler uma nota fiscal.

Related MCP server: brasil-mcp-essentials

O que ele faz

Ferramenta

O que faz

validar_nfe

schema XSD oficial, regras fiscais (IBS/CBS incluso), totais e chave — com o que fazer em cada achado

explicar_nfe

resumo estruturado do XML, em vez do documento inteiro

validar_nfse

NFS-e do padrão nacional: estrutura, DPS embutida, prestador, serviço

explicar_nfse

resumo estruturado da NFS-e

explicar_rejeicao

código da SEFAZ → significado → ação, e se é reversível

validar_chave_acesso

decompõe os 44 dígitos da NF-e e confere o dígito verificador

validar_chave_nfse

decompõe os 50 dígitos da NFS-e nacional

listar_rejeicoes_conhecidas

o que o catálogo cobre

Nenhuma delas assina, transmite, emite ou cancela documento. Não existe caminho, nesta versão, para causar efeito fiscal — e um teste verifica isso a cada mudança.

Como usar

Na linha de comando

fiscal-mcp validar nota.xml          # NF-e ou NFS-e, ele descobre sozinho
fiscal-mcp validar nota.xml --json   # para script e CI
fiscal-mcp validar nota.xml --sem-schema
fiscal-mcp explicar nota.xml         # resumo estruturado
fiscal-mcp chave 4326081234...       # 44 dígitos (NF-e) ou 50 (NFS-e)
fiscal-mcp rejeicao 539              # traduz o código da SEFAZ
fiscal-mcp rejeicao                  # lista o catálogo
fiscal-mcp tabelas                   # qual tabela oficial está embarcada

Sai com código 1 quando encontra erro, então serve direto em CI.

Como servidor MCP

pip install "fiscal-mcp[servidor,xsd]"

Copie e cole no seu cliente. Claude Code:

claude mcp add fiscal -- fiscal-mcp-servidor

Claude Desktop (claude_desktop_config.json), Cursor (.cursor/mcp.json), VS Code e a maioria dos outros:

{
  "mcpServers": {
    "fiscal": { "command": "fiscal-mcp-servidor" }
  }
}

Sem instalar Python — útil para quem trabalha com ERP em Delphi ou C#:

{
  "mcpServers": {
    "fiscal": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/josetorquato/fiscal-mcp"]
    }
  }
}

Aí é só perguntar ao agente: "esse XML está pronto para transmitir?"

O que ele não faz

Escrito antes das perguntas, porque prometer demais é o jeito mais rápido de perder a confiança de quem trabalha com fiscal:

  • Não emite, não assina, não transmite. Sem certificado digital envolvido.

  • Passar aqui não garante autorização. É validação local: pega o erro previsível, não substitui a SEFAZ.

  • A validação por schema exige o extra [xsd]. Sem ele, o laudo diz que essa camada não rodou — nunca finge que rodou.

  • NFS-e só no padrão nacional. Município com padrão próprio não é reconhecido (ADR-0006).

  • Não verifica dígito verificador de NFS-e — o algoritmo não foi confirmado, e chutar produziria acusação falsa.

  • Não valida assinatura digital. Documento não assinado nunca passa no XSD oficial; o laudo diz isso como informação, não como erro.

  • Não dá conselho tributário. CFOP, CST e alíquota são do seu contador.

Estado da validação, por documento

Camadas

Regras

Testado contra

NF-e / NFC-e

schema XSD + regras + chave

28

duas NF-e reais autorizadas em produção, 17 amostras públicas e XML sintético

NFS-e nacional

regras + chave

10

✅ uma nota autorizada de verdade

Contra nota real, autorizada em produção

Em 26/08/2026 o validador rodou em duas NF-e reais, ambas autorizadas pela SEFAZ em ambiente de produção:

Nota

Grupo IBS/CBS

Erros

Avisos

emitida em 26/08/2026

presente e preenchido

0

0

emitida em 09/04/2026

ausente (anterior ao grupo)

0

1 — ibs-grupo-ausente

A primeira é o caso que importa: uma nota da reforma, aceita pela SEFAZ, passou limpa nas 28 regras e no XSD oficial. Qualquer achado ali seria falso positivo por definição. A segunda mostra o outro lado — a ferramenta não reprovou uma nota pré-reforma, apontou a ausência como aviso, que é a leitura correta da postergação da UB12-10.

Que as regras não estavam apenas dormentes foi verificado por contraprova: corrompendo o cClassTrib da nota real, três regras disparam; corrompendo o CST, duas.

O que isso ainda não cobre. Duas notas, de um item cada, do mesmo emissor, no caminho tributado normal. Monofasia (CST 620), redução de alíquota, crédito presumido e ajuste de competência continuam testados só contra fixture. A regra ibs-subgrupos-obrigatorios segue como aviso até rodar contra três XMLs reais distintos sem falso positivo — o contrato está no CHANGELOG.

Tem nota real para contribuir? Continua sendo o que mais ajuda, e agora tem ferramenta para isso: python scripts/anonimizar.py nota.xml.

Contra o corpus público

As 17 amostras MIT da nfelib têm estrutura de documento real — 15 passam com zero erros, e as duas que não passam são explicáveis: uma é inválida no XSD oficial de propósito, a outra tem valores de preenchimento incoerentes entre si (vIBS = 0 com vIBSUF = 16). Nenhuma regra de tabela acusa nenhuma delas, e há teste que trava isso.

Das 28 regras de NF-e, 17 são da Camada A de IBS/CBS: CST e cClassTrib conferidos contra a tabela oficial embarcada da SVRS — 18 CST e 164 classificações, versionadas no repositório com URL de origem, data e sha256 (procedência). Mais aritmética por item, exclusividade de regime, presença condicional e as alíquotas de transição de 2026.

fiscal-mcp tabelas diz qual versão da tabela está embarcada. Quem valida contra tabela precisa saber contra qual.

A regra de IBS/CBS emite aviso, não erro: a NT 2025.002 v1.51 reclassificou a regra de rejeição correspondente (UB12-10) como implementação futura, então a nota não é recusada por isso hoje. Ela carrega data de reavaliação, e um teste falha quando essa data passa. Acusar errado é pior que não acusar.

Tem um XML real que pode compartilhar? É a contribuição mais valiosa possível agora — abra uma issue com os dados trocados por fictícios.

Escrever uma regra

Regras são dados, não código. Absorver uma nota técnica deveria ser editar um YAML — e é:

- id: tot-produtos-confere
  tipo: soma_itens
  severidade: erro          # erro | aviso | informacao
  campo_item: prod/vProd
  campo_total: total/ICMSTot/vProd
  tolerancia: "0.01"
  mensagem: O total de produtos não bate com a soma dos itens
  acao: >
    Some o vProd de cada item e compare com total/ICMSTot/vProd.

Tipos disponíveis: existe, nao_vazio, valor_em, formato, soma_itens, condicional.

Escopo. Por padrão a regra roda uma vez, na raiz da nota. Com escopo: item ela roda uma vez por item, com os caminhos relativos ao det — e o achado diz qual item, pelo nItem:

- id: ibs-grupo-ausente
  tipo: existe
  escopo: item              # documento (padrão) | item
  campo: imposto/IBSCBS

Caminho absoluto. Num escopo: item, o caminho que começa com / vale a partir da raiz da nota. É o que permite uma regra olhar o item e algo fora dele ao mesmo tempo:

- id: ibs-totais-presentes
  tipo: condicional
  escopo: item
  quando_campo: imposto/IBSCBS/CST     # relativo ao item
  campo: /total/IBSCBSTot              # a partir da raiz

Vigência. Regra que ainda não estabilizou declara quando será reavaliada. Não é comentário: um teste falha quando a data passa, e é assim que a manutenção deixa de depender de memória.

  vigencia:
    reavaliar_em: "2026-09-01"
    fonte: "Ato Técnico Conjunto RFB/CGIBS nº 1, de 31/07/2026"

Todo achado precisa de acao. Quem lê é um agente que vai tentar de novo — erro sem ação vira loop de retry ou nota duplicada. Um teste falha se alguma regra não tiver.

Contribuir

O que mais ajuda, em ordem:

  1. XML real anonimizado — principalmente NF-e, e municípios de NFS-e diferentes.

  2. Código de rejeição que você levou e não está no catálogo.

  3. Regra nova em regras/, com as duas fixtures.

  4. Leitura da seção 7 da NT 2025.002-RTC v1.51 — o leiaute de IBS/CBS já está mapeado; o que falta confirmar em fonte primária são os códigos de rejeição, e nenhum entra aqui sem leitura humana.

Antes de abrir PR, leia o CONTRIBUTING. Há uma regra sem exceção: PR com dado fiscal real identificável é fechado sem merge.

Como isso vai crescer

O produto é a validação: o validador mais fundo que existe para NF-e, que roda offline e que você pode conferir antes de transmitir. Emissão está suspensa, com gatilho escrito — ver ADR-0011. O que vem depois, e por que nesta ordem, está escrito:

Documento

Para quê

ROADMAP.md

as fases e o critério de saída de cada uma

BACKLOG.md

as tarefas, priorizadas

docs/adr/

as decisões e por que foram tomadas assim

docs/spec/

o produto em detalhe

Três decisões que explicam o resto:

  • ADR-0011 — validação é o produto; emissão sai do caminho crítico e só volta se um gatilho nomeado disparar.

  • ADR-0008 — não escrevo integração com SEFAZ antes de saber que existe quem pague pela manutenção.

  • ADR-0005 — certificado digital de cliente não passa pela minha infra. O A1 é a identidade jurídica da empresa.

Licença

MIT — código e regras.


Feito por José Torquato, que também mantém o Cilada.

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
2Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server for electronic invoicing that enables generating, validating, and parsing Factur-X and ZUGFeRD compliant XML invoices. It supports the French 2026 B2B reform and provides integration with Chorus Pro for automated invoice submission and status tracking.
    23
    1
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Model Context Protocol (MCP) server for Brazilian Electronic Invoicing (NF-e / NFC-e, modelo 55/65, schema 4.00). Provides CPF/CNPJ validation tools, with NF-e/NFC-e generation and SEFAZ integration planned.
    22
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that lets AI agents issue Brazilian NFS-e service invoices via Focus NFe, with tools for creating, querying, and canceling invoices.
    MIT

View all related MCP servers

Related MCP Connectors

  • Brazilian fiscal MCP server - issue NF-e, NFC-e, NFS-e, CT-e, MDF-e and DC-e via SEFAZ.

  • Brazilian SEFAZ e-invoices (NF-e, CT-e) issued against your company. A1 cert, DANFE PDF.

  • A paid remote MCP for hosted MCP server, built to return verdicts, receipts, usage logs, and audit-r

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JoseTorquato/fiscal-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server