shop
Provides read-only access to a SQLite shop database, enabling table listing, schema inspection, read-only SQL queries, and shop analytics such as product ratings and annual revenue.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@shop What were the top 5 products by revenue in 2026?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Read-only MCP server for a store
Python MCP server over stdio for an existing SQLite database of an online store (data/shop.db). The database file is opened read-only; modifying SQL is rejected and not executed.
Installation
Python 3.11+:
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"Related MCP server: Shop SQLite MCP
Running
From the project root (default database path is ./data/shop.db):
python -m shop_mcp
# или
shop-mcpAnother database path:
SHOP_DB_PATH=~/my/test-mcp-db/data/shop.db python -m shop_mcpThe process communicates via MCP through stdin/stdout. Don't enter commands into this terminal until an MCP client is connected to it.
MCP config in Cursor
Add an mcpServers entry (Cursor Settings → MCP, or .cursor/mcp.json in the project). The transport is stdio.
In the examples, the path ~/my/test-mcp-db is this repository. The server expands SHOP_DB_PATH itself (~ → home directory). If Cursor doesn't expand ~ in command / cwd, specify /Users/<you>/my/test-mcp-db/... there.
Locally (venv)
{
"mcpServers": {
"shop": {
"command": "~/my/test-mcp-db/.venv/bin/python",
"args": ["-m", "shop_mcp"],
"cwd": "~/my/test-mcp-db",
"env": {
"SHOP_DB_PATH": "~/my/test-mcp-db/data/shop.db"
}
}
}
}If a console script is more convenient after pip install -e .:
{
"mcpServers": {
"shop": {
"command": "~/my/test-mcp-db/.venv/bin/shop-mcp",
"cwd": "~/my/test-mcp-db",
"env": {
"SHOP_DB_PATH": "~/my/test-mcp-db/data/shop.db"
}
}
}
}Docker
Build the image once:
docker build -t shop-mcp .{
"mcpServers": {
"shop": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-v",
"~/my/test-mcp-db/data/shop.db:/data/shop.db:ro",
"-e",
"SHOP_DB_PATH=/data/shop.db",
"shop-mcp"
]
}
}
}The -i flag is required to keep stdio connected. Mount only shop.db; the container must not overwrite the file on the host.
Tools
Tool | Purpose |
| User tables and a brief description of their role ( |
| Actual columns, types, PK/FK |
| A single |
| Ratings and revenue for a year without manual SQL |
Amounts, quantities, and revenue are calculated as order_items.quantity * order_items.unit_price; orders with the cancelled status are excluded. The calendar year is taken from strftime('%Y', orders.order_date).
Security
SQLite URI
file:<abs>?mode=roComments are stripped; query chains (
SELECT 1; DELETE ...) are rejectedINSERT / UPDATE / DELETE / DROP / ALTER / CREATE / ATTACH / PRAGMA / … → explicit "not allowed" error
SQLite syntax errors and unknown columns are returned in a structured way; the process doesn't terminate
Notes on evaluation
The
customerstable has nocountrycolumn. That is visible throughdescribe_table; don't invent geography.SELECT country FROM customerswill return an SQLite error.Order dates in the current dump are from 2026. Revenue for 2025 may be 0. That's a correct result, not a broken filter.
Tests
pytestThe tests copy data/shop.db to a temporary file and verify that the copy's hash doesn't change after rejected writes.
Example of a processed query

Available Tools
4 toolsdescribe_tableA
Describe columns, types, primary keys, and foreign keys for one table.
Use before writing joins. Returns actual SQLite metadata only — never fabricates fields such as country. Parameters: table (name from list_tables). Returns {table, columns: [{name, type, primary_key, ...}], foreign_keys}.
Inputs: table (required). Returns: object
execute_readonly_sqlA
Run a single read-only SQL statement against shop.db.
Allowed: one SELECT, WITH (CTE), or EXPLAIN. Writes and DDL (INSERT, UPDATE, DELETE, REPLACE, DROP, ALTER, CREATE, TRUNCATE, ATTACH, VACUUM, REINDEX, PRAGMA) are rejected with an explicit not-allowed error. Stacked statements (semicolons) are rejected. Prefer shop_analytics for rankings and yearly revenue.
Pagination: default limit 100, maximum 1000 (error if exceeded), offset default 0. Returns {columns, rows, truncated, row_count, next_offset} or {error, sqlite_error?}. The database is opened read-only; refused mutations leave the file unchanged.
Inputs: sql (required), limit, offset. Returns: object
list_tablesA
List user tables in shop.db with a one-line purpose for each.
Use this first to discover the real schema. Internal SQLite tables such as sqlite_sequence are omitted. Does not invent columns (customers has no country). Returns {tables: [{name, purpose}, ...]}.
Inputs: no named parameters. Returns: object
shop_analyticsA
Shop aggregations without hand-written SQL.
Operations: top_customers_by_spend (name, email, total_amount; default limit 5), customer_most_orders (name, email, order_count), top_products (product_name, units_sold, revenue; default limit 5), top_categories (category, revenue; default limit 3), revenue_by_year (requires year). Spend/units/revenue use quantity * unit_price and exclude cancelled orders. Year is taken from order_date.
Inputs: operation (required), year, limit. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
The schema-discovery tools are clearly separated from the querying/analytics tools. There is some overlap between execute_readonly_sql and shop_analytics, but the descriptions explicitly steer agents toward shop_analytics for rankings and revenue, reducing confusion.
Three tools follow a clear verb-first snake_case pattern: list_tables, describe_table, execute_readonly_sql. shop_analytics breaks that pattern as a nouny resource name, though it is still understandable and not chaotic.
Four tools is a well-scoped set for a read-only shop database. Each tool fills a distinct role: schema discovery, table metadata, raw SQL execution, and prebuilt analytics, with no redundancy.
For a read-only database exploration server, the workflow is complete: list the tables, describe one, run arbitrary safe SQL, and get common analytics. There are no missing mutations or write operations because the server is explicitly read-only.
Maintenance
Related MCP Connectors
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
PostgreSQL, MySQL, and SQL Server in one session. 26 read-only MCP tools for AI agents.
Text-to-SQL MCP server: read-only queries on PostgreSQL, MySQL and SQL Server with your real schema
Read authorized Loam tables and supported external databases through a bounded MCP connection.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables natural-language sales queries against a SQLite database, generating and executing read-only SQL through a secure MCP server with table listing, schema description, and query execution.-
- FlicenseNot gradedqualityDmaintenanceEnables safe, read-only analysis of an online store's SQLite database, providing schema introspection, restricted SELECT queries, and specialized analytics tools through MCP.-
- FlicenseNot gradedqualityCmaintenanceThis MCP server lets an AI agent securely connect to a read-only SQLite store database, inspect its tables and schema, and run analytical SQL queries without modifying any data.-
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to read-only analyze a SQLite e-commerce database, exploring schema and running analytical SQL queries over stdio.-