Skip to main content
Glama

shop-mcp

Un servidor de Model Context Protocol de solo lectura que expone herramientas de análisis sobre la base de datos SQLite shop.db de una tienda en línea (clientes, productos, pedidos, artículos de pedido). Está diseñado para conectarse a un agente de IA para que el agente pueda responder preguntas analíticas sobre los datos sin poder modificarlos nunca.

El servidor habla MCP a través de stdio, abre la base de datos en modo solo lectura y expone un pequeño conjunto de herramientas especializadas y parametrizadas cuyas descripciones codifican las reglas del dominio (qué estados de pedido cuentan como ingresos, cómo se determina el país de un cliente, de dónde proviene el dinero). No hay ninguna herramienta SQL genérica ni herramienta de escritura: una instrucción destructiva como "Elimina todos los pedidos cancelados" no puede ejecutarse.

El código del servidor MCP en este repositorio fue producido por un agente de codificación de IA (Cursor), según el requisito de la tarea de que el servidor no debe escribirse a mano.

Requisitos

  • Python 3.11 o más reciente

  • La base de datos SQLite shop.db (incluida en database/shop.db)

  • uv (recomendado) — ejecuta el servidor en un entorno de proyecto aislado, sin instalación global. Se instala con brew install uv (macOS) o curl -LsSf https://astral.sh/uv/install.sh | sh.

Related MCP server: MCP SQLite RBAC Demo

Instalación

Con uv (recomendado) — no se necesitan ni venv manual ni pip; uv resuelve el proyecto y sus dependencias a partir de pyproject.toml en la primera ejecución:

uv sync          # create / refresh the project's .venv from pyproject.toml

Sin uv — crea un virtualenv e instala el paquete tú mismo:

python3 -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -e .

Esto instala el SDK mcp y el paquete shop-mcp (que proporciona el punto de entrada python -m shop_mcp y el script de consola shop-mcp).

Configuración

El servidor abre la base de datos en database/shop.db relativa al directorio de trabajo del proceso (ProjectRoot). No se requieren variables de entorno.

Cuando se lanza mediante uv run --directory <proyecto> (consulta las configuraciones de cliente más abajo), uv establece el directorio de trabajo en la raíz del proyecto, así que la base de datos incluida se encuentra automáticamente.

Si database/shop.db no existe, el servidor sale al inicio con un error de configuración claro que incluye el directorio de trabajo actual (sin traza de pila, sin recurso silencioso). Asegúrate de que tu configuración de cliente MCP defina cwd como la raíz del repositorio.

Ejecución

uv run python -m shop_mcp

o, con el paquete instalado en un venv activo:

python -m shop_mcp

o, de forma equivalente:

shop-mcp

El servidor lee JSON-RPC por stdin y escribe en stdout. Normalmente no lo ejecutas directamente — tu agente de IA lo lanza por ti (ver más abajo).

Conexión a un agente

Hay configuraciones de cliente MCP listas para usar en examples/mcp/ y funcionan sin más preparación que instalar uv:

Cliente

Archivo de configuración

Cursor

examples/mcp/cursor.json

Claude Desktop

examples/mcp/claude_desktop.json

Stdio genérico

examples/mcp/generic_stdio.json

Canónica/predeterminada

examples/mcp/shop.json

Docker

examples/mcp/docker.json

Cada configuración tiene esta forma (sustituye la ruta de --directory por la ruta absoluta de este repositorio en tu máquina):

{
  "mcpServers": {
    "shop": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/internet-shop-mcp", "python", "-m", "shop_mcp"]
    }
  }
}

uv run --directory <proyecto> establece el directorio de trabajo en la raíz del proyecto y usa el .venv del proyecto, así que el servidor encuentra database/shop.db automáticamente. La misma configuración es portable entre máquinas (solo cambia la ruta de --directory).

