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
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues