Skip to main content
Glama
Llamatron2112

price-verify-mcp

README.md
# price-verify-mcp

**MCP** server for price verification via the **Serper** API (Google Shopping + merchant page scraping).

Built to solve the problem of Google Shopping responses being **too large** and blowing up the LLM context: all data is **truncated and reformatted server-side** before being returned to the model. A price check consumes ~50 tokens instead of several thousand.

## Exposed tools

| Tool | Role | Output |
|---|---|---|
| `verify_price` | Searches a product on Google Shopping, keeps only the top N offers (default 3, max 5) with reduced fields (title, price, merchant, rating, delivery). Optional verdict vs expected price (in line / more expensive / cheaper, ±10 % tolerance by default). | Compact text + structured JSON |
| `scrape_price` | Scrapes a merchant product page and **extracts only the price** (schema.org JSON-LD first, then text regex). One price, minimal context. | Compact text + structured JSON |
| `cache_stats` | Internal cache state (diagnostic). | JSON |

## Why not a Serper "pass-through" server (e.g. `go-serper-mcp-server`)?

Those servers return the full raw Serper JSON (all offers, imageUrl, 300-character links, indented), and `num` is **ignored** by Serper's shopping endpoint (fixed Google Shopping grid). Result: tens of thousands of tokens per call. Here, truncation happens **inside the MCP server**, not via the `num` parameter.

## Installation

Requirements: **Node.js ≄ 18** (only for the local development option; `npx` handles everything else).

### Option 1 — Via npx, directly from GitHub (recommended)

No local install: npx downloads and runs the server on the fly. The repo contains a `package.json` with a `bin` field, so npx can execute it directly:

```json
{
  "mcpServers": {
    "price-verify": {
      "command": "npx",
      "args": ["-y", "github:Llamatron2112/price-verify-mcp"],
      "env": {
        "SERPER_API_KEY": "YOUR_SERPER_KEY"
      }
    }
  }
}
```

Requirements: **public** repository, valid `package.json` at the root, `bin` field present (all already in place). The first run installs the dependencies (a few seconds). You can also pin a commit/tag: `github:<YOUR_USER>/price-verify-mcp#v1.0.0`.

> šŸ’” This format is accepted by any MCP client supporting stdio servers and Claude-style config: **Chatbox, Claude Desktop, Cursor, VS Code** (they all accept the `mcpServers` key).

### Option 2 — Local development

```bash
git clone https://github.com/Llamatron2112/price-verify-mcp.git
cd price-verify-mcp
npm install
```

**Where does the API key go?** Two options, depending on the context:

| Context | Where the key goes | File to fill |
|---|---|---|
| **Chatbox / MCP client (recommended)** | `env` block of the MCP server config (environment variable `SERPER_API_KEY`) | none — just the config |
| **Command-line testing** | `.env` file read by the server at startup (looked up in the current working directory, then the module directory) | `.env` (copy `.env.example`) |

āš ļø Priority: if `SERPER_API_KEY` is defined in the environment (the MCP client case), **it wins over the `.env` file** — the server never overrides an already-defined variable. So you don't need to touch `.env` when the key is in the client config.

API key: https://serper.dev/ (2,500 free searches, no credit card required).

## Configuration in Chatbox

Chatbox accepts the **Claude format** (`mcpServers` key) for importing an MCP server.

### Method A — Via the UI (recommended)

1. **Settings → MCP → Add Server**
2. Paste the content of `mcp.chatbox.json` (Claude format, replace the key):

```json
{
  "mcpServers": {
    "price-verify": {
      "command": "npx",
      "args": ["-y", "github:Llamatron2112/price-verify-mcp"],
      "env": {
        "SERPER_API_KEY": "YOUR_SERPER_KEY"
      }
    }
  }
}
```

3. Save, then enable the server in the conversation.

> šŸ’” The same `claude_desktop_config.json` file (identical format) can be imported as-is into **Claude Desktop** (Settings → Developer → Edit Config).

### Method B — One-click link

```bash
npm run install-link
```

The script prints a `chatbox://mcp/install?server=...` link to open in the browser (Chatbox must be installed). It reads the `mcp.chatbox.json` config (Claude format) and converts it automatically to the flat format expected by the one-click link.

### Quick check

```bash
node server.js   # should start without error (waits for MCP messages on stdin)
npm test         # unit tests for price parsing
```

## Usage examples (prompts)

**Simple check:**
> Verify the price of "Sony WH-1000XM5" with verify_price (gl=fr).

**With expected price (verdict):**
> Use verify_price with product="Sony WH-1000XM5", expected_price=300, gl="fr". Just tell me if the price found is in line and where.

**Exact price at the source:**
> I have this URL https://www.fnac.com/... — use scrape_price to give me the current price.

## Best practices for the LLM (to add to your system prompts)

- Always pass `gl`/`hl` (e.g. `fr`) for localized results.
- `verify_price`: use a precise query (brand + model + variant) to avoid heterogeneous offers.
- `limit`: keep 3 by default, 5 maximum.
- Don't copy the structured JSON into the answer — reply in 1–2 lines (price, merchant, verdict).
- `scrape_price`: reserve for already-known URLs (2nd step), as a scrape can be slower.
- Prices are displayed in the currency's natural format (e.g. `299,99 €` for EUR, `$1,299.99` for USD, `Ā£299.99` for GBP), detected automatically from the offer string.

## Project structure

```
price-verify-mcp/
ā”œā”€ā”€ server.js              # MCP server (stdio) + tool definitions
ā”œā”€ā”€ lib/
│   ā”œā”€ā”€ serper.js          # Serper API client (shopping + scrape)
│   ā”œā”€ā”€ prices.js          # Price parsing (FR/US), verdicts, JSON-LD/regex extraction
│   └── cache.js           # In-memory TTL cache (6 h shopping, 1 h scrape)
ā”œā”€ā”€ scripts/install-link.js # Generates the Chatbox one-click link
ā”œā”€ā”€ test/prices.test.js     # Unit tests
ā”œā”€ā”€ mcp.chatbox.json        # Chatbox config (Claude format)
ā”œā”€ā”€ claude_desktop_config.json # Claude Desktop config (identical)
ā”œā”€ā”€ .env.example            # Configuration template
ā”œā”€ā”€ .gitignore              # node_modules, .env, *.tgz
ā”œā”€ā”€ LICENSE                 # MIT
└── package.json            # bin: price-verify-mcp (required for npx)
```

## Known limitations

- **`num` ignored by Serper shopping**: limiting is done server-side (`limit`), not via the API.
- Google Shopping gives indicative prices; the exact price at the source requires `scrape_price` (some anti-bot or JS-only pages cannot be scraped).
- In-memory cache: cleared on server restart.
- 1 Serper key = 1 shared quota (2,500 free searches, then paid credits).

## License

MIT