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, andoutlierflag.
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 onidImpianto. - 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-daysand check theUPDATEDcolumn /updatedfield. - Some stations are mis-geocoded in the registry. As of v0.4.0
pitstopjoins 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 flaggedcoordinate_suspect(*in the table), and--nearexcludes stations whose declared comune is geographically too far from the query point — even single-station comuni like RASUN-ANTERSELVA. Pass--no-comune-validateto disable.
- Some operators report placeholder values (e.g.
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
stdoutis command output;stderris diagnostics.--jsonemits a stable object withsource,*_extraction_date,generated_at,query,count,stations[], anddisclaimer.- Exit codes:
0success,1runtime error,2usage error. - Source files are cached (default 24h) under
$XDG_CACHE_HOME/pitstop; use--refreshto 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pitstop_cli-1.0.1.tar.gz.
File metadata
- Download URL: pitstop_cli-1.0.1.tar.gz
- Upload date:
- Size: 37.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62ba472a0befbb4085443511a7503f1e755d9932bef23e36ea49515b1bf837bf
|
|
| MD5 |
dcee357304ae124aee14ad565bd35286
|
|
| BLAKE2b-256 |
9656de4b855f5d203d655cebfb0db77f0df9849159d567e949b9a302e5d15ba5
|
File details
Details for the file pitstop_cli-1.0.1-py3-none-any.whl.
File metadata
- Download URL: pitstop_cli-1.0.1-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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dda31ae39601ab7ceb173df674ce551ddde8d178471012b0d9cb5c1d50051ffa
|
|
| MD5 |
89c3eb855c7cd198c7650b9e9122abf1
|
|
| BLAKE2b-256 |
2aa722cd6e67a51cde1a2bf25aceac907300739d3a4601364a8d13e251f256b8
|