GBFS France
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., "@GBFS Francefind the 3 nearest Vélib stations with bikes near the Eiffel Tower"
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.
GBFS France
Live bike-share availability for France, for AI assistants. An MCP server that reads the official GBFS feeds listed on transport.data.gouv.fr and answers "where can I get a bike (or drop one) near here?".
Tools
Tool | Input | Returns |
|
| network ids, plus matching networks that are not supported and why |
|
| nearest stations with bikes, e-bikes, free docks and distance |
|
| one station's live status |
All tools are read-only, return structured content (with output schemas) plus a short text, and credit the data producer on every answer.
Example (live data, Vélo'v Lyon):
> search_networks { "query": "Lyon" }
Vélo'v Lyon [stations-velov-de-la-metropole-de-lyon-disponibilites-temps-reel] (467 stations)
Not supported: Autopartage Citiz Métropole de Lyon (not a bike-share network (carsharing))
> nearby_stations { "network_id": "stations-velov-…", "lat": 45.7578, "lon": 4.832, "limit": 3, "need": "bikes" }
3 station(s) on Vélo'v Lyon.
BELLECOUR / ST EXUPÉRY (128 m): 14 bikes, 2 e-bikes, 25 docks [last report over 30 min ago]
PLACE ANTONIN PONCET (187 m): 17 bikes, 3 e-bikes, 22 docks [last report over 30 min ago]
BELLECOUR / RÉPUBLIQUE (202 m): 12 bikes, 7 e-bikes, 2 docks [last report over 30 min ago]
Data: Métropole de Lyon, Licence Ouverte v2.0 (Etalab), https://transport.data.gouv.fr/datasets/…Related MCP server: data-sncf
Install
Requires Node.js 22 or later. In Claude Desktop (claude_desktop_config.json) or any MCP client:
{
"mcpServers": {
"gbfs-france": { "command": "npx", "args": ["-y", "gbfs-france-mcp"] }
}
}Claude Code: claude mcp add gbfs-france -- npx -y gbfs-france-mcp.
Coverage
Docked bike-share networks with an open licence (Licence Ouverte v1/v2, ODbL) and a GBFS 1.x, 2.x or 3.0 feed:
60 networks (snapshot 2026-11-02): Altervélo Saint-Pierre La Réunion (CIVIS), AQTA (Auray Quiberon Terre Atlantique), Auch-Vélo’c Grand Auch, Brennus à Vélo Grand Sénonais, C Vélo Clermont-Ferrand, Calivélo communauté d'agglomération du Libournais (La Cali), Cap Cotentin Vélo, Choletbus 2 Roues Cholet, CYCLOlibre Carcassonne, IDEcycle Pau, Impulsyon La Roche Sur Yon, Karu'vélo Pointe-à-Pitre La Guadeloupe, Le Vélo Baulois La Baule-Escoublac, Le Vélo TBM Bordeaux Métropole, Les petites reines Sables d'Olonne Agglomération, LeVélo Marseille, Libélo Valence Romans, Lovélo Rouen, MontenVélo CC Pays du Mont-Blanc (CCPMB), Naolib Micromob', Naolib Nantes Métropole, NemoVélo Nîmes Métropole, Ogalo Saumur, Optymo Belfort, Périvélo Grand Périgueux, R'Houle ports de Piriac-sur-Mer et de La Turballe, Rubis'Vélo Grand Bourg Agglomération, Semo CA Seine-Eure, STAR Rennes, Tanlib Niort, Tarbes Lourdes Pyrénées (TLP), Tempo Vélo Agen, Ti Vélo Pays de Landerneau-Daoulas, V'lille Lille, Vel'in Grand Calais (SITAC), Vélam Amiens, Vélhop Strasbourg Eurométropole, Vélib Paris et communes limitrophes, Vélibéo CA Bassin de Brive, VéliVert Saint-Etienne, Vélo d'Aqui Argelès-sur-mer, Vélo Fluo Grand Est, Vélo Modalis Grand Angoulême, Vélo'Cité Laon, Vélo'v Lyon, VéloCité Besançon, VéloCité Mulhouse, Vélomagg Montpellier Méditerranée Métropole, VéloMoove Bassin de Pompey, Velonecy Grand Annecy, Velopop’ Avignon, VélOstan’lib Nancy, VélôToulouse Toulouse Métropole, VéloZef Brest, VélYcéo Saint-Nazaire, Vernou-en-Sologne (Vernou Vélo), Vertuose Grand Longwy, ViVélo Vichy Communauté, Vivolt agglomération d'Epinal, Zébullo Grand Reims.
Not served yet: free-floating operators (Lime, Dott, Pony), scooters, car sharing, and datasets published without a licence. search_networks names them with the reason.
Data and licences
Network list: transport.data.gouv.fr (national access point). Availability: each operator's GBFS feed, fetched live. Every answer returns the publisher, licence and dataset page, as ODbL and Licence Ouverte require. Station counts are what operators publish: null means unknown, stations not reporting for 30 minutes are flagged outdated.
How it works
apps/mcp (stdio) -> packages/gbfs-core: createGbfsFrance()
catalog.json (committed snapshot, rebuilt weekly)
discovery -> adapter v2 (1.x/2.x) | v3 (3.0)
feed loader: cache, single-flight, timeout, stale-if-error
join station_information x station_status -> StationViewDesign patterns, by file:
Facade:
facade.tshides versions, the feed join, caching and errors behind three calls, shared with the future Expo app.Adapter:
feeds/v2.tsandfeeds/v3.tsturn each GBFS version into the same records.Cache-Aside with single-flight:
fetch/feed-loader.tscaches each feed for its ownttlclamped per feed kind (live status 30-60 s), merges concurrent identical requests, serves the last good data up to 10 min when an operator fails, and keeps at most 64 feeds (LRU).Result type: the facade never throws on data failures; it returns
{ ok: false, error }with a typedkind.
The core has no Node imports and avoids APIs missing on Hermes (React Native), enforced by ESLint.
Development
fnm use # Node 24 from .nvmrc
pnpm install
pnpm lint && pnpm typecheck && pnpm test
pnpm build # apps/mcp/dist/index.js
pnpm catalog # rebuild the network snapshot and this listMaintainer notes
First npm release by hand (
pnpm --filter gbfs-france-mcp build, thennpm publishinapps/mcp), then set up npm trusted publishing forrelease.yml. After that, pushing avX.Y.Ztag publishes to npm (with provenance) and to the MCP registry.GitHub turns off scheduled workflows after 60 days without activity: merging the weekly catalog PR keeps them running.
Follow-ups are in TODOS.md.
License
MIT. Data stays under each producer's licence.
Available Tools
3 toolsget_stationBike station statusBRead-onlyIdempotent
Live status of one station: bikes, e-bikes, free docks and whether it rents or accepts returns.
| Name | Required | Description | Default |
|---|---|---|---|
| network_id | Yes | Network id returned by search_networks, e.g. "velib-velos-et-bornes-disponibilite-temps-reel". | |
| station_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| network | Yes | |
| station | Yes | |
| freshness | Yes | |
| attribution | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint and openWorldHint, so safety and repeatability are covered. The description adds the useful 'live'/real-time qualifier and lists what status fields are surfaced, but says nothing about what happens for an unknown station_id or about rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the resource first and the returned fields after the colon. No filler, no repetition of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Since an output schema exists, the description needn't explain return values, and the live-status framing is enough on that front. However, for a 2-required-parameter tool with an entirely undocumented station_id, the definition leaves the agent guessing where that identifier comes from.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 50%: network_id is documented inline (including its source tool), while station_id has no schema description whatsoever. The description does not mention any parameter and so fails to compensate for that gap, e.g. by explaining that station_id must come from nearby_stations or how it is formatted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (one station) and enumerates the state it returns (bikes, e-bikes, free docks, rental/return capability), which clearly separates it from the list-style siblings search_networks and nearby_stations. It does not explicitly name those siblings, so it stops short of full disambiguation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"One station" implies the tool is for a known station id, which is useful implied guidance, but there is no explicit when-to-use vs. when-to-use-nearby_stations statement and no pointer to how a station_id should be obtained. Nothing actively misleading, just under-specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nearby_stationsNearby bike stationsARead-onlyIdempotent
Nearest stations of one network to a point, with live bikes, e-bikes and free docks. Get network_id from search_networks first.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| need | No | "bikes" keeps stations renting with bikes left, "docks" stations with free docks. | |
| limit | No | ||
| network_id | Yes | Network id returned by search_networks, e.g. "velib-velos-et-bornes-disponibilite-temps-reel". | |
| max_distance_meters | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| network | Yes | |
| stations | Yes | |
| freshness | Yes | |
| attribution | Yes | |
| droppedStations | Yes | |
| outsideNetworkArea | Yes | |
| nearestDistanceMeters | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so safety behavior is covered. The description adds real value by disclosing that results carry live availability (bikes, e-bikes, free docks) and that the search is confined to a single network. It says nothing about ordering, distance units, or how the default limit/distance caps behave.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The what-it-returns content is front-loaded and the prerequisite follows, which is the right order for an agent skimming for capability first, then constraints.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value detail is unnecessary here, and annotations cover the safety profile. For a 6-parameter spatial query the remaining gaps (distance units, result ordering, default limit behavior) are modest but real.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 33%, so the schema documents just 'need' and 'network_id' while lat, lon, limit and max_distance_meters are bare. The description compensates partially by framing the operation as 'nearest ... to a point,' which gives meaning to the coordinate pair and the distance-based ranking, but it adds nothing for limit or max_distance_meters beyond their self-descriptive names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Nearest stations of one network to a point') plus what the result carries ('live bikes, e-bikes and free docks'), which is far more than the name alone. It implicitly separates itself from search_networks by naming it as a prerequisite, but never explicitly contrasts itself with the other sibling, get_station.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete prerequisite and call ordering: 'Get network_id from search_networks first,' which is the key sequencing decision for an agent. It stops short of stating exclusions or when to prefer get_station for a single known station, so no 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_networksSearch French bike-share networksARead-onlyIdempotent
Find docked bike-share networks by city, area or name. Returns network ids for nearby_stations and get_station, plus matching networks that are not supported and why.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | City, area or network name, e.g. "Lyon" or "Vélib". |
Output Schema
| Name | Required | Description |
|---|---|---|
| networks | Yes | |
| unsupported | Yes | |
| snapshotDate | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds one genuinely new behavioral fact — that results include unsupported networks with a reason — but says nothing about ordering, result count behavior, or how the limit interacts with that unsupported list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no waste; the core search capability is front-loaded and the return-value note follows immediately. Nothing could be removed without losing routing or contract information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-shape detail is unnecessary, and the description still flags the non-obvious 'unsupported + why' payload. The only gap is the unexplained limit parameter (default 5, max 20), which matters for an open-world search that may match many networks.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: 'query' is documented in the schema itself, and 'limit' carries only min/max/default with no prose. The description's 'by city, area or name' merely restates the query parameter's own description and adds no meaning for 'limit', so the schema is doing essentially all the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Find docked bike-share networks') and enumerates the matching dimensions (city, area, name). It also clarifies the output contract ('network ids') and the downstream tools it feeds, so an agent knows exactly what this tool produces versus the station-level siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
By saying it returns network ids 'for nearby_stations and get_station', it implicitly establishes itself as the prerequisite discovery step before those tools. That is clear contextual guidance, though it never states explicit exclusions or when not to use it (e.g., if you already have a network id).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.4- First observed
get_station - First observed
nearby_stations - First observed
search_networks
TDQS
Scored across 3 tools
Each tool has a distinct scope: network discovery, single-station status, and nearby-station lookup. The only mild overlap is spatial search (search_networks by area vs. nearby_stations), but the descriptions clarify the network-vs-station granularity and prerequisite network_id.
search_networks and get_station follow a clear verb_noun pattern, while nearby_stations is an adjective_noun phrase. The deviation is minor and still readable, since all names are snake_case and intuitively describe their action or result.
Three tools is well-scoped for a focused read-only GBFS France server. Each tool covers a distinct need—network discovery, station status, and proximity lookup—without bloat or missing obvious companions.
The surface covers network search and live station status/proximity, but there are notable gaps such as station lookup by name or id without relying on nearby search, listing all stations in a network, and retrieving network-level metadata. These gaps may force workarounds for common queries.
Maintenance
Related MCP Connectors
Mobility, geocoding and nearby urban services for AI agents.
Plan door-to-door trips across French trains, buses, transit and flights.
French open data: communes, parcels, risks, property sales, water, crime, planning.
French address quality, geocoding, routing, company lookup & catchment stats (BAN, INSEE, OSM).
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides real-time access to Montreal's Bixi bike-sharing data through the GBFS API. Enables querying station information, availability, nearby stations, and system alerts.MIT
- AlicenseNot gradedqualityBmaintenanceEnables querying SNCF Open Data (train schedules, stations, punctuality, etc.) through natural language or direct tool calls, with dataset search, metadata retrieval, and ODSQL querying.11 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables searching and querying Île-de-France open data datasets (transport, environment, economy, etc.) via natural language or direct tool calls.490 npmMIT
- AlicenseBqualityBmaintenanceEnables discovery and summarization of public French transport data, including datasets, GTFS resources, regions, networks, and data-quality information, via transport.data.gouv.fr.5MIT