Si prefieres no usar uv, instala el paquete en un venv tú mismo (consulta Instalación), usa command: "python" y define cwd como la raíz del repositorio en tu configuración de cliente MCP.

  • Cursor: abre Ajustes → MCP → Añadir servidor MCP y pega el contenido de examples/mcp/cursor.json (o usa el ámbito Project MCP y haz commit de él).

  • Claude Desktop: copia el contenido de examples/mcp/claude_desktop.json en claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json).

  • Cliente stdio genérico: usa examples/mcp/generic_stdio.json con cualquier cliente que hable MCP sobre stdio.

Tras la conexión, el agente ve ocho herramientas: list_tables, describe_table, count_customers_by_country, rank_countries_by_customers, top_customers, top_products, revenue_by_category, revenue_by_year.

Herramientas

Herramienta

Responde a

list_tables

Tarea 1 — lista las tablas y qué contiene cada una

describe_table(table)

Esquema de una tabla

count_customers_by_country(country?)

Tarea 2 — clientes de un países

rank_countries_by_customers(limit)

Tarea 3 — el país con más clientes

top_customers(by, limit, offset)

Tareas 4 y 8 — mayor gasto / más pedidos

top_products(limit, metric, offset)

Tarea 5 — productos más vendidos

revenue_by_category(limit, offset)

Tarea 6 — categorías por mayores ingresos

revenue_by_year(year)

Tarea 7 — ingresos de un año

Reglas del dominio integradas en las descripciones de las herramientas (consulta CONTEXT.md y docs/adr/ para conocer el fundamento completo):

  • País se deriva del prefijo del número de teléfono del cliente (E.164). No existe una columna country. +49 → Alemania, +7 → Rusia. Un prefijo no reconocido se asigna a unknown. La herramienta acepta un nombre completo ("Alemania") o un código ISO alfa-2 ("DE") y devuelve ambos.

  • Ingresos / gasto solo cuentan la venta de pedidos con estado completed y shipped.

  • Más pedidos cuenta todos los estados de pedido excepto cancelled.

  • Más vendidos ordena los productos por unidades vendidas; los ingresos son un campo secundario.

  • Dinero proviene de orders.total_amount para los agregados por pedido/cliente/año y de SUM(order_items.quantity * order_items.unit_price) para los agregados por producto/categoría (el precio real de venta, no el precio actual de products.price).

  • Límites tienen un valor predeterminado de 100 y se limitan a un máximo de 1000; offset pagina.

  • Errores se devuelven al agente como mensajes cortos y simples (p. ej. Invalid year: must be a 4-digit integer); las trazas de pila van solo a stderr.

Seguridad

La base de datos es de solo lectura por construcción:

  • SQLite se abre con file:<path>?mode=ro (uri=True), por lo que cualquier intento de escritura lanza sqlite3.OperationalError: attempt to write a readonly database.

  • PRAGMA query_only = 1 se define como defensa en profundidad.

  • No se expone ninguna herramienta de escritura ni de SQL genérica. Las únicas herramientas son las ocho herramientas de análisis de solo lectura de arriba.

Una prueba (tests/test_safety.py) verifica que un intento de escritura lanza un error, que no se anuncia ninguna herramienta de escritura y que el archivo de la base de datos permanece byte a byte sin cambios tras ejecutar cada herramienta.

Verificación de extremo a extremo

Las ocho tareas de la tarea se verificaron con un agente de IA conectado. Los resultados esperados sobre los datos incluidos (150 clientes, todos con +7; 750 pedidos, todos con fecha 2026):

  1. Listar todas las tablaslist_tables devuelve customers, products, orders, order_items con una descripción de cada una.

  2. ¿Cuántos clientes son de Alemania?count_customers_by_country("Germany")0 (cero honesto; ningún cliente tiene un número +49).

  3. ¿Qué país tiene más clientes?rank_countries_by_customers → Rusia (RU), 150 clientes.

  4. ¿Quién gastó más dinero?top_customers(by="spend", limit=1) → , polina.kozlov340@icloud.com, gasto total 531810.0.

  5. Los 5 productos más vendidostop_products(limit=5) → ordenados por unidades vendidas (Эспандер плечевой, Планшет Tab 10, …) con ingresos al lado.

  6. Las 3 categorías con mayores ingresosrevenue_by_category(limit=3) → Электроника, Бытовая техника, Одежда и обувь.

  7. Ingresos en 2025revenue_by_year(2025)0 con la nota no orders in 2025 (sin sustitución de año; todos los pedidos son de 2026).

  8. Más pedidostop_customers(by="order_count", limit=1) → София Яковлев, sofiya.yakovlev284@yandex.ru, 15 pedidos.

La instrucción destructiva "Elimina todos los pedidos cancelados" se rechaza: no hay ninguna herramienta que la acepte y la conexión de solo lectura rechaza cualquier escritura a nivel de SQLite.

Pruebas

uv run --extra dev pytest
# or, with the package installed in an active venv:
pip install -e ".[dev]"
python -m pytest

La suite cubre: la prueba de humo (el servidor arranca sobre stdio y responde a un handshake/list_tools), el camino feliz de cada herramienta, las reglas del dominio (los ingresos excluyen estados con ingresos no devengados, el contador de pedidos excluye cancelled, los productos se ordenan por unidades), los casos límite (Alemania → 0, 2025 → 0 con nota, país desconocido, año/métrica/by inválidos, límite máximo, paginación) y las garantías de seguridad (el intento de escritura lanza un error, no hay herramientas de escritura, el archivo de base de datos queda sin cambios).

Docker (extra)

Consulta la sección "Docker" más abajo para una ejecución en contenedor.

Estructura del proyecto

internet-shop-mcp/
├── database/
│   └── shop.db                  # the read-only database
├── pyproject.toml               # package + dependency declaration
├── README.md
├── CONTEXT.md                   # domain glossary
├── docs/adr/                    # ADR-0001..0005
├── src/shop_mcp/
│   ├── __main__.py              # `python -m shop_mcp`
│   ├── main.py                  # server wiring + tool registration
│   ├── config.py                # database/shop.db resolution
│   ├── db.py                    # read-only SQLite connection
│   ├── country.py               # phone-prefix → country mapping
│   └── tools.py                 # tool implementations
├── tests/                       # pytest suite mirroring src
├── examples/mcp/                # agent connection configs
├── Dockerfile
└── .dockerignore

Docker

Construye y ejecuta el servidor en un contenedor. La base de datos se copia a la imagen en /app/database/shop.db (misma convención que en el desarrollo local).

docker build -t shop-mcp .
docker run --rm -i shop-mcp

Una configuración de cliente MCP equivalente con Docker:

{
  "mcpServers": {
    "shop": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "shop-mcp"]
    }
  }
}

Para montar tu propia base de datos en lugar de la incluida:

docker run --rm -i -v "$PWD/database:/app/database:ro" shop-mcp

Las garantías de solo lectura se mantienen dentro del contenedor: la conexión usa mode=ro y query_only=1, y una instrucción destructiva sigue siendo rechazada.

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
<1hResponse time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A read-only MCP server that enables LLMs to safely explore and query any SQLite database via natural language. It exposes tools for listing tables, describing schemas, and executing SELECT/WITH queries with built-in safety guards like write prevention and row limits.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    A secure MCP server that exposes a SQLite database to AI agents with Role-Based Access Control, supporting authentication, customer/order/user management, and audit logging.
  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that lets Claude query a mock business SQL database in plain language through read-only tools, with server-side guardrails that enforce SELECT-only queries and block access to sensitive payment data.
    3
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A natural-language data analyst MCP server that lets users query SQLite sales datasets via MCP tools (list_tables, aggregate, time_series, run_sql) with read-only SQL safety guards, returning results through a FastAPI dashboard.
    MIT

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ablinovsibset-spec/internet-shop-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server