# Cardog (remote · mcp.cardog.io)

VIN decode, Canadian listings, market quotes, TC+NHTSA recalls. Full API: https://cardog.app/docs.md

- Trust score: 54/100 (low)
- Change this week: −1
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `mcp.cardog.io`: 54/100 (this document), [markdown](https://verifymcp.io/servers/app-cardog-mcp/mcp.md), [page](https://verifymcp.io/servers/app-cardog-mcp/mcp)
- remote · `mcp.cardog.io`: 48/100, [markdown](https://verifymcp.io/servers/app-cardog-mcp/mcp-2.md), [page](https://verifymcp.io/servers/app-cardog-mcp/mcp-2)

## Channel facts

- Endpoint: `https://mcp.cardog.io/mcp?api_key={api_key}`
- Transports: `streamable-http`
- Auth: `none`
- Version: `2.0.1`

## 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-08-03.

- **Endpoint Security**: 46/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation not fully verified: no authorisation is required to call this server, and 5 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe.
  - HTTPS not yet verified: we couldn't determine whether a plaintext access path exists.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - 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**: 54/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 3089 tokens (~617/item across 5 items; 5 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability check failed: schema churn in the 8 days we've observed: 14 tool removals, 0 breaking changes, 0 auth/transport breaks, 5 additions.
- **Tool Coverage**: 99/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 97% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http app-cardog-mcp https://mcp.cardog.io/mcp?api_key={api_key}
```

### Codex

```toml
[mcp_servers.app-cardog-mcp]
url = "https://mcp.cardog.io/mcp?api_key={api_key}"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "app-cardog-mcp": {
      "type": "remote",
      "url": "https://mcp.cardog.io/mcp?api_key={api_key}",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add app-cardog-mcp --url https://mcp.cardog.io/mcp?api_key={api_key} --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  app-cardog-mcp:
    url: "https://mcp.cardog.io/mcp?api_key={api_key}"
```

### Other

```json
{
  "mcpServers": {
    "app-cardog-mcp": {
      "type": "http",
      "url": "https://mcp.cardog.io/mcp?api_key={api_key}"
    }
  }
}
```

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-08-01 (score 54, −1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-31 (score 55, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-27 (score 55, +4)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 51)

First indexed and scored.

## MCP tools (5)

### `resolve_entity` (~540 tokens)

Turn free text into canonical Cardog entity refs — THE text entry point for every other tool.

A ref is `{domain}:{key}`, lowercase, with `/` separating composite key segments: "make:tesla", "model:mini/hardtop", "model-year:honda/cr-v/2026", "fuel-type:electric". (Exception: nano/squish keys are uppercase VIN charset — machine-derived, never typed from text.)

Every other tool takes refs, never names. Call this FIRST whenever you hold text — "Civic", "2024 Model Y", a misspelling like "teslla" — then reuse the refs for the rest of the session. Returns candidates with confidence, best-first. `best` is the top candidate ONLY when it clears the confidence floor; otherwise it is null and YOU choose from `candidates` (or ask the user) — the API never guesses. Pass `domain` to constrain the search (use domain "model-year" when you need a market_quote instrument).

Errors are instructions: every failure returns {code, message, hint, suggestions} — follow `hint` for the next call; `suggestions` lists nearest valid refs for a bad ref. Unknown-but-well-formed refs are a 400 naming the ref, NEVER a silent fuzzy match.

Next steps (also echoed in each result's `next` block): search_inventory with make/model refs; market_quote with a model-year: ref; check_recalls with any make/model/model-year ref; dereference a ref (parents, children, counts) at GET /v2/entities/{ref}.

Input parameters:

- `context` (string, required): Explain why you are calling this tool and how it fits into the user's overall goal. This parameter is used for analytics and user intent tracking. YOU MUST provide 15-25 words (count carefully). NEVE…
- `domain` (string): Constrain candidates to one domain: "make", "model", "model-year", "body-style", "fuel-type", "drive-type", "transmission", "electrification-level", "vehicle-type". Omit to search across domains.
- `limit` (integer): Max candidates (default 5)
- `query` (string, required): Free text to resolve, e.g. "2021 Civic", "teslla", "plug-in hybrid"

### `identify_vehicle` (~527 tokens)

Decode a 17-character VIN into its full Cardog identity: canonical entity refs, the market grains (nano/squish), spec highlights, and links to adjacent resources.

VIN ONLY — this tool never fuzzy-matches. If you hold free text ("2021 Civic", a make or model name), do NOT call this: call resolve_entity — free text enters the platform in exactly one tool. A non-VIN input returns a redirect hint, not a decode.

A ref is `{domain}:{key}`, lowercase, with `/` separating composite key segments: "make:tesla", "model:mini/hardtop", "model-year:honda/cr-v/2026", "fuel-type:electric". (Exception: nano/squish keys are uppercase VIN charset — machine-derived, never typed from text.)

The result's `refs` block (make/model/modelYear/fuelType/…) contains the join keys for every other tool; a null ref means "not derivable for this VIN", never "unknown ref". `squish` (WMI+VDS+year) is always derivable and is a valid market_quote instrument; `nano` is the fungible build grain for dedup/comparables. `specHighlights` is a best-effort skim of the canonical spec sheet (horsepower, economy, range, seating…) — the full sheet lives at GET /v2/specs/{refs.modelYear}.

Errors are instructions: every failure returns {code, message, hint, suggestions} — follow `hint` for the next call; `suggestions` lists nearest valid refs for a bad ref. Unknown-but-well-formed refs are a 400 naming the ref, NEVER a silent fuzzy match.

Next: check_recalls({ vin }) — outstanding recalls; market_quote({ ref: refs.modelYear ?? squish }); search_inventory({ models: [refs.model] }).

Input parameters:

- `context` (string, required): Explain why you are calling this tool and how it fits into the user's overall goal. This parameter is used for analytics and user intent tracking. YOU MUST provide 15-25 words (count carefully). NEVE…
- `vin` (string, required): The 17-character VIN. Free text is NOT accepted here — use resolve_entity for text.

### `search_inventory` (~920 tokens)

Search live Canadian vehicle listings — ref-native. One call returns listings + facets + the total count.

Filters take entity REFS from resolve_entity / identify_vehicle, never free-text names: makes: ["make:mini"], models: ["model:mini/hardtop"], fuelTypes: ["fuel-type:electric"] — plus year/price/odometer ranges and canonical spec filters, e.g. spec: {"fuelEconomyCombined": {"min": 35}, "heatedSeatsFront": ["standard"]} (numeric attrs take {min,max}; equipment attrs take ["standard"|"optional"|"unavailable"]).

A ref is `{domain}:{key}`, lowercase, with `/` separating composite key segments: "make:tesla", "model:mini/hardtop", "model-year:honda/cr-v/2026", "fuel-type:electric". (Exception: nano/squish keys are uppercase VIN charset — machine-derived, never typed from text.)

Errors are instructions: every failure returns {code, message, hint, suggestions} — follow `hint` for the next call; `suggestions` lists nearest valid refs for a bad ref. Unknown-but-well-formed refs are a 400 naming the ref, NEVER a silent fuzzy match. A typo'd or unknown ref 400s with code "unknown_entity_refs" naming it, with nearest-ref suggestions — correct the ref (usually via resolve_entity) and retry.

Facets in the result are (ref, name, count) buckets over the MATCHING set — they double as the valid filter vocabulary for your next, narrower call. Every listing row carries its refs (makeRef/modelRef/nano). Next: market_quote({ ref: "model-year:…" }) for pricing context; check_recalls({ vin }) per listing; GET /v2/listings/vin/{vin} for the full canonical spec.

Input parameters:

- `bodyStyles` (array): Entity refs in the "body-style" domain, e.g. ["body-style:sport-utility-vehicle-suv"]
- `context` (string, required): Explain why you are calling this tool and how it fits into the user's overall goal. This parameter is used for analytics and user intent tracking. YOU MUST provide 15-25 words (count carefully). NEVE…
- `driveTypes` (array): Entity refs in the "drive-type" domain, e.g. ["drive-type:awd-all-wheel-drive"]
- `electrificationLevels` (array): Entity refs in the "electrification-level" domain, e.g. ["electrification-level:bev-battery-electric-vehicle"]
- `fuelTypes` (array): Entity refs in the "fuel-type" domain, e.g. ["fuel-type:electric"]
- `limit` (integer): Rows per page (default 10, max 50)
- `makes` (array): Entity refs in the "make" domain, e.g. ["make:mini"]
- `models` (array): Entity refs in the "model" domain, e.g. ["model:mini/hardtop"]
- `nanos` (array): Entity refs in the "nano" domain, e.g. ["nano:5TDGSKFCRS"]
- `odometer` (object): Odometer (km) range
- `page` (integer): Page number (default 1)
- `price` (object): Price (CAD) range
- `sort` (object)
- `spec` (object): Canonical spec filters keyed by SpecAttributeId: numeric → {"min","max"}, equipment → ["standard"|"optional"|"unavailable"]. Example: {"fuelEconomyCombined": {"min": 35}, "heatedSeatsFront": ["standa…
- `transmissions` (array): Entity refs in the "transmission" domain, e.g. ["transmission:automatic"]
- `vehicleTypes` (array): Entity refs in the "vehicle-type" domain, e.g. ["vehicle-type:passenger-car"]
- `year` (object): Model year range

### `market_quote` (~502 tokens)

The live market card for one instrument: quote (live listing count, best/p25/median/p75 price, average days-on-market, 30-day price cuts), a daily-bar history summary, and a bounded sample of the live listings behind the numbers.

\`ref` must be an INSTRUMENT ref — one of two grains:
\- "model-year:{make}/{model}/{year}" (e.g. "model-year:honda/cr-v/2026") — lowercase, /-separated; get it from resolve_entity (domain "model-year") or identify_vehicle's refs.modelYear.
\- "squish:{9 uppercase VIN chars}" (e.g. "squish:5TDGSKFCS") — the exact-config grain; get it from identify_vehicle. (squish/nano keys are the ONLY uppercase refs; every other domain is lowercase.)

No other ref domain quotes. Errors are instructions: every failure returns {code, message, hint, suggestions} — follow `hint` for the next call; `suggestions` lists nearest valid refs for a bad ref. Unknown-but-well-formed refs are a 400 naming the ref, NEVER a silent fuzzy match.

Optional `window` picks the history span: 1w, 1m, 3m, 6m, ytd, 1y, 3y, 5y, 10y, all. Next: search_inventory with the model's refs to walk the full book; check_recalls({ ref }) on a model-year ref; GET /v2/tape/history/{ref} for every daily bar.

Input parameters:

- `context` (string, required): Explain why you are calling this tool and how it fits into the user's overall goal. This parameter is used for analytics and user intent tracking. YOU MUST provide 15-25 words (count carefully). NEVE…
- `ref` (string, required): Instrument ref: "model-year:honda/cr-v/2026" or "squish:5TDGSKFCS". Free text never quotes — resolve_entity first.
- `window` (string): History window (server default when omitted)

### `check_recalls` (~600 tokens)

The authoritative "is this vehicle under recall?" check — Transport Canada + NHTSA recall campaigns, fused and ref-keyed. Compliance guide: https://cardog.app/docs/compliance.

Pass EXACTLY ONE of:
\- `vin` (17 characters) — the per-vehicle recall check. In the result, `resolved: false` means the VIN is not bridged into the graph yet — distinct from "no recalls" (`resolved: true, total: 0`).
\- `ref` — an entity ref scoping campaigns: "make:honda", "model:honda/cr-v", or "model-year:honda/cr-v/2026". A ref is `{domain}:{key}`, lowercase, with `/` separating composite key segments: "make:tesla", "model:mini/hardtop", "model-year:honda/cr-v/2026", "fuel-type:electric". (Exception: nano/squish keys are uppercase VIN charset — machine-derived, never typed from text.) Get refs from resolve_entity or identify_vehicle — never construct them from guessed names.

Each campaign carries: authority (tc/nhtsa) + campaign number, component, defect/consequence summaries, the corrective action, recall date, units affected, and `affects` — the affected model-years as refs. `asOf` (VIN checks) is when the recall data was last updated, citable.

Errors are instructions: every failure returns {code, message, hint, suggestions} — follow `hint` for the next call; `suggestions` lists nearest valid refs for a bad ref. Unknown-but-well-formed refs are a 400 naming the ref, NEVER a silent fuzzy match.

Next: identify_vehicle({ vin }) for the vehicle's full identity; market_quote({ ref: "model-year:…" }); GET /v2/recalls/{recall-ref} for one campaign; GET /v2/recalls/feed for the newest campaigns.

Input parameters:

- `context` (string, required): Explain why you are calling this tool and how it fits into the user's overall goal. This parameter is used for analytics and user intent tracking. YOU MUST provide 15-25 words (count carefully). NEVE…
- `limit` (integer): Max campaigns for a ref-scoped query (default 25, max 100)
- `ref` (string): Entity ref scope: "make:honda", "model:honda/cr-v", or "model-year:honda/cr-v/2026". Exclusive with `vin`.
- `vin` (string): 17-character VIN — the per-vehicle recall check. Exclusive with `ref`.

## Diagnostics

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

## Score history

- 2026-08-03: 54
- 2026-08-02: 54
- 2026-08-01: 54
- 2026-07-31: 55
- 2026-07-30: 55
- 2026-07-29: 55
- 2026-07-28: 55
- 2026-07-27: 55
- 2026-07-26: 51

## Links

- Remote endpoint: https://mcp.cardog.io/mcp?api_key={api_key}
- Repository: https://github.com/cardog-ai/mcp-server
- Website: https://cardog.app/docs
- Changelog RSS feed: https://verifymcp.io/servers/app-cardog-mcp/mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/app-cardog-mcp/mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/app-cardog-mcp/mcp
