mcpField
B
Bike Router

Bike Router

本地服务
github.com地图与出行02 天前更新

关于 Bike Router

Bike Router 是面向骑行者、基于 OSM 的可自托管路线规划器,提供 Web 界面、API 和命令行。它依据路线引擎数据并明确呈现不确定性,不会猜测含糊地点或路线细节。

主要功能

  1. 01基于 OSM 的骑行路线规划
  2. 02支持多种路线与地理编码服务
  3. 03路线评分与说明
  4. 04导出 GeoJSON 和 GPX
  5. 05Web 规划器、API 与命令行

适用场景

  1. 01按起点、终点和车型规划骑行
  2. 02在规划前确认含糊的地点名称
  3. 03比较路线选项及其地图元数据
  4. 04将规划路线导出为 GeoJSON 或 GPX

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"jonasheinickebio-bike-router": {
"command": "uvx",
"args": [
"bike-router"
],
"env": {
"BIKE_ROUTER_API_URL": "<BIKE_ROUTER_API_URL>"
}
}
}
}
启动命令uvx bike-router
需要配置的环境变量
BIKE_ROUTER_API_URLAddress of the running pyBikeRouter API this server asks (http or https).

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypibike-router0.3.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

bike-routing-agent

CI

一个基于 OSM 的骑行路线规划服务:包含类型化、与服务提供商无关的领域模型、 完整的 openrouteservice API 客户端及路线规划适配器,以及一个 LangGraph 工作流,可将经过验证的路线请求转换为可解释、可导出的骑行路线。

LLM(如使用)可以解析自由文本、提出澄清问题并解释所选路线。它不会凭空编造坐标、几何形状、高程或路线适用性——所有这些都来自基于 OSM 的路线引擎。

轻松安装(无需编程)

从 Releases 页面下载 pybikerouter-easy-<version>.zip,解压,安装 Docker Desktop,然后双击适用于你电脑的 Start 文件。首次启动时会询问一个问题——你在哪里骑行——随后下载该区域的地图数据,并在浏览器中打开规划器。以下是简单明了的分步说明: docs/easy-install.md(以及下载包中的 START-HERE.txt)。

文档

完整文档集位于 docs/:

文档内容
架构图节点、状态、分支、终止状态、错误模型
API端点契约、响应状态、产物提供
配置所有环境变量、验证规则、部署说明
服务提供商协议、ORS 客户端/适配器行为、地理编码器、BRouter/Valhalla 适配器、添加后端
后端比较按自行车类型测得的 ORS 与 BRouter 行为、结合两种引擎
地理编码Nominatim 与 Pelias、置信度/歧义语义、调优
评分与导出评分计算、不确定性策略、解释规则、GeoJSON/GPX
用文字规划用一句话描述骑行路线;可选的 LLM 会将其转换为结构化请求(绝不生成坐标)
天气出发时间沿途的天气预报:温度、降雨、相对于骑行方向的风(免费、无需密钥的服务提供商)
可自托管的技术栈使用一份 OSM 提取数据在本地运行路线规划和/或地理编码;硬件要求及小型 PC 选项
测试测试布局、模拟约定、实时测试、CI
网页规划器将地点添加到行程中;点击地图上的某个点,并选择它在路线中的位置
iPhone/Tailscale通过 tailnet 将规划器作为主屏幕应用在 iPhone 上使用
路线图计划中的工作和明确的非目标

架构

FastAPI
  |
  v
LangGraph RouteAgentState
  |
  +--> parse_request        (structured input first; LLM extraction is an injectable dependency)
  +--> validate_request      (Pydantic)
  +--> geocode_locations     (Nominatim by default, public or self-hosted; ambiguity -> clarification, never a guess)
  +--> route_with_provider   (openrouteservice; engine-neutral RoutingRequest in, RouteCandidate out)
  +--> score_candidates      (deterministic distance/elevation/warning scoring)
  +--> explain_and_export    (facts-only explanation + GeoJSON/GPX export)
  |
  v
JSON response + GeoJSON/GPX artifacts

图分支:

START -> parse_request
      -> validate_request -> (invalid | awaiting_clarification) -> END
      -> geocode_locations -> (awaiting_clarification | provider_failure) -> END
      -> route_with_provider -> (no_route | provider_failure) -> END
      -> score_candidates -> (no_route) -> END
      -> explain_and_export -> END

每条路径都会以明确的 status 结束;只有验证和地理编码均成功后,图才会调用路线规划服务提供商,并且始终会以终止状态返回。

设置

需要 Python 3.11+ 和 Poetry。

poetry install
cp .env.example .env

poetry install 会在项目内创建虚拟环境(.venv/,参见 poetry.toml),并安装运行时和开发依赖项。使用 poetry run <command> 在其中运行任意命令,或运行 poetry shell 直接激活环境。

编辑 .env 并将 ORS_API_KEY 设置为有效的 openrouteservice API 密钥。

环境变量
变量用途默认值
ORS_API_KEYopenrouteservice API 密钥(实时路线规划必需)
ORS_BASE_URLopenrouteservice 基础 URLhttps://api.openrouteservice.org
ORS_TIMEOUT_SORS 请求超时时间(秒)10.0
ORS_MAX_RETRIES超时或 5xx 错误时的重试次数2
GEOCODER_PROVIDER地理编码器后端:nominatim(公共或可自托管)或 pelias(需要在 ORS_BASE_URL 后配置 Pelias API,参见 docs/geocoding.md;启动时会拒绝使用公共 ORS URL)nominatim
GEOCODER_BASE_URLNominatim 基础 URL(当 GEOCODER_PROVIDER=pelias 时忽略)https://nominatim.openstreetmap.org
GEOCODER_TIMEOUT_S地理编码器请求超时时间5.0
GEOCODER_USER_AGENTNominatim 使用政策要求的值bike-routing-agent/0.1
GEOCODER_CACHE_TTL_S内存中的地理编码缓存 TTL3600
GEOCODER_AMBIGUITY_MARGIN前两个结果被视为“有歧义”时的置信度差值上限0.05
GEOCODER_MIN_CONFIDENCE自动接受排名第一结果所需的最低置信度0.3
VALHALLA_BASE_URL可自托管的 Valhalla(meili)服务基础 URLhttp://localhost:8002
VALHALLA_TIMEOUT_S每个 Valhalla 请求的超时时间(秒)30.0
VALHALLA_MAX_RETRIESValhalla 超时或 5xx 错误时的重试次数1
EXPORT_DIR存放 GeoJSON/GPX 产物的本地目录exports
DATABASE_URLPostgreSQL/PostGIS URL:记录路线历史记录,启用 /v1/history/*(docs/persistence.md)未设置
ARTIFACT_BACKENDlocal 或 database(产物存储在 PostgreSQL 中)local
LOG_LEVEL日志级别INFO

运行 API

poetry run uvicorn bike_routing_agent.api:app --reload

应用还会在 http://localhost:8000/ 提供内置 Web UI(基于地图的路线规划器),交互式 API 文档位于 /docs。

命令行界面

安装软件包后会提供 bike-router 命令(也可通过 python -m bike_routing_agent.cli 运行),命令按子命令组组织:

bike-router route plan --origin "Berlin Hbf" --destination "Potsdam" \
    --bike-type gravel --target-distance-km 30 --output plan.json
bike-router serve start --port 8000
bike-router docker up            # docker compose -f docker/compose.yaml up -d --build
bike-router docker logs -f
bike-router config show          # effective settings, secrets redacted
bike-router config check         # validate settings against the environment
bike-router providers list       # provider names and bike-type -> ORS profile map
bike-router route plan ... --format text --gpx best.gpx   # alternatives, sight stops, exports
bike-router route show plan.json # a saved plan again; `route export` writes any alternative
bike-router poi along --route plan.json   # sights near a route, ranked by fame
bike-router brouter needed|info|download  # BRouter map tiles (asks before downloading)
bike-router history list|show|stats       # past plans (needs DATABASE_URL)
bike-router status show          # readiness of every component and the active features
bike-router chat start           # plan routes by chatting (docs/chat.md)

API 和 Web 表单支持的所有功能都可通过 CLI 使用——参见 docs/cli.md。

route plan --text "50 km gravel loop from Braunschweig" 使用可选的 LLM 解析器(docs/llm-parser.md)。

route plan 接受 lat,lon 坐标对或地点文本,用于 --origin、 --destination 和可重复指定的 --via 路径点;命令会输出 JSON 结果,并在状态为 ready 时以退出码 0 退出,在需要澄清或提供方失败时以 1 退出,在用法错误时以 2 退出。设置 DATABASE_URL 后,还会尽力将规划记录到路线历史记录中(输出包含 plan_id,可使用 --no-record 跳过记录),并提供路线沿线在 --departure-time 的天气预报(docs/weather.md);bike-router db migrate / db status 用于管理数据库架构(docs/persistence.md)。

使用 Docker 运行

所有容器相关资源都位于 docker/:

cp .env.example .env        # set ORS_API_KEY
docker compose -f docker/compose.yaml up --build

打开 http://localhost:8000/ 使用 Web UI。路线产物存储在名为 pybikerouter-exports 的卷中。可选的本地路线规划/地理编码技术栈详见 docs/self-hosted.md,其中包括所需条件,以及如何在小型机器上仅运行其中一部分。

请求示例
curl -X POST http://localhost:8000/v1/route/plan \
  -H 'Content-Type: application/json' \
  -d '{
    "origin": "Braunschweig Hauptbahnhof",
    "destination": "Wolfenbüttel",
    "constraints": {
      "bike_type": "gravel",
      "avoid_high_traffic_roads": true,
      "max_ascent_m": 500
    }
  }'
响应示例
{
  "status": "ready",
  "route": {
    "provider": "ors",
    "provider_profile": "cycling-regular",
    "geometry_geojson": {"type": "LineString", "coordinates": []},
    "metrics": {
      "distance_m": 12500,
      "duration_s": 2700,
      "ascent_m": 85,
      "descent_m": 90,
      "surface_coverage": {},
      "unknown_surface_fraction": null
    },
    "score": 0.91,
    "score_breakdown": {"distance_fit": 1.0, "elevation_fit": 1.0, "warning_penalty": 0.0},
    "warnings": [],
    "provenance": {"provider": "ors", "profile": "cycling-regular"}
  },
  "candidates": [
    {"provider": "ors", "provider_profile": "cycling-regular", "score": 0.91},
    {"provider": "brouter", "provider_profile": "trekking", "score": 0.84}
  ],
  "explanation": "...",
  "artifacts": {
    "geojson_url": "/v1/routes/<id>.geojson",
    "gpx_url": "/v1/routes/<id>.gpx"
  },
  "clarification": [],
  "errors": []
}

如果 origin/destination 有歧义或无法解析,status 将为 awaiting_clarification,而 clarification 会列出可供选择的候选地点——不会根据猜测生成路线。

自行车类型

constraints.bike_type 按引擎选择路由配置文件,默认值为 gravel。支持的值:road、gravel、touring、mountain、city、 ebike、commuter(快速、低交通量)、recumbent。ORS 提供四种骑行 配置文件,例如,ebike 使用 cycling-electric,而 commuter 使用 cycling-regular;可自托管的 BRouter 提供商区分得更细—— gravel、touring、mountain、city、commuter 和 recumbent 各自使用 独立的配置文件,而 road 和 ebike 共用 fastbike(BRouter 没有 电助力成本模型)(参见 docs/configuration.md)。

Make 目标

make 会列出日常命令;这些命令使用项目的 .venv(或当前激活的环境):

make install       # poetry install
make hooks         # the git hooks (commit: lint + types; push: the whole suite)
make run           # the API with auto-reload (HOST=127.0.0.1 PORT=8000)
make check         # lint + types + tests without coverage, stops at the first failure
make ci            # what CI runs: lint, types, tests with the 80 % coverage floor
make test-fast ARGS="tests/nodes -k geocode"     # a part of the suite (no coverage floor)
make deploy        # build and restart the local container (bike-router deploy up)

代码检查和类型检查

poetry run ruff check .
poetry run mypy src

每次推送和拉取请求时,CI 都会运行这两项检查(参见 .github/workflows/ci.yml)。

运行测试

poetry run pytest

每次运行都会收集覆盖率,且测试套件的覆盖率低于 80% 时会失败 (tool.pytest.ini_options.addopts 中的 --cov-fail-under=80;当前总覆盖率为 97%, 每个模块均 ≥84%)。

访问真实外部服务的实时测试标记为 @pytest.mark.live, 默认不运行(参见 pyproject.toml 中的 tool.pytest.ini_options.addopts)。显式运行这些测试:

poetry run pytest -m live

Pre-commit 钩子

每次提交或推送前,pre-commit 都会自动运行质量检查。 执行 poetry install 后,安装这两个 git 钩子阶段:

poetry run pre-commit install --hook-type pre-commit --hook-type pre-push

提交时会运行空白字符/EOF/YAML/TOML/合并冲突/大文件检查、 ruff check --fix 和 mypy src;完整的 pytest 测试套件仅在 git push 时的 pre-push 阶段运行(与 CI 保持一致)。使用 poetry run pre-commit run --all-files 手动运行 commit 阶段,使用 poetry run pre-commit run --hook-stage pre-push --all-files 运行 pre-push 阶段。

已知限制

  • OSM 标签的完整性因地区而异;地表/通行权限元数据经常缺失,并会 表示为不确定性,而非视作有利条件。
  • 路由引擎(ORS、Valhalla、BRouter)将自行车类别映射到各自配置文件的方式 不同;config.py 中的映射是近似值,尤其是碎石路骑行。
  • 不同提供商的海拔数据(爬升/下降)准确度各异,且不一定始终可用。
  • 此服务生成的路线均不构成安全保证。说明会使用谨慎措辞(“与现有地图元数据 更为吻合”),而非“安全路线”之类的说法。
  • BRouter 和 Valhalla 已完成端到端接入,但仅支持可自托管的部署 (ROUTING_PROVIDER=brouter / valhalla / all; BRouter 通过 compose 配置文件接入,详见 docker/brouter/README.md),而 openrouteservice 仍是默认引擎。
  • Pelias 地理编码选项需要在 <ORS_BASE_URL>/pelias/v1 提供 Pelias API: 公共服务 api.openrouteservice.org 和标准的可自托管 ORS 均不提供此 API, 且该适配器仅针对模拟对象进行过测试(参见 docs/geocoding.md)。 如需在本地使用地理编码器,请使用可自托管的 Nominatim。

仓库结构

src/bike_routing_agent/
├── api.py            FastAPI app (POST /v1/route/plan)
├── config.py          Settings + provider profile mapping
├── models.py          Pydantic v2 domain models
├── state.py            LangGraph RouteAgentState
├── graph.py            LangGraph wiring
├── errors.py           Structured provider/geocoding errors
├── providers/         GeocodeProvider / RoutingProvider adapters
│                      (ors_client.py: full ORS client -- directions, export,
│                       isochrones, matrix, snap, POIs, Vroom, elevation,
│                       Pelias geocoding, health; ors.py: the RoutingProvider;
│                       geocoder.py: Nominatim; pelias.py: Pelias on
│                       self-hosted ORS)
├── nodes/              One module per graph node
├── scoring/            Deterministic route scoring
├── exporters/          GeoJSON / GPX export
├── frontend/           Static web UI served at /
└── cli/                bike-router command line (route/serve/docker/config/providers)
docker/                 Dockerfile + compose.yaml
tests/
├── fixtures/           Sample provider responses
├── nodes/               One test module per graph node
├── providers/          Adapter unit tests (mocked HTTP)
├── graph/              Graph branch tests
├── exporters/          Export format tests
└── live/                Tests marked @pytest.mark.live
docs/                   Documentation suite (see docs/README.md)

许可证

MIT,详见 LICENSE。

第三方许可证

本项目基于 BRouter(MIT)和 OpenStreetMap 数据(ODbL)构建,并在 THIRD_PARTY_LICENSES.md 中致谢,同时附有完整的 BRouter 许可证文本。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。