Zovo Quotes MCP Server

Crea, envía y rastrea cotizaciones y presupuestos de clientes desde tus archivos locales. Servidor MCP offline-first con licencia Pro opcional; plan gratuito, sin registro.

Documentación

mcp-quotes

Di "cotiza a Acme por 12 horas a 90 EUR más una configuración de 300 EUR, 23% de IVA, válido por 14 días" y obtén una cotización numerada que puedes enviar hoy: la tabla de líneas con IVA por tarifa, el total en unidades monetarias enteras, una fecha de validez calculada en tu propia zona horaria, una versión en texto plano para pegar directamente en un correo y, en Pro, el mismo diseño PDF A4 que usan tus facturas. Cuando el cliente dice que sí, quote_accept la convierte en una factura real en el almacén de mcp-invoice, bajo la misma lista de clientes y la misma serie de numeración, con los números copiados de la cotización en lugar de recalcularse. Todo se almacena en archivos JSON simples en tu propia máquina; nada se sube a ningún sitio.

En el Registro oficial de MCP (io.github.theluckystrike/quotes-estimates-proposals-vat-win-rate).

Listado en el Índice de Productos de IA — endpoint remoto en vivo en mcp.zovo.one/s/quotes, nivel gratuito, sin registro.

quotes demo

Envía una cotización con precio e IVA correcto desde el chat, y convierte el "sí" en una factura con una sola llamada.

Instalación en 60 segundos

La publicación en npm para @theluckystrike/mcp-quotes está pendiente. Hasta entonces, el paquete de un clic .mcpb o una clonación y compilación es la vía funcional.

Un clic (.mcpb): descarga quotes.mcpb desde la última versión y haz doble clic en 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): la misma entrada que Claude Desktop.

Desde el código fuente:

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

Compila servers/invoice primero: el motor de dinero, IVA, clientes y numeración se importa de él. Luego apunta el command de tu cliente a node con un argumento, la ruta absoluta a servers/quotes/dist/index.js.

Para ejecutar en modo Pro, establece MCP_LICENSE_KEY en el mismo bloque de configuración, o llama a license_activate una vez con tu clave.

Herramientas

HerramientaQué hace
quote_createCotiza a un cliente: líneas de detalle con cantidad y precio unitario en unidades menores, IVA por línea o el predeterminado del negocio, un descuento opcional, una ventana de validez. Asigna Q-YYYY-NNNN
quote_listCada cotización con cliente, total, validez y estado: abierta, vencida, aceptada o rechazada. Filtra por estado, cliente o fecha de cotización
quote_getEl registro completo almacenado de una cotización, incluida la factura en la que se convirtió
quote_updateRevisa una cotización que sigue abierta. Los totales se recalculan; una cotización aceptada o rechazada nunca se edita
quote_send_textUna cotización en texto plano con la tabla de líneas alineada, líneas de IVA, total y fecha de validez, lista para pegar en un correo. Gratis
quote_acceptMárcala como aceptada y conviértela en factura: se crea directamente en el servidor de facturas cuando su almacén está presente; de lo contrario, se devuelve como elementos listos para invoice_create
quote_declineMárcala como perdida, con un motivo, para que deje de contar contra las cotizaciones abiertas y entre en la tasa de éxito
quote_deleteElimina una cotización borrador que nadie ha visto y recupera su espacio de cotización abierta. Se rechaza, nombrando la dependiente, una vez que se ha enviado, aceptado, facturado o exportado. Gratis
quote_pdfRenderiza el PDF A4 y devuelve la ruta. Pro
quote_reportTotales abiertos, aceptados, rechazados y vencidos por moneda, el valor aún abierto y la tasa de éxito. Gratis para el año calendario actual hasta la fecha
license_statusMuestra el modo gratuito o Pro
license_activateActiva una clave Pro (verificada sin conexión)

Recurso: quotes://open devuelve cada cotización aún dentro de su ventana de validez como JSON.

Indicación: quote_followup revisa qué está abierto, qué vence pronto y qué ya venció, luego redacta el seguimiento.

Lo que puedes decir

Tú dicesHerramienta
"Cotiza a Acme por 12 horas a 90 EUR más una configuración de 300 EUR, 23% de IVA, válido por 14 días."quote_create
"Redáctalo como un correo que pueda enviar."quote_send_text
"Haz Q-2026-0003 20 horas en su lugar y dales otras dos semanas."quote_update
"Acme dijo que sí. Factúralo."quote_accept
"Beta se fue con alguien más barato."quote_decline
"Coticé a Acme dos veces por error, elimina la segunda."quote_delete
"¿Qué sigue abierto y cuál es mi tasa de éxito?"quote_report
"¿Qué cotizaciones han vencido sin respuesta?"quote_list con state: "expired"

Ejemplo práctico

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

Los precios se ingresan en unidades menores: 9000 es EUR 90.00 y 150000 es JPY 150,000. No hay decimales en ningún lugar del lado de entrada, por lo que un precio nunca puede ingresarse diez veces más pequeño.

Gratis vs Pro

GratisPro
Cotizaciones abiertas5 a la vezIlimitadas
quote_send_text (texto listo para correo)Sí, ilimitadoSí, ilimitado
Aceptar, rechazar, revisar, IVA, descuentos, multimoneda
quote_delete (solo borradores) y la protección contra duplicados
quote_pdfNo
quote_report (canal y tasa de éxito)Año calendario actual hasta la fechaCualquier rango de fechas
Marca en PDFn/aSin crédito de pie de página y tu logotipo

El límite cuenta las cotizaciones que siguen ABIERTAS. Aceptar, rechazar o dejar que una venza libera el espacio, por lo que un autónomo que cierra sus cotizaciones nunca lo alcanza. Dos cosas más evitan que un espacio se desperdicie, ambas gratuitas: quote_create rechaza una cotización idéntica a una ya abierta y nombra la que tienes, y quote_delete elimina un borrador que nadie ha visto y devuelve el espacio de inmediato.

Pro es un pago único de $19, o $39 por cada servidor de la colección, de por vida.

Una cosa medida: por qué una cotización aceptada se copia, no se recalcula

quote_accept escribe la factura desde las líneas almacenadas de la cotización. La alternativa obvia, recalcular los totales desde los precios en el momento de la aceptación, se midió y se rechazó, porque la tasa de IVA que usaría es la del perfil de negocio compartido hoy, no la que se cotizó al cliente.

Medido (test/adversarial.test.mjs, "un cambio de tasa de IVA entre la cotización y la aceptación nunca mueve el total acordado"): una cotización de EUR 1,000.00 netos se emite con la tasa predeterminada del perfil del 23%, por lo que al cliente se le da EUR 1,230.00. El default_tax_rate del perfil se cambia luego al 8%, un cambio de tasa, una nueva clase de cliente, una configuración corregida, antes de que el cliente responda. Recalcular en la aceptación factura EUR 150.00 por debajo del documento que acordaron, en una sola cotización, sin nada en ninguno de los registros que explique por qué difieren. Copiar las líneas almacenadas factura EUR 1,230.00 y la afirmación se cumple tax_lines[0].rate === 23.

La misma regla es por qué la cotización toma precios en unidades menores y rechaza un decimal: el número en la cotización y el número en la factura son el mismo entero, en todo el proceso.

Números, dinero y fechas

Los identificadores de cotización son Q-YYYY-NNNN. El contador es por año y se escribe antes de almacenar la cotización, por lo que un fallo quema un identificador en lugar de reutilizar uno, y los identificadores existentes también se escanean, por lo que un quotes.json restaurado nunca puede devolver un identificador que ya esté en un documento que un cliente ha visto. El año es parte del identificador deliberadamente: un Q-0001 simple reiniciado cada enero colisiona con la cotización de enero pasado.

