Skip to main content
Glama
Amxxxxr

MCP E-Commerce

by Amxxxxr

šŸ›’ ShopMind AI — E-Commerce Operations Agent

Ask your e-commerce database a question in plain English. Get a real, data-backed answer.

ShopMind AI is a conversational analytics agent for an e-commerce business. Instead of writing SQL or building dashboards, you type a question like "What are the top 5 best-selling products?" or "How many users signed up last month?" — the agent figures out the right query, runs it safely against the real database, and answers in plain business language.


Why this project exists

Most small e-commerce teams have the data (orders, products, users, reviews, events) but not the SQL skills to dig into it on demand. This project is an exploration of agentic tool-use with the Model Context Protocol (MCP): rather than letting an LLM touch the database directly, the LLM only ever sees a single, narrow, read-only tool — it never gets raw database credentials or write access. That separation is the actual point of the project, not just the chat UI on top of it.


Related MCP server: ECommerce MCP Server

How it works

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”      question       ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  Streamlit  │ ──────────────────▶ │   Gemini model    │
│   Chat UI   │                     │ (gemini-3.6-flash)│
│  (app.py)   │ ◀────────────────── │                    │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜   final answer      ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                                                │ decides it needs data,
                                                │ requests a tool call
                                                ā–¼
                                     ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
                                     │   MCP Server          │
                                     │  (mcp_server.py)      │
                                     │  tool: execute_       │
                                     │  readonly_sql(query)  │
                                     ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                                                │ validated SELECT only
                                                ā–¼
                                     ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
                                     │   MySQL database       │
                                     │   (database.py)        │
                                     │   users, products,     │
                                     │   orders, order_items, │
                                     │   reviews, events       │
                                     ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
  1. You type a question into the Streamlit chat box.

  2. app.py sends the question to Gemini, along with the database schema and a set of ground rules (only SELECT, only the given tables, never invent data, exclude cancelled/returned orders from revenue, etc.).

  3. Gemini decides it needs data and calls the one tool it's been given: execute_readonly_sql, generating the SQL itself.

  4. That tool call goes over MCP (not a direct function call) to a separate MCP server process (mcp_server.py), which is the only thing with a database connection.

  5. The MCP server validates the query (must start with SELECT, only one statement allowed, no destructive keywords), runs it, and returns the rows as JSON.

  6. That result is fed back to Gemini, which turns raw rows into a plain-English, business-friendly answer.

  7. The agent can loop this up to 5 times if a query needs correcting — e.g. if the first attempt references a column that doesn't exist.

The AI never sees your database password and can never run INSERT/UPDATE/DELETE/DROP — it only ever gets to ask the MCP server to run one SELECT at a time, and the server enforces that.


Tech stack

Layer

Technology

UI

Streamlit chat interface

LLM / reasoning

Google Gemini (gemini-3.6-flash) via the google-genai SDK, using its tool-calling / Interactions API

Agent ↔ data bridge

Model Context Protocol (MCP) — the emerging standard for giving LLMs safe, structured tool access

Data layer

MySQL, accessed only through mysql-connector-python inside the MCP server

Data

~170k rows of synthetic e-commerce data: users, products, orders, order items, reviews, and behavioral events


Features

  • šŸ’¬ Natural-language querying — no SQL knowledge needed to explore the data.

  • šŸ”’ Read-only by design — the MCP tool rejects anything that isn't a single SELECT statement.

  • šŸ” Self-correcting agent loop — if a generated query is wrong, the agent sees the error and tries again (up to 5 rounds).

  • 🧠 Schema-aware prompting — the model is given the exact table/column names up front, so it doesn't guess.

  • šŸ“Š Business-sensible answers — rules baked into the prompt handle real analytics nuance, like excluding cancelled/returned orders from revenue figures.

  • 🧩 Decoupled architecture — the LLM, the tool server, and the database are three separate processes talking over well-defined protocols, not one tangled script.


Project structure

MCP/
ā”œā”€ā”€ app.py              # Streamlit chat app — the main entry point
ā”œā”€ā”€ mcp_server.py        # MCP server exposing the execute_readonly_sql tool
ā”œā”€ā”€ mcp_client.py         # CLI version of the full agent loop (for debugging without the UI)
ā”œā”€ā”€ agent.py              # Minimal CLI version — no MCP, calls the DB function directly
ā”œā”€ā”€ database.py            # MySQL connection handling
ā”œā”€ā”€ test_database.py        # Sanity check: run a query directly against the DB
ā”œā”€ā”€ test_mcp.py               # Sanity check: spin up the MCP server and call the tool
ā”œā”€ā”€ requirements.txt            # Python dependencies
ā”œā”€ā”€ .env                          # API key + database credentials (not committed in real projects)
└── data/
    ā”œā”€ā”€ schema.sql                # Table definitions matching the CSVs below
    ā”œā”€ā”€ users.csv, products.csv, orders.csv,
    │   order_items.csv, reviews.csv, events.csv   # Source data
    └── MCP.ipynb                                   # Exploratory notebook used while building this

