SooTool
Servidor de cálculo determinístico exclusivamente decimal para uso de ferramentas LLM.
Documentação
SooTool
MCP de cálculo de precisão para uso por LLMs.
Servidor MCP que assume os cálculos no lugar do LLM. Executa com precisão Decimal cálculos de impostos, folha de pagamento, finanças, estatística e engenharia, e retorna junto a base do cálculo. Oferece 276 ferramentas básicas em 18 domínios de cálculo + 10 ferramentas administrativas de política, até 500 cálculos paralelos por vez (core.batch), cálculos encadeados em etapas (core.pipeline) e 4 tipos de transporte (stdio/Streamable HTTP/Unix, SSE obsoleto). Requer Python 3.12 ou superior.
Por que é necessário
LLMs não calculam números; geram números plausíveis. Por isso, erram com frequência nos limites das faixas de impostos progressivos, na direção do arredondamento e nas alíquotas anuais. Abaixo está o resultado da mesma prova de 20 questões (medido em 24/04/2026).
| Quem resolveu | Exato | Aproximado (erro ≤ 0,01%) | Errado |
|---|---|---|---|
| SooTool | 20 | 0 | 0 |
| gemini-3-pro-preview | 12 | 4 | 4 |
| claude-opus-4-7 | 9 | 3 | 8 |
| gpt-5.4 | 5 | 3 | 12 |
Os pontos de erro são semelhantes entre modelos: limites das faixas do imposto de renda, dedução especial de longo prazo no imposto sobre ganho de capital, arredondamento do IVA e precisão de impedância CA. A composição das questões e os dados originais estão em bench/.
O SooTool fixa esses cálculos com três mecanismos.
- Cálculo exclusivo com Decimal. Os números de entrada são recebidos como string ou Decimal. Erros de ponto flutuante não entram no cálculo.
- Externalização dos valores legais. Alíquotas, deduções e taxas de contribuição ficam em arquivos de política (YAML) com o dispositivo legal e a data de vigência. Informando a data (
as_of), o cálculo usa os valores em vigor naquele dia. - Retorno da base do cálculo. Toda resposta inclui
tracecom fórmula, entradas, valores intermediários e resultado, além de um recibo (_meta.integrity) para verificação por reexecução.
Estrutura
LLM 에이전트 / CLI / 파이썬 코드
│
│ MCP(stdio, HTTP, Unix) sootool call ... from sootool.sdk import tax
▼ ▼ ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ 경계 검사 인자 이름·타입·크기 검증, 숫자 문자열 → Decimal, 인증 범위 확인 │
├──────────────────────────────────────────────────────────────────────────────┤
│ 레지스트리 도구 286개를 이름으로 찾아 실행 (core.batch / core.pipeline 포함) │
├───────────────────────────────┬──────────────────────────────────────────────┤
│ 도메인 도구 │ 정책 로더 │
│ tax · payroll · finance · │ policies/<도메인>/<이름>_<연도>.yaml │
│ realestate · stats · ... │ 해시 검증 → as_of 시점의 시행 버전 선택 │
└───────────────────────────────┴──────────────────────────────────────────────┘
│
▼
{ 결과 필드, trace(공식·입력·단계·출력), 정책 출처와 근거 조문, _meta.integrity(영수증) }
Os três pontos de entrada (MCP, CLI, SDK) passam pelo mesmo registro. Com a mesma entrada, o resultado e o recibo são idênticos em qualquer caminho.
Início rápido
Instalação
pip install sootool # 기호 계산(symbolic.*)까지 쓰려면 pip install "sootool[symbolic]"
Registro no Claude Code
claude mcp add --scope user sootool -- uvx sootool
Para clonar o repositório e executar o código em desenvolvimento, registre assim.
git clone https://github.com/JinHo-von-Choi/SooTool.git
cd SooTool && uv sync
claude mcp add --scope user sootool -- uv run --directory "$PWD" python -m sootool
Primeiro cálculo
No cliente MCP, pergunte "qual é o imposto de renda de 2026 para uma base tributável de 50 milhões de won?" e o agente chamará tax.kr_income. Você também pode executar a mesma ferramenta diretamente no terminal.
sootool call tax.kr_income --arg taxable_income=50000000 --arg year=2026 --format raw
{
"tax": "6240000",
"effective_rate": "0.12480000",
"marginal_rate": "0.15",
"breakdown": [ ... 구간별 과세표준과 세액 ... ],
"policy_effective_date": "2026-01-01",
"policy_citations": [{"law": "소득세법", "article": "제55조제1항", "url": "https://www.law.go.kr/법령/소득세법/제55조"}]
}
Como ler a resposta
Resposta real de finance.npv(rate="0.08", cashflows=["-1000","300","400","500","200"], rounding="HALF_EVEN", decimals=2).
{
"npv": "164.64",
"trace": {
"tool": "finance.npv",
"formula": "NPV = sum(CF_t / (1+r)^t, t=0..n)",
"inputs": {"rate": "0.08", "cashflows": ["-1000", "300", "400", "500", "200"], "rounding": "HALF_EVEN", "decimals": 2},
"steps": [{"label": "npv_raw", "value": "164.63539696786661172171511042618089308126395968697"}],
"output": "164.64"
},
"_meta": {
"integrity": {
"tool": "finance.npv",
"input_hash": "00da5199...",
"result_hash": "d7a0ecfe...",
"tool_version": "1.0.0",
"sootool_version": "0.2.0"
},
"engine": "decimal"
}
}
| Campo | Significado |
|---|---|
Campos de resultado como npv | Resultado do cálculo. Todos os números são strings. |
trace.steps | Cálculo intermediário com valores antes do arredondamento. Usado para conferência manual. |
policy_* | Presente apenas em ferramentas de política. Data de vigência, status, dispositivo legal e hash do arquivo de política aplicado. |
_meta.integrity | Recibo. Hash da entrada e do resultado; pode ser comparado executando novamente o mesmo cálculo com sootool receipt verify. |
_meta.engine | Mecanismo de cálculo. decimal (exato), mpmath (com casas decimais definidas), float64 (aproximado), composite, none. |
_meta.hints | Sugestão de próximas ferramentas. Não afeta o valor do resultado. |
Principais recursos
O chamador escolhe o arredondamento
Ferramentas financeiras e contábeis em que a prática de arredondamento varia conforme o contexto (IVA, fluxo de caixa, depreciação, câmbio etc.) aceitam rounding (HALF_EVEN, HALF_UP, DOWN, UP, FLOOR, CEIL) e decimals. O cálculo reverso do IVA usa truncamento para a unidade (DOWN); a contabilidade geral usa HALF_EVEN — as regras variam conforme o uso. Tributos cuja legislação define o tratamento de frações (ex.: imposto local com truncamento abaixo de 10 won) seguem essa regra e a descrevem na documentação da ferramenta.
Cálculo de política com data específica
A legislação tributária e as alíquotas de contribuição mudam durante o ano. As ferramentas de política aceitam, além de year, os parâmetros as_of (AAAA-MM-DD) e include_proposed.
policies/payroll/kr_4insurance_2026.yaml 2026-01-01 ~ 2026-06-30
policies/payroll/kr_4insurance_2026@2026-07-01.yaml 2026-07-01 ~ 2026-10-31 ◀── as_of="2026-08-15"
policies/payroll/kr_4insurance_2026@2026-11-01.yaml 2026-11-01 ~ 2026-12-31
as_of가 속한 버전으로 계산하고, 응답에 그 버전의 시행일과 근거 조문을 싣는다.
Se as_of não for informado, usa-se a versão definitiva do ano com a data de vigência mais recente. Propostas de emenda ainda não aprovadas pelo parlamento (status: proposed) só são usadas quando include_proposed=true. O procedimento para alterar arquivos de política sem redistribuir o servidor está em docs/policy_management.md.
Vários itens de uma vez: batch e pipeline
core.batch 독립 계산 N건을 병렬로 core.pipeline 앞 단계 결과를 다음 단계 입력으로
┌ s1: finance.npv(rate=0.05) ┐ annual = core.mul(3000000, 12)
├ s2: finance.npv(rate=0.08) ┼─▶ id 순서로 결과 │ ${annual.result.result}
└ s3: finance.npv(rate=0.10) ┘ ▼
tax = tax.kr_income(annual, 2026)
최대 500건, 항목당 10초, 전체 60초 최대 50단계, 깊이 10, 단계당 2초, 전체 30초
core.batch registra sucesso, erro e timeout separadamente por item e retorna os resultados na ordem de entrada. core.pipeline marca as etapas seguintes como skipped quando uma etapa anterior falha, e há core.pipeline_resume (retenção de 10 minutos) para retomar a partir do ponto de falha.
{
"name": "core.pipeline",
"arguments": {
"steps": [
{"id": "annual", "tool": "core.mul", "args": {"operands": ["3000000", "12"]}},
{"id": "tax", "tool": "tax.kr_income", "args": {"taxable_income": "${annual.result.result}", "year": 2026}}
]
}
}
Na prática, use assim.
| Tarefa | Escala | Combinação |
|---|---|---|
| Fechamento de folha | 500 funcionários | core.batch + payroll.kr_salary |
| Sensibilidade de investimento | 9 taxas de desconto × 5 cenários de fluxo de caixa | core.batch + finance.npv, finance.irr |
| Separação do IVA em extratos de transação | Centenas de itens | core.batch + accounting.vat_extract |
| Do salário bruto ao líquido | 4 etapas | core.pipeline |
Cálculo reverso, comparação e explicação
core.solve_for: encontra o valor de entrada que produz o resultado desejado. Ex.: salário bruto que resulta em 3 milhões de won líquidos.core.compare: gera uma tabela com valores e diferenças por cenário em relação ao cenário-base.core.explain: descreve o processo de cálculo e as políticas aplicadas em frases em coreano ou inglês. Não altera os números.
Verificação por reexecução do recibo
sootool receipt verify --tool finance.fv \
--arguments '{"present_value":"1000","rate":"0.05","periods":10}' \
--receipt receipt.json
Execute a mesma ferramenta novamente e compare nome da ferramenta, hash de entrada, hash de resultado, versão da ferramenta e hash de política. Se SOOTOOL_RECEIPT_KEY_FILE apontar para um arquivo de chave privada ed25519, o recibo recebe uma assinatura.
Catálogo de ferramentas (276 básicas + 10 admin, 18 domínios de cálculo + ferramentas operacionais)
| Namespace | Quantidade | Ferramentas representativas |
|---|---|---|
| core | 11 | add, sub, mul, div, calc (fórmula), batch, pipeline, pipeline_resume, solve_for, compare, explain |
| accounting | 12 | vat_extract, vat_add, balance, depreciação 3 tipos, dupont 2 tipos, ratios, income_statement, cashflow_operating, break_even |
| finance | 18 | pv, fv, npv, irr, roi, cagr, payback_period, loan_schedule, bond_ytm, bond_duration, black_scholes, var 2 tipos, sharpe, sortino |
| tax | 17 | kr_income, kr_comprehensive_income_tax, kr_withholding_simple, capital_gains_kr, kr_gift, kr_inheritance, kr_corporate, kr_eitc, imposto local adicional 3 tipos |
| tax_us | 4 | federal_income, capital_gains, state_tax, fica |
| payroll | 15 | kr_salary, kr_gross_from_net, kr_severance_pay, kr_year_end_tax_settlement, kr_overtime_pay, kr_minimum_wage_check, deduções 4 tipos |
| realestate | 10 | kr_acquisition_tax, kr_transfer_tax, kr_property_tax, kr_comprehensive, kr_ltv, kr_dti, kr_dsr, kr_subscription_score |
| stats | 14 | descriptive, teste t 3 tipos, anova_oneway, regression_linear, ci_mean, bootstrap_ci, testes não paramétricos |
| probability | 30 | pdf, cdf e ppf das distribuições normal, binomial, Poisson, gama, beta, exponencial, lognormal, qui-quadrado e F; bayes, nCr, nPr |
| datetime | 14 | cálculo de dias úteis, day_count, age, diff, tz_convert, conversão de calendário lunissolar, 24 termos solares, ano fiscal, período de apuração do imposto de renda |
| math | 10 | integração numérica 2 tipos, derivação numérica 2 tipos, interpolação 2 tipos, polynomial_roots, polynomial_horner, fft, ifft |
| geometry | 15 | área e volume 7 tipos, vetores 3 tipos, matrizes 4 tipos, haversine |
| engineering | 56 | circuitos elétricos e CA, fluidos, transferência de calor, mecânica dos materiais, controle, confiabilidade, conversão de prefixos SI |
| units | 8 | convert, fx_convert, fx_triangulate, temperature, conversão de energia, pressão, tamanho de dados e tempo |
| medical | 12 | bmi, bsa, egfr, dose_weight_based, pregnancy_weeks, cha2ds2_vasc, has_bled, framingham_cvd_10y, QTc 4 tipos |
| science | 11 | half_life, ideal_gas, molar_mass, stoichiometry, nernst, snell_law, thin_lens, bragg e outros |
| crypto | 10 | gcd, lcm, egcd, modinv, modpow, crt, is_prime, euler_totient, carmichael_lambda, hash |
| pm | 5 | critical_path, pert, evm, earned_schedule, monte_carlo_schedule |
| symbolic | 2 | solve, diff (quando sootool[symbolic] estiver instalado) |
| sootool | 2+10 | skill_guide, verify_receipt, gerenciamento de políticas 10 tipos (4 de escrita exigem modo administrador) |
Versão, nível de precisão e descrição de cada ferramenta estão em docs/tool_catalog.md. Esse arquivo é gerado automaticamente a partir do registro.
Execução do servidor
sootool # stdio (MCP 클라이언트 기본)
sootool --transport http --http-port 10535 # Streamable HTTP
sootool --transport unix --socket /tmp/sootool.sock # Unix 소켓
sootool --transport stdio,http --socket /tmp/sootool.sock # 여러 전송 동시 기동
| Transporte | Uso | Observações |
|---|---|---|
| stdio | Clientes locais como Claude Code, Claude Desktop etc. | Padrão |
| http | Acesso remoto (Streamable HTTP) | Sem estado; pode ficar atrás de um balanceador de carga. Porta padrão 10535 |
| unix | Outros processos no mesmo host | Controle de acesso pela permissão do arquivo de socket (padrão 0600) |
| sse-legacy | Compatibilidade com clientes MCP 2024-11 | Obsoleto. Ativado apenas com --enable-sse-legacy. Porta padrão 10536 |
As regras de segurança para transporte de rede são:
- O bind padrão é
127.0.0.1. Para expor externamente com--host 0.0.0.0, é necessário--auth-token(ouSOOTOOL_AUTH_TOKEN) para iniciar. - As 4 ferramentas de escrita que alteram políticas são expostas apenas via stdio e socket Unix. Para uso em rede, é necessário
--admin --remote-admin --admin-token <토큰>e apenas requisições autenticadas com token de administrador executam escritas.
Perfis de exposição
sootool --profile full # 기본값. 도구 286개를 모두 노출
sootool --profile lean # sootool.search, describe, call, skill_guide 4개만 노출
lean não carrega todas as definições de ferramentas no contexto. O agente encontra ferramentas com sootool.search, confere os argumentos com sootool.describe e executa com sootool.call. Resultado e recibo são idênticos aos de uma chamada direta. sootool.call executa apenas ferramentas somente leitura.
Linha de comando
Com um subcomando, a ferramenta é executada diretamente sem iniciar o servidor.
sootool call core.add --arg 'operands=["1.5","2.5"]'
sootool call finance.npv --arg-json '{"rate":"0.1","cashflows":["-100","50","60","70"]}'
sootool call payroll.kr_gross_from_net --arg net_monthly=3000000 --arg year=2026 --format raw
sootool tools list --search 양도세 # 줄임말과 일상 표현으로 검색
sootool tools describe tax.kr_income # 인자와 정책 인자 확인
sootool batch -f items.json # -f - 는 표준입력
sootool policy show --arg domain=tax --arg name=kr_income --arg year=2026
sootool skill-guide --section triggers
sootool version
| Item | Conteúdo |
|---|---|
| Argumentos | Repita --arg 이름=값 ou passe tudo de uma vez com --arg-json. Argumentos de string usam o valor literal; inteiros, booleanos, listas e objetos são lidos como JSON. |
| Formato de saída | --format pretty (padrão), json (completo), raw (sem trace e _meta), trace |
| Destino da saída | Resultado na saída padrão; erros na saída de erro, em JSON. |
| Código de saída | 0 sucesso, 1 erro de ferramenta, 2 erro de entrada, 3 requer modo administrador (SOOTOOL_ADMIN_MODE=1), 70 erro interno |
Uso como biblioteca Python
Chame as mesmas ferramentas como funções sem servidor MCP. Resultado, recibo e tratamento de as_of são idênticos ao MCP, e os tipos de resultado são declarados, permitindo que o type checker valide os campos.
from sootool.sdk import tax
out = tax.kr_income(taxable_income=50_000_000, year=2026)
out["tax"] # "6240000"
out["_meta"]["integrity"]["input_hash"] # 재실행 검증용 영수증
Para configurações em que o agente executa Python em sandbox, veja docs/sdk.md.
Informando regras de uso ao agente
Mesmo com as ferramentas registradas, o agente às vezes faz contas de cabeça. Use uma das opções abaixo para incluir a regra "cálculos numéricos com o SooTool".
- Faça a chamada de
sootool.skill_guideno início da sessão. Ela retorna uma tabela de gatilhos com quando usar cada ferramenta, exemplos, padrões proibidos e playbooks (section:triggers,examples,anti_patterns,playbooks,all/lang:ko,en). - Regras para colar no arquivo de configuração do cliente: Claude Code, Cursor, AGENTS.md
Documentação
| Documento | Conteúdo |
|---|---|
| Guia do usuário | Visão geral das ferramentas por domínio, argumentos comuns, regras de resposta |
| Catálogo de ferramentas | Versão, nível de precisão e descrição das 286 ferramentas |
| Gerenciamento de políticas | Estrutura dos arquivos de política, seleção de data, procedimentos de atualização e rollback, log de auditoria |
| SDK | Uso da biblioteca Python e configuração de sandbox |
| Pacote de políticas externas | Geração, validação e instalação de pacotes de política assinados |
| Contrato de estabilidade | Escopo de compatibilidade garantida e procedimento de descontinuação |
| Cookbook | Exemplos de chamadas por cenário: tributário, financeiro, engenharia elétrica |
| Registro de decisões de arquitetura | Decisões de design e justificativas (ADR) |
| Procedimento de release | Do incremento de versão à publicação no PyPI |
Desenvolvimento
uv sync --extra symbolic
make test # pytest와 커버리지
make lint # ruff
make typecheck # mypy
uv run python scripts/mcp_smoke_test.py # stdio 연결 점검 (http, sse, unix 스크립트도 있다)
Para criar uma nova ferramenta, crie uma função em src/sootool/modules/<도메인>/, adicione @REGISTRY.tool(namespace, name, description, version) e importe-a no domínio __init__.py — ela será registrada. Se alterar a descrição ou os tipos da ferramenta, regenere os documentos com scripts/gen_tool_catalog.py e scripts/gen_sdk_stubs.py. Se alterar arquivos de política, atualize o hash com scripts/policy_stamp.py.
Licença
MIT. Consulte LICENSE.