DEV Community

KazKN
KazKN

Posted on • Edited on

I Built an MCP Server for Vinted. Here's How Cross-Border Price Gaps Make You Money

I was browsing Vinted France and saw Nike Air Force 1s for €45. Out of curiosity, I checked the same shoe on Vinted Germany. €89. Almost double.

That's when I realized: Vinted isn't one marketplace. It's 23 separate ones, each with its own pricing universe. And nobody is comparing them.

So I built a tool that does.

The Problem: 23 Countries, Zero Cross-Border Search

Vinted operates in 23 countries. France, Germany, Italy, Spain, Netherlands, Poland, Czech Republic, Lithuania... the list goes on. Each country has its own domain, its own user base, and its own supply and demand dynamics.

Here's the thing: there's no way to search across countries. If you're on vinted.fr, you only see French listings. If you're on vinted.de, only German ones. Vinted keeps these markets completely siloed.

This creates massive price gaps. And I don't mean 5-10% differences. I mean this:

Item Cheapest Country Price Most Expensive Price Spread
PS5 Console Poland €285 Netherlands €415 46%
iPhone 16 Pro Lithuania €480 France €1,260 162%
Louis Vuitton Neverfull Italy €620 Sweden €1,000 61%
Dyson V15 Czech Republic €195 Belgium €380 95%
Canada Goose Expedition Poland €310 Denmark €575 85%

162% spread on an iPhone. Let that sink in.

The reasons are straightforward. Different average incomes, different brand popularity, different levels of competition among sellers. A PS5 in Poland where the average salary is lower gets listed cheaper. The same PS5 in the Netherlands, where people have more disposable income, gets listed higher. Basic economics, but almost nobody is exploiting it because the data is locked behind country silos.

Enter MCP: An App Store for AI Tools

If you haven't heard of MCP yet, here's the quick version. Model Context Protocol is an open standard (created by Anthropic) that lets AI assistants like Claude connect to external tools and data sources. Think of it as a USB-C port for AI. One standard interface, infinite tools you can plug in.

Instead of copy-pasting data into ChatGPT, your AI assistant can directly call APIs, query databases, or scrape websites through MCP servers. Each server exposes "tools" that the AI can invoke when it needs specific data.

The analogy I like: MCP is the App Store for AI tools. Each MCP server is an app. My Vinted server is one of those apps.

Architecture: How It Works Under the Hood

The server is built in TypeScript and exposes 5 tools:

  • search_items - Search listings on any Vinted country domain
  • compare_prices - Search the same item across multiple countries simultaneously
  • get_item - Get full details on a specific listing
  • get_seller - Check a seller's profile, ratings, and history
  • get_trending - See what's hot on any given country's Vinted

The tricky part isn't the MCP protocol itself. It's getting data from Vinted without being blocked.

Vinted has aggressive bot detection. Standard HTTP requests get blocked instantly. They check TLS fingerprints, cookie sessions, and request patterns. To handle this, the server uses got-scraping, a library that mimics real browser TLS fingerprints. Combined with residential proxy support, it can reliably fetch data across all 23 domains.

Here's the core MCP tool definition for compare_prices:

server.tool(
  "compare_prices",
  "Compare prices for an item across multiple Vinted country domains",
  {
    query: z.string().describe("Search query (e.g., 'PS5', 'iPhone 16 Pro')"),
    countries: z
      .array(z.string())
      .optional()
      .describe("Country codes to compare (e.g., ['fr', 'de', 'es']). Defaults to all."),
    limit: z
      .number()
      .optional()
      .describe("Max results per country (default: 5)"),
  },
  async ({ query, countries, limit }) => {
    const results = await compareAcrossCountries(query, countries, limit);
    return {
      content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
    };
  }
);
Enter fullscreen mode Exit fullscreen mode

When you ask Claude "Compare PS5 prices across Europe," it calls compare_prices and gets back something like this:

{
  "query": "PS5",
  "cheapest": { "country": "pl", "avgPrice": 285 },
  "mostExpensive": { "country": "nl", "avgPrice": 415 },
  "spread": "45.6%",
  "comparison": {
    "fr": { "avgPrice": 320, "minPrice": 280, "itemCount": 5 },
    "de": { "avgPrice": 355, "minPrice": 310, "itemCount": 5 },
    "pl": { "avgPrice": 285, "minPrice": 240, "itemCount": 5 },
    "nl": { "avgPrice": 415, "minPrice": 370, "itemCount": 5 },
    "es": { "avgPrice": 305, "minPrice": 265, "itemCount": 5 },
    "it": { "avgPrice": 310, "minPrice": 270, "itemCount": 5 }
  }
}
Enter fullscreen mode Exit fullscreen mode

Claude then takes that raw data and turns it into a nice summary with recommendations. "Buy in Poland, sell in the Netherlands" type insights. That's the beauty of MCP. The server handles the data fetching, the AI handles the analysis and presentation.

How to Use It

Option 1: Local Install (npm)

Install the package globally:

npm install -g vinted-mcp-server
Enter fullscreen mode Exit fullscreen mode

Then add it to your Claude Desktop config (claude_desktop_config.json):

{
  "mcpServers": {
    "vinted": {
      "command": "npx",
      "args": ["-y", "vinted-mcp-server"],
      "env": {
        "PROXY_URL": "your-residential-proxy-url"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The proxy is optional but recommended. Without it, you might get rate-limited on some country domains.

Option 2: Hosted on Apify (No Setup)

If you don't want to run anything locally, there's a hosted version on Apify. It runs as an MCP Actor, so you can connect it to Claude Desktop without installing anything:

{
  "mcpServers": {
    "vinted": {
      "type": "url",
      "url": "https://kazkn--vinted-mcp-server.apify.actor/mcp"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The Apify version handles proxies and scaling for you. It also has a standalone scraper Actor at apify.com/kazkn/vinted-smart-scraper if you just want raw data without the MCP layer.

What People Are Actually Doing With This

The obvious use case is arbitrage. Buy cheap in one country, sell expensive in another. Vinted supports cross-border shipping in most of Europe, so this is totally doable. The margins on luxury items like Louis Vuitton or Canada Goose can easily cover shipping costs and still leave a healthy profit.

But there are other uses too. Sellers use it to price their items competitively. If you're listing a Dyson in France, knowing that the average price in France is €320 but only €195 in Czech Republic tells you something about your market position.

Buyers use it to find the best deals. Why pay €89 for Nike AF1s in Germany when you can get them for €45 from France with €5 shipping?

What's Next

The current version is solid for manual comparisons. But there's a lot more I want to build:

  • Price alerts: "Tell me when a PS5 drops below €250 in any country"
  • Historical trends: Track how prices move over time, spot seasonal patterns
  • Arbitrage calculator: Factor in shipping costs, Vinted fees, and currency to show actual profit margins
  • Auto-categorization: Group similar listings even when they have different titles across languages

The GitHub repo is at github.com/KinderCN/vinted-mcp-server. Stars, issues, and PRs are all welcome.

Try It

The price gaps on Vinted are genuinely surprising. I expected maybe 10-15% differences across countries. Finding 100%+ spreads on popular items was an eye-opener. The data is just sitting there, scattered across 23 siloed marketplaces, waiting for someone to connect the dots.

MCP makes it ridiculously easy to put that data in the hands of an AI that can actually reason about it. Instead of manually checking 23 websites, you ask Claude one question and get a complete cross-border analysis.

If you try it, I'd love to hear what price gaps you find. Drop a comment or open an issue on GitHub. Some of the wildest spreads are on items you'd never expect.

Top comments (0)