Skip to main content
Glama
IamMichael23

rangeview-mcp

by IamMichael23
README.md
# rangeview-mcp

MCP server for read-only access to the [Rangeview Sports](https://www.rangeviewsports.ca) product catalog — ~5,600 products across firearms, ammunition, optics, reloading and accessories.

Backed by the store's public WooCommerce Store API. **No credentials required.** Read-only by design: nothing in this server can add to a cart, place an order, or write anything.

## Install

```bash
git clone https://github.com/IamMichael23/rangeview-mcp.git
cd rangeview-mcp
npm install && npm run build
```

## Use it with Codex

Add to `~/.codex/config.toml`:

```toml
[mcp_servers.rangeview]
command = "node"
args = ["/absolute/path/to/rangeview-mcp/dist/index.js"]
```

## Use it with Claude Code

```bash
claude mcp add rangeview -- node /absolute/path/to/rangeview-mcp/dist/index.js
```

Or commit a `.mcp.json` in your project to share it with collaborators:

```json
{
  "mcpServers": {
    "rangeview": {
      "command": "node",
      "args": ["/absolute/path/to/rangeview-mcp/dist/index.js"]
    }
  }
}
```

## Tools

| Tool | Purpose |
|---|---|
| `search_products` | Free-text + category, caliber, brand, price, stock and sale filters |
| `get_product` | Full detail for one product by id, slug, or SKU |
| `list_categories` | Walk the 376-category tree |
| `list_filter_values` | Discover the 83 filterable attributes and their valid values |
| `check_availability` | Bulk price/stock lookup for up to 20 items |

```
"What bolt-action rifles in 6.5 Creedmoor do they have in stock under $2000?"
"Is SKU 20260728001 still available?"
"What calibers do they carry the most of?"
```

## Two problems this server exists to solve

Anything that just proxies the Store API straight through will get both of these wrong.

### 1. A raw product is ~1,300 tokens, and 81% of it is dead weight

Measured against a live product:

| Field | Share of payload | Needed in a search result? |
|---|---|---|
| `description` | 44.1% | No — detail view only |
| `images` (5 sizes each) | 15.8% | No — one URL at most |
| `_links` | 7.4% | Never |
| `add_to_cart` | 6.3% | Never — this server is read-only |
| `price_html` | 2.6% | No — raw cents is enough |
| `extensions`, `tags` | 5.1% | Never |

So results come back in two shapes: a **compact** projection for search (~340 bytes / ~85 tokens) and a **full** shape only from `get_product`, with the description HTML-stripped and truncated. That is a **~15x reduction**, and it is the difference between 50 results fitting in context and blowing it out. Every response also carries `total_matches`, `page` and `total_pages` so a model paginates deliberately instead of asking for everything.

### 2. Attribute filters take term IDs, and this catalog's terms are dirty

The Store API filters on `term_id`, never on names. And one cartridge is spelled many ways:

```
.223  |  .223 Rem  |  223 Rem  |  223 Remington  |  .223 Rem/5.56 NATO  |  5.56×45mm NATO
```

Inch marks arrive as **two different entities for the same value** — `6.5 Creedmoor/20”` and `6.5 Creedmoor/20″`.

Picking the single best-matching term returns **126** products for `.223`. ORing the whole family returns **138**. So resolution deliberately fans out — you pass `caliber: "223"` and the server expands it to every term in the family and joins the IDs, which the Store API treats as OR. The response reports the expansion in `notes`.

The matching rule that makes this safe is a domain distinction: in cartridge naming a **slash** means "chambers both" (`.223 Rem/5.56 NATO`) while a **hyphen** means "wildcat built on that parent case" — a different cartridge that will not chamber. So `6mm-223`, `.17-223` and `7mm-223 Ingram` are correctly excluded from a `.223` search even though all three contain the string "223".

## Catalog hygiene

Two quirks of the live store are handled by default, because both produce confidently wrong answers otherwise:

- **15 internal `Shipping test product #N` rows are live at $0.01.** Without filtering, "what's the cheapest item?" returns a QA artifact. They are hidden by default; pass `include_test_products: true` to see them. (The cheapest genuine item is a $0.49 pack of earplugs.)
- **`$0.00` means "call for price", not free.** Special orders such as a Beretta 693 shotgun list at zero. These are reported as `price_on_request: true` with a `null` price, so a model never announces a $2,775 shotgun is free.

Also worth knowing: **only ~34% of the catalog (1,923 of 5,602) is in stock.** Pass `in_stock_only: true` for buyable items.

## Configuration

All optional:

| Variable | Default | Purpose |
|---|---|---|
| `RANGEVIEW_BASE_URL` | `https://www.rangeviewsports.ca` | Point at another WooCommerce store |
| `RANGEVIEW_TIMEOUT_MS` | `20000` | Per-request timeout |
| `RANGEVIEW_MAX_RETRIES` | `3` | Retries on 429/5xx with backoff |
| `RANGEVIEW_TAXONOMY_TTL_MS` | `3600000` | Category/attribute cache lifetime |
| `RANGEVIEW_DESC_MAX_CHARS` | `1500` | Description truncation in `get_product` |

## Tests

```bash
npm test              # all 35
npm run test:unit     # 22, offline
npm run test:integration  # 13, hits the live API
```

Set `RANGEVIEW_SKIP_INTEGRATION=1` to skip the network tests.

## Notes

This reads a public, unauthenticated endpoint that the store already serves to every browser, and it is rate-limit-friendly (single-page queries, cached taxonomy, backoff on 429). It is not affiliated with or endorsed by Rangeview Sports. Product data, availability and pricing belong to them and change without notice — confirm anything that matters on the site itself.

MIT licensed.

TDQS

A4.4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool targets a distinct function: searching, getting details, browsing categories, discovering filter values, and bulk checking availability. No overlap exists, and the descriptions clearly differentiate their use cases.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (search_products, get_product, list_categories, list_filter_values, check_availability). The verbs are descriptive and the nouns clearly indicate the resource.

Tool Count5/5

With 5 tools, the server covers the essential operations for a product catalog (search, detail, category navigation, filter discovery, stock check) without being overly sparse or excessive. Each tool serves a clear purpose.

Completeness5/5

The tool set covers the full workflow for browsing and evaluating products: exploring categories and filters, searching with filters, getting full details, and checking availability. No obvious gaps exist for a read-only catalog.

Maintenance

ActivityStale
ResponsivenessNo issues