shiwake-mcp
Teste de lançamentos contábeis (JET) para auditorias contábeis. 11 regras de triagem, zero dependências.
Documentação
shiwake-mcp
Servidor MCP que realiza a triagem inicial de dados de lançamentos contábeis. Zero dependências de bibliotecas.
Recebe lançamentos do razão geral, aplica 15 regras e os retorna ordenados pela ordem em que um humano deve revisá-los primeiro. É o chamado Teste de Lançamentos (Journal Entry Testing) do campo de auditoria, disponibilizado para ser chamado por agentes de IA.
Por que não ter dependências de bibliotecas
Não há nenhum item incluído via npm install. O dependencies do package.json está vazio.
Adicionar dependências externas a uma ferramenta que lida com dados contábeis faz com que, a cada implantação, seja necessário explicar "o que este pacote faz". Ao operar em redes de firmas de auditoria ou escritórios de contabilidade, esse custo de explicação acaba sendo maior do que o esforço de implementação. Com zero dependências, o código que precisa ser lido fica contido apenas neste repositório.
O transporte stdio do MCP é JSON-RPC 2.0 separado por linhas. Dá para escrever em cerca de 200 linhas sem usar SDK.
Como executar
É necessário Node.js 20 ou superior.
Conectar como servidor MCP
Como está publicado no npm, você pode iniciá-lo com npx. Não é necessária instalação prévia. O único pacote baixado é este. Como não há dependências, nada mais é instalado.
No Claude Code, basta uma linha.
claude mcp add shiwake -- npx -y shiwake-mcp
Adicionar --scope project antes do nome grava a configuração em .mcp.json na raiz do projeto, permitindo o compartilhamento com a equipe.
No Claude Desktop, adicione ao arquivo de configuração (claude_desktop_config.json).
{
"mcpServers": {
"shiwake": {
"command": "npx",
"args": ["-y", "shiwake-mcp"]
}
}
}
Se quiser fixar a versão, especifique algo como shiwake-mcp@0.1.0. Se preferir revisar o código antes de executar, clone o repositório e aponte diretamente para "command": "node" e "args": ["/path/to/shiwake-mcp/src/server.js"].
Razões grandes: envie por arquivo
Para razões com centenas de registros, passe o caminho do arquivo em vez de listar os lançamentos na conversa. Se os lançamentos forem enviados pela conversa, a IA precisará reproduzir tudo, o que é inviável para dezenas de milhares de registros.
As pastas que o servidor pode ler são definidas na inicialização com --data-dir (pode ser especificado várias vezes; também é possível usar a variável de ambiente SHIWAKE_DATA_DIR).
claude mcp add shiwake -- npx -y shiwake-mcp --data-dir /path/to/ledgers
No Claude Desktop, use "args": ["-y", "shiwake-mcp", "--data-dir", "C:\\audit\\ledgers"].
Arquivos fora das pastas especificadas não são abertos, mesmo que a IA forneça o caminho. Se um link simbólico ou junção apontar para fora, a verificação é feita no destino e o arquivo não é lido.
Depois, basta pedir algo como "analise 2025年度_仕訳帳.csv com screen_journals" e o file será passado para a ferramenta. Caminhos relativos têm como base a primeira pasta especificada. São aceitos .json e .csv (UTF-8 e Shift_JIS), com limite de 256MB. Em medições locais, 380 mil registros (CSV de 76MB) levaram cerca de 9 segundos, com resposta de aproximadamente 80 mil caracteres.
Teste primeiro localmente
Ao clonar o repositório, você pode verificar o comportamento com os dados de exemplo inclusos (383 registros sintéticos, com anomalias conhecidas misturadas). npm install não é necessário.
git clone https://github.com/USHIKUNDESUYO/shiwake-mcp.git
cd shiwake-mcp
npm run demo
検査対象 383 件
検出 54 件 / 対象仕訳 25 件
重要度 high 13 / medium 16 / low 25
ベンフォード MAD 0.012241 → 許容の限界(n=383)
ルール別:
営業時間外の入力 11 件
キリのよい金額 9 件
!! 承認限度額の直下 7 件
! 重複仕訳 5 件
!! 起票者と承認者が同一 4 件
! 期末直前の大口計上 4 件
! 計上日と入力日の乖離 3 件
! 稀な勘定科目の組み合わせ 3 件
休日の計上 3 件
!! 貸借不一致 2 件
摘要が空 2 件
! 期末後の入力 1 件
確認の優先順位(上位 20 件):
[ 23] JV-0382 2025-09-06 3000000 self_approval, rare_account_pair, weekend_or_holiday, after_hours, round_amount, missing_description
[ 19] JV-0365 2026-03-30 8900000 self_approval, period_end_large, after_hours, round_amount
開発委託費
[ 17] JV-0362 2026-01-22 1200000 unbalanced, rare_account_pair, round_amount
業務委託費計上
(以下省略)
383 registros são reduzidos a 25. A pontuação é a soma da importância de cada regra; lançamentos que acionam múltiplas regras simultaneamente ficam mais acima.
Ferramentas
| Ferramenta | O que retorna |
|---|---|
screen_journals | Aplica todas as regras e retorna a lista ordenada por risco |
check_balance | Lançamentos com débito e crédito divergentes e a diferença |
benford_analysis | Distribuição do primeiro dígito dos valores, MAD, χ² |
detect_duplicates | Grupos de lançamentos exatamente idênticos |
list_rules | Lista das regras implementadas e sua finalidade |
Todas as ferramentas declaram, por meio das anotações de ferramentas do MCP, que são "somente leitura (readOnlyHint) e não acessam nada externo (openWorldHint: false)". Nada é alterado nem enviado a serviços externos.
Os lançamentos são passados em journals ou, alternativamente, o caminho do arquivo é informado via file (seção anterior).
As detecções individuais (findings) retornadas por screen_journals referem-se apenas aos top lançamentos de maior pontuação (padrão: 50). A contagem de ocorrências é sempre calculada sobre o total. Se precisar de tudo, passe allFindings: true. As listas de check_balance e detect_duplicates também são limitadas a 200 itens por padrão.
Os lançamentos de entrada podem estar no formato simplificado ou no formato detalhado.
{
"id": "JV-0001",
"date": "2026-03-31",
"entered_at": "2026-04-02T23:41:00+09:00",
"debit_account": "売掛金",
"credit_account": "売上高",
"amount": 12000000,
"description": "3月度売上計上",
"created_by": "acc01",
"approved_by": "mgr01"
}
Itens que geram mais linhas, como impostos sobre consumo ou lançamentos compostos, devem ser enviados no formato detalhado.
{
"id": "JV-0002",
"date": "2026-03-31",
"lines": [
{ "account": "外注費", "debit": 1000000 },
{ "account": "仮払消費税", "debit": 100000 },
{ "account": "買掛金", "credit": 1100000 }
]
}
Se houver pelo menos um lançamento ilegível, por padrão o processamento é interrompido e é retornado em qual posição e onde está o problema. Para ignorar linhas ilegíveis e continuar, passe skipInvalid: true. As linhas ignoradas são retornadas em invalidRows com a posição, o número do comprovante e o motivo.
entered_at aceita apenas a data. Nesse caso, é usado para "divergência entre data de contabilização e data de entrada", mas não para "entrada fora do horário comercial".
Como ler o CSV
Você pode enviar diretamente o CSV exportado do software contábil. Os nomes das colunas são identificados automaticamente entre os candidatos a seguir. Diferenças entre caracteres de largura total e meia largura, espaços e anotações entre parênteses, como "(税込)", são ignoradas.
| Item | Candidatos a nome de coluna |
|---|---|
| Número do comprovante | 伝票番号・伝票No・仕訳番号・取引番号・No, etc. |
| Data | 日付・取引日・計上日・伝票日付・仕訳日, etc. |
| Data/hora de entrada | 入力日時・登録日時・作成日時・入力日, etc. |
| Conta débito / conta crédito | 借方勘定科目・借方科目, 貸方勘定科目・貸方科目 |
| Valor | 借方金額 e 貸方金額, ou 金額 |
| Descrição | 摘要・内容 |
| Elaborador / aprovador | 入力者・起票者・作成者, 承認者 |
Colunas não identificadas podem ser especificadas com columns (exemplo: { "date": "伝票日付", "amount": "金額(税込)" }). As colunas utilizadas são informadas em source.columnsUsed na resposta; confira antes de interpretar os resultados.
Considera-se o formato com débito e crédito na mesma linha; linhas com o mesmo número de comprovante e data são agrupadas em um único lançamento. O termo "諸口" (diversos), usado como contrapartida em lançamentos compostos, é removido quando débito e crédito são iguais dentro do mesmo comprovante. Se não forem iguais, é mantido para não ocultar divergências entre débito e crédito.
Datas como 2026/3/31, 20260331, 2026年3月31日, R8.3.31, 令和8年3月31日, etc., são reconhecidas. Separadores de milhar e o símbolo de iene são removidos; △ e parênteses são tratados como números negativos (valores negativos interrompem o processamento por padrão). Mesmo que haja uma linha de título antes do cabeçalho, a linha do cabeçalho é localizada e os dados são lidos. Erros e exclusões são informados pelo número da linha no CSV.
O "formato de importação Yayoi" do Yayoi Kaikei (CSV de 25 ou 27 itens sem linha de cabeçalho) é identificado pelo flag no primeiro item e lido pela posição das colunas. Os códigos 2000 e 2111 representam um lançamento por linha; linhas de 2110 a 2101 são agrupadas em um único lançamento. A data da transação pode estar em 20260331, 2026/3/31 ou R08/03/31. A ordem das colunas segue a tabela "Itens e formato de descrição dos dados de lançamentos" do suporte do Yayoi Kaikei. Esse formato não possui coluna de data/hora de entrada, portanto as três regras que usam data/hora de entrada (divergência entre data de contabilização e data de entrada, entrada após o fim do período e entrada fora do horário comercial) não são aplicadas.
Regras
| ID | Conteúdo | Importância | O que indica |
|---|---|---|---|
unbalanced | Divergência entre débito e crédito | alta | Entrada manual, falha de importação ou alteração |
self_approval | Elaborador e aprovador são a mesma pessoa | alta | Segregação de funções ineficaz |
threshold_avoidance | Logo abaixo do limite de aprovação | alta | Evasão de aprovação por lançamentos fracionados |
duplicate | Lançamentos duplicados | média | Dupla contabilização ou lançamento periódico legítimo |
reversal | Lançamentos de estorno/correção | média | Estorno ou correção de erro; pares que cruzam o fim do período exigem verificação de atribuição temporal |
backdated | Divergência entre data de contabilização e data de entrada | média | Erro de atribuição temporal, contabilização retroativa |
post_period_entry | Entrada após o fim do período | média | Ajustes após o fechamento; costuma revelar controles ineficazes |
period_end_large | Lançamento de grande valor pouco antes do fim do período | média | Se houver ajuste de resultados, aparece nesta janela |
rare_account_pair | Combinação incomum de contas | média | Processamento fora do fluxo normal de transações |
weekend_or_holiday | Lançamento em feriado | baixa | Processamento fora do ciclo de trabalho |
after_hours | Entrada fora do horário comercial | baixa | Fraco isoladamente, mas relevante quando combinado |
round_amount | Valores redondos | baixa | Estimativas, aproximações, reclassificações |
missing_description | Descrição vazia | baixa | Qualidade como trilha de auditoria |
description_keyword | Palavras-chave na descrição | baixa | Ajustes posteriores, contabilizações com conteúdo indefinido |
voucher_gap | Números de comprovante ausentes | baixa | Comprovantes excluídos/cancelados, falha de exportação |
As premissas são passadas opcionalmente.
{
"fiscalYearEnd": "03-31",
"businessHours": [9, 18],
"holidays": ["2026-01-01", "2026-01-12"],
"approvalThresholds": [1000000, 5000000],
"backdatedDaysThreshold": 30
}
Se approvalThresholds e fiscalYearEnd não forem fornecidos, as regras correspondentes não são aplicadas. A decisão é parar explicitamente em vez de deixar regras irrelevantes gerarem falsos positivos.
"Lançamento em feriado" exclui por padrão lançamentos com data de fim de mês. Isso porque lançamentos de ajuste mensais ou de encerramento costumam ser datados no fim do mês, mesmo em fins de semana. Em anos como o período fiscal encerrado em março de 2024, quando 31 de março caiu num domingo, sem essa exclusão todos os ajustes de encerramento seriam sinalizados. Para incluir também o fim do mês, passe exemptMonthEnd: false.
"Lançamento em feriado" considera automaticamente, além de sábados e domingos, os feriados japoneses (incluindo feriados compensatórios e dias de descanso nacional, de 2000 a 2099). Os feriados são calculados a partir das disposições da Lei de Feriados, sem importar a lista do Gabinete. A conformidade com a lista do Gabinete foi verificada para todos os dias de 2000 a 2027. Feriados específicos da empresa, como o período de Ano-Novo, podem ser adicionados com holidays. Para razões fora do Japão, passe japaneseHolidays: false.
"Lançamentos duplicados" e "combinação incomum de contas" comparam as contas de débito e crédito após ordená-las. A ordem das linhas de detalhe não afeta o resultado.
"Entrada após o fim do período" identifica lançamentos com data anterior ou igual ao fim do período, mas inseridos após essa data. Ajustes de encerramento e correções pós-fechamento aparecem aqui. "Divergência entre data de contabilização e data de entrada" só captura atrasos superiores a 30 dias por padrão; atrasos curtos, como um lançamento datado de 31 de março inserido em 10 de abril, são capturados por esta regra. Ela só é ativada quando fiscalYearEnd e entered_at estão presentes.
"Lançamentos de estorno/correção" retorna pares de lançamentos com o mesmo valor e contas invertidas entre débito e crédito, dentro de 30 dias (reversalWindowDays), indicando o número do comprovante da contraparte em ambos. Cada lançamento entra em apenas um par. Pares que cruzam o fim do período recebem essa observação no motivo, mas a importância não é aumentada, pois lançamentos de reabertura no início do período têm o mesmo formato.
As palavras-chave padrão de "palavras-chave na descrição" são "修正", "訂正", "取消", "調整", "仮計上" e "不明". Elas podem ser substituídas com descriptionKeywords; passar um array vazio desativa a regra. O caractere "仮" isolado não está incluído por padrão, pois capturaria muitos casos como adiantamentos.
"Comprovantes ausentes" separa o número do comprovante em prefixo e sufixo numérico (JV-0382 → JV- e 382) e procura lacunas na sequência para cada prefixo. Como o que falta é o próprio lançamento, isso não entra na pontuação dos lançamentos vizinhos; é retornado como uma lista de números ausentes. Números com mais da metade da faixa ausente são considerados como não sequenciais e ignorados. Lançamentos sem número de comprovante também são ignorados.
Sobre a análise de Benford
Os limites de MAD usam os valores da Tabela 5.1 de Nigrini, M. J. Benford's Law (Wiley, 2012). São valores amplamente citados na prática, mas não são definidos por lei ou normas de auditoria.
Se a amostra tiver menos de 300 itens, uma observação é adicionada ao resultado, pois esses limites pressupõem amostras grandes.
Além disso, Benford é uma ferramenta para observar propriedades da população, não para julgar lançamentos individuais. Mesmo que a distribuição esteja distorcida, isso normalmente pode ser explicado pela natureza do negócio (preços fixos, preços regulados, setores com muitas transações de baixo valor).
Limitações desta ferramenta
A detecção não é evidência de fraude. Todas as regras capturam muitos processamentos legítimos. A maioria dos lançamentos duplicados são lançamentos periódicos mensais de mesmo valor, e grandes valores no fim do período são normais em negócios que reconhecem receita no encerramento.
O que esta ferramenta faz é apenas decidir por onde começar a examinar a população. Avaliar os lançamentos detectados continua sendo trabalho humano.
A seguir, o que esta ferramenta não faz:
- Substituir procedimentos de auditoria em si (não é possível obter evidência de auditoria suficiente e adequada com ela)
- Concluir sobre a existência ou não de fraude
- Julgar a validade substantiva das contas
- Determinar o tratamento tributário
Não pode ser usada como base para formar opinião de auditoria ou para declarações fiscais.
Tratamento de dados reais
O conteúdo de examples/ são dados sintéticos. Como são gerados com semente fixa, node examples/generate.js produz sempre os mesmos arquivos, independentemente de quantas vezes for executado.
.gitignore exclui *.csv, *.xlsx, journals.json e /data/. É uma proteção para evitar o commit de dados reais de lançamentos.
O servidor em si não acessa a rede. Ele lê apenas o stdin e, dentro das pastas permitidas na inicialização via --data-dir, arquivos .json e .csv. A saída é apenas pelo stdout; nada é gravado em arquivos.
Testes
npm test
São executados 107 testes. Os testes do servidor MCP são escritos para iniciar o servidor como processo filho e enviar JSON-RPC de fato.
O CI roda em Node 20 / 22 / 24. Além dos testes, verifica-se que nenhuma dependência foi adicionada, que package-lock.json não foi gerado e que os dados de exemplo com semente fixa permanecem idênticos após regeneração. Zero dependências é uma premissa deste repositório, protegida pelo CI e não apenas pela atenção humana.
Artigo explicativo
A motivação e as decisões de design deste servidor estão documentadas em um artigo.
Licença
MIT
Autor
Hoshino Ushio (Contador Público Certificado e tributarista)