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.1.tar.gz (37.3 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.1-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

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

Hashes for pitstop_cli-1.0.1.tar.gz
Algorithm Hash digest
SHA256 62ba472a0befbb4085443511a7503f1e755d9932bef23e36ea49515b1bf837bf
MD5 dcee357304ae124aee14ad565bd35286
BLAKE2b-256 9656de4b855f5d203d655cebfb0db77f0df9849159d567e949b9a302e5d15ba5

See more details on using hashes here.

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

Hashes for pitstop_cli-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dda31ae39601ab7ceb173df674ce551ddde8d178471012b0d9cb5c1d50051ffa
MD5 89c3eb855c7cd198c7650b9e9122abf1
BLAKE2b-256 2aa722cd6e67a51cde1a2bf25aceac907300739d3a4601364a8d13e251f256b8

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