Skip to main content
Glama
genvjacobc

lightspeed-x

by genvjacobc

lightspeed-x-mcp

Un servidor de Model Context Protocol para Lightspeed X (Lightspeed Retail POS, la plataforma anteriormente conocida como Vend). Ofrece a Claude, o a cualquier cliente MCP, acceso de solo lectura a las ventas, el inventario, los productos y los clientes de tu tienda, y hace la agregación por ti: ingresos, unidades, COGS, beneficio bruto, margen, descuento, valor medio de cesta y tamaño de cesta, agrupados por la dimensión que pidas.

Solo lectura por construcción. Cada herramienta emite peticiones GET. No hay ninguna ruta de código en este servidor que pueda crear, actualizar o eliminar nada en tu cuenta, así que puedes apuntarlo a un negocio minorista real sin preocuparte.

"What sold best yesterday?"                → lightspeed_sales_report
"Revenue by store last week"               → lightspeed_sales_report, group_by: outlet
"Which SKUs need reordering?"              → lightspeed_inventory_report, status: reorder_needed
"What are our busiest hours?"              → lightspeed_sales_report, group_by: hour
"Margin by brand this month"               → lightspeed_sales_report, group_by: brand
"Pull up invoice 162220"                   → lightspeed_list_sales

Por qué existe esto

La API de Lightspeed X es una superviviente de la era Vend y tiene algunas aristas que hacen que los clientes ingenuos sean lentos o se equivoquen silenciosamente. Este servidor las maneja para que el modelo no tenga que hacerlo:

Realidad

Lo que hace este servidor

/sales acepta date_from y date_to, y luego los ignora silenciosamente. Todos los resultados vuelven independientemente de las fechas que hayas pedido.

Localiza un rango de fechas mediante búsqueda binaria en la secuencia de versiones y luego filtra localmente. Un cliente ingenuo que confía en los parámetros devuelve respuestas incorrectas con total confianza.

La paginación se basa en versiones, no en cursores. No hay clave cursor; las respuestas llevan version: {min, max} y paginas con ?after=<version>.

Gestionado de forma transparente por el helper paginate del cliente.

El page_size máximo documentado es 200, pero la API realmente sirve hasta 5000.

Los escaneos masivos usan 5000 (las ventas usan 1000, porque las ventas llevan sus líneas de detalle completas). Un escaneo de inventario de 126 000 filas tarda 26 peticiones en lugar de 630.

Las líneas de detalle de venta solo llevan product.id. Sin nombre, sin SKU, sin categoría.

Hace un join contra un catálogo de productos en caché para que cada informe sea legible por humanos.

El día de una tienda no empieza a medianoche UTC, así que una división ingenua archiva las ventas de la tarde en el día equivocado.

Los grupos de día, mes, día de la semana y hora se resuelven en la zona horaria IANA del propio outlet.

Las devoluciones se registran como líneas de detalle con cantidad negativa y totales negativos.

Se compensan correctamente en todas las métricas, sin necesidad de casos especiales.

/product_categories devuelve una forma de sobre completamente diferente a la de cualquier otro endpoint.

Gestionado como un caso propio.

El límite de tasa es 300 x registers + 50 por 5 minutos, y los 429 no llevan un Retry-After fiable.

Backoff exponencial con reintentos en 429 y 5xx.

Cómo se deriva el cálculo de ingresos

Verificado contra 200 ventas reales consecutivas. Cada una conciliada con el totals.price de la propia venta con una diferencia de dos céntimos:

line revenue excl tax = line_items[].pricing.total        (net of discount, already x quantity)
line COGS             = line_items[].pricing.cost_total
line discount given   = line_items[].pricing.discount_total
line tax              = line_items[].tax.total

Tres comprobaciones adicionales sobre datos reales, todas exactas:

  • La suma de los ingresos por día durante una semana equivale al total general de la semana.

  • La fila de un outlet en un informe group_by: outlet equivale al mismo informe reejecutado con el filtro del lado del servidor de ese outlet.

  • La suma de los importes pagados por tipo de pago equivale a los ingresos con impuestos incluidos.


