Sneaker Catalog MCP Server
README.md
# Sneaker Catalog — Data Layer, MCP Server & Agent
A small e-commerce catalog for sneakers, built in three layers:
1. **Data layer** — Postgres + pgvector, with keyword and semantic search over products.
2. **MCP server** — exposes the catalog as tools (`search`, `get_product_details`, `get_stock`) over the [Model Context Protocol](https://modelcontextprotocol.io).
3. **Agent** — a CLI chat agent that connects to the MCP server and answers questions about the catalog purely by calling those tools.
## Architecture
```
┌─────────────┐ MCP (stdio) ┌──────────────┐ ┌────────────────┐
│ agent/cli │ ──────────────▶ │ mcp_server │ ─────▶ │ Postgres + │
│ (OpenAI llm) │ ◀────────────── │ (tool calls) │ ◀───── │ pgvector │
└─────────────┘ └──────────────┘ └────────────────┘
```
- `db/` — plain Python functions (`search_products`, `get_product`, `check_stock`, `filter_products`) that query Postgres directly.
- `mcp_server/` — wraps those functions as MCP tools using the official Python MCP SDK.
- `agent/` — a REPL that spawns the MCP server as a subprocess, converts its tool schemas to OpenAI's function-calling format, and runs the request → tool-call → result loop until the model has a final answer.
Search is hybrid: full-text keyword ranking (Postgres `tsvector`) blended with semantic similarity (OpenAI embeddings + pgvector cosine distance).
## Prerequisites
- Docker (recommended path), **or** Python 3.14 + a local Postgres with the `vector` extension
- An OpenAI API key with access to an embeddings model (`text-embedding-3-small`) and a chat model (e.g. `gpt-5-mini`)
## Quickstart (Docker)
```bash
make setup # cp .env.example .env — then edit it: POSTGRES_* / OPENAI_API_KEY
make up # starts Postgres, seeds the catalog
make logs # confirm "Seed complete." (Ctrl+C to stop tailing)
make agent # chat with the catalog
```
> `agent` (and `mcp-server`) depend on `seed`, so `make agent` re-runs the seed step first on every invocation. Seeding checks whether the catalog is already populated and skips instantly if so, so this is fast and harmless.
Type a question at the `> ` prompt. Type `exit` (or Ctrl+D) to quit.
### Other services
```bash
make mcp-server # run the MCP server standalone, e.g. to attach MCP Inspector
make inspector # run MCP Inspector against the containerized server
```
The MCP server uses stdio transport, so it only runs attached to a terminal — it's excluded from `make up`'s default services (behind the `tools` compose profile) to avoid a crash loop when started detached.
Run `make help` to see all available commands, or `make down` to stop everything.
## Quickstart (local, no Docker)
```bash
make venv # create venv + install requirements
make db-up # just the Postgres container
make seed-local # seed the catalog once
make agent-local # chat with the agent
```
To test the MCP server directly with Inspector:
```bash
source venv/bin/activate
npx @modelcontextprotocol/inspector python -m mcp_server.server
```
## Project layout
```
db/
schema.sql products, variants, inventory, prices + pgvector/tsvector indexes
seed.py idempotent catalog seeding (embeds descriptions via OpenAI)
search.py hybrid keyword + semantic search
product.py get_product() — product + all variants
stock.py check_stock() — inventory by SKU
filters.py SQL filtering by category / price
mcp_server/
server.py MCP tool definitions (search, get_product_details, get_stock)
agent/
cli.py interactive chat agent (OpenAI function-calling + MCP client)
docker-compose.yml db, seed, mcp-server, agent services
Dockerfile shared image for seed / mcp-server / agent
Makefile `make help` for all available commands
agent-start.sh local (non-Docker) launcher for the agent
```
## Environment variables
| Variable | Used by | Notes |
|---|---|---|
| `POSTGRES_USER` / `POSTGRES_PASSWORD` / `POSTGRES_DB` | db, all Python services | |
| `POSTGRES_HOST` / `POSTGRES_PORT` | db connections | defaults to `localhost:5432`; Docker services override `POSTGRES_HOST=db` |
| `OPENAI_API_KEY` | seeding (embeddings), search (query embeddings), agent (chat) | |
See `.env.example` for a template.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues