# Whirrwork (remote · whirrwork.com)

Robot jobs, sourced prices with history, providers by country, robot-vs-human costs, and RFQs.

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

## Components

- remote · `whirrwork.com`: 75/100 (this document), [markdown](https://verifymcp.io/servers/com-whirrwork-whirrwork/whirrwork.md), [page](https://verifymcp.io/servers/com-whirrwork-whirrwork/whirrwork)

## Channel facts

- Endpoint: `https://whirrwork.com/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.3.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, 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.

- **Endpoint Security**: 80/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - No authorisation is required to call this server. Every tool declares its destructiveHint and none is destructive, so open access doesn't expose one.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 56/100
  - 57% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 5621 tokens (~208/item across 27 items; 23 tools + 4 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 37/100
  - Stability observed for 11 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 91/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 68% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 23 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 25 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

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

Whirrwork is a hosted endpoint at https://whirrwork.com/mcp, so there is nothing to install locally. 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 --transport http com-whirrwork-whirrwork 'https://whirrwork.com/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "com-whirrwork-whirrwork": {
      "url": "https://whirrwork.com/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "com-whirrwork-whirrwork": {
      "type": "http",
      "url": "https://whirrwork.com/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.com-whirrwork-whirrwork]
url = "https://whirrwork.com/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "com-whirrwork-whirrwork": {
      "type": "remote",
      "url": "https://whirrwork.com/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add com-whirrwork-whirrwork --url 'https://whirrwork.com/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  com-whirrwork-whirrwork:
    url: "https://whirrwork.com/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "com-whirrwork-whirrwork": {
      "Transport": "http",
      "Url": "https://whirrwork.com/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add com-whirrwork-whirrwork -t streamable-http -u 'https://whirrwork.com/mcp'
```

### Other

```json
{
  "mcpServers": {
    "com-whirrwork-whirrwork": {
      "type": "http",
      "url": "https://whirrwork.com/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## 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 75, +1)

- [security] The server rewrote its instructions, which are the text every model session reads
- [functional regression] Schema quality: 189 → 208

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

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

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

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

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

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

### 2026-10-27 (score 71, +1)

- [security] The server rewrote its instructions, which are the text every model session reads
- [functional regression] Schema quality: 157 → 189
- [functional improvement] Tool coverage: 60% → 68%
- [functional] Server version: 1.4.0 → 1.8.0
- [functional] New tool “buy_rent_or_hire”
- [functional] New tool “compare_robot_models”
- [functional] New tool “estimate_drone_show_cost”
- [functional] New tool “estimate_drone_spraying_cost”
- [functional] New tool “find_robots_for_job”
- [functional] New tool “get_robot_model”
- [functional] New tool “robot_or_ladder”

### 2026-10-26 (score 70, +1)

- [functional improvement] Stability: unverified → 0.03
- [functional] Server version: 1.3.0 → 1.4.0

### 2026-10-25 (score 69)

First indexed and scored.

## MCP tools (23)

### `search_use_cases` (~180 tokens)

Search robot jobs

Find the robot job (use case) that matches what the buyer wants, in plain words and in any of 12 languages. Returns matching use cases (id, name, price summary, provider count) plus matching providers and guides. Start here, then call get_use_case with the best id.
Examples: "drone light show for a wedding", "robotic floor scrubbing for a warehouse", "limpieza de ventanas con drones", "无人机灯光秀".

Input parameters:

- `country` (string): Buyer country: ISO 3166-1 alpha-2 ("AE") or English name ("United Arab Emirates").
- `language` (string): Language for use-case text (machine-translated; English is authoritative). Default en.
- `limit` (integer)
- `query` (string, required): What the buyer needs done, in their words

Output parameters:

- `country` (string|null)
- `detected_language` (string|null)
- `guides` (array)
- `language` (string)
- `match_quality` (string)
- `next` (string)
- `providers` (array)
- `query` (string)
- `use_cases` (array)

### `get_use_case` (~189 tokens)

Get a robot job

Everything about one job: what it is, robot types, ways to buy (service/rental/RaaS/purchase), honest buyer tips (including when a robot is overkill), regulatory notes, every sourced price benchmark (with source_url, as_of and a USD conversion), price-history counts, the RFQ checklist, and providers. Pass country (and optionally region) to rank providers by who serves that place, with the reason.

Input parameters:

- `country` (string): Buyer country: ISO 3166-1 alpha-2 ("AE") or English name ("United Arab Emirates").
- `id` (string, required): Use case id from search_use_cases
- `language` (string): Language for use-case text (machine-translated; English is authoritative). Default en.
- `region` (string): Optional sub-country region (e.g. "US-CA", "California", "Mendoza")

Output parameters:

- `buyer_phrases` (array)
- `buyer_tips` (array)
- `category` (string|null)
- `category_id` (string)
- `country` (string|null)
- `description` (string)
- `engagement_models` (array)
- `geo_url` (string|null)
- `id` (string)
- `language` (string)
- `machine_translated` (boolean)
- `name` (string)
- `name_en` (string)
- `price_benchmarks` (array)
- `price_history` (object|null)
- `price_summary` (object|null)
- `providers` (array)
- `region` (string|null)
- `regulatory_notes` (string|null)
- `rfq_template_url` (string)
- `rfq_url` (string)
- `robot_types` (array)
- `url` (string)
- `what_to_specify_in_rfq` (array)

### `list_categories` (~49 tokens)

List categories

The 20 job categories with use-case counts, for browsing when the buyer is vague.

Input parameters:

- `language` (string): Language for use-case text (machine-translated; English is authoritative). Default en.

Output parameters:

- `categories` (array)

### `find_providers` (~410 tokens)

Find providers

Shortlist providers for a job and place. Ranked: lists the region > lists the country > lists part of the country > headquartered there (HQ is not a service area) > works worldwide. Each result has coverage + coverage_reason, engagement models, published pricing with USD conversion, min_published_price_usd and public contact routes. Coverage is country-level unless the provider published regions. Filters combine (AND).
Example: {"use_case":"drone-light-show","country":"AE"}; {"use_case":"commercial-floor-scrubbing","country":"CA","region":"ON","engagement_model":"raas"}.

Input parameters:

- `country` (string): Buyer country: ISO 3166-1 alpha-2 ("AE") or English name ("United Arab Emirates").
- `engagement_model` (string)
- `has_contact` (boolean): Only providers with a public email, phone or quote form
- `has_pricing` (boolean): Only providers that publish prices
- `hq_country` (string): Only providers headquartered in this country
- `include_global` (boolean): Include providers that only say "worldwide" when a country is given
- `limit` (integer)
- `max_price_usd` (number): Only providers whose lowest published price (converted to USD) is at or below this. Excludes providers without published prices.
- `near` (string): "me" = the country Cloudflare sees for this request (never stored), or a country name/code. Coordinates are not supported.
- `offset` (integer)
- `query` (string): Keyword filter on name/description
- `region` (string): Sub-country region code or name, e.g. "US-CA", "ON", "Mendoza"
- `robot_type` (string): Substring match on robot types, e.g. "drone", "AMR", "humanoid"
- `sort` (string)
- `use_case` (string): Use case id (recommended)

Output parameters:

- `count` (integer)
- `country` (string|null)
- `near_source` (string)
- `next_offset` (integer|null)
- `note` (string)
- `providers` (array)
- `ranking` (string)
- `region` (string|null)
- `use_case` (string|null)

### `get_provider` (~89 tokens)

Get a provider

Full public profile of one provider: website, HQ, service regions and explicit service areas (with sources), jobs, robot types, engagement models, published prices (with USD), contact routes, sources and last-checked date.

Input parameters:

- `country` (string): Buyer country: ISO 3166-1 alpha-2 ("AE") or English name ("United Arab Emirates").
- `id` (string, required)

Output parameters:

- `contact` (object|null)
- `contact_routes` (object)
- `coverage` (string|null): How this provider relates to the requested place (serves region / country / part / HQ only / worldwide)
- `coverage_reason` (string|null)
- `description` (string)
- `engagement_models` (array)
- `has_published_pricing` (boolean)
- `hq_country` (string|null)
- `id` (string)
- `last_checked` (string|null)
- `min_published_price_usd` (number|null)
- `name` (string)
- `pricing` (array)
- `published_price_count` (integer)
- `robot_types` (array)
- `service_areas` (array)
- `service_regions` (array)
- `source_urls` (array)
- `url` (string): Whirrwork profile page
- `use_case_ids` (array)
- `website` (string|null)

### `compare_providers` (~96 tokens)

Compare providers

Side-by-side comparison of 2-10 providers: coverage for a country, engagement models, published prices (USD-normalized), HQ, contact routes, shared jobs, last checked. Facts only, no ratings.

Input parameters:

- `country` (string): Buyer country: ISO 3166-1 alpha-2 ("AE") or English name ("United Arab Emirates").
- `ids` (array, required)
- `use_case` (string)

Output parameters:

- `country` (string|null)
- `matrix` (object): attribute -> provider id -> value
- `note` (string)
- `providers` (array)
- `shared_use_cases` (array)
- `use_case` (string|null)

### `get_prices` (~134 tokens)

Get current prices

Current sourced prices for a job (benchmarks + provider-published), or for one provider. Every row has source_url and as_of. Set convert (e.g. "USD") to add a clearly labelled conversion with the FX rate, date and source. Benchmarks, not quotes.

Input parameters:

- `convert` (string): Convert to this ISO 4217 currency (dated ECB reference rate)
- `currency` (string): Only rows quoted in this ISO 4217 currency
- `include_providers` (boolean)
- `limit` (integer)
- `provider` (string)
- `use_case` (string)

Output parameters:

- `count` (integer)
- `fx_date` (string|null)
- `license` (string)
- `note` (string)
- `prices` (array)
- `summary` (object|null)

### `get_price_history` (~133 tokens)

Get price history

Every price observation we have recorded (append-only; never overwritten) for a job and/or provider, grouped into series with trend (change_pct between first and latest observation). observed_at = when we recorded it; as_of = the date the source states. If every series has one observation, say so: there is no trend yet.

Input parameters:

- `limit` (integer)
- `provider` (string)
- `series` (string): A series_key to follow one price over time
- `since` (string): YYYY-MM-DD; only observations recorded on/after this date
- `use_case` (string)

Output parameters:

- `license` (string)
- `note` (string)
- `observations` (array)
- `pagination` (object)
- `series` (array)
- `source` (string)
- `source_rechecks` (object|null)
- `total` (integer)
- `tracking_since` (string|null)

### `estimate_cost` (~255 tokens)

Estimate a job cost from sourced benchmarks

Arithmetic on published prices: unit price × quantity, using exact unit conversions (acre↔hectare, sq ft↔m², mile↔km), preferring benchmarks whose region matches the country, converting currency at a dated ECB rate. Returns the range plus the basis rows (each with source_url, as_of, region match) and caveats. Returns estimate=null with a reason when no sourced benchmark fits; never invents a number. Example: {"use_case":"crop-spraying-drone","quantity":500,"unit":"hectare","country":"BR","currency":"USD"}.

Input parameters:

- `country` (string): Buyer country: ISO 3166-1 alpha-2 ("AE") or English name ("United Arab Emirates").
- `currency` (string): Express the result in this ISO 4217 currency
- `quantity` (number): How many units (hectares, shows, months, inspections…). Omit for a per-unit price.
- `unit` (string): Unit of quantity, e.g. "hectare", "acre", "show", "month", "sq ft". Omit to use the most common benchmark unit.
- `use_case` (string, required)

Output parameters:

- `available_units` (array)
- `basis` (array)
- `country` (string|null)
- `currency` (string|null)
- `estimate` (object|null): null = no sourced benchmark fits; never guessed
- `fx_date` (string|null)
- `fx_source` (string)
- `method` (string)
- `notes` (array)
- `quantity` (number|null)
- `reason` (string)
- `unit` (string|null)
- `use_case` (string)
- `use_case_id` (string)

### `compare_robot_vs_human` (~476 tokens)

Robot or human? Compare the cost

Cost comparison of human labour (or a human service) against robot options (buy, lease, robots-as-a-service, robot service provider) for one of 22 jobs in one of 8 countries (US, DE, GB, JP, CN, IN, BR, MX). Uses the same model as whirrwork.com/tools/robot-vs-human/: every default input has a source or is flagged as an assumption (see input_sources). Returns monthly/annual cost, cost per unit, payback months, break-even utilisation, 5-year NPV vs the baseline, a verdict, non-cost factors, sensitivity ranking, and projections to 2035 with a crossover year range (robots-fast, base, robots-slow). Projections are modelled estimates, not facts: say so, and quote the range rather than one year.
Examples: {"job":"warehouse-picking","country":"US"}; {"job":"commercial-floor-cleaning","country":"DE","inputs":{"volume":60000}}; {"job":"machine-tending","country":"US","region":"US-TX","include_projections":false}.

Input parameters:

- `baseline` (string): Which human option to compare against (e.g. "human" or "service"). Defaults to the job default.
- `country` (string): Country for wage, on-cost and currency defaults (sourced: BLS, ILOSTAT, MHLW, NBS, Eurostat).
- `include_projections` (boolean): Include 2026-2035 projections for three scenarios and the crossover year range.
- `include_tornado` (boolean): Include the sensitivity (tornado) ranking of inputs by NPV swing.
- `inputs` (object): Optional overrides of default inputs, in the country currency. Fractions as 0-1 (uptime 0.85, rate 0.08).
- `job` (string, required): Job slug. One of the 22 jobs in GET /api/v1/robot-vs-human/jobs.
- `region` (string): Optional regional wage preset: US states US-CA, US-TX, US-NY, US-FL, US-IL, US-WA, US-PA, US-OH; China CN-E, CN-C, CN-W, CN-NE.

Output parameters:

- `baseline` (string|null)
- `best_robot` (string|null)
- `calculator_url` (string)
- `country` (string)
- `crossover` (object)
- `currency` (string)
- `input_sources` (object): Per input: status (sourced | derived | converted | assumption | user), source_id, source_url, note
- `inputs` (object): Resolved inputs actually used (defaults + overrides), in the country currency; fractions 0-1
- `job` (object)
- `label` (string): Always "Whirrwork modelled estimates, not facts"
- `license` (string)
- `methodology_url` (string)
- `model_version` (string)
- `noncost` (object)
- `options` (array)
- `projections` (object): Per scenario (slow, base, fast): yearly cost per unit 2026-2035, constant 2026 money
- `region` (string|null)
- `sensitivity` (object)
- `verdict` (object)
- `wage_basis` (string|null)

### `robot_or_ladder` (~342 tokens)

Robot or ladder? (the Ladder Test)

Does this job need a robot at all? Rule-based verdict from the Ladder Test (the same rules as whirrwork.com/tools/robot-or-ladder/): answer up to 6 questions yes / no / unsure and get ladder, robot, both or tossup, the reasons on each side with their points, what to find out first, and (with job) the sourced price and provider counts for that job. No numbers except our own counts; nothing is stored. Questions: ladder = could a competent person with a ladder do it in an afternoon?; risk = is it dangerous for a person (height, confined space, live wires)?; scale = is it big (many hectares, a whole facade, a warehouse)?; repeat = will it repeat often (weekly, daily)?; data = do you need measurements or records (maps, thermal, logs)?; hands = does it need hands-on fixing (repair, not just looking)?
Examples: {"ladder":"yes","risk":"no","scale":"no","repeat":"no"}; {"ladder":"no","risk":"yes","scale":"yes","data":"yes","job":"roof-inspection-drone"}.

Input parameters:

- `data` (string)
- `hands` (string)
- `job` (string): Optional job (use case) id from search_use_cases, to add its sourced price and provider counts
- `ladder` (string)
- `language` (string): Language for use-case text (machine-translated; English is authoritative). Default en.
- `repeat` (string)
- `risk` (string)
- `scale` (string)

Output parameters:

- `answered` (integer)
- `answers` (object)
- `buy_hint` (string|null)
- `explanation` (string|null)
- `find_out` (array)
- `guide` (string)
- `headline` (string)
- `job` (object|null)
- `label` (string): Rule-based verdict, not a measurement or a cost estimate
- `language` (string)
- `method` (string)
- `of` (integer)
- `person_points` (integer)
- `questions` (array)
- `reasons` (array)
- `robot_points` (integer)
- `rules` (object|array|string)
- `tool` (string)
- `url` (string)
- `verdict` (string)
- `version` (string)

### `estimate_drone_spraying_cost` (~395 tokens)

Drone spraying cost for a field

Cost of drone crop spraying for the buyer's field: every published per-acre, per-hectare, per-mu (China) and per-10-are (Japan) drone spraying rate in the dataset x area x passes, with the best-matching rate for the country (national, recent first), the same-country span, flags taken from the source (chemicals extra, minimum area, starting price, older than 12 months) and every rate's source_url and as_of. Same maths as whirrwork.com/tools/drone-spraying-cost/. Only unit conversion (1 ha = 2.4710538 acres = 15 mu = 10 x 10 a); currencies are NEVER converted. Not a quote and not a Whirrwork estimate: say so. If country_has_rates is false, say there is no published rate for that country rather than borrowing one.
Examples: {"area":100,"unit":"acre","country":"US"}; {"area":40,"unit":"ha","passes":3,"country":"BR"}; {"area":250,"unit":"ha","country":"CN"}.

Input parameters:

- `area` (number): Field area in the chosen unit
- `country` (string): Buyer country, ISO 3166-1 alpha-2
- `currency` (string): Currency of own_rate (ISO 4217)
- `language` (string): Language for use-case text (machine-translated; English is authoritative). Default en.
- `own_rate` (number): A rate the buyer was quoted, per chosen unit, to compare
- `passes` (integer): Number of spray passes (default 1)
- `rate_index` (integer): Use this published rate (index from rates[].index) as the headline instead of the automatic pick
- `unit` (string): Area unit (default: the unit of the best-matching rate)

Output parameters:

- `area` (number|null)
- `countries_with_rates` (array)
- `country_has_rates` (boolean)
- `formula` (string)
- `hectare_in_acres` (number)
- `hourly_rates_not_converted` (array)
- `input` (object)
- `job` (object)
- `label` (string)
- `language` (string)
- `method` (string)
- `passes` (integer)
- `rates` (array)
- `same_country_span` (object|null)
- `selected` (object|null): Best-matching published rate for the country (null when none applies)
- `tool` (string)
- `unit` (string)
- `url` (string)
- `version` (string)
- `your_rate` (object|null)

### `estimate_drone_show_cost` (~314 tokens)

Drone light show cost

Cost of a drone light show of N drones: every published per-drone price x drones (best match for the country first, peak-date prices only when peak=true), plus the published whole shows closest in drone count (NEVER scaled to your size; implied per drone = show price / stated drones), the same-country span, a check of a quote the buyer received (per drone vs the published range in that currency) and too_few_receipts when fewer than 3 prices apply to the country. Every price has source_url and as_of. Same maths as whirrwork.com/tools/drone-show-cost/. Currencies are NEVER converted. Not a quote and not a Whirrwork estimate: say so.
Examples: {"drones":200,"country":"US"}; {"drones":100,"country":"GB","quote":9000,"currency":"GBP"}; {"drones":500,"country":"CN"}.

Input parameters:

- `country` (string): Buyer country, ISO 3166-1 alpha-2
- `currency` (string): Currency of quote (ISO 4217)
- `drones` (integer): Number of drones in the show
- `language` (string): Language for use-case text (machine-translated; English is authoritative). Default en.
- `peak` (boolean): Peak date (e.g. July 4th, New Year's Eve): include peak-date prices
- `quote` (number): Total price the buyer was quoted, to check against published prices

Output parameters:

- `countries_with_prices` (array)
- `country` (string|null)
- `drones` (integer|null)
- `formula` (string)
- `input` (object)
- `job` (object)
- `label` (string)
- `language` (string)
- `method` (string)
- `nearest_published_shows` (array)
- `peak` (boolean)
- `prices` (array)
- `receipts_for_your_country` (integer|null)
- `same_country_span` (object|null)
- `selected` (object|null): Best-matching per-drone price applied to your drone count (null when none applies)
- `too_few_receipts` (boolean|null)
- `tool` (string)
- `url` (string)
- `version` (string)
- `your_quote` (object|null)

### `buy_rent_or_hire` (~545 tokens)

Buy, rent or hire a robot service?

Total cost of buying a robot vs renting it (lease / robots-as-a-service) vs hiring a service over a period, with break-even months and the cheapest option ("within_10_percent" = too close to call). Defaults come only from sourced price rows hand-tagged buy / rent / service for the job (each with source_url and as_of; pick another with buy_receipt / rent_receipt / service_receipt, or "none"); any number the buyer gives overrides the receipt. Running costs (upkeep, staff hours x wage, setup fee, resale) are the buyer's own and have no default. Same maths as whirrwork.com/tools/buy-rent-or-hire/. Without job, returns jobs_with_receipts. Not a quote, not a forecast.
Examples: {"job":"commercial-floor-scrubbing","months":36}; {"job":"crop-spraying-drone","months":24,"qty":300}; {"job":"commercial-floor-scrubbing","months":60,"upkeep":150,"hours":20,"wage":18}.

Input parameters:

- `buy` (number): Purchase price (overrides the receipt)
- `buy_receipt` (integer|string): Receipt index from receipts_available, or "none" to leave this option out
- `currency` (string): Currency of your own numbers (ISO 4217)
- `end` (string): Which end of each published range to use (default low)
- `hours` (number): Staff hours per month to run it (buy and rent)
- `job` (string): Job (use case) id; omit to list jobs that have tagged receipts
- `language` (string): Language for use-case text (machine-translated; English is authoritative). Default en.
- `months` (integer): Period in months (default 36)
- `qty` (number): Service amount per month in the service receipt's unit (hectares, sq ft, visits...)
- `rent` (number): Rent / RaaS per month (overrides the receipt)
- `rent_receipt` (integer|string): Receipt index from receipts_available, or "none" to leave this option out
- `resale` (number): Resale value at the end when bought
- `service` (number): Service price per unit (overrides the receipt)
- `service_receipt` (integer|string): Receipt index from receipts_available, or "none" to leave this option out
- `setup` (number): One-off setup fee when renting
- `upkeep` (number): Upkeep per month when bought
- `wage` (number): Wage per staff hour

Output parameters:

- `break_even_months` (object|null)
- `cheapest` (string|null)
- `currency` (string|null)
- `formula` (string)
- `input` (object)
- `issues` (array)
- `job` (object|null)
- `jobs_with_receipts` (array)
- `label` (string)
- `language` (string)
- `method` (string)
- `months` (integer)
- `options` (object): buy / rent / service: totals, per month, source (receipt | yours) and the receipt used
- `ranked` (array)
- `receipts_available` (object|null)
- `receipts_reviewed` (string|object|null)
- `tool` (string)
- `url` (string)
- `version` (string)
- `warnings` (array)
- `within_10_percent` (boolean|null)

### `find_robots_for_job` (~114 tokens)

Find robot types and models for a job

Which kinds of robot do a job (primary type first, then alternatives), with the commercial models we have catalogued for each type: maker-published key specs, list price where published, and the Whirrwork assessment (a score only when independent trials or tests exist; otherwise "Not enough evidence to rate"). Use search_use_cases first to get the job id.
Example: {"job":"crop-spraying-drone"}

Input parameters:

- `job` (string, required): Job (use case) id from search_use_cases

Output parameters:

- `job` (object)
- `methodology_url` (string)
- `model_count` (integer)
- `note` (string)
- `types` (array)

### `get_robot_model` (~111 tokens)

Get a robot model

One commercial robot model: every maker-published spec with its source URL and the date we checked it (unknown specs are absent, never guessed), maker claims labelled as such, list price if published, independent evidence (trials, tests, certifications, documented deployments) with findings, the jobs its type does, and the Whirrwork assessment with its components. Quote specs with their source.

Input parameters:

- `id` (string, required): Model id from find_robots_for_job or /api/v1/robot-models

Output parameters:

- `assessment` (object)
- `evidence` (array)
- `id` (string)
- `jobs` (array)
- `list_price` (object|null): Maker-published list price with source (not a quote)
- `maker` (string)
- `maker_claims` (array)
- `name` (string)
- `note` (string|null)
- `official_url` (string)
- `provider_id` (string|null)
- `spec_url` (string|null)
- `specs` (array)
- `specs_note` (string)
- `status` (string)
- `summary` (string)
- `type_ids` (array)
- `types` (array)
- `url` (string)

### `compare_robot_models` (~87 tokens)

Compare robot models

Side-by-side specs of 2-4 models of the same robot type: one row per spec with each model's maker-published value and source (null = not published), plus each model's assessment. Models of different types are refused with an explanation.
Example: {"ids":["tennant-x4-rovr","avidbots-neo-2"]}

Input parameters:

- `ids` (array, required)

Output parameters:

- `models` (array)
- `note` (string)
- `rows` (array)
- `type` (object)
- `url` (string)

### `list_countries` (~70 tokens)

Coverage by country

For each country: providers that list it as a service area, providers serving parts of it (with sub-regions), and providers headquartered there; plus the number of worldwide providers. Use to tell the buyer honestly how well their country is covered.

Input parameters:

- `country` (string): Optional: just this country

Output parameters:

- `code` (string)
- `countries` (array)
- `global_providers` (integer)
- `name` (string)
- `providers_hq` (integer)
- `providers_serving` (integer)
- `providers_serving_part` (integer)
- `sub_regions` (array)
- `url` (string)

### `get_rfq_template` (~98 tokens)

Get the RFQ template for a job

The exact fields to collect from the buyer before submit_rfq: core fields (required flags, formats) plus the job-specific checklist suppliers need to price it (as extra.{key}), regulatory notes, and a filled example. Ask the buyer for these, then call submit_rfq.

Input parameters:

- `language` (string): Language for use-case text (machine-translated; English is authoritative). Default en.
- `use_case` (string, required)

Output parameters:

- `buyer_tips` (array)
- `engagement_models` (array)
- `example` (object)
- `fields` (array)
- `notes` (array)
- `regulatory_notes` (string|null)
- `submit` (object)
- `supplier_checklist` (array)
- `supplier_checklist_localized` (array)
- `use_case` (string)
- `use_case_id` (string)

### `submit_rfq` (~343 tokens)

Submit a request for quotes

Submit a request for quotes for a real buyer who explicitly agreed to be contacted by matched suppliers (consent=true). Stored, auto-matched to providers by job + country, and reviewed by a human before anything is forwarded; nothing is emailed automatically. Returns id, status, matched provider ids, and a private status_url/access key for get_rfq_status. Use test=true for testing.

Input parameters:

- `agent_name` (string): Your agent/product name
- `budget_currency` (string): ISO 4217
- `budget_max` (number)
- `budget_min` (number)
- `consent` (boolean, required): Must be true: the buyer agreed to share the request (incl. email) with matched suppliers
- `contact_company` (string)
- `contact_email` (string, required)
- `contact_name` (string)
- `contact_phone` (string): Optional phone/WhatsApp/WeChat, international format
- `country` (string, required): Buyer country: ISO 3166-1 alpha-2 ("AE") or English name ("United Arab Emirates").
- `date_end` (string)
- `date_flexible` (boolean)
- `date_start` (string)
- `details` (string)
- `extra` (object): Answers to the job checklist, keyed as in get_rfq_template
- `job` (string, required): One sentence: what, where, how big
- `location` (string): City / site
- `provider_hint` (string): Optional provider id the buyer prefers
- `test` (boolean): Mark as a test (excluded from stats, deleted)
- `use_case_id` (string)

Output parameters:

- `access_key` (string)
- `id` (string)
- `is_test` (boolean)
- `matched_provider_ids` (array)
- `message` (string)
- `status` (string)
- `status_url` (string)

### `get_rfq_status` (~70 tokens)

Check an RFQ

Status of a submitted RFQ (received → matched → sent_to_suppliers → quoted → closed) with its status history. Needs the id and the access key returned by submit_rfq (the key= part of status_url).

Input parameters:

- `id` (string, required)
- `key` (string, required)

Output parameters:

- `country` (string|null)
- `created_at` (string)
- `id` (string)
- `matched_provider_count` (integer)
- `status` (string)
- `status_history` (array)
- `updated_at` (string|null)
- `use_case_id` (string|null)

### `search_stats` (~242 tokens)

Search citable robot statistics

Search Whirrwork Research: 100+ citable statistics on robot adoption, industrial and service robots, humanoids, drones, agriculture, cleaning, warehouses, labour shortages, wages, prices and funding, plus figures from Whirrwork's own dataset. Each result has the exact figure with unit and scope, the primary source (publisher, title, date, URL, Wayback archive), access and last-verified dates, a confidence level (high/medium/low), source_type (primary/secondary/whirrwork) and a permanent URL. Quote figures with their source and date; prefer high-confidence primary sources. Call get_stat for the verbatim quote, caveats and ready-made APA/Chicago/MLA/BibTeX citations.
Examples: "humanoid robots sold 2025", "robot density Korea", "drone spraying price per acre", "robotics funding", topic="labour".

Input parameters:

- `confidence` (string)
- `limit` (integer)
- `query` (string): Keywords (English). Omit to list by topic.
- `source_type` (string)
- `topic` (string): Optional topic filter

Output parameters:

- `attribution` (string)
- `count` (integer)
- `license` (string)
- `note` (string)
- `query` (string|null)
- `release` (string)
- `standards_url` (string)
- `stats` (array)
- `topic` (string|null)
- `topics` (array)
- `total` (integer)

### `get_stat` (~116 tokens)

Get one statistic with citations

One Whirrwork Research statistic by slug: claim, figure, scope, measure type, primary source with archive link, publication/access/last-verified dates, verbatim source passage (when licensing allows), confidence, caveats, and citations in APA, Chicago, MLA and BibTeX (plus an APA citation of the original source). Licensed CC BY 4.0: attribute "Whirrwork (https://whirrwork.com), CC BY 4.0" and the original source.

Input parameters:

- `slug` (string, required)

Output parameters:

- `accessed` (string)
- `attribution` (string)
- `caveats` (array)
- `citations` (object)
- `claim` (string): One-sentence claim (English)
- `confidence` (string)
- `figure` (object)
- `last_verified` (string)
- `license` (string)
- `link_check` (object|null)
- `measure` (string): How the figure was produced: official statistic, company claim, list price, survey, estimate, forecast...
- `quote` (object|null)
- `quote_note` (string|null)
- `release` (string|null)
- `report_url` (string|null)
- `scope` (object)
- `slug` (string)
- `source` (object)
- `source_type` (string)
- `stale` (boolean): true = not re-verified for more than 180 days
- `topic` (string)
- `url` (string): Permanent Whirrwork page for this statistic
- `verification` (string|null)

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/com-whirrwork-whirrwork/whirrwork#diagnostics

## Score history

- 2026-11-05: 75
- 2026-11-04: 74
- 2026-11-03: 74
- 2026-11-02: 73
- 2026-11-01: 73
- 2026-10-31: 72
- 2026-10-30: 72
- 2026-10-29: 71
- 2026-10-28: 71
- 2026-10-27: 71
- 2026-10-26: 70
- 2026-10-25: 69

## Common questions

### What is the Whirrwork MCP server?

Whirrwork is an MCP server listed in the public MCP registry as com.whirrwork/whirrwork. Robot jobs, sourced prices with history, providers by country, robot-vs-human costs, and RFQs. This page covers its hosted endpoint (https://whirrwork.com/mcp).

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

Whirrwork scores 75 out of 100 on VerifyMCP. 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 Whirrwork MCP server expose?

Whirrwork exposes 23 tools: search_use_cases, get_use_case, list_categories, find_providers, get_provider, and 18 more. Their descriptions and schemas cost roughly 4,858 tokens of context every time the server is loaded.

### Does the Whirrwork MCP server require authentication?

No. We connected to Whirrwork without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

### Is the Whirrwork MCP server still maintained?

Whirrwork 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.

## Links

- Remote endpoint: https://whirrwork.com/mcp
- Website: https://whirrwork.com/agents/
- Changelog RSS feed: https://verifymcp.io/servers/com-whirrwork-whirrwork/whirrwork.xml
- Changelog JSON feed: https://verifymcp.io/servers/com-whirrwork-whirrwork/whirrwork.json
- HTML version of this page: https://verifymcp.io/servers/com-whirrwork-whirrwork/whirrwork