Related MCP server: Toast MCP

Instalación

Opción 1: como plugin de Claude Code (recomendado)

Tres comandos, sin clonar, sin compilar, sin rutas que editar:

/plugin marketplace add genvjacobc/lightspeed-x-mcp
/plugin install lightspeed-x@lightspeed-x-mcp
/lightspeed-x:setup

El tercer comando ejecuta una skill de configuración incluida que te guía para obtener un token, lo escribe en el lugar correcto y verifica la conexión contra tu cuenta real antes de decirte que ha funcionado.

El plugin también incluye una skill reports para que Claude sepa qué herramienta responde a cada tipo de pregunta minorista y cómo leer los números que recibe.

Las credenciales viven en ${CLAUDE_PLUGIN_DATA}/credentials.env, un directorio por usuario que sobrevive a las actualizaciones del plugin. Nada se comparte entre máquinas o compañeros de equipo.

Ten en cuenta que /plugin uninstall elimina ese directorio, así que desinstalar y reinstalar significa volver a ejecutar la configuración. El token en sí permanece activo en Lightspeed de todos modos, así que revócalo allí si has terminado con él.

Opción 2: como servidor MCP independiente

git clone https://github.com/genvjacobc/lightspeed-x-mcp.git
cd lightspeed-x-mcp
npm install
npm run build

Requiere Node 18 o superior.

Obtener un token de API

En el back office de Lightspeed X: Setup → Personal Tokens → Add Personal Token. Cópialo antes de cerrar el diálogo; solo se muestra una vez.

Dos límites que conviene conocer antes de planificar un despliegue:

  • Solo los usuarios administradores pueden crear tokens personales, y Lightspeed restringe la función a los planes Plus. Si Personal Tokens no aparece en Setup, alguien con acceso de administrador tiene que crear el token por ti.

  • Lightspeed no ofrece tokens de solo lectura. Un token lleva todos los permisos del usuario que lo creó. Este servidor solo emite GET, pero el token en sí es una credencial de propósito general, así que trátalo como una contraseña y revócalo desde la misma pantalla si se filtra.

Comprobar que funciona

npm run doctor

Esto valida tus credenciales, llama a la API real y nombra la causa exacta de cualquier fallo. Un dominio de tienda incorrecto y un token malo devuelven ambos HTTP 401 de Lightspeed, así que el doctor informa de ambas posibilidades en lugar de adivinar.

Configurar

Copia .env.example a .env y rellena tu tienda:

LIGHTSPEED_DOMAIN=mystore
LIGHTSPEED_TOKEN=your_personal_token

LIGHTSPEED_DOMAIN acepta un prefijo simple (mystore), un host (mystore.retail.lightspeed.app) o una URL completa. Los tres resuelven al mismo lugar.

Varias tiendas. Cualquier par LIGHTSPEED_<NAME>_DOMAIN + LIGHTSPEED_<NAME>_TOKEN define una cuenta llamada <name>, en minúsculas. Las herramientas aceptan entonces un argumento opcional account:

LIGHTSPEED_NORTH_DOMAIN=northstore
LIGHTSPEED_NORTH_TOKEN=token_for_north
LIGHTSPEED_SOUTH_DOMAIN=southstore
LIGHTSPEED_SOUTH_TOKEN=token_for_south
LIGHTSPEED_DEFAULT_ACCOUNT=north

Los valores ya presentes en el entorno siempre ganan al archivo .env, así que un host que inyecta credenciales directamente tiene prioridad.

Registrar con Claude Code (solo ruta independiente)

Omite esto si instalaste el plugin; el plugin registra el servidor por sí mismo.

claude mcp add lightspeed-x -s user -- node /absolute/path/to/lightspeed-x-mcp/dist/index.js

O añádelo a tu configuración manualmente:

