npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

marktplaats-mcp

v1.0.6

Published

MCP server for efficient Marktplaats.nl access and scraping

Readme

marktplaats-mcp

A Model Context Protocol (MCP) server that provides efficient, token-optimized access to Marktplaats.nl listings for AI agents.

npm version npm downloads

TypeScript Playwright MCP

Overview

This MCP server replaces the need for agents to use generic Playwright commands to scrape Marktplaats. Instead of receiving full HTML pages (which are token-heavy), agents get structured JSON responses with only the relevant data.

Perfect for AI agents shopping for specific items with progressive search refinement.

Quick Start

# Install the MCP server
npm install -g marktplaats-mcp

# Install required browser
npx playwright install chromium

# Add to Claude Code
claude mcp add marktplaats marktplaats-mcp

Now you can ask Claude Code: "Find me a racing bike under €500 in Amsterdam"

Key Benefits

  • Token Efficient: Returns structured JSON instead of full HTML pages
  • Smart Search: Provides pagination metadata so agents can refine searches
  • Image Access: All image URLs are provided in full resolution
  • Rate Limited: Built-in protection against overwhelming Marktplaats servers
  • Cached Results: 15-minute cache for recently accessed listings

Tools

1. search_marktplaats

Search for products on Marktplaats with optional filters.

Input:

{
  "searchTerm": "racefiets",
  "priceMin": 100,        // Optional: minimum price in EUR
  "priceMax": 500,        // Optional: maximum price in EUR  
  "postcode": "2021ZH",   // Optional: Dutch postcode for location filtering
  "radius": 10            // Optional: search radius in km
}

Output:

{
  "listings": [
    {
      "url": "https://www.marktplaats.nl/v/...",
      "title": "Cube Aerial Racefiets",
      "price": "€ 450",
      "description": "Cube Aerial racefiets in goede staat...",
      "thumbnail": "https://...",
      "location": "Haarlem",
      "isAd": false,
      "isCommercial": false
    }
    // ... more listings
  ],
  "metadata": {
    "totalResults": 450,
    "totalPages": 18,
    "currentPage": 1,
    "resultsPerPage": 25,
    "searchTerm": "racefiets",
    "filters": {
      "priceMin": 100,
      "priceMax": 500,
      "postcode": "2021ZH",
      "radius": 10
    }
  }
}

2. get_listing_details

Get detailed information about a specific listing.

Input:

{
  "url": "https://www.marktplaats.nl/v/fietsen-en-brommers/fietsen-racefietsen/m2291207164-cube-aerial-racefiets"
}

Output:

{
  "title": "Cube Aerial Racefiets Carbon Voorvork",
  "price": "€ 450",
  "description": "Cube Aerial racefiets in zeer goede staat...\n\nSpecificaties:\n- Carbon voorvork\n- Shimano 105 groepset\n- Maat 58cm\n...",
  "images": [
    "https://cdn.marktplaats.com/...?rule=ecg_mp_eps$_86",  // Full-size (1024px)
    "https://cdn.marktplaats.com/...?rule=ecg_mp_eps$_86",
    "https://cdn.marktplaats.com/...?rule=ecg_mp_eps$_86"
  ],
  "seller": {
    "name": "Jan de Vries",
    "location": "Haarlem, Noord-Holland",
    "memberSince": "2015",
    "verified": false
  },
  "attributes": [
    { "label": "Categorie", "value": "Racefietsen" },
    { "label": "Merk", "value": "Cube" },
    { "label": "Framemaat", "value": "58 cm" },
    { "label": "Materiaal frame", "value": "Aluminium" },
    { "label": "Aantal versnellingen", "value": "20" }
  ],
  "location": {
    "city": "Haarlem",
    "province": "Noord-Holland",
    "postcode": "2021"
  },
  "listingId": "m2291207164",
  "url": "https://www.marktplaats.nl/v/fietsen-en-brommers/fietsen-racefietsen/m2291207164-cube-aerial-racefiets",
  "postedDate": "2024-12-15",
  "viewCount": 234
}

Usage Example

Here's how an agent might use this MCP server to find a racing bike:

  1. Initial Search

    Agent: "I'll search for racing bikes in Haarlem under €500"
    Calls: search_marktplaats({ searchTerm: "racefiets", priceMax: 500, postcode: "2021ZH" })
    Result: 450 results across 18 pages
  2. Refine Search

    Agent: "That's too many results. Let me narrow it down to €200-€500 within 5km"
    Calls: search_marktplaats({ searchTerm: "racefiets", priceMin: 200, priceMax: 500, postcode: "2021ZH", radius: 5 })
    Result: 73 results across 3 pages
  3. Get Details

    Agent: "This Cube Aerial looks interesting, let me check the details"
    Calls: get_listing_details({ url: "https://..." })
    Result: Full details with 5 high-resolution image URLs
  4. Analyze Images

    Agent: "Let me download these images to check the bike's condition"
    Downloads images directly from provided URLs
    Analyzes frame condition, components, etc.

