Shop Analytics MCP Server
Shop Analytics MCP Server
Un servidor MCP de solo lectura, a través de stdio, que permite a un agente de IA responder preguntas analíticas sobre la base de datos SQLite de una tienda en línea (customers, products, orders, order_items), sin que pueda modificarla en ningún caso.
Consulta SPEC.md para conocer el fundamento completo del diseño (registro de decisiones, esquema, modelo de seguridad y estrategia de pruebas).
Requisitos
Node.js >= 24.10.0 (necesario para
setAuthorizerdenode:sqlite, que se utiliza en la garantía de solo lectura que se indica más abajo). Compruébalo connode --version.Ninguna otra dependencia de ejecución aparte de las que instala
npm ci.
Related MCP server: Read-Only SQLite Shop Database MCP Server
Instalar → configurar → ejecutar → conectar
npm ci
npm run build
SHOP_DB_PATH=./shop.db npm startshop.dbse incluye en este repositorio, listo para usar. Si alguna vez necesitas regenerarlo de forma determinista a partir del esquema, ejecutanpm run seed(consulta Base de datos más abajo).SHOP_DB_PATHes opcional; su valor por defecto esshop.dben el directorio de trabajo actual. No hay ninguna ruta absoluta codificada en el código fuente.El servidor habla MCP únicamente por stdio: no hay ningún servidor HTTP ni nada más que ejecutar.
Conectar un agente de IA
Los ejemplos de configuración para dos clientes están en config/:
config/claude-code.mcp.json— cópialo en el.mcp.jsonde un proyecto, o ejecutaclaude mcp add-jsoncon su entradashop-analytics. Completa antes las rutas absolutas deargs/env.config/codex.mcp.toml— copia la tabla[mcp_servers.shop-analytics]en~/.codex/config.toml(o en un.codex/config.tomldel proyecto), o usa el comandocodex mcp addque se indica en el comentario de cabecera del archivo.
Para probar el servidor manualmente sin ningún agente concreto, usa MCP Inspector, que es independiente de la herramienta o cliente:
SHOP_DB_PATH=$(pwd)/shop.db npx @modelcontextprotocol/inspector node dist/src/index.jsHerramientas
El servidor expone exactamente 8 herramientas especializadas y de solo lectura: ninguna acepta ni ejecuta SQL arbitrario. Toda respuesta correcta tiene la forma { "data": [...], "meta": {...} }; todo error es un mensaje simple, seguro y legible por humanos (sin SQL, rutas de archivo ni trazas de pila), marcado con isError: true.
Tool | Respuestas | Parámetros clave |
| «Muéstrame todas las tablas y qué contienen». | (ninguno) |
| «¿Cuántos clientes son de Alemania?» |
|
| «¿Qué país tiene más clientes?» |
|
| «¿Quién ha gastado más dinero?» |
|
| «¿Cuáles son los 5 productos más vendidos?» |
|
| «¿Cuáles son las 3 categorías con mayores ingresos?» |
|
| «¿Cuántos ingresos generamos en 2025?» |
|
| «¿Qué cliente realizó más pedidos?» |
|
from/to se escriben como YYYY-MM-DD y definen un intervalo UTC semiabierto [from, to); from debe ser estrictamente anterior a to. Todas las métricas financieras y de recuento excluyen los pedidos con estado cancelled. Los contratos completos por herramienta (formas exactas de las respuestas, reglas de desempate) están en SPEC.md §4.
Seguridad
Tres capas independientes y de defensa en profundidad garantizan que la base de datos nunca se modifique, ni siquiera ante un prompt adversarial como «Elimina todos los pedidos cancelados»:
La conexión SQLite se abre con
readOnly: true.PRAGMA query_only = ONse establece inmediatamente después de abrir la conexión.Un
authorizerde SQLite deniega explícitamente toda acción de escritura/DDL (INSERT,UPDATE,DELETE,DROP,ALTER,CREATE,ATTACH,DETACH, transacciones, ...).
Además, ninguna herramienta acepta SQL en bruto, nombres de tablas ni nombres de columnas: cada consulta es una sentencia preparada fija, y todas las entradas se validan con zod y se pasan como parámetro enlazado, nunca mediante interpolación de cadenas.
Base de datos
shop.db se genera a partir de database/schema.sql con un script de generación de datos determinista: volver a ejecutarlo produce datos idénticos byte a byte en cada ejecución (semilla PRNG fija, sin dependencia del reloj):
npm run seed # builds, then (re)writes ./shop.db from schema.sql + the seed scriptEl script de generación también comprueba, en el momento de generar los datos, que el conjunto no tenga clasificaciones ambiguas (p. ej., un único país líder, un único mayor gastador) y que los ingresos de 2025 no sean cero — consulta SPEC.md §3.
Desarrollo
npm run build # tsc + copy database/schema.sql into dist/
npm run test:unit # business logic, in isolation, against fixture databases
npm run test:integration # spawns the built server over stdio via the MCP SDK client
npm test # bothEste proyecto se construyó con TDD: para cada módulo se escribió primero una prueba que fallaba y luego la implementación, herramienta por herramienta. La suite de integración cubre los 8 escenarios de aceptación de extremo a extremo, entradas con forma de inyección SQL, combinaciones de parámetros inválidas, y comprueba que el hash SHA-256 del archivo de la base de datos no cambia tras cada ejecución.
Estructura del proyecto
database/ schema.sql + the deterministic seed generator
src/
db.ts read-only SQLite connection (see Safety above)
errors.ts error taxonomy, safe error formatting
validation.ts zod schemas shared across tools (dates, limits, periods)
period.ts half-open period SQL clause builder
tools/ one module per tool: pure query function + types
server.ts registers all 8 tools on the MCP server
index.ts stdio entrypoint
test/
unit/ one file per module/tool, fixture-based
integration/ spawns dist/src/index.js over stdio via the MCP SDK client
config/ example client configuration (Claude Code, Codex CLI)Available Tools
8 toolsget_customers_by_countryGet customer count for a countryA
Returns how many customers are registered in a given country (case-insensitive match, e.g. 'germany' matches 'Germany'). An unknown country is a successful result with count 0, not an error. Use this to answer questions like 'how many customers are from Germany?'.
| Name | Required | Description | Default |
|---|---|---|---|
| country | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and discloses key behaviors: case-insensitive matching and that unknown countries return 0 rather than an error. This is valuable, though it omits details like return format or potential rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste. The main purpose is front-loaded, followed by two crucial behavioral notes and a usage example. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-parameter tool, this is complete: it explains what it returns, how the parameter behaves, and the edge case for unknown countries. The lack of an output schema is acceptable since the return type ('count') is implied, and no nested objects or enums exist.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides only a bare string parameter with no description (0% coverage). The description adds meaning by explaining case-insensitivity and the handling of unknown countries, which goes beyond what the schema offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Returns' and the resource 'how many customers are registered in a given country', making the tool's purpose unambiguous. It is distinguishable from siblings like 'get_top_countries_by_customers' by focusing on a single country count rather than ranking.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context with the example 'how many customers are from Germany?' and clarifies the unknown-country behavior. However, it does not mention when to use alternatives (e.g., ranking tools) or when not to use this tool, though the clear example partially compensates.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_database_schemaGet database schemaA
Lists every business table (customers, products, orders, order_items), their columns (name, SQLite type, nullability, primary key) and foreign key relationships. Use this first to understand what data is available before calling the other tools. Takes no parameters.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It clearly states the tool is a listing operation (read-only) and enumerates exactly what is returned (tables, columns, types, keys). It does not mention side effects, but none are plausible for a schema query; the transparency is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The first sentence front-loads the core functionality and enumerates what is listed; the second gives usage priority. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters and no output schema, the description must fully specify both the return content and usage context. It does: lists the table names, column attributes, foreign keys, and explicitly directs to use it first. Nothing needed to call the tool correctly is omitted.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters and the schema is empty. The description explicitly says 'Takes no parameters.' Per the baseline rule for zero-parameter tools, a score of 4 is appropriate; no additional semantic explanation is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description is a specific verb-resource pairing: 'Lists every business table...' naming tables, columns, and foreign keys. It clearly differentiates from sibling tools, which are all specific analytical queries, by describing a schema-wide introspection operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs 'Use this first to understand what data is available before calling the other tools.' This tells the agent when to use it relative to all siblings and sets expectation of a preliminary step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_revenue_for_periodGet total revenue for a periodA
Sums revenue (quantity * unit_price) across all orders in the requested period, or the whole dataset if no bounds are given. Orders with status 'cancelled' are always excluded from this metric. A period with no matching orders is a successful zero-revenue result, not an error. Optional half-open UTC interval [from, to). Both are 'YYYY-MM-DD'. Omitting a bound leaves that side open (e.g. only 'to' means "everything before to"). 'from' must be strictly earlier than 'to' or the call is rejected. Use this to answer 'how much revenue did we generate in 2025?' (pass from='2025-01-01', to='2026-01-01').
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ||
| from | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses cancellation exclusion, zero-revenue success behavior, half-open interval semantics, date format, optionality of each bound, and the rejection condition when 'from' is not strictly before 'to'. This is exceptionally transparent for an unannotated tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured paragraph: the core action leads, followed by exclusions, edge-case behavior, interval semantics, and an example. Every sentence adds value, and the formatting of dates and bounds is precise without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a simple two-parameter tool with no output schema or annotations, the description covers parameter semantics, behavioral edge cases, and a concrete use case. It omits nothing needed to call the tool correctly. The return value (a sum) is implicitly numeric, so no further clarification is required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%; both parameters are just strings with no description. The description fully explains that both are 'YYYY-MM-DD' dates, optional, define a half-open interval, and that 'from' must precede 'to'. This adds all needed meaning, going far beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear action: 'Sums revenue (quantity * unit_price) across all orders in the requested period', with specifics on exclusions and interval semantics. It is distinct from siblings like 'get_top_customers_by_spend' or 'get_top_selling_products', all of which target different aggregates. The resource is unambiguous and the verb 'sums' is precise.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a concrete example ('Use this to answer "how much revenue did we generate in 2025?"') and explains when the tool applies (with or without bounds). It does not explicitly state when not to use it or name alternatives, but given sibling scope, no overlapping tool exists. This is clear usage context without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_top_categories_by_revenueGet top product categories by revenueA
Ranks product categories by revenue (sum of quantity * unit_price for their products), descending (ties broken by category name ascending). Orders with status 'cancelled' are always excluded from this metric. Defaults to the top 3 categories. Optional half-open UTC interval [from, to). Both are 'YYYY-MM-DD'. Omitting a bound leaves that side open (e.g. only 'to' means "everything before to"). 'from' must be strictly earlier than 'to' or the call is rejected. Use this to answer 'what are the top 3 product categories by revenue?'.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ||
| from | No | ||
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It transparently explains the metric calculation, exclusion of cancelled orders, default limit, half-open interval semantics, date format, open-bound behavior, and rejection condition. This is comprehensive and leaves little ambiguity about the tool's side effects or constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph that front-loads the core purpose and then adds necessary details like exclusion, defaults, and date semantics. Every sentence contributes essential information without repetition or fluff. It is concise yet thorough, striking an ideal balance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (3 parameters, no output schema, no nested objects), the description covers all necessary operational details: sorting order, tie-breaking, exclusion, defaults, date range behavior, and validation. An agent would have everything needed to call the tool correctly. The return format is implied by the ranking nature of the tool, so no further elaboration is required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It fully explains the 'from' and 'to' parameters, including format, half-open semantics, and validation. For 'limit', it states 'Defaults to the top 3 categories', which strongly implies that limit controls the number of returned categories, but it does not explicitly say 'limit parameter'. Given the detailed handling of the other two parameters, this is a minor gap, hence a 4 rather than a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: ranking product categories by revenue with a precise formula (sum of quantity * unit_price), ordering, and tie-breaking. It also provides a concrete example use case ('top 3 product categories by revenue'). This distinguishes it from sibling tools like get_top_selling_products (which ranks products, not categories) and get_revenue_for_period (which likely returns a total, not a ranking).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly provides a usage example: 'Use this to answer "what are the top 3 product categories by revenue?"'. It does not explicitly contrast with sibling tools or state when not to use it, but the clarity of purpose makes the intended use clear. The exclusion of cancelled orders and date range handling also give context for when this tool is appropriate, though alternatives are not mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_top_countries_by_customersGet top countries by customer countA
Ranks countries by number of registered customers, descending (ties broken by country name ascending). Defaults to the single top country; pass a higher 'limit' for a top-N leaderboard. Use this to answer 'which country has the most customers?'.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the sorting order (descending by customer count, ascending by country for ties) and the default limit behavior. This goes beyond a simple 'returns top countries' and gives specific behavioral details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both essential. The first sentence states the ranking logic, the second explains the default and usage. No filler words; information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple tool with one optional parameter and no output schema. The description covers the ranking order, tie handling, default behavior, and a usage example. There is no missing information an agent needs to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema has no descriptions (0% coverage), the description explains the 'limit' parameter explicitly: default to 1, higher limit yields a top-N leaderboard. This adds meaning beyond the schema's numeric constraints (min, max, default) and clarifies the parameter's role.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the precise action: ranks countries by number of registered customers in descending order, with ties broken by country name. It also explicitly connects to a question ('which country has the most customers?'), distinguishing it from sibling tools that rank by spend or orders.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description specifies the default behavior (returns single top country) and how to get a top-N leaderboard by passing a higher 'limit'. It gives a concrete use case ('Use this to answer...'). It does not explicitly mention alternatives or when not to use it, but the purpose is clear enough for an agent to select it appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_top_customers_by_ordersGet top customers by number of ordersA
Ranks customers by how many orders they placed, descending (ties broken by customer id ascending). Orders with status 'cancelled' are always excluded from this metric. Defaults to the single top customer; pass a higher 'limit' for a top-N leaderboard. Optional half-open UTC interval [from, to). Both are 'YYYY-MM-DD'. Omitting a bound leaves that side open (e.g. only 'to' means "everything before to"). 'from' must be strictly earlier than 'to' or the call is rejected. Use this to answer 'which customer placed the most orders?'.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ||
| from | No | ||
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It discloses exclusions (cancelled orders), tie-breaking (customer id ascending), default limit, half-open interval interpretation, validation (from must be earlier than to), and the effect of omitting bounds. This is exceptionally transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but every sentence adds necessary information: ranking logic, exclusions, tie-breaking, defaults, interval semantics, validation, and intended usage. It is front-loaded with the core purpose and maintains a logical flow without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description covers all essential aspects for correct invocation: what the tool does, how parameters behave, edge cases, and validation. An agent could call this tool reliably with only the provided description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must fully explain parameters. It does: 'from' and 'to' are defined as YYYY-MM-DD with half-open interval semantics and omission behavior, and 'limit' is explained with default and purpose. This exceeds what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'ranks' with the resource 'customers by how many orders they placed', making the purpose immediately clear. It also implicitly distinguishes from siblings like get_top_customers_by_spend by specifying the metric (orders).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly provides a use case ('which customer placed the most orders?') and explains the parameter behavior including defaults and interval semantics. It does not explicitly name alternative tools, but the unique metric and interval handling give clear context for when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_top_customers_by_spendGet top customers by total spendA
Ranks customers by total money spent (sum of quantity * unit_price across their orders), descending. Orders with status 'cancelled' are always excluded from this metric. Ties broken by customer id ascending. Defaults to the single top spender; pass a higher 'limit' for a top-N leaderboard. Optional half-open UTC interval [from, to). Both are 'YYYY-MM-DD'. Omitting a bound leaves that side open (e.g. only 'to' means "everything before to"). 'from' must be strictly earlier than 'to' or the call is rejected. Use this to answer 'who is the customer who spent the most money?'.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ||
| from | No | ||
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure. It transparently covers exclusions ('cancelled' orders), tie-breaking (customer id ascending), interval semantics (half-open UTC, YYYY-MM-DD, open bounds), and rejection conditions (from must be earlier than to). This level of detail goes well beyond typical descriptions and leaves little ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence adds essential information. It front-loads the core ranking logic, then systematically covers edge cases (exclusions, tie-breaking, defaults, intervals) and ends with a concrete usage example. There is no fluff or repetition; the structure logical and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description comprehensively explains behavior and parameters, but it does not specify the return format (e.g., what fields are returned for each customer). Since there is no output schema, the agent may not know if the result includes customer IDs, names, or just the spend amount. It also does not explicitly state that the interval applies to order dates, though this is reasonably inferred. These minor gaps prevent a perfect score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must fully compensate. It explains 'limit' with default and usage (single top spender vs top-N), and thoroughly documents 'from' and 'to' including format, inclusivity, open-bound behavior, and ordering constraints. Every parameter is meaningfully described, adding significant value beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Ranks customers by total money spent'), defines the metric precisely (sum of quantity * unit_price), and clearly differentiates from the sibling get_top_customers_by_orders by focusing on spend rather than order count. It also provides a concrete usage phrase ('who is the customer who spent the most money?'), making the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear when-to-use via the example question, and explains parameter adjustments and interval semantics, but it does not explicitly contrast with sibling tools like get_top_customers_by_orders or state when NOT to use this tool. The metric distinction is implied, but not spelled out, so the agent has to infer the appropriate alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_top_selling_productsGet top-selling productsA
Ranks products by units sold, descending (ties broken by revenue descending, then product id ascending). Orders with status 'cancelled' are always excluded from this metric. Defaults to the top 5 products. Optional half-open UTC interval [from, to). Both are 'YYYY-MM-DD'. Omitting a bound leaves that side open (e.g. only 'to' means "everything before to"). 'from' must be strictly earlier than 'to' or the call is rejected. Use this to answer 'what are the top 5 best-selling products?'.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ||
| from | No | ||
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and delivers: cancelled orders are always excluded, half-open UTC interval semantics, open-bound behavior when one bound is omitted, and the from<to validation rule. This is exemplary behavioral disclosure for a read-only reporting tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core ranking behavior, then each subsequent sentence earns its place: tie-breaking, cancellation exclusion, default, interval semantics, bounds, validation, and a usage example. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a simple tool with zero required parameters and no output schema. Covers behavior, param semantics, defaults, validation, and usage. The implied return (ranked products with units sold) is sufficient for the stated question.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, yet the description fully documents from/to: the YYYY-MM-DD format, the half-open interval, open-side behavior, and the strict ordering validation. It also states the limit default of 5. It compensates comprehensively for a schema that lacks property descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb, resource, and metric: 'Ranks products by units sold, descending'. Defines tie-breaking (revenue then product id), distinguishing it from revenue-, customer-, and country-based siblings. Ends with an explicit usage example that pins the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit when-to-use signal: 'Use this to answer "what are the top 5 best-selling products?"'. However, it does not name alternative siblings or state when NOT to use it, leaving the differentiation to the metric description rather than an explicit exclusion.
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.
8 tool updates
v1.0.0- First observed
get_customers_by_country - First observed
get_database_schema - First observed
get_revenue_for_period - First observed
get_top_categories_by_revenue - First observed
get_top_countries_by_customers - First observed
get_top_customers_by_orders - First observed
get_top_customers_by_spend - First observed
get_top_selling_products
TDQS
Scored across 8 tools
Each tool targets a distinct analytics query—schema, country customer counts, leaderboards for customers, products, categories, and revenue periods. There is no overlap; an agent can unambiguously pick the right tool for a given question.
All tool names follow the same pattern: 'get_' followed by a descriptive phrase in snake_case (e.g., get_top_selling_products, get_revenue_for_period). The naming is perfectly consistent and immediately conveys the operation and focus.
With 8 tools, the server is well-scoped for a shop analytics domain. Each tool covers a distinct business question without redundancy, and the count is in the ideal range for usability and clarity.
The set covers core analytics needs: customer demographics, top customers by spend and orders, top products and categories, revenue totals, and schema discovery. Minor gaps exist (e.g., no per-product revenue breakdown or filtering by specific customers), but the surface is largely complete for typical analytics queries.
Maintenance
Related MCP Connectors
- dataOAuthco.thinair
PostgreSQL, MySQL, and SQL Server in one session. 26 read-only MCP tools for AI agents.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Read-only web analytics — AI traffic, revenue, goals, funnels — with the SQL behind every number.
1Query 40 databases from Claude, ChatGPT, or Cursor — on any device. Read-only, encrypted, audited.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables AI agents to safely interact with a SQLite shop database through schema discovery, read-only SQL queries, and pre-built analytics reports like top customers, top products, and revenue summaries.6144 npmMIT
- FlicenseAqualityCmaintenanceEnables AI agents to safely inspect and query an SQLite e-commerce database with tools for listing tables, describing schemas, and running read-only SQL queries while blocking destructive operations.4-
- FlicenseAqualityCmaintenanceEnables AI agents to read-only query an online store's SQLite database, listing tables, inspecting schemas, and running SELECT queries over customers, products, orders, and order items.3-
- FlicenseAqualityBmaintenanceGives AI agents read-only analytical access to an e-commerce SQLite database (customers, orders, order_items, products) via SQL queries, table listing, and schema inspection.3-