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 stations --fuel Gasolio --near 41.9,12.5 --cheapest
  • "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, find_chargers, get_stats) 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

v1.0.2 — stable public release: 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, agent skill, tests, CI.

Planned, roughly in order:

  • per-station EV tariff data once Italy exposes a documented public API for PUN / AFIR data;
  • 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.2.tar.gz (37.5 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.2-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pitstop_cli-1.0.2.tar.gz
  • Upload date:
  • Size: 37.5 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.2.tar.gz
Algorithm Hash digest
SHA256 774dbfaf47ed227c2c4fc333a2942ef453a73c39c62daff27d9410496d5e2a83
MD5 77da9e3b8a413169531f99050e4c909c
BLAKE2b-256 9f07631e5efdc1fbdde53b895d0b65ca7e12181cf2d79b2000489aeaa3101aa7

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pitstop_cli-1.0.2-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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 75dc673e26fd2fa99b38e137197dc33edb7665326dcd3b9f454f5bb780a9b91b
MD5 aeab21cbe24ff7da821c59079ce0c98d
BLAKE2b-256 440243dd69f73cdc34767560554d3255e86a107db6340acecf43c7af4d1e3d2c

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