Database schema

Table

Key columns

users

user_id, name, email, gender, city, signup_date

products

product_id, product_name, category, brand, price, rating

orders

order_id, user_id, order_date, order_status, total_amount

order_items

order_item_id, order_id, product_id, user_id, quantity, item_price, item_total

reviews

review_id, order_id, product_id, user_id, rating, review_text, review_date

events

event_id, user_id, product_id, event_type, event_timestamp

order_status values: processing, completed, cancelled, returned, shipped.


Setup

1. Install dependencies

pip install -r requirements.txt

2. Set up MySQL

mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS mcp CHARACTER SET utf8mb4;"
mysql -u root -p mcp < data/schema.sql

Then load the CSVs (adjust paths to absolute; enable local_infile if disabled):

SET GLOBAL local_infile=1;

LOAD DATA LOCAL INFILE '/absolute/path/to/data/users.csv'
  INTO TABLE users FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n' IGNORE 1 ROWS;

LOAD DATA LOCAL INFILE '/absolute/path/to/data/products.csv'
  INTO TABLE products FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n' IGNORE 1 ROWS;

LOAD DATA LOCAL INFILE '/absolute/path/to/data/orders.csv'
  INTO TABLE orders FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n' IGNORE 1 ROWS
  (order_id, user_id, @order_date, order_status, total_amount)
  SET order_date = STR_TO_DATE(@order_date, '%Y-%m-%dT%H:%i:%s.%f');

LOAD DATA LOCAL INFILE '/absolute/path/to/data/order_items.csv'
  INTO TABLE order_items FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n' IGNORE 1 ROWS;

LOAD DATA LOCAL INFILE '/absolute/path/to/data/reviews.csv'
  INTO TABLE reviews FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n' IGNORE 1 ROWS
  (review_id, order_id, product_id, user_id, rating, review_text, @review_date)
  SET review_date = STR_TO_DATE(@review_date, '%Y-%m-%dT%H:%i:%s.%f');

LOAD DATA LOCAL INFILE '/absolute/path/to/data/events.csv'
  INTO TABLE events FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n' IGNORE 1 ROWS
  (event_id, user_id, product_id, event_type, @event_timestamp)
  SET event_timestamp = STR_TO_DATE(@event_timestamp, '%Y-%m-%dT%H:%i:%s.%f');

3. Configure environment variables

Create/edit .env:

GEMINI_API_KEY=your_key_here

DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_mysql_password
DB_NAME=mcp

4. Sanity-check the pieces

python test_database.py   # confirms the DB connection + a real query work
python test_mcp.py        # confirms the MCP server starts and the tool responds

5. Run the app

streamlit run app.py

Open the local URL Streamlit prints, and start asking questions.


Example questions to try

  • "What are the top 5 best-selling products?"

  • "How many orders were cancelled last quarter?"

  • "Which city has the most signed-up users?"

  • "What's the average rating for the Electronics category?"

  • "What's our total revenue excluding cancelled and returned orders?"


Design decisions & guardrails

  • Least privilege: the database user the app connects as should only have SELECT on the mcp schema — never grant it write access.

  • Defense in depth on SQL: the tool itself rejects anything that isn't a single SELECT statement, independent of whatever the model was told to do in the prompt — a compromised or confused model still can't do damage.

  • Schema-first prompting: the model is always given the real column names, so answers are grounded instead of guessed.

  • Graceful degradation: if the model's answer doesn't land in the expected place, or a query fails, the agent retries or returns a clear message — never a silent blank response.

Known limitations

  • There's no dedicated "profit" column in the data (no cost-of-goods figures), so profit-style questions are answered using revenue instead, with that substitution stated explicitly in the answer.

  • The agent caps itself at 5 tool-call rounds per question to avoid runaway loops on an unanswerable question.

  • This is a single-user local tool, not a multi-tenant production service — there's no authentication layer on the Streamlit app itself.

Possible next steps

  • Add a chat history so follow-up questions ("...and for last month specifically?") retain context.

  • Cache repeated queries to cut down on Gemini calls.

  • Add a lightweight cost/COGS table so real profit questions can be answered.

  • Deploy the MCP server as a long-lived process instead of spawning a new one per question.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

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
    Not graded
    quality
    D
    maintenance
    Enables natural language database operations on MySQL databases with AI integration, supporting CRUD operations, schema inspection, and audit logging with built-in security features including SQL injection protection and permission controls.
    220
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Enables read-only exploration and querying of PostgreSQL or MySQL databases via MCP, with schema discovery, safe SQL validation, natural language to SQL conversion, and CSV export.
    11
    1
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to connect to MySQL databases, execute read-only queries, list tables, and describe table schemas via MCP.
    1
    -

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/Amxxxxr/MCP-E-Commerce-project'

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