Skip to main content
Glama
andreykutsenko

mcp-shop-server

mcp-shop-server

An MCP server that gives an AI agent read-only access to an online store's SQLite database (customers, products, orders, order_items). Through it, the agent answers analytical questions about the data: database structure, aggregates by customers, products, categories, and revenue. Transport — stdio.

Writing to the database is impossible by design: three independent layers of protection — a mode=ro connection, request validation before execution (only SELECT / WITH ... SELECT), and the sqlite3-authorizer.

Measurements, evidence, and deviations from the spec — REPORT.md.


Usage

1. Clone

git clone https://github.com/andreykutsenko/mcp-shop-server.git
cd mcp-shop-server

The repository already contains shop.db (150 customers, 50 products, 750 orders, 1900 line items).

2. Install dependencies

uv venv .venv
uv pip install --python .venv/bin/python -r requirements.txt

Without uv — the same using standard tools:

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

Python 3.11+ is required. Dependencies: mcp (official MCP SDK) and pytest for tests; database work uses sqlite3 from the standard library.

3. Add to the agent config

Minimal configuration form:

{
  "command": "python",
  "args": ["/absolute/path/to/mcp-shop-server/server.py"]
}

A working example for a client with an mcpServers block (Claude Desktop, Cursor, and compatible):

{
  "mcpServers": {
    "shop-db": {
      "command": "/absolute/path/to/mcp-shop-server/.venv/bin/python",
      "args": ["/absolute/path/to/mcp-shop-server/server.py"],
      "env": {
        "MCP_SHOP_DB": "/absolute/path/to/mcp-shop-server/shop.db"
      }
    }
  }
}

For Claude Code, a single command is enough:

claude mcp add shop-db -- /absolute/path/to/mcp-shop-server/.venv/bin/python /absolute/path/to/mcp-shop-server/server.py

MCP_SHOP_DB is optional: if the variable is not set, the server takes shop.db next to server.py. Set it if the database is located elsewhere. It's better to specify the interpreter from .venv — otherwise the system python may not find the mcp package.

4. Launch

The server is launched by the agent; doing it by hand is rarely needed:

.venv/bin/python server.py

The process silently waits for JSON-RPC on stdin; diagnostics go to stderr, stdout is occupied by the MCP protocol.

5. Verification and questions for the agent

.venv/bin/python -m pytest -q

After connecting, the agent sees three tools. Questions are asked in plain language.

The eight tasks from the homework text — these are the ones worth running for verification:

1. Show me all available tables and explain what information each table contains.
2. How many customers are from Germany?
3. Which country has the most customers?
4. Who is the customer who spent the most money?
5. What are the top 5 best-selling products?
6. What are the top 3 product categories by revenue?
7. How much revenue did we generate in 2025?
8. Which customer placed the most orders?

⚠️ Tasks 2, 3, and 7 have no solution in the provided database, and that's expected. customers has no country column — all 150 customers have Russian phone numbers; all 750 orders are dated 2026, there is no data for 2025.

In this case, the server does not invent data: it reports that no such field exists in the schema and lists the existing columns. Nothing is hardcoded — the schema is read from the database, so on another database where country exists, the same questions work normally.

Additionally, questions that the database fully covers are checked: top-5 customers by order total, revenue by category, order distribution by status, average check, product stock.

Write-protection check. On "Delete all cancelled orders" the agent gets a clear refusal, not an error: the server is read-only, and 102 cancelled orders remain in place.

Tools

Tool

Purpose

list_tables()

All tables with purpose, row count, columns, relationships, list of order statuses, and date format.

describe_table(table)

Real columns with types, foreign keys in both directions, and a sample row.

run_select_query(sql, limit=100, offset=0)

Execute a single SELECT (or WITH ... SELECT) and return rows page by page.

Output is limited: 100 rows by default, 1000 maximum. When truncated, the response reports how many rows were returned, how many were found in total, and with which offset to continue reading.