{
  "mcpServers": {
    "lightspeed-x": {
      "command": "node",
      "args": ["/absolute/path/to/lightspeed-x-mcp/dist/index.js"],
      "env": {
        "LIGHTSPEED_DOMAIN": "mystore",
        "LIGHTSPEED_TOKEN": "your_personal_token"
      }
    }
  }
}

Para Claude Desktop, el mismo bloque va en claude_desktop_config.json.

Verifícalo localmente con el MCP Inspector:

npm run inspect

Herramientas

lightspeed_sales_report

El plato principal. Agrega un rango de fechas y lo agrupa.

Argumento

Notas

date_from, date_to

YYYY-MM-DD, inclusivo, leído en la zona horaria del informe

group_by

product (predeterminado), sku, category, brand, supplier, tag, outlet, register, salesperson, customer, day, month, weekday, hour, payment_type, none

metrics

revenue, revenue_incl_tax, units, sale_count, cogs, gross_profit, margin_pct, discount, tax, basket_value, basket_size, customer_count

sort_by, sort_direction, limit

Controles de clasificación

outlet_id

Aplicado en el lado del servidor, así que es realmente rápido

states

Por defecto closed, que es lo que significa un informe

timezone

Anulación de zona IANA para los límites de día

| Outlet          |   Revenue | Units | Sales | Basket value | Gross profit | Margin |
| --------------- | --------: | ----: | ----: | -----------: | -----------: | -----: |
| South Lincoln   | $3,401.60 |   193 |    91 |       $37.38 |    $2,342.35 |  68.9% |
| York            | $3,222.86 | 159.2 |    73 |       $44.15 |    $2,238.77 |  69.5% |

lightspeed_list_sales

Transacciones individuales, de más reciente a más antigua, con expansión opcional de líneas de detalle. Para profundizar en un recibo, auditar un total o revisar devoluciones. Filtros por outlet_id, customer_id y min_total.

lightspeed_inventory_report

Existencias disponibles unidas a los nombres de producto y outlet, con el valor de venta al público y de coste de lo que hay en el estante.

status es el argumento que importa:

Estado

Significado

low_stock

Todavía vendible pero en o por debajo del punto de reorden. Lo que se está agotando.

reorder_needed

En o por debajo del punto de reorden, incluidos cero y negativos. La lista de compra completa.

out_of_stock

Exactamente cero.

negative

Por debajo de cero, lo que significa un error de recuento de existencias.

in_stock / all

Más de cero / todo.

group_by agrega a product, outlet, category, brand o supplier, que es como respondes a «cuánto valor de inventario hay en cada categoría».

lightspeed_search_products

Búsqueda de texto libre sobre nombre, nombre de variante, SKU y handle, con filtros de marca / proveedor / categoría / etiqueta. La coincidencia se ejecuta localmente contra el catálogo en caché porque el endpoint de búsqueda de la propia API clasifica mal, así que los resultados son coincidencias exactas de subcadena.

lightspeed_get_product

Detalle completo de un producto por ID o SKU exacto, incluido el stock por outlet y el margen calculado.

lightspeed_search_customers / lightspeed_get_customer

Busca clientes por correo electrónico (enviado a la API), o por nombre, teléfono o código de cliente (coincidencia local). Devuelve el UUID que las herramientas de ventas aceptan como filtro customer_id. Esto devuelve datos personales; trátalos en consecuencia.

lightspeed_list_outlets / lightspeed_list_registers / lightspeed_list_accounts

Resuelve nombres de tienda a los UUID de outlet que aceptan los filtros de informe, lista las líneas de TPV incluidos los registros de comercio electrónico, y ve a qué cuentas puede llegar el servidor. lightspeed_list_accounts nunca devuelve tokens.

lightspeed_list_reference_data

Una herramienta sobre brands, suppliers, product_categories, tags, customer_groups, payment_types, promotions, taxes y users. Úsala para obtener la ortografía exacta de una marca o categoría antes de filtrar un informe por ella.

lightspeed_api_get

