milano-mobility-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@milano-mobility-mcp Can I drive a diesel Euro 4 car in Milan Area B tomorrow?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Milano Mobility MCP
MVP Python funzionante del Nodo Mobilità & Restrizioni: quattro tool MCP stdio per ridurre l'asimmetria informativa su Area B, Area C, MoVe-In e antismog a Milano. Urbanistica esclusa.
Non è un'autorizzazione alla circolazione né consulenza legale. Verificare sempre le disposizioni delle autorità e la propria situazione prima di viaggiare. Nessuna garanzia contro sanzioni.
Cosa funziona davvero
Tool | Supporto nel MVP |
| Profilo, data e perimetro validati; attualmente sempre |
| Adapter non live: livello, territorio del provvedimento, validità e ultima verifica sconosciuti. Riferimenti ufficiali per verifica esterna. |
| Calcolo esatto |
| Attualmente sempre |
SDK ufficiale mcp, modelli Pydantic, Python 3.11+. Nessuna richiesta di rete effettuata dai tool. Risposte con structuredContent e contenuto JSON testuale MCP.
Esiti e prove
decision:consentito,vietato,non_determinabile. Questa versione non emette maiconsentito: la copertura complessiva è incompleta.Il motore supporta
vietatoper un divieto ordinario documentato sul profilo dichiarato, condizionato all'assenza di deroghe applicabili dichiarata dall'utente. Questo ramo è esercitato da fixture sintetiche nei test, non da regole distribuite nel catalogo attuale.Un divieto verificato prevale su componenti sconosciute, tutte visibili in
assessments.Per budget/costi,
decisionrestanon_determinabilerispetto alla circolazione;calculation_statusdistinguecalcolato,documentato,non_determinabile.Input:
user_unverified. Il motore richiedeofficial_publicper fonti operative; recordsynthetic_testo non verificati non sostengono regole. Isource_checksrestituiti sono riferimenti documentali (reference_only), non prove di regole applicabili.Fonti mancanti, scadute, consultate nel futuro o fuori copertura non producono divieti documentati, costi certi o autorizzazioni. Sconosciuto non significa nessun blocco, ticket gratuito o deroga garantita.
Related MCP server: ECRVSP Documentos: Baixar Veículo
Quickstart
Accesso al repository privato necessario. Nessun token applicativo, account MoVe-In o credenziale da inserire nel progetto.
Windows / PowerShell
gh repo clone bsab/milano-mobility-mcp
Set-Location milano-mobility-mcp
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e '.[test]'
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe -m milano_mobility_mcpEntry point alternativo: .\.venv\Scripts\milano-mobility-mcp.exe.
Linux / macOS
gh repo clone bsab/milano-mobility-mcp
cd milano-mobility-mcp
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[test]'
.venv/bin/python -m pytest -q
.venv/bin/python -m milano_mobility_mcpEntry point alternativo: .venv/bin/milano-mobility-mcp.
Il processo attende messaggi MCP su stdin: non è una REPL né un server HTTP. Nessun banner su stdout; arresto manuale con Ctrl+C. Normalmente lo avvia il client MCP. Installazione senza pytest: pip install -e . con l'interprete dell'ambiente.
Configurazione client MCP
Usare l'interprete assoluto del virtualenv, non python dipendente dal PATH. Sostituire il percorso d'esempio con quello reale. Il package installato non dipende dalla directory corrente del client.
Windows:
{
"mcpServers": {
"milano-mobility": {
"command": "C:\\progetti\\milano-mobility-mcp\\.venv\\Scripts\\python.exe",
"args": ["-m", "milano_mobility_mcp"]
}
}
}Linux/macOS:
{
"mcpServers": {
"milano-mobility": {
"command": "/home/utente/milano-mobility-mcp/.venv/bin/python",
"args": ["-m", "milano_mobility_mcp"]
}
}
}La posizione del file di configurazione dipende dal client. Nessuna variabile segreta richiesta. Non abilitare log degli argomenti nel client se contengono dati personali: il server non registra input e non accetta targhe.
Esempi dei quattro tool
Argomenti MCP sempre nella forma {"request": {...}}. Risposte sotto come estratti; motivazioni e metadati completi vengono restituiti.
1. Profilo veicolo esplicito
check_vehicle_access:
{
"request": {
"vehicle": {
"category": "M1", "fuel": "elettrico", "euro_class": null,
"exemptions": "da_verificare", "resident_in_milan": true
},
"at": "2026-09-08T12:00:00+02:00",
"area": "area_b",
"inside_area_confirmed_by_user": true,
"destination": "Destinazione dichiarata in Area B, non geocodificata"
}
}Risultato decision: "non_determinabile", anche per elettrico: restano situazione personale, geografia e misure non coperte. Residenza non significa esenzione. exemptions: "nessuna_applicabile_dichiarata" è solo una dichiarazione; usare da_verificare se accessi gratuiti, deroghe o MoVe-In potrebbero essere applicabili.
Obbligatori: categoria, alimentazione, classe Euro (null esplicito ammesso solo per elettrico), stato deroghe, area e conferma perimetro. Valori enumerati esposti da list_tools; categorie/alimentazioni non coperte non vengono assimilate ad altre.
Data/ora ISO 8601 con offset di Europe/Rome: +01:00 in inverno, +02:00 in estate. Date naive, offset errati, ore locali inesistenti e timestamp numerici rifiutati. Le due occorrenze dell'ora ambigua autunnale si distinguono con l'offset. Nessun divieto prospettico per istanti futuri. Nessuna geocodifica di civici, confini, itinerari o verifica varchi/telecamere.
2. Antismog: sconosciuto non è livello zero
get_active_smog_level:
{"request": {"territory": "Comune di Milano"}}Risposta: decision: "non_determinabile", active_level: null, authority_status: "non_verificato", authoritative_territory: null, valid_from: null, valid_until: null, last_checked: null, freshness: "missing".
evaluated_at è l'ora della chiamata, non la consultazione di un bollettino. Il territorio richiesto non è presentato come ambito di un provvedimento. Le misurazioni ARPA non provano attivazione/revoca; il MVP non converte PM10 in uno stato amministrativo.
3. MoVe-In: solo aritmetica dichiarata
query_movein_allowance:
{"request": {"km_percorsi": "100.1", "soglia_annuale": "100.4", "distanza_viaggio": "0.2"}}Estratto:
{
"decision": "non_determinabile", "calculation_status": "calcolato",
"input_provenance": "user_unverified",
"km_residui": "0.3", "km_eccedenti": "0",
"viaggio_nel_budget_dichiarato": true,
"km_residui_dopo_viaggio": "0.1", "km_eccedenti_dopo_viaggio": "0",
"authenticated_balance": false
}Numeri dimostrativi, non soglie normative. Decimal serializzati come stringhe: preferirle anche negli input. Ammessi 0–1.000.000.000 km, massimo sei decimali (limiti tecnici). Negativi, NaN, infiniti e booleani rifiutati. Sopra soglia il residuo è zero, l'eccedenza esplicita e neppure un viaggio nullo rientra nel budget. Nessun saldo autenticato, rinnovo, soglia spettante o autorizzazione dedotti.
4. Costi non coperti
get_daily_costs:
{"request": {"area": "area_b", "on_date": "2026-09-08", "tariff": "ordinaria"}}Risposta: calculation_status: "non_determinabile", ordinary_ticket_eur: null, total_due_eur: null, activation_deadline_exclusive: null. Non afferma che Area B sia a pagamento: non è calcolato un costo totale per quell'area.
Anche per Area C il risultato attuale è sconosciuto: prove mancanti. Il motore è predisposto per tariffa ordinaria/scadenza solo con fonte verificata per la data; nessuna tariffa reale è abilitata. Tariffe agevolate/sconosciute non diventano ordinarie. Totale dovuto sempre null: non si verifica l'obbligo individuale. Il campo scadenza esclusiva, quando sarà supportato, indica attivazione prima di quell'istante, non una scadenza universale di pagamento.
Fonti, aggiornamento e limiti
Registro fonti: URL, consultazione, regole, periodo e limiti. Catalogo in src/milano_mobility_mcp/sources.py, incluso nel package; nessun aggiornamento automatico o parametro client per sovrascrivere fonti/orologio.
Consultazione dei riferimenti: 8 settembre 2026; nessuna data operativa coperta da regole/tariffe distribuite. Le pagine comunali necessarie hanno restituito HTTP 403; InfoAria soltanto una shell JavaScript. Le pagine Regione/ARPA leggibili documentano cautele e ruoli, non un bollettino attivo. Il motore impone alle future fonti operative una freschezza massima di 24 ore, non una scadenza normativa. Un timestamp nuovo non basta: occorre verifica documentale e temporale. Nessun calendario generale di festivi/sospensioni. Il calcolo MoVe-In è già utilizzabile senza queste fonti mancanti.
Non supportati: storico completo, regole future, tutte le classi/categorie, deroghe e accessi residui, targa, importo personale dovuto, geocodifica, API varchi, funzionamento telecamere, saldo privato MoVe-In, antismog live, pagamento o scraping autenticato. Nessun deploy/acquisto. Repository privato, nessuna licenza aggiunta.
Test e sviluppo
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe -m pytest -q tests\test_mcp_integration.py
.\.venv\Scripts\python.exe -m pip checkSu Unix usare .venv/bin/python e separatori /. Test offline deterministici: calcoli, input invalidi, timezone/DST, confini, fonti mancanti/scadute/periodi, divieto con unknown, costi sconosciuti non zero. Lo smoke avvia veri processi da modulo ed entry point, usa il client SDK per initialize, list_tools, call_tool sui quattro tool, verifica JSON strutturato e sopravvivenza agli input invalidi. CI Windows/Linux, Python 3.11/3.13.
Validazione locale dell'8 settembre 2026: Python 3.13.14, SDK mcp 1.30.0; python -m pytest -q 122 passati, inclusi due smoke stdio reali; python -m pip check senza problemi. Wheel costruita con python -m pip wheel . --no-deps --wheel-dir <directory-artifact> e verificata per package, fonti ed entry point, senza fixture di test. La matrice CI è configurata separatamente: questi risultati locali non attestano da soli gli altri sistemi/interpreti.
Architettura: models.py contratti; catalog.py provenienza/tempo; sources.py snapshot; service.py valutazioni con clock interno; adapters.py indisponibilità antismog; server.py stdio. Nessun log applicativo degli input; stdout solo protocollo MCP.
Prossimi passi: roadmap.
Available Tools
4 toolscheck_vehicle_accessDRead-onlyIdempotent
Profilo/perimetro dichiarati, ora Europe/Rome: nessun divieto abilitato nel catalogo attuale.
Inputs: request (required). Returns: area, reasons, decision, assessments, +6 more
get_active_smog_levelBRead-onlyIdempotent
Stato antismog: adapter non live, restituisce onestamente livello e validità sconosciuti.
Inputs: request (required). Returns: reasons, decision, authority, freshness, +10 more
get_daily_costsCRead-onlyIdempotent
Nessuna tariffa/scadenza abilitata nel catalogo attuale: importi null, mai zero implicito.
Inputs: request (required). Returns: area, on_date, reasons, currency, +8 more
query_movein_allowanceARead-onlyIdempotent
Sottrae km dichiarati con Decimal; NON saldo autenticato né autorizzazione alla circolazione.
Inputs: request (required). Returns: rule, reasons, decision, km_residui, +11 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
Each tool targets a different mobility concept—vehicle access, Move-In allowance, smog level, and daily costs—so an agent can generally select correctly. The only mild ambiguity is between check_vehicle_access and query_movein_allowance, since both concern circulation restrictions.
All names use snake_case and a verb-like prefix, but the verbs are inconsistent: check, query, get, get. This is readable but does not follow a single uniform verb_noun convention.
Four tools is on the lean side but reasonable for a focused Milan mobility server. The count is not bloated, though the domain could justify a few more tools if live functionality were present.
The tools cover four distinct query areas, but the descriptions repeatedly admit to non-live adapters, empty catalogs, and non-authenticated data. This leaves obvious gaps for agents needing real smog levels, actual Move-In balances, enabled restrictions, or applicable fees.
Maintenance
Related MCP Connectors
Official Openapi® MCP server: Italian company data, PEC, SMS, vehicles, geocoding and more APIs.
dati.gov.it MCP — Italy's national open-data portal (CKAN API).
A paid remote MCP for CLI tool MCP, built to return verdicts, receipts, usage logs, and audit-ready
A paid remote MCP for AI SDK data query MCP, built to return verdicts, receipts, usage logs, and aud
Related MCP Servers
AlicenseAqualityDmaintenanceMCP server for checking vehicle routes against Low Emission Zones (ZBE/LEZ) in Spain and Portugal.5MIT- AlicenseNot gradedqualityDmaintenanceEnables consultation of vehicle documents from an official source via a single read-only tool, with prepaid per-query pricing and compatibility across MCP clients.MIT
- AlicenseNot gradedqualityBmaintenanceProvides read-only access to open, verified vehicle brand, model, and specification data (Italy first, later EU) through MCP tools, enabling AI agents and apps to query the dataset programmatically.1Apache 2.0
- AlicenseNot gradedqualityDmaintenanceEnables querying official ECRVSP/RENAINF traffic fine information by license plate, with read-only access and pay-per-query prepaid credit through any MCP-over-HTTP client.MIT