Skip to main content

JSON-first CLI + MCP server for Italian fuel-station prices and EV charging — MIMIT, OpenStreetMap, ISTAT.

Project description

pitstop

A JSON-first CLI and MCP server for Italian fuel-station prices and EV charging stations, designed for AI agents, scripts, and humans.

Italy publishes per-station fuel prices daily (MIMIT Osservaprezzi Carburanti open data) and OpenStreetMap maps every EV charger in the country, but raw access means downloading multi-megabyte CSVs, joining files, sorting through misreports, and translating between Italian comune names and the ones a user actually types. pitstop does all of that locally and returns a small, well-formed JSON envelope.

Built for questions like:

  • "What's the cheapest diesel near Rome right now?"pitstop find_cheapest --fuel Gasolio --near 41.9,12.5
  • "Where can I fast-charge my EV in Bolzano?"pitstop chargers --comune Bozen --fast
  • "Are these station prices statistically reliable?" → every price carries a regional_median, deviation_pct, and outlier flag.

International city names work out of the box (Rome, Milan, Bozen, Mailand, Venise, …).

Disclaimer

Unofficial community project. Not affiliated with or endorsed by MIMIT. Fuel data belongs to MIMIT and is redistributed here under its open-data terms; pitstop always emits source and extraction-date provenance in its output.

Data scope & freshness

  • Source: MIMIT Osservaprezzi Carburanti open data — a station registry (anagrafica, ~23.8k active stations) and a daily practiced-price file, joined on idImpianto.
  • Freshness: prices reflect values reported by operators as of ~08:00 the day before the published extraction date. This is daily, not real-time.
  • Coverage: Italy only (by design, for now).
  • Known caveats:
    • Some operators report placeholder values (e.g. 1.000); use --min-price (e.g. 1.2) to drop them.
    • Some price records are stale (a few were last updated years ago); use --fresh-within-days and check the UPDATED column / updated field.
    • Some stations are mis-geocoded in the registry. As of v0.4.0 pitstop joins a second data source (ISTAT-derived comune coordinates from opendatasicilia/comuni-italiani, 97.5% match) to validate each station's coordinate against its declared comune's true location. Stations >30 km off are flagged coordinate_suspect (* in the table), and --near excludes stations whose declared comune is geographically too far from the query point — even single-station comuni like RASUN-ANTERSELVA. Pass --no-comune-validate to disable.

Install

Requires Python ≥ 3.10. No third-party runtime dependencies.

From PyPI (the package is published as pitstop-cli; the CLI binary is pitstop):

pipx install pitstop-cli           # or
uv tool install pitstop-cli        # or just run on-demand:
uvx --from pitstop-cli pitstop --help

For the MCP server (optional extra):

pipx install "pitstop-cli[mcp]"
pitstop-mcp                        # stdio MCP server

Run from a source checkout during development:

PYTHONPATH=src python3 -m pitstop --help

Usage

# Cheapest *fresh* diesel in a municipality (skip placeholder + stale prices)
pitstop stations --comune ROMA --fuel Gasolio --cheapest --min-price 1.2 --fresh-within-days 90 --limit 5

# Self-service petrol within 5 km of a coordinate, as JSON
pitstop stations --near 46.498,11.354 --radius 5 --fuel Benzina --self --json

# Discover the fuel-type names present in the data
pitstop fuels

# Fast EV chargers (≥50 kW) within 5 km of Bolzano
pitstop chargers --near 46.498,11.354 --radius 5 --fast --json

stations flags: --comune, --provincia, --brand, --near "lat,lon", --radius, --fuel (substring, case-insensitive), --self, --served, --cheapest (needs --fuel), --min-price (drop values below a floor; e.g. 1.2 to skip placeholders), --fresh-within-days (drop stale prices), --max-deviation-pct (drop prices more than N% below their fuel's provincial median — catches misreports), --no-comune-validate, --limit, --json. Loading flags (--refresh, --max-age, --timeout) apply to any data command.

Every returned price carries regional_median, deviation_pct, and an outlier flag (true when >15% below the local median or below the Tukey lower fence Q1−1.5·IQR — the Tukey rule catches misreports in tight markets that the percent rule alone misses). Pass --drop-outliers to remove flagged prices entirely.

MCP server

For agents that speak MCP, the same data is exposed as tools (list_fuels, find_stations, find_cheapest) over the shared core:

pip install "pitstop-cli[mcp]"   # or: uv tool install "pitstop-cli[mcp]"
pitstop-mcp                      # stdio MCP server

Example client config entry:

{ "mcpServers": { "pitstop": { "command": "pitstop-mcp" } } }

Development

pip install -e ".[dev]"
pytest -q

Automation contract

  • stdout is command output; stderr is diagnostics.
  • --json emits a stable object with source, *_extraction_date, generated_at, query, count, stations[], and disclaimer.
  • Exit codes: 0 success, 1 runtime error, 2 usage error.
  • Source files are cached (default 24h) under $XDG_CACHE_HOME/pitstop; use --refresh to bypass.
  • Non-interactive; no hidden browser state or scraping.

Status & roadmap

v0.9.0 — fuel-price core (registry+price join, filters, proximity, cheapest, --min-price floor, --fresh-within-days freshness, combined 15% + Tukey IQR outlier rule, ISTAT comune-coordinate validation, JSON) + EV charging stations via OSM Overpass (operator, plug types, max kW, fee, access — pitstop chargers) + operator tariff-page URLs attached to each EV result. Includes multi-fuel query support, international municipality mapping (EN/FR/DE), macro price statistics (pitstop stats), and navigation/GeoJSON support. MCP server, Claude skill, tests, CI.

Planned, roughly in order:

  • EV charging (locations via Open Charge Map; prices via the AFIR National Access Point / DATEX II as that data matures);
  • additional countries behind a per-country source adapter (e.g. Germany Tankerkönig, France/Spain official feeds).

Data sources & attributions

  • Fuel stations and prices: MIMIT Osservaprezzi Carburanti open data.
  • Comune coordinates (validation): opendatasicilia/comuni-italiani (ISTAT-derived).
  • EV charging stations: OpenStreetMap via the Overpass API (© OpenStreetMap contributors, ODbL).

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pitstop_cli-1.0.0.tar.gz (37.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pitstop_cli-1.0.0-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

File details

Details for the file pitstop_cli-1.0.0.tar.gz.

File metadata

  • Download URL: pitstop_cli-1.0.0.tar.gz
  • Upload date:
  • Size: 37.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for pitstop_cli-1.0.0.tar.gz
Algorithm Hash digest
SHA256 fe1c10327db47cb4c06799d507aaf447df960e30baf9827f14d5fdb31fa045e9
MD5 534ef12a4e2c15f9c02ba4b2056ec212
BLAKE2b-256 25ac896c243be253a38a35d1c7dcf69d4e15c05c27aaba90e9a18522da5c5a97

See more details on using hashes here.

File details

Details for the file pitstop_cli-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: pitstop_cli-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 30.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for pitstop_cli-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4505a96380692933cc035b1bcf83c905eadfacc0d7bf7523cacc5718a413016a
MD5 3f40aacd5de6c1da8a883dc73e39f5c2
BLAKE2b-256 7206805067b943d9ffb65868f3e74422d11e1f887519e567bf7780fdc5d7e075

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page