Help us shape the future of Go! Take the 2026 Go Developer Survey

cars-search-mcp

module
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: MIT

README

cars-search-mcp

CI Release Coverage Go Reference Go version License

Static Go MCP for used / new car inventory search (dealer + private party) via the MarketCheck Cars API.

Built for ai-gantry / LOCAL_AGENT: lean tool surface, stdio only, CGO_ENABLED=0 binary that fits distroless. Search + recommend + listing handoff — never contacts dealers, submits leads, or purchases vehicles.

Naming follows ai-gantry MCP tool naming: host server id cars → tools like cars__listings_search (tool names do not repeat the server id).

Publish from a personal GitHub account only (never a work org). Module / release URLs assume shotah — see TODO.md.

What this is (and is not)

In scope Out of scope
Active for-sale car inventory (US / CA) Motorcycles / RVs / heavy equipment (later)
Dealer + FSBO (+ auction later) Financing applications / lead forms
VIN decode, fair-price predict, market stats Negotiating or buying for the human
Listing URL handoff Scraping Cars.com / Autotrader directly

Sibling of rentals-search-mcp and flights-search-mcp: same packaging vibes, different upstream.

Tools (MVP)

Tool Description
listings_search Zip/city/radius + year/make/model/price/mileage/body filters
listings_get One listing by MarketCheck listing id
listings_stats Active-inventory snapshot: price / miles / DOM aggregates
vin_get NeoVIN decode (trim, options, fuel economy when available)
dealers_search Dealers near a zip/city (inventory size, type, inventory URL)
price_predict Fair retail price for a VIN + miles (+ zip)
markets_get Market Days Supply for year/make/model (+ zip)
link_format Fallback public search URL (Cars.com; no API)
account_get Local usage counter (used/left) + dashboard link — MarketCheck has no public quota API

Host names: cars__listings_search, cars__listings_get, cars__listings_stats, cars__vin_get, cars__dealers_search, cars__price_predict, cars__markets_get, cars__link_format, cars__account_get.

Agent contract
listings_search → [listings_get] → present listing / dealer url
            ↘ vin_get / price_predict / listings_stats / markets_get / dealers_search
  1. Where + budget: listings_search with zip or city+state, plus make / model / year_min–year_max / price_max / miles_max.
  2. Detail: listings_get when the human picks a candidate id.
  3. Context (optional): vin_get for a known VIN; price_predict for fair value; listings_stats for market price/DOM bands; markets_get for MDS; dealers_search for rooftops in a market.
  4. Handoff: give the human the VDP / dealer URL. Do not submit leads or call the dealer for them.

Setup

  1. Create a MarketCheck API account (Free plan ≈ 500 calls / month, 100-mile radius cap — pricing).
  2. Export the key:
export MARKETCHECK_API_KEY=...
# optional (tests / proxies):
# export MARKETCHECK_BASE_URL=https://api.marketcheck.com/v2
Boot safety (learned the hard way)

This MCP starts stdio even if MARKETCHECK_API_KEY is missing. Tools that need the network return a clear error. That way a missing key cannot take down ai-gantry at MCP initialize (pair with gantry’s fail-soft boot).

Docker / containers

The binary is static (CGO_ENABLED=0) and fine in distroless — pass MARKETCHECK_API_KEY via env/secrets, never bake it into the image.

Local usage counter: on by default — no env needed. Persists under the OS user config dir (…/cars-search-mcp/usage.json), with home/temp fallbacks. In Docker that path is usually ephemeral (or unwritable in distroless), so counts reset on recreate and can undercount real MarketCheck spend. Mitigations:

  • Mount a volume and set MARKETCHECK_USAGE_FILE=/data/marketcheck-usage.json, or
  • Treat the dashboard as source of truth and/or set MARKETCHECK_USAGE_TRACK=0

Development

make help                 # list targets
make tools                # install goimports-reviser + golangci-lint v2
make install-hooks        # git pre-commit: autofix + lint + test + coverage ≥70%
make check                # same checks as the pre-commit hook
make cli                  # static binary → ./bin/cars-search-mcp
make self-test

Coverage ≥70% is mandatory locally (make coverage / pre-commit) and in CI.

Status: MVP client wired. Remaining publish / gantry consumer steps are in TODO.md.

Releasing

GoReleaser publishes static binaries on v* tags (see .github/workflows/release.yml).

make version                 # show VERSION + next patch (dry-run)
make release                 # patch bump, commit VERSION, tag, push
make release BUMP=minor
make release TAG=v0.1.0

Archive name for ai-gantry download_url:

cars-search-mcp_{version}_{os}_{arch}.tar.gz

Run as MCP (stdio)

./bin/cars-search-mcp

Logs go to stderr only — stdout is reserved for the MCP protocol.

Example Cursor / client config:

{
  "mcpServers": {
    "cars": {
      "command": "cars-search-mcp",
      "env": {
        "MARKETCHECK_API_KEY": "…"
      }
    }
  }
}

ai-gantry wiring (when published)

[[server]]
name = "cars"
command = "cars-search-mcp"
download_tag = "latest"
download_url = "https://github.com/shotah/cars-search-mcp/releases/download/{tag}/cars-search-mcp_{version}_{os}_{arch}.tar.gz"

Also set MARKETCHECK_API_KEY in compose / deploy/gantry.env (regenerate with make remote-native-env — .env alone is not enough on native).

Do not publish this to a work GitHub org. Use a personal account / org (module path assumes shotah).

More: docs/ai-gantry.md. Agent tool recipes: docs/agent.md.

License

MIT

Directories

Path Synopsis
cmd
cars-search-mcp command
release command
Command release bumps the semver tag, updates VERSION, and pushes.
Command release bumps the semver tag, updates VERSION, and pushes.
internal
mcp

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL