Skip to main content
Glama

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?".

Version française

Tools

Tool

Input

Returns

search_networks

query (city, area or name)

network ids, plus matching networks that are not supported and why

nearby_stations

network_id, lat, lon, limit?, need? (bikes / docks), max_distance_meters?

nearest stations with bikes, e-bikes, free docks and distance

get_station

network_id, station_id

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 -> StationView

Design patterns, by file:

  • Facade: facade.ts hides versions, the feed join, caching and errors behind three calls, shared with the future Expo app.

  • Adapter: feeds/v2.ts and feeds/v3.ts turn each GBFS version into the same records.

  • Cache-Aside with single-flight: fetch/feed-loader.ts caches each feed for its own ttl clamped 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 typed kind.

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 list

Maintainer notes

  • First npm release by hand (pnpm --filter gbfs-france-mcp build, then npm publish in apps/mcp), then set up npm trusted publishing for release.yml. After that, pushing a vX.Y.Z tag 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 tools
get_stationBike station statusB
Read-onlyIdempotent

Live status of one station: bikes, e-bikes, free docks and whether it rents or accepts returns.

NameRequiredDescriptionDefault
network_idYesNetwork id returned by search_networks, e.g. "velib-velos-et-bornes-disponibilite-temps-reel".
station_idYes

Output Schema

NameRequiredDescription
networkYes
stationYes
freshnessYes
attributionYes

TDQS

B3.3/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 stationsA
Read-onlyIdempotent

Nearest stations of one network to a point, with live bikes, e-bikes and free docks. Get network_id from search_networks first.

NameRequiredDescriptionDefault
latYes
lonYes
needNo"bikes" keeps stations renting with bikes left, "docks" stations with free docks.
limitNo
network_idYesNetwork id returned by search_networks, e.g. "velib-velos-et-bornes-disponibilite-temps-reel".
max_distance_metersNo

Output Schema

NameRequiredDescription
networkYes
stationsYes
freshnessYes
attributionYes
droppedStationsYes
outsideNetworkAreaYes
nearestDistanceMetersYes

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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 networksA
Read-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.

NameRequiredDescriptionDefault
limitNo
queryYesCity, area or network name, e.g. "Lyon" or "Vélib".

Output Schema

NameRequiredDescription
networksYes
unsupportedYes
snapshotDateYes

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 3 tool updatesv0.1.4
    • First observedget_station
    • First observednearby_stations
    • First observedsearch_networks

TDQS

A3.6/5.0

Scored across 3 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness3/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides 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
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables 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 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables searching and querying Île-de-France open data datasets (transport, environment, economy, etc.) via natural language or direct tool calls.
    490 npm
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Enables discovery and summarization of public French transport data, including datasets, GTFS resources, regions, networks, and data-quality information, via transport.data.gouv.fr.
    5
    MIT