# MarketMirror (pypi · marketmirror)

Test ads, prices and sales pitches on simulated buyers; get a go / iterate / no-go report.

- Trust score: 64/100 (medium)
- Change this week: −11
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- pypi · `marketmirror`: 64/100 (this document), [markdown](https://verifymcp.io/servers/darkworldcoder-market-mirror/marketmirror.md), [page](https://verifymcp.io/servers/darkworldcoder-market-mirror/marketmirror)

## Channel facts

- Registry: `pypi`
- Package: `marketmirror`
- Version: `0.4.2`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 50/100
  - Malware scan not yet available for this package.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised build step with no custom scripting around it.
  - No production dependencies, so there is no dependency health to assess.
- **Provenance & Transparency**: 100/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to DarkWorldCoder/market-mirror).
  - Clear OSI-approved license (AGPL-3.0-only).
  - Actively maintained (last published 10 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 61/100
  - AI-judged instruction clarity (fair).
  - Tool/resource definitions use about 2746 tokens (~101/item across 27 items; 27 tools + 0 resources), lean.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 33/100
  - Stability observed for 10 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 68/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 4% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 27 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 28 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 40/100
  - Spec-recency check failed: implements MCP spec 2025-03-26; the latest is 2026-07-28.

## Install

### How do I install the MarketMirror MCP server?

MarketMirror runs locally as a PyPI package, launched with uvx marketmirror. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add darkworldcoder-market-mirror -- uvx marketmirror
```

### Cursor

```json
{
  "mcpServers": {
    "darkworldcoder-market-mirror": {
      "command": "uvx",
      "args": [
        "marketmirror"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "darkworldcoder-market-mirror": {
      "command": "uvx",
      "args": [
        "marketmirror"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add darkworldcoder-market-mirror -- uvx marketmirror
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "darkworldcoder-market-mirror": {
      "type": "local",
      "command": [
        "uvx",
        "marketmirror"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add darkworldcoder-market-mirror --command uvx --arg marketmirror
```

### Hermes

```yaml
mcp_servers:
  darkworldcoder-market-mirror:
    command: "uvx"
    args: ["marketmirror"]
```

### Netclaw

```json
{
  "McpServers": {
    "darkworldcoder-market-mirror": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "marketmirror"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add darkworldcoder-market-mirror -t stdio -c uvx -a marketmirror
```

### Other

```json
{
  "mcpServers": {
    "darkworldcoder-market-mirror": {
      "command": "uvx",
      "args": [
        "marketmirror"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-05 (score 64, −14)

- [security regression] Malware scan: pass → unverified

### 2026-11-03 (score 78, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-01 (score 77, +1)

No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-30 (score 76, +1)

No change was recorded against any check on this day. Stability & Change Management went from 10 to 13. That category is still filling its 30-day observation window: 3 days of observed history at the previous scan, 4 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-28 (score 75, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-26 (score 74)

First indexed and scored.

## MCP tools (27)

### `website_test` (~84 tokens)

Run prepared synthetic visitors on a real website URL. Actions and screenshots are observed; only supplied DOM checks verify goals. Cart changes are enabled by cart/checkout goals; signup submission requires explicit test data and opt-in. No payments/orders. Background job: poll job_status.

Input parameters:

- `out` (string)
- `simulation_id` (string, required)
- `spec` (object, required)

### `provider_setup` (~103 tokens)

List provider choices and official key guides, inspect masked local settings, configure a local model or an existing key environment variable, or discover available models. Never paste an API key into tool arguments. ChatGPT/CLI login choices return local login commands.

Input parameters:

- `action` (string, required)
- `base_url` (string)
- `key_env` (string): Environment variable NAME only; never the key itself
- `model` (string)
- `provider` (string)

### `doctor` (~27 tokens)

Check MarketMirror: engine installed, Python deps, API key configured (never shown), backend running.

### `setup` (~33 tokens)

Install or update the MarketMirror engine (git clone + uv sync). Background job; poll job_status. Needs git and uv.

### `start_backend` (~40 tokens)

Start the MarketMirror backend (port 5001). Configure an API-key, eligible ChatGPT sign-in, local CLI gateway, or local-model provider first.

### `market_test` (~157 tokens)

All-in-one market test. Config keys: name, title, seeds (absolute paths to documents), requirement (text), personas (persona spec object or absolute path) or auto_personas (int), creatives (feed-test object with creatives, landing, benchmarks), seeds_n (int, repeat the feed test with N seeds and report ranges), rounds (int), survey {offer, goal, messages (list), split, pricing}, panel {analysts, brief}, report (bool), simulation_id (reuse), approve_spend (bool). Without approve_spend it stops after creating the personas so you can show them to the user; then call again with simulation_id and approve_spend true. Background job.

Input parameters:

- `config` (object, required)

### `job_status` (~28 tokens)

Status, log tail and final result of a background job.

Input parameters:

- `job_id` (string, required)

### `results` (~51 tokens)

Key results of a run: decision, verdicts, segments, objections, messages, pricing, feed-test metrics, ROI projections, files.

Input parameters:

- `run` (string, required): run name under mirofish_runs or absolute path

### `list_runs` (~15 tokens)

List previous runs with their decision.

### `start_live` (~43 tokens)

Serve the live dashboard at http://127.0.0.1:5050/ (newest run, or a given run).

Input parameters:

- `run` (string)

### `ads_import` (~55 tokens)

Turn a Meta/Google Ads export (CSV or JSON, absolute path) into a seed Markdown file plus benchmarks JSON.

Input parameters:

- `file` (string, required)
- `out` (string, required): absolute path of the seed .md to write

### `campaign_plan` (~95 tokens)

Save an evidence-led campaign plan and runnable test specs from a profile or existing project. No campaign is sent.

Input parameters:

- `budget` (object, required)
- `channels` (array)
- `goal` (string, required)
- `out` (string)
- `profile` (object)
- `profile_file` (string)
- `project` (string)
- `research` (object)
- `research_file` (string)

### `actuals_import` (~91 tokens)

Normalize a local ads, email, website, CRM or survey CSV/JSON export, retaining provenance and row-level validation errors.

Input parameters:

- `date` (string)
- `file` (string, required)
- `mapping` (object)
- `market` (string)
- `out` (string)
- `quality` (string)
- `source` (string)
- `source_type` (string, required)

### `holdout_backtest` (~40 tokens)

Evaluate independent held-out real experiments against a training-mean no-persona baseline.

Input parameters:

- `out` (string)
- `pairs` (array, required)

### `backtest` (~53 tokens)

Score a run's feed test against real ad results (from ads_import): rank correlation, winner match, calibration.

Input parameters:

- `actuals` (string, required)
- `map` (array)
- `run` (string, required)

### `understand` (~156 tokens)

Step one for any product: read the user's documents (absolute paths to .md/.txt), a landing page URL and/or an ads export into one product profile (what it is, for whom, pricing, offer, proofs, differentiators, competitors, channels, likely objections, brand voice, KPIs, unknowns). Every later step uses it. Synchronous, one Claude call. Writes product_profile.json; pass `project` instead of docs to profile an existing project (also seeds the market map before the graph build).

Input parameters:

- `ads_file` (string)
- `docs` (array)
- `name` (string)
- `out` (string)
- `project` (string)
- `url` (string)

### `quickstart` (~175 tokens)

Easiest start. Answer a few questions and get a ready scenario folder (brief, personas, two template captions per platform, messages, launch calendar, pitch) plus the simulated people (stops before any paid rounds). Keys: brand, product (what, for whom, price), buyers (who and where), platforms (comma list), tests (ads, messages, price, launch, pitch), budget ('300 USD'), size (small|medium|large), past_ads (absolute path, optional), docs (paths, optional). Background job; poll job_status. The result names the files to edit and the exact next command.

Input parameters:

- `answers` (object, required)
- `from_docs` (array): documents to understand first; prefills the answers
- `no_run` (boolean)
- `url` (string)

### `pitch` (~134 tokens)

Sales rehearsal: pitch a script to every simulated buyer of a simulation (its environment must be alive: run market_test with rounds first, or start it), collect objections and the questions they ask back, then answer with rebuttals ({objection_type: text, '*': generic}). Scores the pitch, each rebuttal, and every person (lead score). Background job.

Input parameters:

- `channel` (string)
- `product` (string)
- `rebuttals` (object)
- `run` (string)
- `script` (string, required)
- `segment` (string)
- `simulation_id` (string, required)

### `ideas` (~149 tokens)

Next test ideas from real data: pass ad rows you fetched from a connected ads tool (Meta/Google/TikTok: name, campaign, spend, impressions, clicks, conversions, country...) and/or an export file path, plus a previous run (its objections, audiences and decision). Returns prioritised experiments, each citing its evidence, with the MarketMirror config to simulate it first. Writes ideas.json/.md into the run folder and adds a 'Test ideas' section to the dashboard.

Input parameters:

- `ads_file` (string)
- `brand` (string)
- `brief` (string)
- `n` (integer)
- `rows` (array)
- `run` (string)

### `push_context` (~115 tokens)

While a simulation is running (or before it starts), push what people are saying today into every persona card from the next round on: a news item, a competitor's move, a real thread you just read with your browser, a price change. Each update is one or two sentences; the runner re-reads the file every round. Use it to ground the rounds in live reality.

Input parameters:

- `round` (integer)
- `simulation_id` (string, required)
- `source` (string)
- `text` (string, required)

### `research` (~172 tokens)

What real people say about a product, category or competitor, from public keyless sources: Hacker News stories and comments, App Store listings and recent reviews for a country storefront (in, ph, ke, us...), Reddit public search when it answers (it often blocks non-browser clients; the result says so, then use your own browser tools and add what you find as seed files), and any page URLs. Writes research.md (themes with quotes and links), research.json and voices.json (short real quotes the personas and feeds draw on) under scenarios/<query>/research. Run it before planning personas.

Input parameters:

- `country` (string)
- `out` (string)
- `query` (string, required)
- `sources` (string)
- `subreddits` (array)
- `urls` (array)

### `predict` (~166 tokens)

Predictions with intervals for a run: CTR per ad, cost per lead, would-convert overall and per audience, email click rates, each scaled by the real-vs-simulated results stored so far (from backtest and calibrate) and labelled with its basis ('calibrated on N real results' or 'uncalibrated prior'); optional targets (e.g. {ctr: 2, cpl: 10}) give a probability of success. Also a 30/60/90-day adoption forecast from the best ad, its landing conversion and the word of mouth seen in the rounds.

Input parameters:

- `brand` (string)
- `days` (integer)
- `run` (string, required)
- `spend` (number)
- `targets` (object)

### `study` (~158 tokens)

Several scenarios x several seeds on the same simulated people, one defended conclusion. spec: {name, base (a market_test config object: creatives, survey, pitch, emails, rounds...), simulation_id (the people to reuse), scenarios: [{name, overrides}], seeds: [1,2,3], steps: [feed_test, rounds, survey, pitch, email_test]}. Writes study_summary.json (per-scenario mean, spread and 95% interval of every metric, deltas, winner stability, decision agreement matrix, conclusion with confidence), study_report.md and study.html under mirofish_runs/<name>/. Finished cells are reused on rerun. Background job.

Input parameters:

- `out` (string)
- `spec` (object, required)

### `run_test` (~176 tokens)

Test anything from one spec on a prepared simulation: type = ad | message | price | offer | positioning | naming | landing | launch | pitch | email | creator_post | channel_mix; variants = the things to compare (ad creatives, message lines, prices, offer wordings, names, landing pages, launch posts with rounds, pitch scripts, emails); audience {segments, countries}; metric (default per type); budget {amount, cpm, currency}; rounds (launch). Returns one result shape for every type: each variant's metric with a 95% margin, the winner, the lift, whether it is clear or a tie, and how to read it. Background job.

Input parameters:

- `brand` (string)
- `run` (string)
- `simulation_id` (string, required)
- `spec` (object, required)

### `email_test` (~202 tokens)

Email campaign test on the simulated people's inboxes: pass emails [{id, from_name, subject, preheader, body, cta, send_time (morning|midday|evening|night), segments?, sequence?: [{delay_days, subject, body}]}] plus optional list_size and benchmarks {cost_per_send, lead_value, close_rate, deal_value}. Each person gets a realistic inbox for the day; an attention gate decides opens, Claude decides skim/read/click/reply/unsubscribe/spam with honest odds. Returns open, click, click-to-open, unsubscribe and spam rates per variant and audience, subject-line ranking, sequence funnel, projection from list size to leads and revenue, spam-word warnings. Needs a prepared simulation (simulation_id). Background job.

Input parameters:

- `benchmarks` (object)
- `emails` (array, required)
- `list_size` (integer)
- `run` (string)
- `simulation_id` (string, required)

### `calibrate` (~125 tokens)

Check a run's simulated survey against real answers (absolute path to a CSV with segment,country,gender,age,y where y is yes/maybe/no or 0-1; 50-300 rows is enough): covariate overlap, per-audience calibration, a trust / correct / walk-away verdict and an AIPW-corrected rate. Writes calibration.json into the run folder.

Input parameters:

- `by` (string)
- `field` (string)
- `map` (array)
- `real_csv` (string, required)
- `run` (string, required)

### `cli` (~53 tokens)

Advanced: run any MarketMirror CLI command as a background job, e.g. ['survey','--simulation','sim_x','--offer','...']. See CLAUDE.md in the engine.

Input parameters:

- `args` (array, required)

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/darkworldcoder-market-mirror/marketmirror#diagnostics

## Score history

- 2026-11-05: 64
- 2026-11-04: 78
- 2026-11-03: 78
- 2026-11-02: 77
- 2026-11-01: 77
- 2026-10-31: 76
- 2026-10-30: 76
- 2026-10-29: 75
- 2026-10-28: 75
- 2026-10-27: 74
- 2026-10-26: 74

## Common questions

### What is the MarketMirror MCP server?

MarketMirror is an MCP server listed in the public MCP registry as io.github.DarkWorldCoder/market-mirror. Test ads, prices and sales pitches on simulated buyers; get a go / iterate / no-go report. This page covers its PyPI package (marketmirror).

### Is the MarketMirror MCP server safe to use?

MarketMirror scores 64 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the MarketMirror MCP server expose?

MarketMirror exposes 27 tools: website_test, provider_setup, doctor, setup, start_backend, and 22 more. Their descriptions and schemas cost roughly 2,696 tokens of context every time the server is loaded.

### Is the MarketMirror MCP server still maintained?

MarketMirror is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the MarketMirror MCP server under?

MarketMirror declares the AGPL-3.0-only licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/marketmirror/
- Socket report: https://socket.dev/pypi/package/marketmirror
- Repository: https://github.com/DarkWorldCoder/market-mirror
- Website: https://darkworldcoder.github.io/market-mirror/demo/
- Changelog RSS feed: https://verifymcp.io/servers/darkworldcoder-market-mirror/marketmirror.xml
- Changelog JSON feed: https://verifymcp.io/servers/darkworldcoder-market-mirror/marketmirror.json
- HTML version of this page: https://verifymcp.io/servers/darkworldcoder-market-mirror/marketmirror
