One server mounting every installed connector as a namespaced toolset:
wb_*, ozon_*, yandex_*, detmir_*, avito_*, taobao_*, megamarket_*,
lamoda_*, dns_*, citilink_*, aliexpress_*, cian_*, mpstats_* plus
compare_prices / compare_sources and its own marketplace_sources. Tool
names keep their prefixes, so habits and configs carry over — but the operator
wires a single marketplace entry instead of fourteen. The server exposes 40
tools: 39 mounted plus marketplace_sources. mpstats_* is the optional paid
source: without MPSTATS_MP_AUTH its tools answer auth_missing while
everything else is unaffected.
When to use
- "Where is X cheapest" — compare_prices fans out across all searchable sources
- Client setup: one config entry, not fourteen
- Health overview: the CLI's
doctorruns every selfcheck at once - A source came back empty and you can't tell installed-but-quiet from never-loaded
→
marketplace_sources
Tools
marketplace_sources()— no arguments; returns{mounted, skipped, mounted_count, skipped_count, capabilities, server_version}.capabilitiesis static routing metadata per source: access tier, CDP/login requirements, currency, text-search support, and whether the connector is mounted.skippedmaps a source name to the import error that dropped it, usually a missing dependency. Connectors are imported defensively, so a missing dep removes a marketplace instead of killing the server — but from the client an absent source looks identical to one that found nothing. Call this to tell the two apart: a name inskippedwas never queried at all.
Operator CLI
marketplace-mcp install [client]— print the exact mcpServers JSON to paste. From a source checkout it prints the real filesystem path of that checkout, so there's no/path/to/ru-marketplace-mcpplaceholder to hand-edit; installed as a wheel, it prints the console-script paths on PATH instead.clientmust be one ofclaude,claude-code,cursor— an unknown name is rejected, not answered with a Claude block.marketplace-mcp doctor [--status-file path]— per-source health plus a CDP session probe, with an optional machine-readable JSON snapshot for monitoring. Exit codes are meaningful for cron and CI:0everything healthy,1a parser drifted (the alarm — someone has to look),2nothing drifted but at least one source couldn't be judged (blocked, no CDP, wrong region). "Couldn't check anything" is a2, never a0.
Gotchas
- Recovery-aware clients should read
source_outcomes.requires_user_actionbefore scheduling retries. Keep answered sources visible, show the affected marketplace andchallenge_type, and retry that source after the browser interaction completes. A challenge is not an empty product search. See the compare-prices skill for the retry contract.handoff_expires_atconfirms that the source retained its tab; repeat the same operation in the same MCP session after browser action and before that expiry. See docs/CDP_SETUP.md for opt-in configuration and supported sources. - A source whose optional deps are missing is simply absent from the set —
marketplace_sourcessays which and why. - Set
MARKETPLACE_SOURCESon the unified server to mount only a comma-separated subset (wildberries,ozon,compare); unset or blank keeps every source. The aliaseswb,ym/yandex,detmir, andaliwork too. Unknown names fail at startup instead of silently producing a partial server, and deselected sources are reported with adeselectedreason. - compare_prices ranks on everyday ruble prices; Taobao (CNY) is reported in
price_nativebut never ranked against rubles.
DSH activation
In DeepSeek Harness, the default profile exposes only compare_prices and
compare_sources through the cheap compare mount. Per-marketplace tools and
marketplace_sources require RU_MARKETPLACE_MCP_FULL=1 and a profile restart;
do not call them in the default mode.