marktplaats-mcp
marktplaats-mcp is an MCP server that lets AI agents search and browse Marktplaats (Netherlands) and 2dehands (Belgium) second-hand classifieds without any account or API key.
Search listings (
search_listings): Search for ads using free text, category, price range, item condition (new, as-good-as-new, used, refurbished, not working), distance from a postal code, recency, sorting (relevance, date, price, location), and pagination — on either marktplaats.nl or 2dehands.be.Get full listing details (
get_listing_details): Retrieve a complete ad including the full description, all photos, view/favorite counts, listing age, seller info, and item attributes.Check seller trustworthiness (
get_seller_profile): Look up a seller's trust signals — verified bank account, identity, and phone number — plus their review score and review count.Browse categories (
list_categories): Explore the full category tree (top-level and subcategories) to find names and IDs for use in search filters.Monitor new listings (
check_new_listings): Poll for listings posted after a specific timestamp (ISO 8601), using a stateless cursor to incrementally check only genuinely new ads; paid promotions are filtered out by default.
Provides tools for GitHub Copilot to search Marktplaats and 2dehands listings, retrieve listing details and seller profiles, browse categories, and monitor new listings.
Provides tools for JetBrains IDEs (AI Assistant / Junie) to search Marktplaats and 2dehands listings, retrieve listing details and seller profiles, browse categories, and monitor new listings.
Provides tools for OpenAI Codex CLI to search Marktplaats and 2dehands listings, retrieve listing details and seller profiles, browse categories, and monitor new listings.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@marktplaats-mcpsearch for OLED TV under €400 near 3011 AB"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
marktplaats-mcp
marktplaats-mcp is an MCP server that lets Claude, Cursor, Codex, opencode and every other MCP client search Marktplaats and 2dehands, the Dutch and Belgian second-hand classifieds. Find bargains, vet sellers, browse categories and monitor new listings in plain language.
✨ Features
🔍 Powerful search: free text, categories, price range, condition, distance from a postal code, recency, sorting
🇳🇱🇧🇪 Two marketplaces, one server: marktplaats.nl (Netherlands) and 2dehands.be (Belgium) via a
siteparameter📄 Full listing details: complete description, all photos, view and favorite counts, listing age
🛡️ Seller vetting: verified bank account, identity and phone, review score
🔔 New-listing monitoring: poll for ads placed after a timestamp with a stateless cursor
🧠 Built for LLMs: compact token-efficient output, paid promotions filtered out, structured results, pagination hints
🔁 Resilient: retries with exponential backoff, jitter and
Retry-Afterhandling🔓 No account, no API key
Related MCP server: Begagnad MCP
🚀 Quickstart
The only prerequisite is uv (brew install uv or curl -LsSf https://astral.sh/uv/install.sh | sh).
Claude Code, one command:
claude mcp add marktplaats -- uvx marktplaats-mcpThen ask: "Search Marktplaats for an OLED TV under €400 near 3011 AB."
🌐 Use on claude.ai (no install)
You can skip the terminal entirely. A hosted copy of this server runs at https://marktplaats-mcp.jaspnerd.dev/mcp, ready to plug into claude.ai in your browser or the Claude mobile app. Custom connectors work on every Claude plan, including Free.
Open claude.ai and go to Settings → Connectors.
Click Add custom connector.
Paste
https://marktplaats-mcp.jaspnerd.dev/mcpas the URL and click Add. No account or key needed.Ask Claude: "Search Marktplaats for an OLED TV under €400 near 3011 AB."
The hosted endpoint runs the same code as the PyPI package, rate-limited per client. If you'd rather have requests come from your own machine, install it locally below.
📦 Install in your favorite client
Every config runs the same stdio server via uvx marktplaats-mcp.
Add to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then fully restart Claude Desktop:
{
"mcpServers": {
"marktplaats": {
"command": "uvx",
"args": ["marktplaats-mcp"]
}
}
}If Claude Desktop can't find uvx, use the absolute path (which uvx, e.g. /Users/you/.local/bin/uvx).
Add to ~/.codex/config.toml:
[mcp_servers.marktplaats]
command = "uvx"
args = ["marktplaats-mcp"]Or: codex mcp add marktplaats -- uvx marktplaats-mcp
Add to opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"marktplaats": {
"type": "local",
"command": ["uvx", "marktplaats-mcp"],
"enabled": true
}
}
}Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project):
{
"mcpServers": {
"marktplaats": {
"command": "uvx",
"args": ["marktplaats-mcp"]
}
}
}Add to .vscode/mcp.json (note the servers key and explicit type):
{
"servers": {
"marktplaats": {
"type": "stdio",
"command": "uvx",
"args": ["marktplaats-mcp"]
}
}
}Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"marktplaats": {
"command": "uvx",
"args": ["marktplaats-mcp"]
}
}
}Add to ~/.gemini/settings.json:
{
"mcpServers": {
"marktplaats": {
"command": "uvx",
"args": ["marktplaats-mcp"]
}
}
}Settings → Tools → AI Assistant → Model Context Protocol (MCP) → Add:
{
"mcpServers": {
"marktplaats": {
"command": "uvx",
"args": ["marktplaats-mcp"]
}
}
}🧰 Tools
Tool | What it does |
| Search with query, category, price range, condition, distance, recency, sorting and pagination |
| Full ad: complete description, all images, view and favorite counts, listing age |
| Trust signals: verified bank, identity and phone, review score and count |
| Browse the category tree (names + ids) used for filtering |
| Newest-first monitoring with a stateless cursor: returns only ads placed after |
All five tools are read-only and carry the matching MCP annotations, so clients skip the confirmation prompts.
Example prompts
"Find a second-hand iPhone 15 under €600 in as-good-as-new condition, sorted by price."
"Search 2dehands for a bakfiets within 20 km of postcode 2000 Antwerpen."
"Is seller 12345 trustworthy? Check their profile."
"Check for new 'vintage lamp' listings since my last check and summarize the interesting ones."
❓ FAQ
Does this need a Marktplaats account or API key? No. It uses the same public JSON endpoints the website itself uses.
Is this an official Marktplaats product? No. This is an independent open source project with no ties to Marktplaats or Adevinta. The underlying API is undocumented and may change. The server backs off politely on rate limits; keep your own usage reasonable.
Why do I sometimes see fewer results than the limit?
Paid promotions (DAGTOPPER/TOPADVERTENTIE) are filtered out by default. Pass include_sponsored=true if you want them.
Which Python versions are supported? 3.10 and up. CI tests 3.11 through 3.13 on Linux, macOS and Windows.
🗺️ Roadmap
Persistent saved searches with price-drop detection
Notifications (Discord/Telegram/ntfy via Apprise)
Authenticated tools (your messages, favorites and bids)
Docker image + Docker MCP Catalog
🤝 Contributing
PRs welcome. See CONTRIBUTING.md for the dev setup: uv sync --all-groups, then uv run pytest.
This project reuses proven ideas from marktplaats-py, marktplaats-monitor, marktplaats-2dehands-mcp and PonClick/marktplaats-mcp. Details in THIRD_PARTY_NOTICES.md.
📄 License
MIT © 2026 jasp-nerd
mcp-name: io.github.jasp-nerd/marktplaats-mcp
Available Tools
5 toolscheck_new_listingsCheck new listingsARead-onlyIdempotent
Poll for listings placed after a given moment (newest first, paid promotions filtered out). Stateless: store the returned 'cursor' and pass it as 'since' on the next call to only see genuinely new listings.
| Name | Required | Description | Default |
|---|---|---|---|
| site | No | Which marketplace: marktplaats (Netherlands) or 2dehands (Belgium). | marktplaats |
| limit | No | Max new listings to return (1-100). | |
| query | No | Free-text search, e.g. 'racefiets' or 'iphone 15'. May be empty if a category is given. | |
| since | No | ISO 8601 timestamp (e.g. '2026-07-15T09:00:00Z'); only listings placed after this moment are returned. Defaults to 24 hours ago. Pass the 'cursor' from the previous call to poll incrementally. | |
| category | No | Top-level category name (Dutch, e.g. 'Fietsen en Brommers') or numeric id. See list_categories. | |
| postcode | No | Dutch/Belgian postal code to search around, e.g. '1011 AB' or '2000'. Required for distance filtering. | |
| price_to | No | Maximum price in euros. | |
| condition | No | Filter by item condition. | |
| price_from | No | Minimum price in euros. | |
| distance_km | No | Max distance from postcode in kilometers. | |
| subcategory | No | Subcategory name (e.g. 'Fietsen | Racefietsen') or numeric id. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds significant behavioral context beyond annotations: statelessness, cursor mechanism, paid promotions filtering, and incremental polling. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no wasted words. The first sentence states the primary purpose, the second explains the critical usage pattern. Front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (11 params, output schema), the description covers the core novel aspects (cursor/polling, paid filtering). The schema handles parameter details, output schema covers returns. Complete for the agent's needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with thorough parameter descriptions. The tool description adds overall context (polling flow) but does not significantly enhance individual parameter meaning. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'poll' and the resource 'listings', with specific behaviors: newest first, paid promotions filtered out, and cursor-based incremental polling. It effectively distinguishes from sibling tools like search_listings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear usage pattern: store cursor and pass it as 'since' for next call. However, it does not explicitly contrast with search_listings or state when not to use this tool, though the context of sibling tools offers some guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_listing_detailsGet listing detailsARead-onlyIdempotent
Fetch the full advertisement: complete description, all images, view and favorite counts, listing age, seller and item attributes.
| Name | Required | Description | Default |
|---|---|---|---|
| site | No | Which marketplace: marktplaats (Netherlands) or 2dehands (Belgium). | marktplaats |
| listing_id | Yes | Listing id from search results, e.g. 'm2400641485'. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the description adds value by listing the returned fields. However, it does not disclose potential limitations (e.g., missing fields for some listings) or operational details beyond what annotations cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the key information ('Fetch the full advertisement') and lists included attributes. No redundant or unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema and comprehensive annotations, the description adequately covers what the tool returns. It lacks details on edge cases or behavior but is sufficient for a read-only tool with well-defined parameters and return structure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with both parameters having clear descriptions. The tool description does not add additional parameter-level semantics beyond what the schema already provides, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Fetch' and resource 'full advertisement', listing exactly what is included (description, images, counts, age, attributes). This clearly conveys the tool's purpose and distinguishes it from siblings like 'search_listings' (which returns summaries) and 'get_seller_profile'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when full listing details are needed, but it does not explicitly state when to use or when not to use this tool versus alternatives like 'search_listings' or 'check_new_listings'. No usage exclusions or prerequisite information is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_seller_profileGet seller profileARead-onlyIdempotent
Look up a seller's trust signals: verified bank account / identity / phone number, review score and number of reviews.
| Name | Required | Description | Default |
|---|---|---|---|
| site | No | Which marketplace: marktplaats (Netherlands) or 2dehands (Belgium). | marktplaats |
| seller_id | Yes | Numeric seller id from a listing's seller field. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the description is not required to disclose these. The description adds context on returned data (trust signals) but no new behavioral traits beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that conveys the tool's purpose without unnecessary words. Front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, annotations, and presence of an output schema, the description is complete. No missing behavioral or parameter details are needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with both parameters described. The description does not add extra meaning beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it looks up a seller's trust signals, listing specific items (verified bank account, identity, phone number, review score, number of reviews). It distinguishes from siblings like get_listing_details and search_listings, which deal with listings rather than seller profiles.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use when needing seller trust information. Sibling tools focus on listings, so context is clear. However, it lacks explicit 'when not to use' or alternative recommendations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_categoriesList categoriesARead-onlyIdempotent
Browse the category tree (shared by marktplaats.nl and 2dehands.be) to find names/ids for search_listings' category and subcategory filters.
| Name | Required | Description | Default |
|---|---|---|---|
| parent | No | Omit for all top-level categories; pass a top-level category name or id for its subcategories. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds that the category tree is shared between marktplaats.nl and 2dehands.be, which is useful but not extensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that communicates the purpose and key usage without extraneous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is sufficient for a simple browsing tool with an output schema. It explains the purpose and parameter usage completely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description covers the 'parent' parameter similarly to the input schema ('omit for top-level, pass name/id for subcategories'). Since schema coverage is 100%, the description adds no further semantic value, warranting a baseline score of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Browse the category tree' and specifies its purpose for search_listings filters. It distinguishes itself from siblings like search_listings by focusing on category browsing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for finding category names/ids for search_listings filters. However, it does not explicitly state when not to use the tool or mention alternatives among the siblings, leaving some ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_listingsSearch listingsARead-onlyIdempotent
Search second-hand listings on Marktplaats or 2dehands with filters for category, price range, condition, recency and distance from a postal code.
| Name | Required | Description | Default |
|---|---|---|---|
| site | No | Which marketplace: marktplaats (Netherlands) or 2dehands (Belgium). | marktplaats |
| limit | No | Results per page (1-100). | |
| query | No | Free-text search, e.g. 'racefiets' or 'iphone 15'. May be empty if a category is given. | |
| offset | No | Pagination offset: page_number * limit. | |
| compact | No | True (default) returns a token-efficient shortlist; False adds description, seller, images and attributes per listing. | |
| sort_by | No | 'relevance' (default), 'date' (newest first with desc), 'price' or 'location'. | relevance |
| category | No | Top-level category name (Dutch, e.g. 'Fietsen en Brommers') or numeric id. See list_categories. | |
| postcode | No | Dutch/Belgian postal code to search around, e.g. '1011 AB' or '2000'. Required for distance filtering. | |
| price_to | No | Maximum price in euros. | |
| condition | No | Filter by item condition. | |
| price_from | No | Minimum price in euros. | |
| sort_order | No | 'asc' or 'desc'. | desc |
| distance_km | No | Max distance from postcode in kilometers. | |
| subcategory | No | Subcategory name (e.g. 'Fietsen | Racefietsen') or numeric id. | |
| include_sponsored | No | Include paid promotions (DAGTOPPER/TOPADVERTENTIE) and the sponsored top block. | |
| offered_since_days | No | Only listings placed within the last N days. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description does not add behavioral context beyond the purpose, but it is consistent with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence efficiently conveys core functionality without redundancy. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 16 parameters fully documented in schema, an output schema, and sibling tools listed, the description adequately covers the tool's scope. Slightly brief for the complexity but sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with thorough descriptions. The description summarizes filter types but adds no new meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches second-hand listings on named platforms with specific filter types, distinguishing it from siblings like check_new_listings or list_categories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
While the description lists filters, it does not explicitly instruct when to use this tool versus alternatives or provide exclusion criteria. Usage is implied but not guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.1- First observed
check_new_listings - First observed
get_listing_details - First observed
get_seller_profile - First observed
list_categories - First observed
search_listings
TDQS
Scored across 5 tools
Each tool has a distinct purpose: polling new listings, fetching listing details, retrieving seller profiles, browsing categories, and searching listings. No functional overlap.
All tools follow a consistent snake_case verb_noun pattern: check_new_listings, get_listing_details, get_seller_profile, list_categories, search_listings.
With 5 tools, the server is well-scoped for browsing and fetching marketplace data, neither too sparse nor too heavy.
The set covers reading operations (search, details, new listings, seller info, categories) but lacks write operations like creating or managing listings, which may be intentional for a read-only use case.
Maintenance
Related MCP Connectors
Search and browse global classifieds across 80 markets. No auth required for read-only access.
AI marketplace: search, buy, sell across Amazon, eBay, AliExpress. 13 tools.
Pay-per-use tool marketplace for AI agents. Search, price-check, and call APIs via MCP.
Search products in nearby stores. Agents can also list items for sale on a user's behalf.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with New Zealand's largest online marketplace through the Trade Me API. Supports searching listings, managing watchlists, placing bids, making purchases, and accessing marketplace data across all Trade Me categories.5-
- FlicenseNot gradedqualityFmaintenanceEnables AI agents to search and retrieve listings from Sweden's largest second-hand marketplaces, Blocket and Tradera. Returns unified data including prices, images, seller information, and direct links to listings.8-
- AlicenseNot gradedqualityFmaintenanceEnables AI assistants to search and view advertisements on Marktplaats.nl with extensive filtering options.16MIT
- AlicenseAqualityBmaintenanceEnables AI agents to search Dutch housing listings on Kamernet.nl, retrieve full listing details, and optionally reply to landlords; designed for personal use in finding rooms, studios, and apartments.31MIT