Technical Implementation

Architecture

┌─────────────┐     MCP Protocol      ┌─────────────────┐     Playwright     ┌──────────────┐
│   AI Agent  │◄───────────────────────┤  MCP Server     │◄─────────────────►│ Marktplaats  │
│  (Claude)   │     Structured JSON    │  (TypeScript)   │     Web Scraping  │   Website    │
└─────────────┘                        └─────────────────┘                    └──────────────┘

Key Components

  1. MCP Server (index.ts)

    • Handles MCP protocol communication
    • Routes tool calls to appropriate handlers
    • Manages server lifecycle
  2. Marktplaats Scraper (marktplaats-scraper.ts)

    • Playwright-based web scraping
    • Intelligent data extraction
    • Image URL resolution
    • Caching layer
  3. Rate Limiting

    • 2-3 seconds between search requests
    • 1-2 seconds between detail requests
    • Exponential backoff on errors
  4. Data Extraction

    • JSON-LD structured data parsing
    • DOM fallback strategies
    • Dutch number format handling

Quick Start

Prerequisites

  • Node.js 18+
  • npm or yarn

Installation

# Install globally from npm
npm install -g marktplaats-mcp

# Install Playwright browsers (REQUIRED - the package won't work without this)
npx playwright install chromium

⚠️ Important: You must run npx playwright install chromium after installing the package, otherwise the MCP server will fail to start.

Development/Source Installation (Optional)

If you want to modify the source code:

# Clone and setup
git clone https://github.com/vabole/marktplaats-helper.git
cd marktplaats-helper/mcp/

# Install dependencies
npm install

# Install Playwright browsers (required)
npx playwright install

# Build the server
npm run build

Configuration for Claude Code

# Option 1: Use the npm package command (may require manual Playwright setup)
claude mcp add marktplaats marktplaats-mcp

# Option 2: Use absolute path to ensure it works (recommended)
claude mcp add marktplaats node $(npm root -g)/marktplaats-mcp/dist/index.js

# Verify it was added
claude mcp list

Note: If you encounter connection issues with the npm command, use Option 2 (absolute path) which is more reliable.

Configuration for Claude Desktop

Add to your Claude Desktop configuration:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json

Using npm package (recommended):

{
  "mcpServers": {
    "marktplaats": {
      "command": "npx",
      "args": ["marktplaats-mcp"]
    }
  }
}

Using global installation:

{
  "mcpServers": {
    "marktplaats": {
      "command": "marktplaats-mcp"
    }
  }
}

Using local build:

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

Important: For local builds, use absolute paths, not relative paths.

Configuration for Claude.ai

If using the web version of Claude, you'll need to deploy this as a remote MCP server. See MCP documentation for details.

Verification

Test your setup:

# Test the globally installed package
marktplaats-mcp --version

# Test with Claude Code (if configured)
# Just ask Claude: "Find me a laptop under €500"

Testing the npm Package

To verify the globally installed package works correctly:

# Quick test (requires marktplaats-mcp to be installed globally)
git clone https://github.com/vabole/marktplaats-helper.git
cd marktplaats-helper/mcp/

# Run the npm package E2E test
node run-npm-e2e-test.js

# Or use npm script
npm run test:npm:dev

This test verifies that:

  • The globally installed package starts correctly
  • MCP protocol communication works
  • Search and detail fetching work as expected
  • Progressive search refinement works
  • All data fields are properly extracted

Development Testing

For development and source code testing:

# Run E2E test against local build
npm run test:e2e

# Use the friendly test runner  
node run-e2e-test.js

Usage with AI Agents

Once configured, you can use the MCP server in your conversations with Claude:

Example Agent Conversations

Finding a Racing Bike:

You: I'm looking for a racing bike under €500 in the Amsterdam area. Can you help me find some options?

Claude: I'll help you search for racing bikes in Amsterdam under €500. Let me start with a broad search and then refine it based on what we find.

[Calls search_marktplaats with searchTerm="racefiets", priceMax=500, postcode="1012", radius=25]

I found 247 racing bikes under €500 in the Amsterdam area (25km radius). Let me get details on a few promising options...

[Calls get_listing_details for top 3 results]

Here are the best options I found:
1. **Trek 1.2 Road Bike** - €450 (Excellent condition, Shimano 105 groupset)
2. **Giant Defy 3** - €380 (Good starter bike, aluminum frame)  
3. **Cannondale CAAD8** - €495 (Carbon fork, very light)

