Skip to main content

Wine Semantic Search MCP Server

A Model Context Protocol (MCP) server that enables semantic search capabilities over a PostgreSQL database containing wine listings and descriptions. The system uses vector embeddings to perform intelligent searches that understand the meaning and context of wine-related queries, returning relevant wine recommendations based on semantic similarity rather than just keyword matching.

Features

  • Semantic Search: Uses OpenAI's text-embedding-3-small model for intelligent wine recommendations
  • Vector Database: PostgreSQL with pgvector extension for efficient similarity search
  • MCP Protocol: Full compliance with Model Context Protocol for AI assistant integration
  • Configurable: Flexible search parameters and result limits
  • Production Ready: Comprehensive error handling, logging, and connection management
  • Type Safe: Full type annotations and validation using Pydantic

Requirements

  • Python: 3.8 or higher
  • PostgreSQL: 12+ with pgvector extension installed
  • OpenAI API Key: For generating embeddings

Quick Start

1. Install Dependencies

# Clone the repository
git clone <repository-url>
cd wine-semantic-search

# Install the package
pip install -e .

# For development
pip install -e ".[dev]"

2. Database Setup

Install PostgreSQL and pgvector

Ubuntu/Debian:

sudo apt-get install postgresql postgresql-contrib
sudo apt-get install postgresql-14-pgvector  # Adjust version as needed

macOS (using Homebrew):

brew install postgresql
brew install pgvector

Docker (Alternative):

docker run --name wine-postgres -e POSTGRES_PASSWORD=password -p 5432:5432 -d pgvector/pgvector:pg16

Create Database and Schema

# Connect to PostgreSQL
psql -U postgres -h localhost

# Create database
CREATE DATABASE wine_database;

# Connect to the new database
\c wine_database

# Run the schema setup
\i database_schema.sql

Or use the provided schema file:

psql -U postgres -h localhost -d wine_database -f database_schema.sql

3. Configuration

Copy the example configuration file and customize it:

cp .env.example .env

Edit .env with your settings:

# Required settings
DATABASE_URL=postgresql://username:password@localhost:5432/wine_database
OPENAI_API_KEY=your_openai_api_key_here

# Optional settings
MAX_RESULTS=50
SIMILARITY_THRESHOLD=0.7

4. Load Wine Data (Optional)

If you have wine data to import, you can use the following format:

INSERT INTO wine (country, description, designation, points, price, province, region_1, region_2, variety, winery)
VALUES 
('France', 'A rich, full-bodied Bordeaux with notes of blackcurrant and oak', 'Château Example 2020', 92, 45.99, 'Bordeaux', 'Left Bank', 'Pauillac', 'Cabernet Sauvignon', 'Château Example'),
-- Add more wine records...

Note: Embeddings will be generated automatically when you perform searches.

5. Run the Server

# Start the MCP server
wine-search-server

# Or run directly with Python
python -m wine_semantic_search.main

Usage

As an MCP Server

The server exposes a single tool called search_wines that can be used by any MCP-compatible client:

Tool Schema:

{
  "name": "search_wines",
  "description": "Search for wines using natural language descriptions",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "Natural language description of desired wine characteristics"
      },
      "limit": {
        "type": "integer",
        "description": "Maximum number of results to return (default: 10, max: 50)",
        "minimum": 1,
        "maximum": 50,
        "default": 10
      }
    },
    "required": ["query"]
  }
}

Example Queries:

  • "I want a full-bodied red wine from France under $30"
  • "Light, crisp white wine perfect for seafood"
  • "Bold Cabernet Sauvignon with high ratings"
  • "Sweet dessert wine from Germany"

Testing the Installation

You can test your setup using the built-in health check:

# Test database connection and configuration
python -c "
from wine_semantic_search.main import test_setup
import asyncio
asyncio.run(test_setup())
"

Database Schema

The system uses two main tables:

wine table

