shop-mcp
shop-mcp
Ein schreibgeschützter Model Context Protocol-Server, der Analysetools für die SQLite-Datenbank shop.db eines Online-Shops bereitstellt (Kunden, Produkte, Bestellungen, Bestellartikel). Er ist dafür ausgelegt, mit einem KI-Agenten verbunden zu werden, damit der Agent analytische Fragen zu den Daten beantworten kann, ohne sie jemals verändern zu können.
Der Server spricht MCP über stdio, öffnet die Datenbank im Nur-Lese-Modus und stellt eine kleine Menge spezialisierter, parametrisierter Tools bereit, deren Beschreibungen die Domänenregeln kodieren (welche Bestellstatus als Umsatz zählen, wie das Land eines Kunden abgeleitet wird, woher das Geld stammt). Es gibt kein generisches SQL-Tool und kein Schreib-Tool – ein destruktiver Prompt wie „Alle stornierten Bestellungen löschen“ kann nicht ausgeführt werden.
Der MCP-Servercode in diesem Repository wurde von einem KI-Codier-Agenten (Cursor) erstellt, gemäß der Hausaufgaben-Anforderung, dass der Server nicht von Hand geschrieben werden darf.
Voraussetzungen
Python 3.11 oder neuer
Die SQLite-Datenbank
shop.db(versioniert unterdatabase/shop.db)uv(empfohlen) – führt den Server in einer isolierten Projektumgebung ohne globale Installation aus. Installation mitbrew install uv(macOS) odercurl -LsSf https://astral.sh/uv/install.sh | sh.
Related MCP server: MCP SQLite RBAC Demo
Install
Mit uv (empfohlen) – kein manuelles venv oder pip nötig; uv löst das Projekt und seine Abhängigkeiten beim ersten Lauf aus pyproject.toml auf:
uv sync # create / refresh the project's .venv from pyproject.tomlOhne uv – erstellen Sie ein Virtualenv und installieren Sie das Paket selbst:
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .Dadurch werden das mcp-SDK und das Paket shop-mcp installiert (das den Einstiegspunkt python -m shop_mcp und das Konsolenskript shop-mcp bereitstellt).
Konfiguration
Der Server öffnet die Datenbank unter database/shop.db relativ zum Prozessarbeitsverzeichnis (ProjectRoot). Es sind keine Umgebungsvariablen erforderlich.
Wenn er über uv run --directory <project> gestartet wird (siehe Client-Konfigurationen unten), setzt uv das Arbeitsverzeichnis auf das Projektstammverzeichnis, sodass die versionierte Datenbank automatisch gefunden wird.
Fehlt database/shop.db, wird beim Start ein klarer Konfigurationsfehler ausgegeben, der das aktuelle Arbeitsverzeichnis enthält (kein Stacktrace, kein stiller Fallback). Stellen Sie sicher, dass die MCP-Client-Konfiguration cwd auf das Repository-Stammverzeichnis setzt.
Ausführen
uv run python -m shop_mcpoder, mit dem in ein aktives venv installierten Paket:
python -m shop_mcpoder äquivalent:
shop-mcpDer Server liest JSON-RPC über stdin und schreibt auf stdout. Normalerweise führen Sie ihn nicht direkt aus – Ihr KI-Agent startet ihn für Sie (siehe unten).
Mit einem Agenten verbinden
Einsatzbereite MCP-Client-Konfigurationen sind unter examples/mcp/ versioniert und laufen ohne weitere Einrichtung, sobald uv installiert ist:
Client | Konfigurationsdatei |
Cursor |
|
Claude Desktop |
|
Generischer Stdio |
|
Kanonisch/Standard |
|
Docker |
|
Jede Konfiguration sieht so aus (ersetzen Sie den --directory-Pfad durch den absoluten Pfad dieses Repository auf Ihrer Maschine):
{
"mcpServers": {
"shop": {
"command": "uv",
"args": ["run", "--directory", "/path/to/internet-shop-mcp", "python", "-m", "shop_mcp"]
}
}
}uv run --directory <project> setzt das Arbeitsverzeichnis auf das Projektstammverzeichnis und verwendet das .venv des Projekts, sodass der Server database/shop.db automatisch findet. Dieselbe Konfiguration ist über Maschinen hinweg portabel (nur der --directory-Pfad ändert sich).
Wenn Sie uv nicht verwenden möchten, installieren Sie das Paket selbst in eine venv (siehe Installation), verwenden Sie command: "python" und setzen Sie in Ihrer MCP-Client-Konfiguration cwd auf das Repository-Stammverzeichnis.
Cursor: Öffnen Sie Settings → MCP → Add MCP Server und fügen Sie den Inhalt von
examples/mcp/cursor.jsonein (oder verwenden Sie den Bereich Project MCP und committen Sie ihn).Claude Desktop: Kopieren Sie den Inhalt von
examples/mcp/claude_desktop.jsoninclaude_desktop_config.json(macOS:~/Library/Application Support/Claude/claude_desktop_config.json).Generischer Stdio-Client: Verwenden Sie
examples/mcp/generic_stdio.jsonmit jedem Client, der MCP über stdio spricht.
Nach der Verbindung sieht der Agent acht Tools: list_tables, describe_table, count_customers_by_country, rank_countries_by_customers, top_customers, top_products, revenue_by_category, revenue_by_year.
Tools
Tool | Antwortet auf |
| Aufgabe 1 – Tabellen auflisten und was jede enthält |
| Schema einer Tabelle |
| Aufgabe 2 – Kunden eines Landes |
| Aufgabe 3 – Land mit den meisten Kunden |
| Aufgaben 4 und 8 – größter Ausgeber / meiste Bestellungen |
| Aufgabe 5 – Bestseller-Produkte |
| Aufgabe 6 – Top-Kategorien nach Umsatz |
| Aufgabe 7 – Umsatz für ein Jahr |
In den Tool-Beschreibungen eingebaute Domänenregeln (vollständige Begründung siehe CONTEXT.md und docs/adr/):
Land wird aus der Telefonvorwahl (E.164) des Kunden abgeleitet. Es gibt keine Spalte
country.+49→ Deutschland,+7→ Russland. Eine nicht erkannte Vorwahl wird aufunknownabgebildet. Das Tool akzeptiert einen vollständigen Namen („Germany“) oder einen ISO-Alpha-2-Code (DE) und gibt beides zurück.Umsatz / Ausgaben zählen nur Bestellungen mit Status
completedundshipped.Meiste Bestellungen zählt jeden Bestellstatus außer
cancelled.Bestseller ordnet Produkte nach verkauften Einheiten; Umsatz ist ein sekundäres Feld.
Geld stammt aus
orders.total_amountfür Bestell-/Kunden-/Jahres-Aggregationen und ausSUM(order_items.quantity * order_items.unit_price)für Produkt-/Kategorie-Aggregationen (der tatsächliche Verkaufspreis, nicht der aktuelleproducts.price).Limits sind standardmäßig 100 und werden auf maximal 1000 begrenzt;
offsetpaginiert.Fehler werden dem Agenten als kurze Klartextmeldungen zurückgegeben (z. B.
Invalid year: must be a 4-digit integer); Stack-Traces gehen nur auf stderr.
Sicherheit
Die Datenbank ist konstruktionsbedingt schreibgeschützt:
SQLite wird mit
file:<path>?mode=ro(uri=True) geöffnet, sodass jeder Schreibversuchsqlite3.OperationalError: attempt to write a readonly databaseauslöst.PRAGMA query_only = 1ist als zusätzliche Absicherung gesetzt.Es ist kein Schreib- und kein generisches SQL-Tool vorhanden. Die einzigen Tools sind die acht oben genannten rein lesenden Analysetools.
Ein Test (tests/test_safety.py) stellt sicher, dass ein Schreibversuch eine Exception auslöst, dass kein Schreib-Tool beworben wird und dass die Datenbankdatei nach jedem Ausführen der Tools Byte-für-Byte unverändert bleibt.
End-to-End-Verifizierung
Die acht Hausaufgaben-Aufgaben wurden mit einem verbundenen KI-Agenten verifiziert. Erwartete Ergebnisse auf den versionierten Daten (150 Kunden, alle mit +7-Nummern; 750 Bestellungen, alle aus 2026):
Alle Tabellen auflisten –
list_tablesgibtcustomers,products,orders,order_itemsjeweils mit einer Beschreibung zurück.Wie viele Kunden kommen aus Deutschland? –
count_customers_by_country("Germany")→0(ehrliche Null; kein Kunde hat eine+49-Nummer).Welches Land hat die meisten Kunden? –
rank_countries_by_customers→ Russland (RU), 150 Kunden.Wer hat das meiste Geld ausgegeben? –
top_customers(by="spend", limit=1)→ Полина Козлов,polina.kozlov340@icloud.com, Gesamtausgaben 531810.0.Top 5 der meistverkauften Produkte –
top_products(limit=5)→ nach verkauften Einheiten geordnet (Эспандер плечевой, Планшет Tab 10, …) mit Umsatz daneben.Top 3 der umsatzstärksten Kategorien –
revenue_by_category(limit=3)→ Электроника, Бытовая техника, Одежда и обувь.Umsatz im Jahr 2025 –
revenue_by_year(2025)→0mit dem Hinweisno orders in 2025(keine Jahres-Ersetzung; alle Bestellungen sind 2026).Meiste Bestellungen –
top_customers(by="order_count", limit=1)→ София Яковлев,sofiya.yakovlev284@yandex.ru, 15 Bestellungen.
Der destruktive Prompt „Alle stornierten Bestellungen löschen“ wird abgelehnt: Es gibt kein Tool, das ihn akzeptiert, und die schreibgeschützte Verbindung weist jeden Schreibversuch auf SQLite-Ebene zurück.
Tests
uv run --extra dev pytest
# or, with the package installed in an active venv:
pip install -e ".[dev]"
python -m pytestDie Suite deckt ab: den Smoke-Test (Server startet über stdio und beantwortet Handshake/list_tools), den Happy Path jedes Tools, die Domänenregeln (Ausgaben schließen nicht umsatzrelevante Status aus, Bestellanzahl schließt stornierte aus, Produkte ordnen nach Einheiten), Randfälle (Deutschland → 0, 2025 → 0 mit Hinweis, unbekanntes Land, ungültiges year/metric/by-Argument, Limit-Begrenzung, Pagination) sowie die Sicherheitsgarantien (Schreibversuch löst Exception aus, keine Schreibwerkzeuge, Datenbankdatei unverändert).
Docker (Bonus)
Siehe unten im Abschnitt „Docker“ für eine containerisierte Ausführung.
Projektstruktur
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
└── .dockerignoreDocker
Build und Start des Servers in einem Container. Die Datenbank wird in das Image unter /app/database/shop.db kopiert (gleiche Konvention wie bei der lokalen Entwicklung).
docker build -t shop-mcp .
docker run --rm -i shop-mcpEine passende MCP-Client-Konfiguration mit Docker:
{
"mcpServers": {
"shop": {
"command": "docker",
"args": ["run", "--rm", "-i", "shop-mcp"]
}
}
}Um eine eigene Datenbank zu mounten statt der gebündelten:
docker run --rm -i -v "$PWD/database:/app/database:ro" shop-mcpDie Garantien für den Schreibschutz bleiben im Container erhalten: Die Verbindung nutzt mode=ro und query_only=1, und auch hier wird ein destruktiver Prompt weiterhin abgelehnt.
Maintenance
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
- AlicenseNot gradedqualityCmaintenanceA 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
- FlicenseNot gradedqualityCmaintenanceA 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.
- AlicenseAqualityBmaintenanceAn 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.3MIT
- AlicenseNot gradedqualityBmaintenanceA 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
Related MCP Connectors
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Federated commerce search across independent WooCommerce merchants. Keyless, read-only MCP server.
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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