Vía de escape para cualquier endpoint sin una herramienta específica: /consignments, /price_books, /serial_numbers, etc. Solo se emiten peticiones GET.


Rendimiento y límites

Los informes están condicionados por el hecho de que las ventas no se pueden filtrar por fecha en el servidor.

Consulta

Tiempo típico en frío

Un día, todos los establecimientos (~900 ventas)

De 15 a 20 s en la primera llamada, luego ~2 s

Una semana (~5.900 ventas)

~20 s

Escaneo completo de inventario (~126.000 filas)

~25 s en la primera llamada, luego instantáneo

Búsquedas de producto / establecimiento / referencia

Menos de 1 s después de la primera llamada

La mayor parte de una llamada en frío son las ~30 sondas de una sola fila que localizan el rango de fechas. Esas sondas se recuerdan por cuenta, así que el segundo informe de una sesión normalmente no necesita ninguna. Los escaneos de catálogo, establecimiento, caja, usuario e inventario se almacenan en caché durante 15 minutos.

Para mantener la rapidez: pasa outlet_id cuando solo te interese una tienda, y prefiere rangos de fechas estrechos. LIGHTSPEED_MAX_SALES (por defecto 200.000) limita una sola llamada, y la herramienta te indica claramente cuando trunca en lugar de devolver silenciosamente una respuesta parcial.

Una advertencia honesta. Como el rango de fechas se localiza por versión, una venta creada antes del rango pero editada después puede pasarse por alto. LIGHTSPEED_SEEK_MARGIN_DAYS (por defecto 1) establece cuánto antes del rango apunta la búsqueda, y aumentarlo amplía la red de seguridad a costa de escanear más registros. Esto es inherente a una API que no filtra por fecha, no un atajo tomado aquí.


Referencia de configuración

Variable

Valor por defecto

Propósito

LIGHTSPEED_DOMAIN

obligatorio

Prefijo de tienda, host o URL

LIGHTSPEED_TOKEN

obligatorio

Token personal

LIGHTSPEED_<NAME>_DOMAIN / _TOKEN

opcional

Cuentas adicionales con nombre

LIGHTSPEED_DEFAULT_ACCOUNT

primera cuenta

Cuenta utilizada cuando una herramienta omite account

LIGHTSPEED_API_VERSION

2026-01

Segmento de ruta de la versión de la API

LIGHTSPEED_MAX_SALES

200000

Límite de seguridad por llamada de ventas

LIGHTSPEED_SEEK_MARGIN_DAYS

1

Días de margen al buscar el ancla de versión

LIGHTSPEED_ENV_FILE

opcional

Ruta explícita a un archivo de credenciales. El plugin la establece en ${CLAUDE_PLUGIN_DATA}/credentials.env


Desarrollo

npm run dev      # run from source with tsx
npm run build    # compile to dist/
npm run inspect  # MCP Inspector against the built server
npm run doctor   # credentials + live connectivity check
npm run validate-plugin  # validate the plugin manifests
src/
  index.ts            entry point, env loading, tool registration
  config.ts           account discovery from the environment
  lib/
    client.ts         HTTP client, retry, version pagination
    version-seek.ts   date to version binary search
    sales.ts          sale fetching and metric aggregation
    catalog.ts        cached product, outlet, register, inventory lookups
    time.ts           timezone-aware day boundaries
    format.ts         Markdown table rendering, tool results
  tools/              one file per tool group

Las herramientas devuelven tablas Markdown en lugar de JSON sin procesar: un modelo lee una tabla alineada de forma más fiable que un blob JSON profundo, con una fracción de los tokens. Los números subyacentes también están en structuredContent para quienes llaman programáticamente.

Dos convenciones que vale la pena mantener si contribuyes:

  • Nunca lances una excepción desde un manejador de herramienta. Los fallos se devuelven como resultados isError. El envoltorio guard() lo garantiza.

  • Nunca uses console.log. La salida estándar transporta tramas JSON-RPC. Los diagnósticos van a console.error.


Estructura del repositorio

