Skip to main content
Glama
AkhtarXx

Catawiki MCP Server

by AkhtarXx
README.md
# Catawiki MCP Server

<p align="center">
  <a href="https://modelcontextprotocol.io"><img alt="MCP" src="https://img.shields.io/badge/MCP-1.12-blue" /></a>
  <a href="https://nodejs.org"><img alt="Node.js" src="https://img.shields.io/badge/Node.js-%E2%89%A518-339933?logo=node.js&logoColor=white" /></a>
  <a href="https://www.typescriptlang.org"><img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-5.7-3178C6?logo=typescript&logoColor=white" /></a>
  <a href="#license"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-green" /></a>
</p>

A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that gives AI assistants read-only access to [Catawiki](https://www.catawiki.com) auction marketplace data — search lots, inspect items, browse categories, and explore auctions. Since Catawiki offers no public API, this server reads publicly available data directly from the website.

**Highlights**

- šŸ” **10 tools** — search, lot details, categories, auctions, sellers, images, and more
- šŸ“¦ **3 resources** + **5 prompts** for richer, guided AI workflows
- šŸ›”ļø **Production-hardened** — structured-data parsing, anti-bot detection, rate limiting, caching, and fail-loud error handling

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Usage](#usage)
- [Architecture](#architecture)
- [Reliability & Production Hardening](#reliability--production-hardening)
- [Legal Notice](#legal-notice)
- [License](#license)

## Features

### Tools (10)
| Tool | Description |
|------|-------------|
| `search_lots` | Search for lots/items with filters (price, sort), pagination, and optional `enrich_bids` for live bids on the top 5 results |
| `get_lot_details` | Get detailed info about a specific lot (title, description, bids, seller, images) |
| `list_categories` | List all available auction categories |
| `get_category_lots` | Browse lots within a specific category |
| `get_auction_details` | Get details of a themed auction and its lots |
| `get_upcoming_auctions` | List upcoming/active auctions |
| `get_featured_lots` | Get featured/trending lots from the homepage |
| `get_seller_profile` | Get seller information and recent lots |
| `get_lot_images` | Get all image URLs for a specific lot |
| `scrape_catawiki_page` | Scrape any public Catawiki page (help, about, stories, etc.) |

### Resources (3)
| Resource | URI | Description |
|----------|-----|-------------|
| Platform Info | `catawiki://info` | General platform information, features, URL patterns |
| Categories | `catawiki://categories` | Dynamic list of all auction categories |
| Server Info | `catawiki://server-info` | Server version, capabilities, uptime |

### Prompts (5)
| Prompt | Description |
|--------|-------------|
| `analyze-lot` | Analyze a lot's value, authenticity, and buying considerations |
| `compare-lots` | Side-by-side comparison of multiple lots |
| `explore-category` | Discover what's available in a category with price ranges |
| `find-deals` | Search for potentially undervalued items |
| `market-overview` | Overview of current marketplace activity |

## Installation

```bash
# Clone and install
cd catawiki
npm install
npm run build
```

## Usage

### With Claude Desktop

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "catawiki": {
      "command": "node",
      "args": ["/absolute/path/to/catawiki/build/index.js"]
    }
  }
}
```

### With MCP Inspector (for debugging)

```bash
npm run inspect
```

### Development

```bash
npm run dev          # Run with tsx (hot reload)
npm run build        # Compile TypeScript
npm test             # Run test suite
npm run test:watch   # Run tests in watch mode
```

## Architecture

```
catawiki/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ index.ts                # Entry point (stdio transport)
│   ā”œā”€ā”€ server.ts               # Server assembly
│   ā”œā”€ā”€ tools/
│   │   └── index.ts            # 10 MCP tool definitions
│   ā”œā”€ā”€ resources/
│   │   └── index.ts            # 3 MCP resource definitions
│   ā”œā”€ā”€ prompts/
│   │   └── index.ts            # 5 MCP prompt templates
│   └── services/
│       ā”œā”€ā”€ http-client.ts      # HTTP client with rate limiting & caching
│       └── catawiki-scraper.ts # HTML parser for Catawiki pages
ā”œā”€ā”€ tests/
│   ā”œā”€ā”€ http-client.test.ts     # HTTP client unit tests
│   ā”œā”€ā”€ catawiki-scraper.test.ts# Scraper unit tests
│   └── mcp-server.test.ts      # MCP protocol integration tests
ā”œā”€ā”€ package.json
ā”œā”€ā”€ tsconfig.json
└── vitest.config.ts
```

## Reliability & Production Hardening

This server scrapes a live site, so it is built to **fail loudly and correctly**
rather than silently return wrong data:

- **Structured-data first**: lot, search, category, seller, and auction data are
  read from the page's `__NEXT_DATA__` hydration payload (what the site actually
  renders from) — not from brittle CSS classes or JSON-LD.
- **Fail-loud on structure change**: if a page loads but the expected hydration
  data is gone (e.g. Catawiki ships a markup change or migrates frameworks), the
  affected tool returns a clear error asking for a scraper update — it does **not**
  return an item with every field `N/A`. A live regression test guards this.
- **Anti-bot detection**: a `200 OK` is not trusted blindly — Cloudflare /
  DataDome / PerimeterX challenge pages are detected and surfaced as an access
  error instead of being parsed as empty content.
- **Rate limiting**: 10 requests/minute (sliding window) to respect Catawiki.
- **Caching**: 5-minute default TTL (30 min for categories), with a hard cap on
  cache size and oldest-entry eviction to bound memory in long-running processes.
- **Retries**: exponential backoff on transient errors; honors `Retry-After` on 429.
- **Errors**: 404 / 403 / 429 / network failures map to actionable, sanitized
  messages (`isError: true`) that an agent can act on — no stack traces or
  internal details leak.
- **MCP tool annotations**: all tools are marked `readOnlyHint` + `openWorldHint`.

### Known limitations

- **Live bids on list views**: search/category results don't carry a live bid in
  the page HTML (it's pushed over a realtime channel). Pass `enrich_bids: true`
  to fill bids for the top 5 results, or call `get_lot_details` for a single lot.
- **`get_featured_lots` / `get_upcoming_auctions`**: the homepage no longer
  server-renders this data (it's loaded client-side), so these tools return a
  message pointing you to `search_lots` / `get_category_lots` instead.

## Legal Notice

This server scrapes publicly available data from Catawiki's website. It is intended for personal/research use. Please review Catawiki's [Terms of Service](https://www.catawiki.com/en/help/terms-of-use) before using this server. Be mindful of rate limits and respect the website's `robots.txt` directives.

## License

MIT