El dinero es en unidades menores enteras de principio a fin, y cuántas forman una unidad proviene de la tabla ISO 4217 en mcp-invoice, 2 para la mayoría de las monedas, 0 para JPY, KRW, ISK y el resto, 3 para KWD y los dinares del Golfo, 4 para CLF y UYW. No hay una segunda copia de esa tabla, de la aritmética de IVA o del formateador de dinero aquí: computeTotals, currencyDecimals y formatMoney se importan de @theluckystrike/mcp-invoice/lib, por lo que una cotización y la factura en la que se convierte redondean de manera idéntica, por línea y luego sumadas. Una cotización es una moneda; una mezcla entre líneas se rechaza en lugar de sumarse bajo el encabezado que apareció primero.

Las fechas son ISO YYYY-MM-DD. "Hoy", y por lo tanto si una cotización ha vencido, se calcula en la timezone del perfil de negocio compartido cuando se establece uno, no en la zona de la máquina anfitriona: una cotización emitida a las 00:30 en Varsovia desde una laptop aún en hora de EE. UU. se fecharía el día anterior y vencería un día antes.

Cómo almacena datos

Las cotizaciones y el contador de identificadores viven bajo ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/quotes/ como quotes.json y counter.json, más una subcarpeta pdf/ para archivos renderizados. Las facturas creadas por quote_accept se escriben en el directorio del servidor de facturas, .../mcp-servers/invoice/, por lo que invoice_list allí las muestra y comparten una serie de numeración y una lista de clientes.

Cada llamada mutante se ejecuta bajo un directorio de bloqueo de asesoría en .../quotes/.lock; cualquier cosa que escriba una factura también toma .../invoice/.lock, siempre en ese orden (cotizaciones, luego factura), el mismo orden que usa servers/recurring, por lo que dos procesos no pueden bloquearse mutuamente. Los guardados van a un archivo temporal por proceso y se renombran en su lugar. Medido: 40 cotizaciones creadas por dos procesos contra un directorio de datos dejan 40 cotizaciones y 40 identificadores únicos (test/concurrency.test.mjs).

Un archivo de almacén que no es JSON válido nunca se trata como "sin cotizaciones". Se mueve a un lado byte por byte como quotes.json.corrupt-<timestamp>, se escribe un marcador .corrupt junto a él, y cada llamada posterior, incluidas las lecturas, falla con restore a good copy ... then delete the marker hasta que un humano lo resuelve.

Límites y advertencias honestas

  • El nivel gratuito mantiene 5 cotizaciones abiertas a la vez. La exportación de texto, aceptar, rechazar y revisar no tienen restricciones en el nivel gratuito, y el informe del canal responde gratis para el año calendario actual hasta la fecha; el PDF y un rango de informe más amplio son Pro.
  • Aceptar escribe la factura a través del motor compartido, por lo que el límite gratuito propio del servidor de facturas de 3 facturas por mes calendario no se le aplica. El límite de cotizaciones es el que aplica aquí, y la respuesta lo dice.
  • Una cotización vencida es rechazada por quote_accept hasta que la extiendas (quote_update {valid_until}) o digas allow_expired: true. Es fricción deliberada: un precio vencido debe re-confirmarse.
  • No se envía ningún correo. quote_send_text te da el texto y quote_pdf te da el archivo; hacer que llegue al cliente depende de ti.
  • No hay conversión de moneda. La moneda de una cotización se fija en la creación y cada línea ya debe estar en ella.
  • Aceptar es unidireccional. No hay des-aceptar, porque la factura que creó es un documento con un número; cancela esa factura en el servidor de facturas en su lugar.

Privacidad

Todos los datos permanecen locales: archivos JSON simples en tu propio directorio de datos. Sin cuenta, sin clave de API, sin llamada de red de ningún tipo. Las claves de licencia se verifican sin conexión.

Construido por theluckystrike. Soporte: support@zovo.one