Stores wine information including:

  • Basic details (name, country, region, variety, winery)
  • Ratings and pricing (points, price)
  • Descriptive text (description)

wine_embeddings table

Stores vector embeddings for semantic search:

  • 512-dimensional vectors generated by OpenAI
  • Linked to wine records via foreign key
  • Indexed for efficient similarity search

See database_schema.sql for the complete schema definition.

Configuration Options

Environment Variable Required Default Description
DATABASE_URL Yes - PostgreSQL connection string
OPENAI_API_KEY Yes - OpenAI API key for embeddings
MAX_RESULTS No 50 Maximum search results (1-50)
SIMILARITY_THRESHOLD No 0.7 Minimum similarity score (0.0-1.0)

Development

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=wine_semantic_search

# Run specific test categories
pytest tests/test_database.py  # Database tests
pytest tests/test_embedding.py  # Embedding tests
pytest tests/test_integration.py  # Integration tests

Code Quality

# Format code
black wine_semantic_search/
isort wine_semantic_search/

# Type checking
mypy wine_semantic_search/

# Linting
flake8 wine_semantic_search/

Property-Based Testing

The project uses Hypothesis for property-based testing to ensure correctness across a wide range of inputs:

# Run property-based tests with verbose output
pytest tests/ -v --hypothesis-show-statistics

Troubleshooting

Common Issues

1. pgvector extension not found

ERROR: extension "vector" is not available

Solution: Install pgvector extension for your PostgreSQL version.

2. Database connection failed

ERROR: could not connect to server

Solution: Check your DATABASE_URL and ensure PostgreSQL is running.

3. OpenAI API errors

ERROR: Invalid API key

Solution: Verify your OPENAI_API_KEY is correct and has sufficient credits.

4. No search results

INFO: No wines found matching query

Solution: Check that your database contains wine records and try adjusting the SIMILARITY_THRESHOLD.

Logging

The server provides detailed logging for troubleshooting:

# Enable debug logging
export LOG_LEVEL=DEBUG
wine-search-server

Performance Tuning

For large datasets, consider:

  1. Database Indexing: The schema includes optimized indexes for common queries
  2. Connection Pooling: Adjust DB_POOL_MAX_SIZE for high-concurrency scenarios
  3. Similarity Threshold: Higher thresholds reduce computation but may miss relevant results
  4. Result Limits: Lower limits improve response times

Architecture

The system follows a layered architecture:

  • MCP Server Layer: Handles protocol communication and tool registration
  • Service Layer: Business logic for embeddings and database operations
  • Data Layer: PostgreSQL with pgvector for efficient vector operations

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Run the test suite
  5. Submit a pull request

License

[Add your license information here]

Support

For issues and questions:

  1. Check the troubleshooting section above
  2. Review the test files for usage examples
  3. Open an issue on the repository

Release files for wine-semantic-search 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wine-semantic-search 0.1.1
File Size Uploaded
wine_semantic_search-0.1.1.tar.gz 38.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for wine-semantic-search 0.1.1
File Interpreter ABI Platform
wine_semantic_search-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 63.1 kB

Release files / wine_semantic_search-0.1.1.tar.gz

Download URL wine_semantic_search-0.1.1.tar.gz
Size 38.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f858ba0ffc00dd7d5e0a7e49bce4872b57cc01779e5d7483ea822f5a856e0ff6
BLAKE2b-256 checksum
How to use checksums
eddd98ce1a55c5c534684181bbfdff743a2832174484cc91202665367c3fc01f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / wine_semantic_search-0.1.1-py3-none-any.whl

Download URL wine_semantic_search-0.1.1-py3-none-any.whl
Size 24.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
088917e81a64d91659e10212589a76795467a577a0e091beb8b930e5045b27bc
BLAKE2b-256 checksum
How to use checksums
ecfd56bd92cf4d23f1b2a60576cbb35feade24fa440f02aac057de6be6bacd68
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page