ohneben's Wafeq MCP
Execute seus livros Wafeq pelo Claude, Cursor ou qualquer cliente MCP — todos os 251 endpoints da API como ferramentas MCP categorizadas por segurança, via stdio ou Streamable HTTP, em Docker.
Documentação
MCP Wafeq do ohneben
Licença e Verificações
Registros MCP
Execute seus livros do Wafeq em linguagem natural a partir de assistentes de IA como Claude, Cursor e qualquer outro cliente MCP.
Este servidor Model Context Protocol expõe a API Pública do Wafeq — todos os 251 endpoints, gerados diretamente da especificação OpenAPI para ferramentas MCP, além de dois escritos manualmente. Cada ferramenta carrega uma categoria de segurança (🟢 somente leitura / 🟡 escrita / 🟠 mudança de estado / 🔴 irreversível ou destrutiva) para que seu assistente saiba o que uma ação faz antes de chamá-la — incluindo a diferença entre salvar uma fatura e registrá-la junto à autoridade tributária, algo que nenhum wrapper no formato CRUD consegue informar. Ele roda via stdio (Claude Desktop e outros lançadores locais) ou Streamable HTTP (hospedado em Docker), e vem com novas tentativas, limitação de taxa no lado do cliente, timeouts de requisição, chaves de idempotência, upload multipart e tratamento de PDF binário para aguentar um livro contábil real.
Por que você vai querer isso
Alguns servidores MCP apenas encaminham uma API. Este foi construído para ser seguro de entregar a um LLM e fácil de executar contra dados contábeis reais:
| O que você obtém | Por que importa |
|---|---|
| Todos os 251 endpoints, orientados por especificação | Cobertura completa de faturas, contas a pagar, cotações, notas de crédito e débito, pagamentos, bancos, diários, folha de pagamento, projetos, inventário e relatórios — nada selecionado manualmente ou deixado de fora. |
| Nove categorias de segurança, não quatro 🟢 / 🟡 / 🟠 / 🔴 | Uma dúzia dos POSTs do Wafeq não são criações. Pré-visualizações não gravam nada; encerrar uma amortização antecipadamente lança no razão sem desfazer; reportar uma fatura a uma autoridade tributária deixa sua organização permanentemente. Cada uma recebe seu próprio aviso em vez de ser agrupada com "criar". |
| Instruções do servidor enviadas na conexão | O cliente é informado sobre como ler os avisos de segurança e as poucas convenções do Wafeq — formato de data, separador decimal, intervalos de relatório por período completo — antecipadamente, em vez de descobri-las errando uma chamada primeiro. |
Anotações MCP legíveis por máquina (readOnlyHint, destructiveHint) | Hosts que respeitam anotações (incluindo o Claude) podem confiar automaticamente nas 98 ferramentas somente leitura e exigir confirmação antes de qualquer uma das 44 que excluem ou não podem ser desfeitas. |
| Parâmetros de relatório corretos, por relatório | Cada um dos quatro relatórios tem seu próprio esquema: balanço patrimonial usa date + period_count; DRE e fluxo de caixa usam date_after + date_before; balancete usa from_date + to_date. O Wafeq ignora silenciosamente parâmetros de consulta com erro de digitação, então um nome errado parece uma chamada que funciona. |
| Validação de período completo antes do envio | DRE e fluxo de caixa rejeitam intervalos que não se alinham a meses ou anos completos. O servidor verifica localmente e responde com o intervalo válido mais próximo em vez de gastar uma ida e volta em um HTTP 400. |
| Chaves de idempotência automáticas | Cada um dos 146 endpoints de escrita que suportam X-Wafeq-Idempotency-Key recebe um UUID v4 automaticamente, reutilizado entre novas tentativas — para que uma falha de rede nunca duplique uma fatura. Forneça a sua própria para tornar uma reexecução deliberada segura também. |
| Uploads de arquivos que realmente funcionam | POST /files/ é somente multipart e POST /files/raw/ precisa de um cabeçalho Content-Disposition. Ambos são tratados; você passa conteúdo base64 e um nome de arquivo. |
| PDFs binários tratados como bytes | Os nove endpoints de PDF são codificados em base64 em um envelope pequeno com tamanho e tipo de conteúdo, em vez de serem lidos como texto e corrompidos. |
| Novas tentativas automáticas com backoff | Respostas transitórias 429 / 5xx são repetidas com backoff exponencial com jitter, respeitando Retry-After — com a mesma chave de idempotência, exatamente como o guia de integração do Wafeq exige. |
| Limitação de taxa integrada | Auto-regula para que uma rajada de chamadas de ferramentas não dispare um 429. O Wafeq não publica limite numérico, então o padrão é deliberadamente conservador e configurável. |
| Locatário verificado na inicialização | Uma chave de API do Wafeq é limitada à organização. O servidor chama GET /organization/ antes de servir e publica o resultado em /health, para que uma chave mal configurada apareça como um nome que você pode verificar em vez de gravações nos livros da empresa errada. |
| Dois transportes: stdio e Streamable HTTP | Use localmente no Claude Desktop, ou execute um servidor sempre ativo que qualquer número de clientes MCP alcança via HTTP. |
| Docker + docker-compose, health check, reinício automático | docker compose up e ele permanece ativo, vinculado apenas ao localhost. |
| Autenticação opcional por bearer token no endpoint HTTP | Coloque o servidor atrás de um segredo compartilhado assim que ele estiver acessível além do localhost. |
| Seus segredos nunca chegam ao modelo | As credenciais vivem no ambiente do servidor e são injetadas em cada requisição. A ferramenta de passagem não pode sobrescrever Authorization ou apontar a credencial para outro host. |
| Atualizações de especificação sem esforço | O Wafeq lançou uma especificação mais nova? Substitua um arquivo e reconstrua — novos endpoints viram novas ferramentas automaticamente, sem mudanças de código. |
Como ele se compara
| Capacidade | Este projeto | Wrapper genérico OpenAPI→MCP* |
|---|---|---|
| Todos os 251 endpoints do Wafeq como ferramentas | ✅ | ✅ |
| Categoria de segurança + aviso por ferramenta | ✅ | ❌ |
| Registro junto à autoridade tributária sinalizado como irreversível, não "criar" | ✅ | ❌ |
Anotações MCP readOnlyHint / destructiveHint | ✅ | ➖ |
| Campos somente leitura removidos dos corpos de criação/atualização | ✅ | ❌ |
| Prosa de enum duplicada compactada dos esquemas | ✅ | ❌ |
| Parâmetros de data corretos, por relatório | ✅ | ✅ |
| Intervalo de período completo validado antes do envio | ✅ | ❌ |
X-Wafeq-Idempotency-Key automático, estável entre novas tentativas | ✅ | ❌ |
| Upload de arquivo multipart + binário bruto | ✅ | ➖ |
| Respostas PDF binárias codificadas em base64, não corrompidas | ✅ | ➖ |
| Datas de transação recuperadas para itens de linha do diário | ✅ | ❌ |
Novas tentativas automáticas em 429 / 5xx (respeita Retry-After) | ✅ | ❌ |
| Limitação de taxa no lado do cliente | ✅ | ❌ |
| Identidade da organização verificada na inicialização | ✅ | ❌ |
Transporte stdio | ✅ | ✅ |
| Transporte Streamable-HTTP | ✅ | ➖ |
| Docker + docker-compose, health check, reinício automático | ✅ | ❌ |
| Autenticação opcional por bearer token no endpoint | ✅ | ❌ |
| Licença | MIT | varia |
*Wrappers genéricos OpenAPI→MCP transformam qualquer especificação em ferramentas MCP. Eles podem alcançar os mesmos endpoints, mas tratam toda operação de forma idêntica — e contra a especificação do Wafeq especificamente, eles herdam o problema de campo obrigatório somente leitura descrito em MIGRATION.md. "➖" = varia por ferramenta / não garantido.
O que você pode fazer
Depois de conectado, pergunte ao seu assistente coisas como:
- "Qual foi nosso lucro e prejuízo no primeiro semestre deste ano?"
- "Mostre todas as faturas não pagas com mais de 30 dias, com o nome do cliente."
- "Crie uma fatura rascunho para a Acme Ltda por 3 dias de consultoria a €800/dia."
- "Baixe a fatura INV-2026-014 como PDF."
- "Em qual conta o transferência de €7.000 de janeiro foi lançada?"
- "Anexe este recibo à despesa EXP-118."
- "Concilie as linhas do extrato bancário de março com o razão."
- "Converta a cotação QUO-31 em fatura e registre o pagamento."
Como funciona
Claude / Cursor / any MCP client ──MCP──► this server ──HTTPS──► Wafeq API (your organization)
Na inicialização, o servidor analisa a especificação OpenAPI incluída em ferramentas MCP — resolvendo
$refs, protegendo contra esquemas recursivos e removendo campos atribuídos pelo servidor
(readOnly) dos corpos de requisição — marca cada ferramenta com sua categoria de segurança,
verifica a qual organização do Wafeq as credenciais pertencem e então injeta sua
credencial em cada requisição de saída. Sua chave permanece no ambiente do servidor; o
modelo nunca a vê ou manipula.
Requisitos
- Uma organização Wafeq com acesso à API — seja uma chave de API privada (Wafeq → Configurações → Desenvolvedor → Chaves de API) ou um token de acesso OAuth2. Veja Obtenha suas credenciais de API.
- Docker (Docker Desktop no macOS/Windows) para o início rápido abaixo — ou Node.js ≥ 20 para executar a partir do código-fonte.
Início rápido (Docker)
1. Adicione suas credenciais. Copie a configuração de exemplo e preencha:
cp .env.example .env
Depois edite .env e defina WAFEQ_API_KEY. Se o servidor for acessível além do
localhost, defina MCP_SHARED_TOKEN com uma string aleatória longa também.
2. Inicie o servidor:
docker compose up -d --build
docker-compose.yml vincula-se apenas a 127.0.0.1:8765, então o servidor é acessível da sua
máquina, mas não da rede.
3. Confirme que está rodando — e que está apontado para os livros certos:
curl -s http://localhost:8765/health
{
"status": "ok",
"server": "wafeq-mcp",
"version": "2.0.0",
"tools": 253,
"organization": {
"status": "ok",
"id": "org_...",
"name": "Your Company FZCO",
"base_currency": "EUR",
"country": "AE"
},
"auth_required": false
}
Verifique o campo name. Essa é a organização na qual sua chave grava. Se não for a
empresa que você esperava, pare e corrija a chave antes de fazer qualquer outra coisa. /health
responde 503 e "status": "degraded" quando as credenciais não podem ser verificadas.
4. Aponte seu cliente MCP para ele: http://localhost:8765/mcp (Streamable HTTP).
Endpoints remotos são adicionados ao Claude como um conector personalizado (Configurações →
Conectores), ou conectados localmente com
mcp-remote. Para a ponte, adicione isto
sob mcpServers na configuração do seu cliente e reinicie o aplicativo completamente:
{
"mcpServers": {
"wafeq": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:8765/mcp",
"--header", "Authorization: Bearer YOUR_MCP_SHARED_TOKEN"
]
}
}
}
(Remova a linha --header se você deixou MCP_SHARED_TOKEN vazio.)
Prefere uma imagem pronta?
Cada versão publica uma imagem pronta para executar no GitHub Container Registry, então você pode pular a compilação local completamente:
docker run -d --name wafeq-mcp -p 127.0.0.1:8765:8765 --env-file .env \
ghcr.io/ohneben/wafeq-mcp:latest
Fixe uma versão (:2.0.0) em vez de latest se quiser que as versões sejam algo
que você opta por adotar.
Instalar a partir do Registro MCP
O servidor está publicado no Registro MCP
como io.github.ohneben/wafeq-mcp, então clientes que reconhecem o registro podem instalá-lo pelo nome.
A entrada do registro inicia a imagem via stdio — veja
Executar o contêiner via stdio para a configuração
manuscrita equivalente.
curl -s "https://registry.modelcontextprotocol.io/v0.1/servers/io.github.ohneben%2Fwafeq-mcp/versions/latest"
Obtenha suas credenciais de API
Chave de API privada (para a maioria das pessoas): no Wafeq, vá em Configurações → Desenvolvedor → Chaves
de API e crie uma chave. Ela é limitada a uma organização. Coloque-a em .env como
WAFEQ_API_KEY; o servidor a envia como Authorization: Api-Key <key>.
Aplicativo OAuth2: se você tiver um token de acesso de um aplicativo OAuth2 do Wafeq, coloque-o em
.env como WAFEQ_ACCESS_TOKEN em vez disso. O servidor muda para
Authorization: Bearer <token> automaticamente. Defina WAFEQ_AUTH_SCHEME apenas se você
precisar forçar um esquema enquanto ambas as variáveis estiverem presentes.
Configuração
Toda a configuração é feita por variáveis de ambiente. Tudo, exceto a credencial, tem um padrão funcional.
| Variável | Padrão | O que faz |
|---|---|---|
WAFEQ_API_KEY | — | Chave de API privada da organização. Enviada como Api-Key <key>. Uma credencial é obrigatória. |
WAFEQ_ACCESS_TOKEN | — | Token de acesso OAuth2. Enviado como Bearer <token>. Tem precedência sobre WAFEQ_API_KEY. |
WAFEQ_AUTH_SCHEME | auto | Força api-key ou bearer. Normalmente, deixe sem definir. |
WAFEQ_API_BASE_URL | https://api.wafeq.com/v1 | URL base da API Wafeq. |
WAFEQ_OPENAPI_PATH | spec incluída | Usar um documento OpenAPI diferente (JSON ou YAML). |
MCP_TRANSPORT | stdio | stdio ou http. Docker define http. |
PORT | 8765 | Porta de escuta HTTP. |
HOST | 0.0.0.0 | Endereço de bind HTTP. |
MCP_HTTP_PATH | /mcp | Caminho onde o endpoint MCP é servido. |
MCP_SHARED_TOKEN | — | Token Bearer exigido em /mcp. Vazio = sem autenticação. Defina-o se a porta estiver acessível além de localhost. |
WAFEQ_TOOL_GROUPS | — | Grupos de recursos separados por vírgula para expor, ex.: invoices,bills,reports. Vazio = todos os 251. Execute npm run list-tools para a lista. |
WAFEQ_MAX_REQUESTS | 20 | Limite de taxa no cliente: solicitações por janela. 0 desativa a limitação. |
WAFEQ_RATE_WINDOW_MS | 10000 | Janela do limite de taxa em milissegundos. |
WAFEQ_MAX_RETRIES | 3 | Tentativas em 429 / 5xx / erros de rede. |
WAFEQ_TIMEOUT_MS | 30000 | Tempo limite de solicitação por tentativa. |
WAFEQ_ALLOW_LOCAL_FILE_UPLOAD | false | Permitir que ferramentas de upload leiam o sistema de arquivos desta máquina via file_path. Veja Segurança. |
WAFEQ_MAX_UPLOAD_BYTES | 26214400 | Tamanho máximo de upload decodificado (25 MiB). |
Ferramentas demais?
251 ferramentas é muita coisa. O catálogo completo tem cerca de 0,5 MB de JSON (~133k tokens) em
tools/list, e alguns hosts ficam mais lentos ou menos precisos com tantas. Duas coisas
ajudam.
Os schemas já estão compactados. A spec da Wafeq renderiza os valores de cada enum na
descrição além de em enum — só a lista de moedas tem ~4 KB, embutida
em 203 lugares. O gerador colapsa esses wrappers de allOf de membro único e remove
as listas com marcadores duplicadas, o que reduz ~29% do payload sem remover um
único valor permitido.
Reduza o catálogo se ainda quiser menor — sem mudanças de código:
WAFEQ_TOOL_GROUPS=invoices,bills,contacts,payments,reports,accounts,items,tax-rates
As duas ferramentas escritas à mão estão sempre disponíveis, então nada fica inacessível —
qualquer coisa que você filtrar ainda pode ser chamada via wafeq_request.
Categorias de segurança das ferramentas
A descrição de cada ferramenta abre com um banner, e cada ferramenta carrega as anotações MCP correspondentes. As contagens são para a spec incluída (251 geradas + 2 escritas à mão = 253).
| Banner | Ferramentas | readOnlyHint | destructiveHint | O que cobre |
|---|---|---|---|---|
🟢 READ-ONLY | 85 | ✅ | ❌ | Todo GET, além da ferramenta de conveniência do razão da conta. |
🟢 READ-ONLY · returns a PDF | 9 | ✅ | ❌ | Os downloads de PDF: fatura, fatura simplificada, nota de crédito, nota de débito, conta, cotação, ordem de compra, pagamento, recibo de salário. Retornados codificados em base64. |
🟢 READ-ONLY · preview / simulation | 4 | ✅ | ❌ | Pré-visualizações de amortização e reconhecimento de receita. POST, mas documentado como não gravando nada. |
🟡 WRITE · creates data | 39 | ❌ | ❌ | Criações de coleção, ambos os uploads de arquivo e as duas conversões (cotação→fatura, ordem de compra→conta). Não idempotentes por natureza — daí a chave de idempotência automática. |
🟡 WRITE · updates data | 70 | ❌ | ❌ | Todo PUT e PATCH. |
🟠 STATE CHANGE · moves a document in or out of the ledger | 2 | ❌ | ❌ | Marcar despesa como lançada / rascunho. Reversível — cada um desfaz o outro. |
🔴 IRREVERSIBLE · files the document with an external tax authority | 3 | ❌ | ✅ | Reportar fatura / nota de crédito / fatura simplificada à autoridade fiscal. Sai da sua organização e não pode ser revertido. |
🔴 IRREVERSIBLE · posts the remaining balance to the ledger | 2 | ❌ | ✅ | Encerrar amortização / reconhecimento de receita antecipadamente. Sem desfazer via API — execute a pré-visualização correspondente primeiro. |
🔴 DESTRUCTIVE · deletes | 39 | ❌ | ✅ | Todo DELETE, além do passthrough wafeq_request (seu efeito não pode ser conhecido antecipadamente). |
| 253 | 98 | 44 |
Os três grupos 🔴 todos definem destructiveHint: true, então um host que honra anotações
para e pergunta antes de qualquer um deles — não apenas antes de exclusões. Registrar uma fatura
junto a uma autoridade fiscal é pelo menos tão consequente quanto excluir uma, e ao contrário de uma exclusão,
isso alcança fora da sua organização.
Imprima o catálogo ativo a qualquer momento, sem credenciais:
npm run list-tools
🟢 SOMENTE LEITURA (85)
| Ferramenta | Endpoint |
|---|---|
wafeq_account_ledger | escrita à mão |
wafeq_accounts_list | GET /accounts/ |
wafeq_accounts_retrieve | GET /accounts/{id}/ |
wafeq_amortizations_list | GET /amortizations/ |
wafeq_amortizations_retrieve | GET /amortizations/{id}/ |
wafeq_bank_accounts_ledger_transactions_list | GET /bank-accounts/{bank_account_id}/ledger-transactions/ |
wafeq_bank_accounts_ledger_transactions_retrieve | GET /bank-accounts/{bank_account_id}/ledger-transactions/{id}/ |
wafeq_bank_accounts_list | GET /bank-accounts/ |
wafeq_bank_accounts_retrieve | GET /bank-accounts/{id}/ |
wafeq_bank_accounts_statement_transactions_list | GET /bank-accounts/{bank_account_id}/statement-transactions/ |
wafeq_bank_accounts_statement_transactions_retrieve | GET /bank-accounts/{bank_account_id}/statement-transactions/{id}/ |
wafeq_beneficiaries_list | GET /beneficiaries/ |
wafeq_beneficiaries_retrieve | GET /beneficiaries/{id}/ |
wafeq_bills_line_items_list | GET /bills/{bill_id}/line-items/ |
wafeq_bills_line_items_retrieve | GET /bills/{bill_id}/line-items/{id}/ |
wafeq_bills_list | GET /bills/ |
wafeq_bills_retrieve | GET /bills/{id}/ |
wafeq_branches_list | GET /branches/ |
wafeq_branches_retrieve | GET /branches/{id}/ |
wafeq_contacts_list | GET /contacts/ |
wafeq_contacts_retrieve | GET /contacts/{id}/ |
wafeq_cost_centers_list | GET /cost-centers/ |
wafeq_cost_centers_retrieve | GET /cost-centers/{id}/ |
wafeq_credit_notes_line_items_list | GET /credit-notes/{credit_note_id}/line-items/ |
wafeq_credit_notes_line_items_retrieve | GET /credit-notes/{credit_note_id}/line-items/{id}/ |
wafeq_credit_notes_list | GET /credit-notes/ |
wafeq_credit_notes_retrieve | GET /credit-notes/{id}/ |
wafeq_custom_fields_list | GET /custom-fields/ |
wafeq_custom_fields_retrieve | GET /custom-fields/{id}/ |
wafeq_debit_notes_line_items_list | GET /debit-notes/{debit_note_id}/line-items/ |
wafeq_debit_notes_line_items_retrieve | GET /debit-notes/{debit_note_id}/line-items/{id}/ |
wafeq_debit_notes_list | GET /debit-notes/ |
wafeq_debit_notes_retrieve | GET /debit-notes/{id}/ |
wafeq_employees_list | GET /employees/ |
wafeq_employees_retrieve | GET /employees/{id}/ |
wafeq_expenses_list | GET /expenses/ |
wafeq_expenses_retrieve | GET /expenses/{id}/ |
wafeq_files_list | GET /files/ |
wafeq_files_retrieve | GET /files/{id}/ |
wafeq_invoices_line_items_list | GET /invoices/{invoice_id}/line-items/ |
wafeq_invoices_line_items_retrieve | GET /invoices/{invoice_id}/line-items/{id}/ |
wafeq_invoices_list | GET /invoices/ |
wafeq_invoices_retrieve | GET /invoices/{id}/ |
wafeq_item_units_of_measure_list | GET /item-units-of-measure/ |
wafeq_item_units_of_measure_retrieve | GET /item-units-of-measure/{id}/ |
wafeq_items_list | GET /items/ |
wafeq_items_retrieve | GET /items/{id}/ |
wafeq_journal_line_items_list | GET /journal-line-items/ |
wafeq_journal_line_items_retrieve | GET /journal-line-items/{id}/ |
wafeq_manual_journals_list | GET /manual-journals/ |
wafeq_manual_journals_retrieve | GET /manual-journals/{id}/ |
wafeq_organization_retrieve | GET /organization/ |
wafeq_payment_requests_list | GET /payment_requests/ |
wafeq_payment_requests_retrieve | GET /payment_requests/{id}/ |
wafeq_payments_list | GET /payments/ |
wafeq_payments_retrieve | GET /payments/{id}/ |
wafeq_payslips_list | GET /payslips/ |
wafeq_payslips_pay_items_list | GET /payslips/{payslip_id}/pay-items/ |
wafeq_payslips_pay_items_retrieve | GET /payslips/{payslip_id}/pay-items/{id}/ |
wafeq_payslips_retrieve | GET /payslips/{id}/ |
wafeq_projects_list | GET /projects/ |
wafeq_projects_retrieve | GET /projects/{id}/ |
wafeq_purchase_orders_line_items_list | GET /purchase-orders/{purchase_order_id}/line-items/ |
wafeq_purchase_orders_line_items_retrieve | GET /purchase-orders/{purchase_order_id}/line-items/{id}/ |
wafeq_purchase_orders_list | GET /purchase-orders/ |
wafeq_purchase_orders_retrieve | GET /purchase-orders/{id}/ |
wafeq_quotes_line_items_list | GET /quotes/{quote_id}/line-items/ |
wafeq_quotes_line_items_retrieve | GET /quotes/{quote_id}/line-items/{id}/ |
wafeq_quotes_list | GET /quotes/ |
wafeq_quotes_retrieve | GET /quotes/{id}/ |
wafeq_reports_balance_sheet_list | GET /reports/balance-sheet/ |
wafeq_reports_cash_flow_list | GET /reports/cash-flow/ |
wafeq_reports_profit_and_loss_list | GET /reports/profit-and-loss/ |
wafeq_reports_trial_balance_list | GET /reports/trial-balance/ |
wafeq_revenue_recognitions_list | GET /revenue-recognitions/ |
wafeq_revenue_recognitions_retrieve | GET /revenue-recognitions/{id}/ |
wafeq_simplified_invoices_line_items_list | GET /simplified-invoices/{invoice_id}/line-items/ |
wafeq_simplified_invoices_line_items_retrieve | GET /simplified-invoices/{invoice_id}/line-items/{id}/ |
wafeq_simplified_invoices_list | GET /simplified-invoices/ |
wafeq_simplified_invoices_retrieve | GET /simplified-invoices/{id}/ |
wafeq_tax_rates_list | GET /tax-rates/ |
wafeq_units_of_measure_list | GET /units-of-measure/ |
wafeq_units_of_measure_retrieve | GET /units-of-measure/{id}/ |
wafeq_warehouses_list | GET /warehouses/ |
wafeq_warehouses_retrieve | GET /warehouses/{id}/ |
🟢 SOMENTE LEITURA (PDF) (9)
| Ferramenta | Endpoint |
|---|---|
wafeq_bills_download_retrieve | GET /bills/{id}/download/ |
wafeq_credit_notes_download_retrieve | GET /credit-notes/{id}/download/ |
wafeq_debit_notes_download_retrieve | GET /debit-notes/{id}/download/ |
wafeq_invoices_download_retrieve | GET /invoices/{id}/download/ |
wafeq_payments_download_retrieve | GET /payments/{id}/download/ |
wafeq_payslips_download_retrieve | GET /payslips/{id}/download/ |
wafeq_purchase_orders_download_retrieve | GET /purchase-orders/{id}/download/ |
wafeq_quotes_download_retrieve | GET /quotes/{id}/download/ |
wafeq_simplified_invoices_download_retrieve | GET /simplified-invoices/{id}/download/ |
🟢 SOMENTE LEITURA (PRÉ-VISUALIZAÇÃO) (4)
| Ferramenta | Endpoint |
|---|---|
wafeq_amortizations_preview_create | POST /amortizations/preview/ |
wafeq_amortizations_preview_end_early_create | POST /amortizations/{id}/preview-end-early/ |
wafeq_revenue_recognitions_preview_create | POST /revenue-recognitions/preview/ |
wafeq_revenue_recognitions_preview_end_early_create | POST /revenue-recognitions/{id}/preview-end-early/ |
🟡 ESCRITA · CRIAÇÕES (39)
| Ferramenta | Endpoint |
|---|---|
wafeq_accounts_create | POST /accounts/ |
wafeq_bank_accounts_create | POST /bank-accounts/ |
wafeq_bank_accounts_ledger_transactions_create | POST /bank-accounts/{bank_account_id}/ledger-transactions/ |
wafeq_bank_accounts_statement_transactions_create | POST /bank-accounts/{bank_account_id}/statement-transactions/ |
wafeq_beneficiaries_create | POST /beneficiaries/ |
wafeq_bills_create | POST /bills/ |
wafeq_bills_line_items_create | POST /bills/{bill_id}/line-items/ |
wafeq_branches_create | POST /branches/ |
wafeq_contacts_create | POST /contacts/ |
wafeq_cost_centers_create | POST /cost-centers/ |
wafeq_credit_notes_create | POST /credit-notes/ |
wafeq_credit_notes_line_items_create | POST /credit-notes/{credit_note_id}/line-items/ |
wafeq_custom_fields_create | POST /custom-fields/ |
wafeq_debit_notes_create | POST /debit-notes/ |
wafeq_debit_notes_line_items_create | POST /debit-notes/{debit_note_id}/line-items/ |
wafeq_employees_create | POST /employees/ |
wafeq_expenses_create | POST /expenses/ |
wafeq_invoices_create | POST /invoices/ |
wafeq_invoices_line_items_create | POST /invoices/{invoice_id}/line-items/ |
wafeq_item_units_of_measure_create | POST /item-units-of-measure/ |
wafeq_items_create | POST /items/ |
wafeq_manual_journals_create | POST /manual-journals/ |
wafeq_payment_requests_create | POST /payment_requests/ |
wafeq_payments_create | POST /payments/ |
wafeq_payslips_create | POST /payslips/ |
wafeq_payslips_pay_items_create | POST /payslips/{payslip_id}/pay-items/ |
wafeq_projects_create | POST /projects/ |
wafeq_purchase_orders_bill_create | POST /purchase-orders/{id}/bill/ |
wafeq_purchase_orders_create | POST /purchase-orders/ |
wafeq_purchase_orders_line_items_create | POST /purchase-orders/{purchase_order_id}/line-items/ |
wafeq_quotes_create | POST /quotes/ |
wafeq_quotes_invoice_create | POST /quotes/{id}/invoice/ |
wafeq_quotes_line_items_create | POST /quotes/{quote_id}/line-items/ |
wafeq_simplified_invoices_create | POST /simplified-invoices/ |
wafeq_simplified_invoices_line_items_create | POST /simplified-invoices/{invoice_id}/line-items/ |
wafeq_units_of_measure_create | POST /units-of-measure/ |
wafeq_upload_file | POST /files/ |
wafeq_upload_file_raw | POST /files/raw/ |
wafeq_warehouses_create | POST /warehouses/ |
🟡 ESCRITA · ATUALIZAÇÕES (70)
| Ferramenta | Endpoint | |---|---| | `wafeq_accounts_partial_update` | `PATCH /accounts/{id}/` | | `wafeq_accounts_update` | `PUT /accounts/{id}/` | | `wafeq_bank_accounts_ledger_transactions_partial_update` | `PATCH /bank-accounts/{bank_account_id}/ledger-transactions/{id}/` | | `wafeq_bank_accounts_ledger_transactions_update` | `PUT /bank-accounts/{bank_account_id}/ledger-transactions/{id}/` | | `wafeq_bank_accounts_partial_update` | `PATCH /bank-accounts/{id}/` | | `wafeq_bank_accounts_statement_transactions_partial_update` | `PATCH /bank-accounts/{bank_account_id}/statement-transactions/{id}/` | | `wafeq_bank_accounts_statement_transactions_update` | `PUT /bank-accounts/{bank_account_id}/statement-transactions/{id}/` | | `wafeq_bank_accounts_update` | `PUT /bank-accounts/{id}/` | | `wafeq_beneficiaries_partial_update` | `PATCH /beneficiaries/{id}/` | | `wafeq_beneficiaries_update` | `PUT /beneficiaries/{id}/` | | `wafeq_bills_line_items_partial_update` | `PATCH /bills/{bill_id}/line-items/{id}/` | | `wafeq_bills_line_items_update` | `PUT /bills/{bill_id}/line-items/{id}/` | | `wafeq_bills_partial_update` | `PATCH /bills/{id}/` | | `wafeq_bills_update` | `PUT /bills/{id}/` | | `wafeq_branches_partial_update` | `PATCH /branches/{id}/` | | `wafeq_branches_update` | `PUT /branches/{id}/` | | `wafeq_contacts_partial_update` | `PATCH /contacts/{id}/` | | `wafeq_contacts_update` | `PUT /contacts/{id}/` | | `wafeq_cost_centers_partial_update` | `PATCH /cost-centers/{id}/` | | `wafeq_cost_centers_update` | `PUT /cost-centers/{id}/` | | `wafeq_credit_notes_line_items_partial_update` | `PATCH /credit-notes/{credit_note_id}/line-items/{id}/` | | `wafeq_credit_notes_line_items_update` | `PUT /credit-notes/{credit_note_id}/line-items/{id}/` | | `wafeq_credit_notes_partial_update` | `PATCH /credit-notes/{id}/` | | `wafeq_credit_notes_update` | `PUT /credit-notes/{id}/` | | `wafeq_custom_fields_partial_update` | `PATCH /custom-fields/{id}/` | | `wafeq_custom_fields_update` | `PUT /custom-fields/{id}/` | | `wafeq_debit_notes_line_items_partial_update` | `PATCH /debit-notes/{debit_note_id}/line-items/{id}/` | | `wafeq_debit_notes_line_items_update` | `PUT /debit-notes/{debit_note_id}/line-items/{id}/` | | `wafeq_debit_notes_partial_update` | `PATCH /debit-notes/{id}/` | | `wafeq_debit_notes_update` | `PUT /debit-notes/{id}/` | | `wafeq_employees_partial_update` | `PATCH /employees/{id}/` | | `wafeq_employees_update` | `PUT /employees/{id}/` | | `wafeq_expenses_partial_update` | `PATCH /expenses/{id}/` | | `wafeq_expenses_update` | `PUT /expenses/{id}/` | | `wafeq_invoices_line_items_partial_update` | `PATCH /invoices/{invoice_id}/line-items/{id}/` | | `wafeq_invoices_line_items_update` | `PUT /invoices/{invoice_id}/line-items/{id}/` | | `wafeq_invoices_partial_update` | `PATCH /invoices/{id}/` | | `wafeq_invoices_update` | `PUT /invoices/{id}/` | | `wafeq_item_units_of_measure_partial_update` | `PATCH /item-units-of-measure/{id}/` | | `wafeq_item_units_of_measure_update` | `PUT /item-units-of-measure/{id}/` | | `wafeq_items_partial_update` | `PATCH /items/{id}/` | | `wafeq_items_update` | `PUT /items/{id}/` | | `wafeq_manual_journals_partial_update` | `PATCH /manual-journals/{id}/` | | `wafeq_manual_journals_update` | `PUT /manual-journals/{id}/` | | `wafeq_payment_requests_partial_update` | `PATCH /payment_requests/{id}/` | | `wafeq_payment_requests_update` | `PUT /payment_requests/{id}/` | | `wafeq_payments_partial_update` | `PATCH /payments/{id}/` | | `wafeq_payments_update` | `PUT /payments/{id}/` | | `wafeq_payslips_partial_update` | `PATCH /payslips/{id}/` | | `wafeq_payslips_pay_items_partial_update` | `PATCH /payslips/{payslip_id}/pay-items/{id}/` | | `wafeq_payslips_pay_items_update` | `PUT /payslips/{payslip_id}/pay-items/{id}/` | | `wafeq_payslips_update` | `PUT /payslips/{id}/` | | `wafeq_projects_partial_update` | `PATCH /projects/{id}/` | | `wafeq_projects_update` | `PUT /projects/{id}/` | | `wafeq_purchase_orders_line_items_partial_update` | `PATCH /purchase-orders/{purchase_order_id}/line-items/{id}/` | | `wafeq_purchase_orders_line_items_update` | `PUT /purchase-orders/{purchase_order_id}/line-items/{id}/` | | `wafeq_purchase_orders_partial_update` | `PATCH /purchase-orders/{id}/` | | `wafeq_purchase_orders_update` | `PUT /purchase-orders/{id}/` | | `wafeq_quotes_line_items_partial_update` | `PATCH /quotes/{quote_id}/line-items/{id}/` | | `wafeq_quotes_line_items_update` | `PUT /quotes/{quote_id}/line-items/{id}/` | | `wafeq_quotes_partial_update` | `PATCH /quotes/{id}/` | | `wafeq_quotes_update` | `PUT /quotes/{id}/` | | `wafeq_simplified_invoices_line_items_partial_update` | `PATCH /simplified-invoices/{invoice_id}/line-items/{id}/` | | `wafeq_simplified_invoices_line_items_update` | `PUT /simplified-invoices/{invoice_id}/line-items/{id}/` | | `wafeq_simplified_invoices_partial_update` | `PATCH /simplified-invoices/{id}/` | | `wafeq_simplified_invoices_update` | `PUT /simplified-invoices/{id}/` | | `wafeq_units_of_measure_partial_update` | `PATCH /units-of-measure/{id}/` | | `wafeq_units_of_measure_update` | `PUT /units-of-measure/{id}/` | | `wafeq_warehouses_partial_update` | `PATCH /warehouses/{id}/` | | `wafeq_warehouses_update` | `PUT /warehouses/{id}/` |🟠 MUDANÇA DE ESTADO (2)
| Ferramenta | Endpoint |
|---|---|
wafeq_expenses_mark_as_draft_create | POST /expenses/{id}/mark-as-draft/ |
wafeq_expenses_mark_as_posted_create | POST /expenses/{id}/mark-as-posted/ |
🔴 IRREVERSÍVEL · ARQUIVAMENTO EXTERNO (3)
| Ferramenta | Endpoint |
|---|---|
wafeq_credit_notes_tax_authority_report_create | POST /credit-notes/{id}/tax-authority/report/ |
wafeq_invoices_tax_authority_report_create | POST /invoices/{id}/tax-authority/report/ |
wafeq_simplified_invoices_tax_authority_report_create | POST /simplified-invoices/{id}/tax-authority/report/ |
🔴 IRREVERSÍVEL · RAZÃO (2)
| Ferramenta | Endpoint |
|---|---|
wafeq_amortizations_end_early_create | POST /amortizations/{id}/end-early/ |
wafeq_revenue_recognitions_end_early_create | POST /revenue-recognitions/{id}/end-early/ |
🔴 DESTRUTIVO · EXCLUSÕES (39)
| Ferramenta | Endpoint |
|---|---|
wafeq_accounts_destroy | DELETE /accounts/{id}/ |
wafeq_amortizations_destroy | DELETE /amortizations/{id}/ |
wafeq_bank_accounts_destroy | DELETE /bank-accounts/{id}/ |
wafeq_bank_accounts_ledger_transactions_destroy | DELETE /bank-accounts/{bank_account_id}/ledger-transactions/{id}/ |
wafeq_bank_accounts_statement_transactions_destroy | DELETE /bank-accounts/{bank_account_id}/statement-transactions/{id}/ |
wafeq_beneficiaries_destroy | DELETE /beneficiaries/{id}/ |
wafeq_bills_destroy | DELETE /bills/{id}/ |
wafeq_bills_line_items_destroy | DELETE /bills/{bill_id}/line-items/{id}/ |
wafeq_branches_destroy | DELETE /branches/{id}/ |
wafeq_contacts_destroy | DELETE /contacts/{id}/ |
wafeq_cost_centers_destroy | DELETE /cost-centers/{id}/ |
wafeq_credit_notes_destroy | DELETE /credit-notes/{id}/ |
wafeq_credit_notes_line_items_destroy | DELETE /credit-notes/{credit_note_id}/line-items/{id}/ |
wafeq_custom_fields_destroy | DELETE /custom-fields/{id}/ |
wafeq_debit_notes_destroy | DELETE /debit-notes/{id}/ |
wafeq_debit_notes_line_items_destroy | DELETE /debit-notes/{debit_note_id}/line-items/{id}/ |
wafeq_employees_destroy | DELETE /employees/{id}/ |
wafeq_expenses_destroy | DELETE /expenses/{id}/ |
wafeq_files_destroy | DELETE /files/{id}/ |
wafeq_invoices_destroy | DELETE /invoices/{id}/ |
wafeq_invoices_line_items_destroy | DELETE /invoices/{invoice_id}/line-items/{id}/ |
wafeq_item_units_of_measure_destroy | DELETE /item-units-of-measure/{id}/ |
wafeq_items_destroy | DELETE /items/{id}/ |
wafeq_manual_journals_destroy | DELETE /manual-journals/{id}/ |
wafeq_payment_requests_destroy | DELETE /payment_requests/{id}/ |
wafeq_payments_destroy | DELETE /payments/{id}/ |
wafeq_payslips_destroy | DELETE /payslips/{id}/ |
wafeq_payslips_pay_items_destroy | DELETE /payslips/{payslip_id}/pay-items/{id}/ |
wafeq_projects_destroy | DELETE /projects/{id}/ |
wafeq_purchase_orders_destroy | DELETE /purchase-orders/{id}/ |
wafeq_purchase_orders_line_items_destroy | DELETE /purchase-orders/{purchase_order_id}/line-items/{id}/ |
wafeq_quotes_destroy | DELETE /quotes/{id}/ |
wafeq_quotes_line_items_destroy | DELETE /quotes/{quote_id}/line-items/{id}/ |
wafeq_request | escrito à mão |
wafeq_revenue_recognitions_destroy | DELETE /revenue-recognitions/{id}/ |
wafeq_simplified_invoices_destroy | DELETE /simplified-invoices/{id}/ |
wafeq_simplified_invoices_line_items_destroy | DELETE /simplified-invoices/{invoice_id}/line-items/{id}/ |
wafeq_units_of_measure_destroy | DELETE /units-of-measure/{id}/ |
wafeq_warehouses_destroy | DELETE /warehouses/{id}/ |
Cobertura
| Área | Ferramentas | 🟢 Leitura | 🟡 Escrita | 🔴 Irreversível | 🔴 Exclusão |
|---|---|---|---|---|---|
| Vendas e contas a receber | 69 | 25 | 31 | 3 | 10 |
| Compras e contas a pagar | 54 | 19 | 27 | 0 | 8 |
| Banco | 18 | 6 | 9 | 0 | 3 |
| Razão e relatórios | 31 | 19 | 6 | 2 | 4 |
| Folha de pagamento | 19 | 7 | 9 | 0 | 3 |
| Dados mestre e dimensões | 54 | 18 | 27 | 0 | 9 |
| Arquivos e organização | 6 | 3 | 2 | 0 | 1 |
| Saída de emergência e conveniência | 2 | 1 | 0 | 0 | 1 |
| Total | 253 | 98 | 111 | 5 | 39 |
"Escrita" inclui as duas ferramentas 🟠 de mudança de estado. As áreas mapeiam para os recursos do Wafeq da seguinte forma — Vendas: faturas, faturas simplificadas, cotações, notas de crédito, pagamentos, solicitações de pagamento · Compras: contas, ordens de compra, notas de débito, despesas, beneficiários · Banco: contas bancárias com seu razão e transações de extrato · Razão e relatórios: contas, lançamentos manuais, itens de lançamento, os quatro relatórios, alíquotas de impostos, amortizações, reconhecimentos de receita · Folha de pagamento: recibos de pagamento, funcionários · Dados mestre: contatos, itens, unidades de medida, armazéns, projetos, centros de custo, filiais, campos personalizados.
Duas ferramentas escritas à mão
Tudo acima é gerado. Duas ferramentas são escritas à mão:
wafeq_account_ledger(🟢) — itens de lançamento com sua data real de transação. As linhas de/journal-line-items/do Wafeq carregamcreated_ts(quando a linha chegou ao Wafeq), que geralmente é um mês diferente da transação, e nenhum campo de data. Esta ferramenta recupera a data usando os filtros dedate_after/date_beforedo próprio endpoint, que operam na data da transação. Ela testa um mês por vez e só divide em consultas diárias onde existem linhas, então períodos tranquilos custam uma solicitação cada; o resultado relatarequests_made.wafeq_request(🔴) — a saída de emergência: qualquer método, qualquer caminho, além de query, corpo e cabeçalhos. É o fallback para qualquer coisa que a especificação incluída não cubra, não a interface principal. Categorizada como destrutiva porque seu efeito não pode ser conhecido antecipadamente.
Executar a partir do código-fonte (stdio, sem Docker)
npm ci
npm run build
Em seguida, registre-o com seu cliente MCP. Para Claude Desktop, adicione em
claude_desktop_config.json:
{
"mcpServers": {
"wafeq": {
"command": "node",
"args": ["/absolute/path/to/Wafeq MCP/dist/index.js"],
"env": {
"MCP_TRANSPORT": "stdio",
"WAFEQ_API_KEY": "your-key-here"
}
}
}
}
Para Claude Code:
claude mcp add wafeq --env WAFEQ_API_KEY=your-key-here -- node /absolute/path/to/dist/index.js
Executar o contêiner via stdio
Você também pode deixar seu cliente iniciar a imagem publicada diretamente, sem servidor HTTP e sem build local:
{
"mcpServers": {
"wafeq": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT=stdio",
"-e", "WAFEQ_API_KEY",
"ghcr.io/ohneben/wafeq-mcp:latest"
],
"env": {
"WAFEQ_API_KEY": "your-key-here"
}
}
}
}
MCP_TRANSPORT=stdio é necessário aqui: a imagem usa o transporte HTTP por padrão.
Scripts úteis:
| Comando | O que faz |
|---|---|
npm run build | Compila TypeScript para dist/. |
npm test | Executa a suíte Vitest. |
npm run list-tools | Imprime o catálogo categorizado. Não requer credenciais. |
npm run start:stdio | Executa via stdio. |
npm run start:http | Executa o servidor HTTP Streamable. |
Mantendo a especificação atualizada
As ferramentas são geradas a partir de spec/wafeq-public-api.json na inicialização — não há etapa de geração de código nem lista de ferramentas escrita à mão. Coloque um documento OpenAPI mais recente (JSON ou YAML), recompile, e novos endpoints se tornam novas ferramentas. Veja spec/README.md para saber de onde veio a cópia incluída e o que verificar após uma atualização.
Correções de comportamento observado ficam em src/overrides.ts, identificadas por operationId e datadas, para que uma entrada cuja operação desapareça simplesmente deixe de se aplicar.
Notas e convenções
- Datas são
YYYY-MM-DD. Valores usam ponto como separador decimal. - Paginação: ferramentas de listagem aceitam
limiteoffset, e relatam a contagem total. - Relatórios aceitam parâmetros de data específicos do relatório — balanço patrimonial
date+period_count; lucros e perdas e fluxo de caixadate_after+date_before; balancetefrom_date+to_date. O Wafeq ignora silenciosamente um parâmetro de query com erro de digitação, então um nome errado parece uma chamada bem-sucedida; os esquemas por relatório existem para tornar isso impossível. - Períodos completos: intervalos de lucros e perdas e fluxo de caixa devem cobrir meses ou anos inteiros. O servidor verifica localmente e responde com o intervalo válido mais próximo, em vez de gastar uma ida e volta em um HTTP 400.
- Uploads de arquivos (
wafeq_files_*): envie conteúdo base64 mais um nome de arquivo.POST /files/é somente multipart ePOST /files/raw/precisa de um cabeçalhoContent-Disposition— ambos são tratados para você. - Downloads de PDF retornam codificados em base64 em um envelope pequeno com o tamanho e o tipo de conteúdo, não como texto corrompido.
- Idempotência: todo endpoint de escrita que suporta
X-Wafeq-Idempotency-Keyrecebe automaticamente um UUID v4, reutilizado em novas tentativas. Envie o seu próprio para tornar uma reexecução deliberada segura. - Novas tentativas: respostas transitórias de
429/5xxsão repetidas com backoff exponencial com jitter, respeitandoRetry-After, sob a mesma chave de idempotência. - Limite de taxa: o Wafeq não publica limite numérico, então o padrão do lado do cliente (
WAFEQ_MAX_REQUESTS=20porWAFEQ_RATE_WINDOW_MS=10000) é deliberadamente conservador. Aumente se você souber sua cota. - Uma organização por credencial. Uma chave de API do Wafeq é limitada à organização; toda chamada de ferramenta atua nessa organização, e
/healtha nomeia.
CI e lançamentos
Todo push e pull request é compilado e testado no Node 20 e 22, e o catálogo de ferramentas é gerado sem credenciais presentes — é isso que detecta um nome de ferramenta duplicado ou inválido para o esquema antes de ser publicado. O CI também falha se .env algum dia for rastreado.
Um lançamento é uma tag vX.Y.Z e nada mais. Nenhum número de versão é mantido manualmente. Enviar a tag executa toda a cadeia:
- A versão é derivada uma única vez, a partir da tag.
- A imagem é construída e enviada para
ghcr.io/ohneben/wafeq-mcp— marcada com a versão,MAJOR.MINOR, o SHA curto elatestemmain. - A entrada é publicada no MCP Registry
com
server.jsonfixado nessa tag exata da imagem. A propriedade é comprovada pelo rótuloio.modelcontextprotocol.server.namena imagem, que deve corresponder aonamedeserver.json— um teste garante que isso acontece. - O número publicado é gravado de volta em
package.jsoneserver.jsonemmain, e a tag é movida para esse commit. Assim, o repositório sempre informa a última versão publicada, e o servidor a reporta via MCP e em/healthsem edição de código.
npm version 2.0.1 --no-git-tag-version # optional; CI stamps it either way
git tag v2.0.1 && git push origin v2.0.1
workflow_dispatch republica uma determinada versão sem criar uma nova tag. Pushes para
main constroem uma imagem -dev.g<sha> e param por aí — eles nunca tocam no registro.
Segurança
- As credenciais permanecem no lado do servidor. Elas são lidas do ambiente e injetadas
por requisição. O modelo vê as entradas das ferramentas e as respostas da API, nunca a chave. A
ferramenta de passagem não pode sobrescrever o cabeçalho
Authorizatione se recusa a enviar a credencial para qualquer host que não seja a base da API configurada. - Nunca faça commit de
.env. Ele está no git-ignore, e o CI falha se ele for rastreado..env.examplecontém apenas placeholders. - Vincule ao localhost ou defina um token.
docker-compose.ymlpublica em127.0.0.1apenas. Se você expor a porta além disso, definaMCP_SHARED_TOKENprimeiro; ele é comparado em tempo constante. - Uploads de arquivos locais estão desativados por padrão.
WAFEQ_ALLOW_LOCAL_FILE_UPLOAD=falsesignifica que o servidor não lerá arquivos do próprio sistema de arquivos. Ativá-lo permite que qualquer coisa que possa chamar o servidor peça para ele ler um caminho local — deixe desativado, a menos que você precise e confie em todos os clientes. Uploads em Base64 funcionam de qualquer forma. - Verifique a organização em
/healthantes da primeira gravação. Uma chave de API é limitada a uma organização, e uma chave errada falha ao gravar na empresa errada em vez de gerar um erro. - As ferramentas 🔴 significam o que dizem. Exclusões são permanentes, encerrar um agendamento
antecipadamente não tem desfazer via API, e um envio à autoridade fiscal não pode ser revertido. Mantenha as
confirmações do host ativadas para qualquer coisa que carregue
destructiveHint.
Consulte SECURITY.md para relatar uma vulnerabilidade.
Créditos e licença
MIT — consulte LICENSE.md. Construído sobre o Model Context Protocol TypeScript SDK, seguindo a mesma arquitetura do ohneben's LearnWorlds MCP. Não afiliado ou endossado pela Wafeq.