Zovo Quotes MCP Server
Crie, envie e acompanhe cotações e orçamentos de clientes a partir dos seus arquivos locais. Servidor MCP offline-first com licença Pro opcional; plano gratuito, sem cadastro.
Documentação
mcp-quotes
Diga "faça um orçamento para a Acme por 12 horas a 90 EUR mais uma taxa de setup de 300 EUR, 23% de IVA, válido por 14 dias" e receba um orçamento numerado que você pode enviar hoje: a tabela de linhas com IVA por taxa, o total em unidades monetárias inteiras, uma data de validade calculada no seu próprio fuso horário, uma versão em texto simples para colar diretamente em um e-mail e, no Pro, o mesmo layout em PDF A4 que suas faturas usam. Quando o cliente disser sim, quote_accept transforma isso em uma fatura real no armazenamento do mcp-invoice, sob a mesma lista de clientes e a mesma série de numeração, com os números copiados do orçamento em vez de recalculados. Tudo é armazenado em arquivos JSON simples na sua própria máquina; nada é enviado para lugar nenhum.
No Registro Oficial de MCP (io.github.theluckystrike/quotes-estimates-proposals-vat-win-rate).
Listado no Índice de Produtos de IA — endpoint remoto ao vivo em mcp.zovo.one/s/quotes, plano gratuito, sem cadastro.