.claude-plugin/     plugin + marketplace manifests
.mcp.json           MCP server declaration used by the plugin path
skills/setup/       guided connection walkthrough
skills/reports/     how to answer retail questions with these tools
src/                TypeScript source
dist/               compiled output, committed so plugin installs need no build

dist/ se rastrea intencionadamente en git, porque la instalación del plugin de Claude Code no ejecuta un paso de compilación y el servidor compilado debe viajar con el repositorio. Ejecuta npm run build antes de confirmar un cambio de código fuente, y sube la version en package.json, .claude-plugin/plugin.json y .claude-plugin/marketplace.json a la vez al publicar.

Licencia

MIT. Consulta LICENSE.

No está afiliado ni respaldado por Lightspeed Commerce.

Available Tools

1 tool
lightspeed_setup_statusLightspeed setup statusA
Read-only

Report whether this server has working Lightspeed credentials, and if not, the exact file path to create and what to put in it. Call this first when any Lightspeed tool fails with a credential error, when the user says Lightspeed is not connected, or when setting the server up for the first time. Safe to call at any time and never returns the token itself.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark readOnlyHint=true and openWorldHint=true, so the description need not restate safety labels. It adds valuable context: the tool never returns the token itself, and it reports the exact file path and content to create when credentials are absent. This is a useful disclosure beyond the structured hints, warranting a 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose, then usage conditions, then a safety note. Every word earns its place; there is no fluff or repeated information. Ideal conciseness for a tool of this simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (no parameters, no output schema) and the description covers everything an agent needs to call it correctly: the exact condition to invoke it, what it reveals (success or failure plus remediation info), and its non-sensitive nature. Nothing is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters, the schema is trivially covered at 100%, and the rubric sets a baseline of 4 for this case. The description adds no parameter-specific meaning, but nothing is missing—there is nothing to document. The baseline score is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise statement of what the tool does: report whether the server has working Lightspeed credentials and, if not, provide the exact file path and content to fix it. This is a specific verb-resource pair that leaves no doubt about the tool's role, and it stands alone clearly even without siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit, actionable usage guidance: call this first when a Lightspeed tool fails with a credential error, when the user reports Lightspeed is not connected, or during initial setup. It also notes the tool is safe to call at any time, covering both when to use and the absence of constraints.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev1.2.0
    • First observedlightspeed_setup_status

TDQS

A4.2/5.0

Scored across 1 tool

Disambiguation5/5

With only one tool, there is no possibility of confusion or overlap between tool purposes. The tool's role as a credential/setup status check is clearly defined.

Naming Consistency5/5

A single tool name cannot exhibit inconsistency. 'lightspeed_setup_status' is descriptive, snake_case, and follows a predictable pattern for this server.

Tool Count1/5

A single setup/status tool is an extreme mismatch for a server named 'lightspeed-x'. The tool explicitly references other Lightspeed tools that do not exist, making the surface feel incomplete and unbalanced.

Completeness1/5

The server provides no actual Lightspeed operations—only a credential status check. This is severely incomplete for a Lightspeed integration domain and leaves agents with no way to perform real tasks.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to query live Toast POS data and generate sales, labor, and cash reports while answering restaurant operations questions, all in a read-only manner.
    32 npm
    MIT
  • A
    license
    C
    quality
    B
    maintenance
    Enables Claude or any MCP client to query a Toast POS using plain English, with 55 read-only tools covering orders, sales, labor, employees, menus, inventory, customers, and cash.
    55
    2
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to query a retail and food-service point-of-sale database through predefined business tools for sales summaries, top products, margins, stagnant inventory, cash reconciliation, and optional stock adjustments, returning formatted markdown answers.
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    Enables Claude and other MCP clients to read and write a Loyverse point-of-sale account, covering catalogue items, inventory levels, loyalty customers, receipts and refunds through natural language. Includes a one-call sales summary that aggregates any date range into totals and ranked breakdowns by day, item, category, payment type, employee or store.
    41
    MIT