If a requested field is not in the database (for example, customer country), the server honestly says so and lists the existing columns — nonexistent fields are not invented.


Related MCP server: Shop Analytics MCP Server

How it's made

The project was generated with a single prompt — the file SPEC-mcp-shop.md, sent to the agent in full, without any follow-up clarifications.

Internally, the agent worked in a loop using the skill repo-task-proof-loop (Denis Shiryaev, Apache-2.0): freeze the spec → build → package evidence → verify with a fresh session → minimal fix → verify again, until a PASS verdict.

Run evidence is stored in the repository, in .agent/tasks/mcp-shop-server/:

  • spec.md — the frozen spec with acceptance criteria AC1…AC17;

  • evidence.md / evidence.json — for each criterion, a verdict and concrete evidence;

  • verdict.json — the result of an independent check by a fresh session;

  • problems.md — discrepancies found by the reviewer;

  • raw/ — raw run logs: tests, a live MCP session, stdout cleanliness check.

What's checked is not the source code but the server's behavior with a live agent: the harness raw/mcp_session_check.py starts server.py over stdio with a real MCP client, calls all tools, runs the eight analytical tasks, gets a refusal on deletion, and verifies that stdout contains only JSON-RPC frames.

The development skill itself lives locally in .claude/skills/ and is not committed to the repository — it's third-party code.


Decisions on spec ambiguities

#

Ambiguity

Decision

1

"The agent answers all eight tasks from the spec" — the list of eight tasks is not given in the spec.

The eight analytical questions are derived from the <objective> section ("database structure, aggregates by customers, products, categories, and revenue") and fixed in the "Verification and questions for the agent" section above. Each is run through the server tools in .agent/tasks/mcp-shop-server/raw/test-integration.txt.

2

MCP SDK version is not pinned.

The current mcp>=2.1,<3 line is used (the MCPServer API). In mcp 1.x the class was called FastMCP; the upper bound is pinned so installation is reproducible.

3

"Maximum 1000 rows" — it's not said whether this is an error or truncation.

A limit greater than 1000 is not an error: the value is capped at 1000, and this is reported in the notes field. Only limit < 1 and a negative offset are errors.

4

"How many were found in total" for an unlimited query.

The cursor result is fully counted, but no more than 100,000 rows; if the query returns more, total_is_exact=false and the response says "at least N". This way an honest number doesn't become a hang risk.

5

The authorizer forbids everything except reading, but describe_table needs PRAGMA table_info.

The authorizer allows only three read-only pragmas (table_info, foreign_key_list, index_list). A user PRAGMA in any form is rejected by the second layer — the validator — before execution.

6

Tool response format is not specified.

All tools return a structured object with an ok field. A refusal and an error are ok=false with a textual explanation, not an MCP exception: the agent reads this as a response, not a transport failure.

7

Tool names and their composition ("you design the set yourself").

The recommended minimum of three tools is kept, with exactly the names list_tables, describe_table, run_select_query: everything else (aggregates, tops, year slices) is expressed through run_select_query; separate narrow tools would only bloat the context.

8

Semicolon at the end of a query.

A trailing ; is allowed — it's a single statement. Only a second non-empty statement after ; is rejected; a semicolon inside a string literal is not counted as a second statement.

9

Location of tests and harness.

Tests are in tests/test_server.py (numbered by the <tests> items of the spec), the live MCP session harness is in .agent/tasks/mcp-shop-server/raw/, next to the evidence, so it can be re-run during verification.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables 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.
    6
    83
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Enables AI agents to answer analytical questions about an online store's SQLite database through specialized read-only tools, without any risk of modifying the underlying data.
    8
  • F
    license
    A
    quality
    C
    maintenance
    Enables 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
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to read-only analyze a SQLite e-commerce database, exploring schema and running analytical SQL queries over stdio.

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/andreykutsenko/mcp-shop-server'

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