Envie um orçamento com preço e IVA correto pelo chat, e transforme o "sim" em uma fatura com uma única chamada.
Instalação em 60 segundos
A publicação no npm para @theluckystrike/mcp-quotes está pendente. Até lá, o pacote de um clique .mcpb ou um clone + build é o caminho viável.
Um clique (.mcpb): baixe quotes.mcpb da versão mais recente e clique duas vezes no Claude Desktop:
https://github.com/theluckystrike/mcp-servers/releases/latest
(claude_desktop_config.json):
{
"mcpServers": {
"quotes": {
"command": "npx",
"args": ["-y", "@theluckystrike/mcp-quotes"]
}
}
}
Claude Code:
claude mcp add quotes -- npx -y @theluckystrike/mcp-quotes
(.cursor/mcp.json): a mesma entrada do Claude Desktop.
A partir do código-fonte:
git clone https://github.com/theluckystrike/mcp-servers.git && cd mcp-servers
npm install
npm run build -w packages/mcp-license -w servers/invoice -w servers/quotes
Compile o servers/invoice primeiro: o mecanismo de dinheiro, IVA, clientes e numeração é importado dele. Depois aponte o command do seu cliente para node com um argumento, o caminho absoluto para servers/quotes/dist/index.js.
Para rodar no modo Pro, defina MCP_LICENSE_KEY no mesmo bloco de configuração, ou chame license_activate uma vez com sua chave.
Ferramentas
| Ferramenta | O que faz |
|---|---|
quote_create | Orçar um cliente: itens de linha com quantidade e preço unitário em unidades menores, IVA por linha ou o padrão do negócio, um desconto opcional, uma janela de validade. Aloca Q-YYYY-NNNN |
quote_list | Cada orçamento com cliente, total, validade e estado: aberto, expirado, aceito ou recusado. Filtre por estado, cliente ou data do orçamento |
quote_get | O registro completo armazenado para um orçamento, incluindo a fatura em que ele se tornou |
quote_update | Revisar um orçamento que ainda está aberto. Os totais são recalculados; um orçamento aceito ou recusado nunca é editado |
quote_send_text | Um orçamento em texto simples com a tabela de linhas alinhada, linhas de IVA, total e data de validade, pronto para colar em um e-mail. Grátis |
quote_accept | Marcar como aceito e transformá-lo em fatura: criado diretamente no servidor de faturas quando seu armazenamento está presente, caso contrário devolvido como itens prontos para invoice_create |
quote_decline | Marcar como perdido, com um motivo, para que pare de contar contra os orçamentos abertos e entre na taxa de conversão |
quote_delete | Excluir um rascunho de orçamento que ninguém viu ainda e recuperar sua vaga de orçamento aberto. Recusado, com o dependente nomeado, depois de enviado, aceito, faturado ou exportado. Grátis |
quote_pdf | Renderizar o PDF A4 e retornar o caminho. Pro |
quote_report | Totais abertos, aceitos, recusados e expirados por moeda, o valor ainda aberto e a taxa de conversão. Grátis para o ano calendário atual até a data |
license_status | Mostrar modo gratuito ou Pro |
license_activate | Ativar uma chave Pro (verificada offline) |
Recurso: quotes://open retorna todos os orçamentos ainda dentro da janela de validade como JSON.
Prompt: quote_followup revisa o que está aberto, o que expira em breve e o que já expirou, e então redige o acompanhamento.
O que você pode dizer
| Você diz | Ferramenta |
|---|---|
| "Faça um orçamento para a Acme por 12 horas a 90 EUR mais uma taxa de setup de 300 EUR, 23% de IVA, válido por 14 dias." | quote_create |
| "Escreva isso como um e-mail que eu possa enviar." | quote_send_text |
| "Faça o Q-2026-0003 com 20 horas em vez disso e dê a eles mais duas semanas." | quote_update |
| "A Acme disse sim. Fature." | quote_accept |
| "A Beta foi com alguém mais barato." | quote_decline |
| "Eu orcei a Acme duas vezes por engano, descarte o segundo." | quote_delete |
| "O que ainda está aberto, e qual é minha taxa de conversão?" | quote_report |
| "Quais orçamentos expiraram sem resposta?" | quote_list com state: "expired" |
Exemplo prático
You: Quote Acme for 12 hours of API work at 90 EUR plus a 300 EUR setup fee,
23% VAT, good for 14 days.
quote_create {
client: "Acme", currency: "EUR", validity_days: 14,
items: [
{ description: "API work", quantity: 12, unit_price_minor: 9000, tax_rate: 23 },
{ description: "Setup fee", quantity: 1, unit_price_minor: 30000, tax_rate: 23 }
]
}
-> Q-2026-0001, valid until 2026-09-18
Assistant:
API work 12 x EUR 90.00 = EUR 1080.00
Setup fee 1 x EUR 300.00 = EUR 300.00
Subtotal EUR 1380.00
VAT 23% on EUR 1380.00 EUR 317.40
TOTAL EUR 1697.40
Valid until 2026-09-18.
You: They said yes.
quote_accept { id: "Q-2026-0001" }
-> accepted, invoice INV-2026-0004, due 2026-09-18, total EUR 1697.40
Os preços entram como unidades menores: 9000 é EUR 90,00 e 150000 é JPY 150.000. Não há decimal em lugar nenhum no lado da entrada, então um preço nunca pode ser inserido dez vezes menor.
Grátis vs Pro
| Grátis | Pro | |
|---|---|---|
| Orçamentos abertos | 5 por vez | Ilimitado |
quote_send_text (texto pronto para e-mail) | Sim, ilimitado | Sim, ilimitado |
| Aceitar, recusar, revisar, IVA, descontos, multi-moeda | Sim | Sim |
quote_delete (somente rascunhos) e a proteção contra duplicatas | Sim | Sim |
quote_pdf | Não | Sim |
quote_report (funil e taxa de conversão) | Ano calendário atual até a data | Qualquer intervalo de datas |
| Marca no PDF | n/a | Sem crédito de rodapé, e seu logotipo |
O limite conta orçamentos que ainda estão ABERTOS. Aceitar, recusar ou deixar um expirar libera a vaga, então um freelancer que fecha seus orçamentos nunca atinge o limite. Mais duas coisas evitam que uma vaga seja desperdiçada, ambas grátis: quote_create recusa um orçamento idêntico a um já aberto e nomeia o que você tem, e quote_delete remove um rascunho que ninguém viu e devolve a vaga imediatamente.
Pro é um pagamento único de $19, ou $39 para todos os servidores da coleção, vitalício.
Uma coisa medida: por que um orçamento aceito é copiado, não recalculado
quote_accept escreve a fatura a partir das linhas armazenadas do orçamento. A alternativa óbvia, recalcular os totais a partir dos preços no momento da aceitação, foi medida e rejeitada, porque a taxa de IVA que usaria é a do perfil de negócios compartilhado hoje, não a que foi orçada ao cliente.
Medido (test/adversarial.test.mjs, "uma mudança na taxa de IVA entre orçamento e aceitação nunca altera o total acordado"): um orçamento de EUR 1.000,00 líquidos é emitido com a taxa padrão do perfil de 23%, então o cliente recebe EUR 1.230,00. O default_tax_rate do perfil é então alterado para 8%, uma mudança de taxa, uma nova classe de cliente, uma configuração corrigida, antes de o cliente responder. Recalcular na aceitação fatura EUR 150,00 abaixo do documento que eles concordaram, em um único orçamento, sem nada em nenhum dos registros explicando por que diferem. Copiar as linhas armazenadas fatura EUR 1.230,00 e a afirmação se mantém tax_lines[0].rate === 23.
A mesma regra é o motivo pelo qual o orçamento aceita preços em unidades menores e recusa decimal: o número no orçamento e o número na fatura são o mesmo inteiro, do início ao fim.
Números, dinheiro e datas
Os IDs de orçamento são Q-YYYY-NNNN. O contador é por ano e é gravado antes de o orçamento ser armazenado, então uma falha queima um ID em vez de reutilizar um, e os IDs existentes também são verificados, então um quotes.json restaurado nunca pode devolver um ID que já está em um documento que um cliente viu. O ano faz parte do ID deliberadamente: um Q-0001 simples redefinido todo janeiro colidiria com o orçamento de janeiro passado.
Dinheiro é inteiro em unidades menores de ponta a ponta, e quantas unidades formam uma vem da tabela ISO 4217 em mcp-invoice, 2 para a maioria das moedas, 0 para JPY, KRW, ISK e as demais, 3 para KWD e os dinarares do Golfo, 4 para CLF e UYW. Não há segunda cópia dessa tabela, da aritmética de IVA ou do formatador de dinheiro aqui: computeTotals, currencyDecimals e formatMoney são importados de @theluckystrike/mcp-invoice/lib, então um orçamento e a fatura em que ele se torna arredondam de forma idêntica, por linha e depois somados. Um orçamento é uma moeda; uma mistura entre linhas é recusada em vez de somada sob o primeiro cabeçalho que aparecer.
As datas são ISO YYYY-MM-DD. "Hoje", e portanto se um orçamento expirou, é calculado no timezone do perfil de negócios compartilhado quando um está definido, não no fuso da máquina host: um orçamento emitido às 00:30 em Varsóvia a partir de um laptop ainda no horário dos EUA seria datado no dia anterior e expiraria um dia antes.
Como armazena dados
Orçamentos e o contador de IDs ficam sob ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/quotes/ como quotes.json e counter.json, mais uma subpasta pdf/ para arquivos renderizados. Faturas criadas por quote_accept são gravadas no diretório do servidor de faturas, .../mcp-servers/invoice/, então invoice_list lá as mostra e elas compartilham uma série de numeração e uma lista de clientes.
Toda chamada mutável roda sob um diretório de bloqueio consultivo em .../quotes/.lock; qualquer coisa que grava uma fatura também usa .../invoice/.lock, sempre nessa ordem (orçamentos, depois fatura), a mesma ordem que servers/recurring usa, então dois processos não podem travar. Salvamentos vão para um arquivo temporário por processo e são renomeados no lugar. Medido: 40 orçamentos criados por dois processos contra um diretório de dados deixam 40 orçamentos e 40 IDs únicos (test/concurrency.test.mjs).
Um arquivo de armazenamento que não é JSON válido nunca é tratado como "sem orçamentos". Ele é movido para o lado byte a byte como quotes.json.corrupt-<timestamp>, um marcador .corrupt é gravado ao lado, e toda chamada posterior, incluindo leituras, falha com restore a good copy ... then delete the marker até que um humano resolva.
Limites e ressalvas honestas
- O plano gratuito mantém 5 orçamentos abertos por vez. A exportação de texto, aceitar, recusar e revisar são irrestritas no gratuito, e o relatório de funil responde gratuitamente para o ano calendário atual até a data; o PDF e um intervalo de relatório mais amplo são Pro.
- Aceitar grava a fatura pelo mecanismo compartilhado, então o limite gratuito do próprio servidor de faturas de 3 faturas por mês calendário não é aplicado a ele. O limite de orçamentos é o que se aplica aqui, e a resposta diz isso.
- Um orçamento expirado é recusado por
quote_acceptaté que você o estenda (quote_update {valid_until}) ou digaallow_expired: true. Isso é atrito deliberado: um preço vencido deve ser reconfirmado. - Nenhum e-mail é enviado.
quote_send_textdá a você o texto equote_pdfdá a você o arquivo; levá-lo ao cliente é com você. - Nenhuma conversão de moeda. A moeda de um orçamento é fixada na criação e cada linha já deve estar nela.
- Aceitar é unidirecional. Não há desfazer aceitação, porque a fatura que criou é um documento com número; cancele essa fatura no servidor de faturas em vez disso.
Privacidade
Todos os dados permanecem locais: arquivos JSON simples no seu próprio diretório de dados. Sem conta, sem chave de API, sem chamada de rede de qualquer tipo. Chaves de licença são verificadas offline.
Construído por theluckystrike. Suporte: support@zovo.one