{
  "markdown": "# autoria-mcp\n\n<!-- mcp-name: io.github.yevhen-kalyna/autoria-mcp -->\n\n[![CI](https://github.com/yevhen-kalyna/autoria-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/yevhen-kalyna/autoria-mcp/actions/workflows/ci.yml)\n[![PyPI version](https://img.shields.io/pypi/v/autoria-mcp.svg)](https://pypi.org/project/autoria-mcp/)\n[![Python versions](https://img.shields.io/pypi/pyversions/autoria-mcp.svg)](https://pypi.org/project/autoria-mcp/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\nAn [MCP](https://modelcontextprotocol.io) server that exposes the\n**AUTO.RIA used-cars REST API** (`auto.ria.com`, via `developers.ria.com`) to AI\nagents — programmatic, agent-friendly access to the Ukrainian used-car market\nthrough the sanctioned API, no scraping.\n\nThe full tool surface is live — **30 tools, 7 dictionary resources, and 1\ntemplated resource**: curated search/lookup tools (single and batch listing\ndetails), paid statistics tools, thin endpoint mirrors, and browsable dictionary\nresources, all backed by tiered caching and a typed async client.\n\n## Features\n\n- **Curated, high-level tools** that take human-friendly inputs (brand, model,\n  region, year/price ranges) and resolve them to AUTO.RIA's numeric IDs for you.\n- **Paid statistics tools** (AI average price, price-over-time, VIN decode) that\n  fail fast with a clear error when `AUTORIA_USER_ID` is unset — no wasted quota.\n- **Thin endpoint mirrors** for the long-tail dictionary/lookup endpoints.\n- **Dictionary resources** — browse categories, colours, regions, etc. as\n  addressable `autoria://dict/...` documents.\n- **Aggressive, tiered caching**: large slow-changing dictionaries are cached on\n  disk for 7 days (name→ID resolution costs no quota after the first fetch),\n  while volatile search/statistics responses are cached briefly, in memory only.\n- **stdio and streamable-HTTP** transports.\n\n## Install\n\nRequires Python 3.11+. The package is distributed on PyPI; run it without a\nmanual install using [`uvx`](https://docs.astral.sh/uv/):\n\n```sh\nuvx autoria-mcp\n```\n\nOr install into a tool environment with `pipx` / `uv tool`:\n\n```sh\nuv tool install autoria-mcp   # or: pipx install autoria-mcp\n```\n\n## Quickstart: Claude Desktop (no coding required)\n\nWant to use AUTO.RIA from the **Claude desktop app**? Follow these steps — no\nprogramming needed, just some copy-and-paste. Pick your platform:\n[macOS](#macos) · [Windows](#windows).\n\n### macOS\n\n**1. Install `uv`** (the small tool that runs `autoria-mcp` for you). Open the\n**Terminal** app and paste this, then press Enter:\n\n```sh\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n```\n\n(Full instructions: <https://docs.astral.sh/uv/getting-started/installation/>.)\n\n**2. Get a free AUTO.RIA API key** at <https://developers.ria.com>. Keep it handy.\nA `user_id` is optional — you only need it for the paid price-statistics tools.\n\n**3. Find the full path to `uvx`.** The desktop app can't see your Terminal's\nsettings, so it needs the *full* path. In Terminal, run:\n\n```sh\nwhich uvx\n```\n\nCopy what it prints — usually `/opt/homebrew/bin/uvx` (Apple-Silicon Mac) or\n`/usr/local/bin/uvx` (Intel Mac).\n\n> **This is the #1 reason setup fails.** If you use just `uvx` instead of the full\n> path, the app says it can't find it. Always paste the full path from `which uvx`.\n\n**4. Open Claude Desktop's config file.** In the Claude app: **Settings →\nDeveloper → Edit Config**. This opens a file called `claude_desktop_config.json`\n(on macOS it lives at\n`~/Library/Application Support/Claude/claude_desktop_config.json`).\n\n**5. Add the `autoria` server.** Paste the block below. If the file already has a\n`\"mcpServers\"` section, add `\"autoria\"` *inside* it next to your other servers;\notherwise paste the whole thing. Replace the two placeholder values:\n\n```json\n{\n  \"mcpServers\": {\n    \"autoria\": {\n      \"command\": \"/opt/homebrew/bin/uvx\",\n      \"args\": [\"autoria-mcp\"],\n      \"env\": { \"AUTORIA_API_KEY\": \"paste-your-api-key-here\" }\n    }\n  }\n}\n```\n\n- `command` → the full path from step 3.\n- `AUTORIA_API_KEY` → your key from step 2.\n- For the paid tools (average price, VIN lookup), add `\"AUTORIA_USER_ID\": \"...\"`\n  to `env` — put a comma after the API-key line when you do, e.g.\n  `\"env\": { \"AUTORIA_API_KEY\": \"...\", \"AUTORIA_USER_ID\": \"...\" }`.\n\nSave the file.\n\n**6. Fully quit and reopen Claude.** Press **`Cmd + Q`** (just closing the window\nisn't enough), then open Claude again. The **first** start takes a few seconds\nwhile it downloads the tool; after that it's instant.\n\n**7. Try it.** Ask Claude something like:\n*\"Use autoria to find used BMW 3 Series cars in Kyiv and show me a few with prices.\"*\n\n> **Heads-up on limits:** the free AUTO.RIA key allows roughly **30 requests/hour**\n> and **1000/month** — so ask focused questions rather than broad ones.\n\n**If autoria doesn't show up** after restarting, the log file usually says why:\n\n```sh\ntail -50 ~/Library/Logs/Claude/mcp-server-autoria.log\n```\n\nMost common fixes: use the **full `uvx` path** (step 3), and make sure you\n**fully quit** Claude with `Cmd + Q`.\n\n### Windows\n\nThe same flow on Windows — the commands and a couple of Windows-only gotchas\ndiffer from macOS.\n\n**1. Install `uv`** (it ships the `uvx` command that runs `autoria-mcp`). Open\n**PowerShell** and run either:\n\n```powershell\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n```\n\nor, if you use [winget](https://learn.microsoft.com/windows/package-manager/):\n\n```powershell\nwinget install --id=astral-sh.uv -e\n```\n\nThen **open a new terminal window** so the updated `PATH` takes effect.\n(Full instructions: <https://docs.astral.sh/uv/getting-started/installation/>.)\n\n**2. Get a free AUTO.RIA API key** at <https://developers.ria.com>. Keep it\nhandy. A `user_id` is optional — you only need it for the paid price-statistics\ntools.\n\n**3. Find the full path to `uvx.exe`.** The desktop app can't see your terminal's\n`PATH`, so it needs the *full* path. In **PowerShell**, run:\n\n```powershell\nGet-Command uvx | Select-Object -ExpandProperty Source\n```\n\nor in **Command Prompt** (`cmd`):\n\n```bat\nwhere.exe uvx\n```\n\nCopy what it prints — usually `C:\\Users\\<you>\\.local\\bin\\uvx.exe`.\n\n> **In PowerShell, use `where.exe`, not `where`.** Plain `where` is an alias for\n> `Where-Object` and won't find the executable.\n\n> **This is the #1 reason setup fails.** If you use just `uvx` instead of the full\n> path, the app says it can't find it. Always paste the full path from step 3.\n\n**4. Open Claude Desktop's config file — use the in-app button.** In the Claude\napp: **Settings → Developer → Edit Config**. This opens the correct\n`claude_desktop_config.json` for your install.\n\n> **Don't hand-edit the `%APPDATA%` file.** The documented location is\n> `%APPDATA%\\Claude\\claude_desktop_config.json`\n> (= `C:\\Users\\<you>\\AppData\\Roaming\\Claude\\claude_desktop_config.json`), but the\n> **Microsoft Store / MSIX** build of Claude *virtualizes* that folder — it\n> actually reads from\n> `%LOCALAPPDATA%\\Packages\\Claude_pzs8sxrjxfjjc\\LocalCache\\Roaming\\Claude\\claude_desktop_config.json`.\n> Editing the plain `%APPDATA%` copy then makes your MCP servers **silently fail\n> to load**. The **Edit Config** button always opens the right file — use it.\n\n**5. Add the `autoria` server.** Paste the block below. If the file already has a\n`\"mcpServers\"` section, add `\"autoria\"` *inside* it next to your other servers;\notherwise paste the whole thing. On Windows, backslashes in JSON must be\n**doubled** (`\\\\`) — or use forward slashes (`C:/Users/you/.local/bin/uvx.exe`):\n\n```json\n{\n  \"mcpServers\": {\n    \"autoria\": {\n      \"command\": \"C:\\\\Users\\\\you\\\\.local\\\\bin\\\\uvx.exe\",\n      \"args\": [\"autoria-mcp\"],\n      \"env\": { \"AUTORIA_API_KEY\": \"paste-your-api-key-here\" }\n    }\n  }\n}\n```\n\n- `command` → the full path from step 3, with doubled backslashes.\n- `AUTORIA_API_KEY` → your key from step 2.\n- For the paid tools (average price, VIN lookup), add `\"AUTORIA_USER_ID\": \"...\"`\n  to `env` — put a comma after the API-key line when you do, e.g.\n  `\"env\": { \"AUTORIA_API_KEY\": \"...\", \"AUTORIA_USER_ID\": \"...\" }`.\n\nSave the file. A ready-to-edit copy is at\n[`examples/claude_desktop_config_windows.json`](examples/claude_desktop_config_windows.json).\n\n> Prefer not to keep your key in the config? Omit the `env` block and instead put\n> `AUTORIA_API_KEY` in a `.env` file in the working directory, or set it as a\n> Windows user/system environment variable.\n\n**6. Fully restart Claude.** Right-click the Claude icon in the **system tray**\n(near the clock) and choose **Quit** — just closing the window isn't enough —\nthen open Claude again. The **first** start takes a few seconds while it\ndownloads the tool; after that it's instant.\n\n**7. Try it.** Ask Claude something like:\n*\"Use autoria to find used BMW 3 Series cars in Kyiv and show me a few with prices.\"*\n\nThe same [limits](#quickstart-claude-desktop-no-coding-required) and most-common\nfixes apply: use the **full `uvx.exe` path** (step 3), edit the config via the\n**in-app button** (step 4), and **fully quit** from the tray (step 6). Logs are at\n`%APPDATA%\\Claude\\logs\\mcp-server-autoria.log`.\n\n## Configuration\n\nAll settings are read from environment variables (prefix `AUTORIA_`) or a local\n`.env` file. Copy [`.env.example`](.env.example) to `.env` and fill in your key.\n\n| Variable             | Default                       | Description                                                        |\n| -------------------- | ----------------------------- | ------------------------------------------------------------------ |\n| `AUTORIA_API_KEY`    | — (required for API calls)    | Personal API key from <https://developers.ria.com>. Never logged.  |\n| `AUTORIA_USER_ID`    | —                             | User id, required only by the paid POST endpoints.                 |\n| `AUTORIA_TRANSPORT`  | `stdio`                       | `stdio` or `http` (streamable-HTTP). Also `--transport`.           |\n| `AUTORIA_HOST`       | `127.0.0.1`                   | Bind host for the HTTP transport.                                  |\n| `AUTORIA_PORT`       | `8000`                        | Bind port for the HTTP transport.                                  |\n| `AUTORIA_BASE_URL`   | `https://developers.ria.com`  | API host (only the production host is documented).                 |\n| `AUTORIA_CACHE_DIR`  | `~/.cache/autoria-mcp`        | On-disk dictionary cache location.                                 |\n| `AUTORIA_CACHE_TTL`  | `604800` (7 days)             | Default dictionary cache TTL, in seconds.                          |\n| `AUTORIA_VOLATILE_TTL` | `600` (10 min)              | Memory-only TTL for volatile search/statistics responses.          |\n| `AUTORIA_MEMORY_CACHE_MAX` | `256`                   | Max entries per in-memory cache tier (bounded LRU).                |\n| `AUTORIA_MAX_RETRIES` | `3`                          | Retry attempts on `429` / `5xx` (backoff + full jitter).           |\n| `AUTORIA_BACKOFF_BASE` | `0.5`                       | Base backoff delay, in seconds.                                    |\n| `AUTORIA_BACKOFF_CAP` | `8.0`                        | Max delay for a single backoff sleep, in seconds.                  |\n| `AUTORIA_QUOTA_HOURLY_LIMIT` | `30`                  | Assumed hourly quota; usage warns near it (never blocks).          |\n| `AUTORIA_QUOTA_MONTHLY_LIMIT` | `1000`               | Assumed monthly quota; usage warns near it (never blocks).         |\n| `AUTORIA_QUOTA_WARN_RATIO` | `0.9`                   | Warn once usage crosses this fraction of a window limit.           |\n| `AUTORIA_LOG_LEVEL`  | `INFO`                        | Package log level.                                                 |\n\nThe API key is held in a `SecretStr` and never written to logs.\n\n## Running\n\n```sh\n# stdio (default) — how MCP clients launch it\nautoria-mcp\n\n# streamable-HTTP\nautoria-mcp --transport http --host 127.0.0.1 --port 8000\n# or\nAUTORIA_TRANSPORT=http autoria-mcp\n```\n\nSee [`examples/`](examples/) for ready-to-paste MCP client configs (Claude\nDesktop and a generic stdio client).\n\n## Quota guidance\n\nThe AUTO.RIA free package is metered **per API key across all RIA web services**\nand the limits are tight:\n\n- **~1000 requests / month**\n- **30 requests / hour** (rolling); exceeding either returns `429 OVER_RATE_LIMIT`\n  and temporarily blocks the key.\n\nThere are **no** `X-RateLimit-*` response headers, so the client tracks usage\nlocally (Phase 3). Treat every live call as spending scarce quota: the dictionary\nendpoints are cached aggressively, and search/statistics responses should not be\nre-fetched needlessly.\n\n## Tool catalog\n\n**Curated tools** — natural inputs (names, ranges), resolved to IDs for you:\n\n| Tool                | Description                                                              |\n| ------------------- | ----------------------------------------------------------------------- |\n| `search_used_cars`  | Search by brand/model/region/year/price/engine-volume/power/generation/etc.; returns the match `count` + advert ids. |\n| `get_car_details`   | Compact details for one advert id: price, year, mileage, structured engine volume/power, labelled body/fuel/gearbox, plus `condition`/`risk`/`verification`/`seller`/`photo` provenance, VIN-if-shown, masked phone, URL. |\n| `get_car_details_batch` | Details for up to 50 advert ids in one call (deduped; a dead id returns a sparse entry). |\n| `lookup_brands`     | List passenger-car brands, or resolve one brand name to its id.         |\n| `lookup_models`     | List a brand's models, or resolve one model name to its id.             |\n| `lookup_regions`    | List regions (oblasts), or resolve one region name to its id.           |\n| `lookup_cities`     | List a region's cities, or resolve one city name to its id.             |\n\n**Paid tools** (require `AUTORIA_USER_ID`; fail fast with a clear error otherwise):\n\n| Tool                            | Description                                              |\n| ------------------------------- | ------------------------------------------------------- |\n| `get_average_price`             | AI average price + comparable listings (by params or `omni_id`). |\n| `get_average_price_over_periods`| Monthly average-price time series.                      |\n| `get_params_by_vin`             | Decode a VIN / plate / advert id into car-parameter chips. |\n\n**Thin mirrors** (raw passthrough, 7-day cached): `list_categories`,\n`list_all_models`, `list_models_grouped`, `list_generations`, `list_modifications`,\n`list_modifications_by_body`, `list_equipment`, `list_options`, `list_options_v2`,\n`list_colors`, `list_countries`, `list_drive_types`, `list_fuel_types`,\n`list_gearboxes`, `list_body_styles`, `list_body_styles_grouped`,\n`list_all_body_styles`, `list_bodies_by_generation`, and `raw_search` (raw V1\nsearch; compact `{count, ids}` by default, `verbose=True` for the full payload).\n\n**Resources**: `autoria://dict/{categories,colors,countries,fuel-types,gearboxes,\nbody-styles,states}` and the templated `autoria://dict/models/{categoryId}/{markId}`.\n\n**Health**: `ping` — zero-quota liveness/diagnostic check.\n\n## Attribution\n\nAUTO.RIA's API terms require a **visible link back to `auto.ria.com`** wherever you\ndisplay data sourced from the API. `get_car_details` and the paid endpoints include\na canonical per-listing deep link (`url`); keep it visible in whatever surface\npresents a listing to an end user. (`search_used_cars` returns only ids + a count —\nthe Public API specifies no set-level search link, so none is invented.)\n\n## Known limitations\n\nThese are deliberate scope/behaviour choices worth knowing before you rely on them:\n\n- **Single brand/model per search.** Multi-brand or multi-model search is not yet\n  modelled by `search_used_cars`. For OR-style queries across several brands, drop\n  to `raw_search` and pass the raw V1 params yourself.\n- **Search returns ids, not full listings.** `search_used_cars` gives you advert\n  ids and a `count`. Fetch per-listing detail with `get_car_details` (or\n  `get_car_details_batch` for a whole page of ids) — each lookup spends quota, so\n  resolve only what you need.\n- **Search is V1-only and silently ignores unknown params** — a genuine footgun.\n  The underlying `/auto/search` endpoint does not validate filter keys: a misspelt\n  or unsupported param is dropped, and the search quietly widens to the whole site\n  instead of erroring. The curated tool resolves names to the correct V1 ids to\n  avoid this, but `raw_search` passes your params through verbatim.\n- **Paid POST errors arrive as HTTP 200.** The paid endpoints return errors in the\n  body (`noticeType: \"error\"`) with a 200 status; the paid tools detect and surface\n  these as tool errors.\n- **`get_average_price_over_periods`** accepts only `period ∈ {30, 90, 180, 365}`.\n\n## Development\n\n```sh\nuv sync                     # create venv + install deps (incl. dev group)\nuv run ruff check .         # lint\nuv run ruff format --check .  # format check\nuv run mypy                 # strict type check (src + tests)\nuv run pytest               # tests (no network)\npre-commit install          # enable git hooks\n```\n\nThe OpenAPI 3.1 description lives in\n[`openapi/autoria-used-cars.yaml`](openapi/autoria-used-cars.yaml).\n\n## Roadmap\n\n1. ✅ **Phase 1** — OpenAPI spec, live-verified API facts.\n2. ✅ **Phase 2** — repo scaffold, tooling, CI, packaging, runnable server.\n3. ✅ **Phase 3** — typed async client, TTL dictionary cache, name→ID resolution,\n   recorded-fixture tests (zero live quota).\n4. ✅ **Phase 4** — curated + paid + thin tools, dictionary MCP resources.\n5. ✅ **Phase 5** — docs, examples, first PyPI release (`0.1.0`).\n\n**Post-1.0 backlog** (not scheduled): native multi-brand / multi-model search;\nper-endpoint cache TTLs; a cross-process quota lock (current accounting is\nper-process, warn-only); an `npx` shim for Node-based MCP clients.\n\n## License\n\n[MIT](LICENSE). This is an unofficial project and is not affiliated with or\nendorsed by RIA.com / AUTO.RIA.\n",
  "bytes": 18053,
  "sha": "25494a184da6c08e09901a8ddaa3feacc01281270de9377fd699da063a9ca58f",
  "repo_slug": "yevhen-kalyna/autoria-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_yevhen_kalyna_autoria_mcp_d8033579/readme"
}