← Back to documentation

shopping-assistant-claude-tool

Tutorial 1: Build a Shopping Assistant Claude Tool

Create a Claude Desktop tool that lets users search products, compare prices, and find the best deals across Singapore e-commerce platforms.

What You'll Build

A buywhere_search tool that integrates with Claude Desktop via the Model Context Protocol (MCP). Users can ask Claude to find products and get structured recommendations with prices, ratings, and purchase links.

Prerequisites

Step 1: Set Up the MCP Server

First, install the BuyWhere MCP server:

pip install buywhere-mcp

Create a config file at ~/.config/buywhere/mcp.json:

{
  "mcpServers": {
    "buywhere": {
      "command": "buywhere-mcp",
      "args": [],
      "env": {
        "BUYWHERE_API_KEY": "bw_live_your_key_here"
      }
    }
  }
}

Step 2: Configure Claude Desktop

Add the MCP server to your Claude configuration at ~/Library/Application Support/Claude/claude_desktop_config.json (Mac) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "buywhere": {
      "command": "buywhere-mcp",
      "env": {
        "BUYWHERE_API_KEY": "bw_live_your_key_here"
      }
    }
  }
}

Restart Claude Desktop.

Step 3: Test the Integration

Ask Claude:

Search BuyWhere for the best wireless headphones under SGD 200 in Singapore.

Claude will call the MCP tool and return structured results.

How It Works Under the Hood

The MCP server exposes the BuyWhere product search as a Claude tool:

# buywhere_mcp/server.py
from mcp.server import MCPServer
from buywhere import BuyWhereClient

server = MCPServer("buywhere")
client = BuyWhereClient(api_key=os.environ["BUYWHERE_API_KEY"])

@server.tool()
def search_products(query: str, max_price: float = None, limit: int = 10) -> dict:
    """Search products with optional price filter."""
    params = {"q": query, "limit": limit}
    if max_price:
        params["max_price"] = max_price
    return client.products.search(**params)

Customizing the Tool Behavior

Add Price Filtering

Extend the tool to support category and brand filters:

@server.tool()
def search_with_filters(
    query: str,
    category: str = None,
    brand: str = None,
    min_price: float = None,
    max_price: float = None,
    limit: int = 10
) -> dict:
    """Search with full filtering support."""
    params = {"q": query, "limit": limit}
    if category:
        params["category"] = category
    if brand:
        params["brand"] = brand
    if min_price:
        params["min_price"] = min_price
    if max_price:
        params["max_price"] = max_price
    
    return client.products.search(**params)

Add Price Comparison

Add a best-price endpoint:

@server.tool()
def find_best_price(product_name: str) -> dict:
    """Find the cheapest listing for a product across all platforms."""
    results = client.products.search(q=product_name, limit=20)
    
    if not results.get("items"):
        return {"error": "Product not found"}
    
    best = min(
        results["items"],
        key=lambda p: float(p.get("price_sgd", p["price"]))
    )
    
    return {
        "product": best["name"],
        "price": f"SGD {best['price']}",
        "source": best["source"],
        "url": best.get("affiliate_url", best["buy_url"]),
        "rating": best.get("rating"),
        "savings_vs_avg": calculate_savings(results["items"], best)
    }

Example Conversation Flows

Finding a Specific Product

You: Find me a Nintendo Switch OLED under SGD 400 with good ratings.

Claude: [Calls search_products with query="Nintendo Switch OLED", max_price=400]
→ Nintendo Switch OLED Model... | SGD 385.00 | Shopee SG | ⭐ 4.8 (1,234 reviews)
   Buy: https://api.buywhere.ai/v1/track/abc123

Comparing Options

You: What are the best options for running shoes from Shopee or Lazada?

Claude: [Calls search with category="Sports", brand filters, sorts by rating]
→ Top 3 Running Shoes:
   1. Nike Air Zoom Pegasus... | SGD 189.00 | Lazada SG | ⭐ 4.7
   2. Adidas Ultraboost... | SGD 229.00 | Shopee SG | ⭐ 4.6
   3. ASICS Gel-Kayano... | SGD 199.00 | Lazada SG | ⭐ 4.5

Error Handling

The tool gracefully handles errors:

try:
    results = client.products.search(q=query, limit=limit)
except BuyWhereAuthError:
    return {"error": "Invalid API key. Check your configuration."}
except BuyWhereRateLimitError:
    return {"error": "Rate limit reached. Try again in a few seconds."}
except Exception as e:
    return {"error": f"Search failed: {str(e)}"}

Next Steps

Full Source Code

See the complete MCP server implementation in /home/paperclip/buywhere-api/mcp/server.py.