Would you like me to get more details about any of these, or search for something more specific?

Progressive Search Refinement:

You: The Trek looks interesting, but €450 is still a bit high. Can you find similar bikes for under €350?

Claude: Let me refine the search to focus on bikes under €350 in Amsterdam.

[Calls search_marktplaats with updated price filter]

Great news! I found 89 racing bikes under €350. Here are some excellent alternatives to the Trek...

Agent Capabilities

With this MCP server, AI agents can:

  • Smart Search Strategy: Start broad, progressively narrow based on results
  • Price Comparison: Compare similar items across different price ranges
  • Location Optimization: Find the best deals within travel distance
  • Detailed Analysis: Examine photos and descriptions to assess condition
  • Market Research: Understand pricing trends for specific categories

Rate Limiting & Respectful Usage

The server automatically handles rate limiting:

  • 2 seconds between search requests
  • 1 second between listing detail requests
  • 15-minute caching to avoid redundant requests
  • Single browser instance for efficiency

Development

# Run in development mode
npm run dev

# Build the project
npm run build

# Test the npm-installed package (requires global install)
npm run test:npm
npm run test:npm:dev
node run-npm-e2e-test.js

# Test local development build
npm run test:e2e
npm run test:e2e:dev
node run-e2e-test.js

# Code quality
npm run lint
npm run typecheck

E2E Test Scenario

The E2E test simulates a realistic AI agent workflow:

  1. Initial Search: Broad search for "racefiets" (racing bikes)
  2. Price Filtering: Narrow down to €200-€500 range
  3. Location Filtering: Further limit to Haarlem area (10km radius)
  4. Detail Fetching: Get full details for top 3 results

The test validates:

  • Progressive result count reduction
  • Proper pagination metadata
  • Full-resolution image URLs
  • Complete listing details extraction
  • Token-efficient JSON responses

Best Practices

  1. Search Optimization

    • Start with broad searches to gauge result volume
    • Progressively refine filters based on result count
    • Use location filters to reduce irrelevant results
  2. Image Analysis

    • Images are provided in full resolution (1024px)
    • Download only images you need to analyze
    • Cache downloaded images locally
  3. Rate Limiting

    • Respect the built-in delays
    • Don't make parallel requests to the same tool
    • Use cached data when possible

Troubleshooting

Common Issues

Server not starting:

# Check if Playwright browsers are installed
npx playwright install

# Verify TypeScript compilation
npm run build

Claude Desktop not finding the server:

  • Ensure you're using absolute paths in your config
  • Check that the dist/index.js file exists after building
  • Restart Claude Desktop after config changes

Search returning no results:

  • Try broader search terms (e.g., "fiets" instead of "racefiets")
  • Check if your price range is too restrictive
  • Verify the postcode format (e.g., "2021ZH" not "2021 ZH")

Rate limiting errors:

  • The server automatically handles rate limits
  • If you see timeouts, the 15-minute cache may be helping reduce requests
  • Respect the built-in delays for reliable operation

Performance Tips

  1. Use specific search terms to get better results
  2. Start with broader filters then progressively narrow
  3. Leverage caching - identical searches within 15 minutes are instant
  4. Batch similar requests - get details for multiple listings in sequence

FAQ

Q: Is this legal?
A: Yes, this performs automated browsing similar to what a human would do. It respects rate limits and robots.txt.

Q: Can I use this for commercial purposes?
A: Check Marktplaats's Terms of Service for commercial use restrictions. This tool is designed for personal shopping assistance.

Q: How often should I update?
A: The server is designed to be stable. Update when you need new features or Marktplaats changes their website structure.

Q: Can I add more search filters?
A: Yes! See the SearchFilters interface in src/types.ts. Additional filters can be added to the URL building logic.

Q: Does it work with other Marktplaats categories?
A: Yes! It works with any category. Just adjust your search terms (e.g., "laptop", "bureau", "auto").

Future Enhancements

  • [ ] Additional search filters (condition, seller type, etc.)
  • [ ] Saved searches with notifications
  • [ ] Bulk listing analysis
  • [ ] Historical price tracking
  • [ ] Category-specific attributes
  • [ ] Multi-language support
  • [ ] Export to CSV/JSON functionality

License

MIT

Contributing

Contributions are welcome! Please ensure all scraping remains respectful of Marktplaats's servers and terms of service.

Development Guidelines

  1. Respect rate limits - Don't reduce the built-in delays
  2. Test thoroughly - Use the E2E tests before submitting changes
  3. Document changes - Update this README for new features
  4. Follow TypeScript best practices - Maintain type safety