关于 OpenStreetMap
OpenStreetMap 是面向旅行规划和地点查询的只读 MCP 服务。它通过公共 OSM 服务提供地理编码、按出行方式计算路线、路线优化、等时圈和兴趣点查询,默认无需 API 密钥。
主要功能
- 01地理编码与反向地理编码
- 02步行、驾车和骑行路线
- 03路线矩阵与停靠点优化
- 04可达范围等时圈
- 05附近兴趣点搜索与详情
- 06工具筛选和结构化结果
适用场景
- 01查找坐标和附近地点
- 02比较不同出行方式的耗时
- 03规划多站点行程
- 04查找指定时间内可到达的区域
MCP 相关
它向 MCP 客户端提供 11 个只读工具,也可通过配置启用精选的 6 个工具。结果包含结构化内容和 Schema。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y osm-mcpOSM_USER_AGENTIdentifying User-Agent sent to all OSM services (Nominatim requires one)ORS_API_KEY密钥Optional OpenRouteService key; switches routing/matrix/isochrones to ORSOSM_ALLOW_TOOLSComma-separated tool names or list_* prefixes to register; 'essential' selects a curated preset (default: all tools)OSM_DENY_TOOLSComma-separated tool names or list_* prefixes to remove from whatever OSM_ALLOW_TOOLS left本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
11收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | integer | 否 | 结果的最大数量,默认值为 3 |
| query | string | 是 | 地点名称或地址 |
| language | string | 否 | 地点名称使用的语言(IETF 代码,例如 "en" 或 "de"),默认值为 "en" |
| provider | enum | 否 | 要使用的地理编码器,默认值为 nominatimnominatim | photon |
| countrycodes | string | 否 | 限制国家/地区:以逗号分隔的 ISO 3166-1 alpha-2 代码,例如 "de,lu"(仅限 Nominatim) |
详细介绍
osm-mcp
一个用于旅行规划的 OpenStreetMap Model Context Protocol(MCP)服务。
它让 Claude Code、Claude Desktop 或 Codex 等 MCP 客户端能够回答有关地点的问题:地理编码、步行、驾车和骑行距离及耗时、多站点路线优化、等时圈和兴趣点搜索——共 11 个工具,且全部为只读工具。
11 个工具是上限,而非最低数量:设置 OSM_ALLOW_TOOLS=essential 可改为注册经过精选的 6 个工具。相比 11 个工具,模型从 6 个工具中更容易可靠地选出合适的工具——请参阅选择要加载的工具。
所有后端都是免费的 OpenStreetMap 公共服务,因此无需 API 密钥。也可以选择提供 OpenRouteService 密钥来切换路由引擎。
它的不同之处
- 准确的步行/骑行路线。 OSRM 公共演示服务器会忽略 OSRM URL 路径中的配置段,除非使用 FOSSGIS 的
routed-foot/routed-bike/routed-car路径前缀,否则始终返回驾车路线。大多数现有的 OSM MCP 服务都未能正确处理这一点,因此会在步行查询时悄悄返回驾车耗时。本服务使用这些前缀,并通过实时冒烟测试断言步行路线耗时远高于驾车路线。 - 从设计上确保符合政策。 按服务进行速率限制(Nominatim 和 OSRM:每秒 1 个请求);每个请求都带有标识性 User-Agent(Nominatim 使用政策的要求);缓存响应;限制 Overpass 并发量(2 个槽位);并在除查询格式错误之外的任何情况下,自动故障转移到下一个 Overpass 端点,每次调用的总预算为 50 秒。
- 支持 Photon。 可选使用 komoot 的 Photon 进行容错地理编码。Photon 专为交互式使用而设计,比频繁请求 Nominatim 更适合由大模型驱动的查询。
要求
- Node.js ≥ 22
- 可访问互联网,以使用 OpenStreetMap 公共服务(见下表)
配置
每个变量都是可选的——服务开箱即用。
| 变量 | 默认值 | 描述 |
|---|---|---|
OSM_USER_AGENT | osm-mcp/<version> (+https://github.com/ni-c/osm-mcp) | 发送给每个服务的 User-Agent。Nominatim 要求使用真实且可识别的 User-Agent。 |
NOMINATIM_BASE_URL | https://nominatim.openstreetmap.org | 地理编码/反向地理编码 |
PHOTON_BASE_URL | https://photon.komoot.io | 可容忍拼写错误的地理编码 |
OSRM_BASE_URL | https://routing.openstreetmap.de | 路线规划、矩阵和行程优化。必须提供 routed-{car,bike,foot} 路径前缀(FOSSGIS 布局)。 |
OVERPASS_BASE_URL | https://z.overpass-api.de/api/interpreter,https://lz4.overpass-api.de/api/interpreter | 以逗号分隔的 Overpass 端点,按顺序尝试,直到其中一个响应(查询格式错误时会停止尝试) |
VALHALLA_BASE_URL | https://valhalla1.openstreetmap.de | 等时圈 |
ORS_API_KEY | – | 可选的 OpenRouteService 密钥(机密)。设置后,路线、矩阵和等时圈将使用 ORS,而非 OSRM/Valhalla。免费套餐:每天 2000 次路线查询,每分钟 40 次。 |
ORS_BASE_URL | https://api.openrouteservice.org | OpenRouteService 端点 |
OSM_CACHE_TTL | 3600 | 相同的上游响应从内存缓存中提供的秒数(0 表示禁用缓存) |
OSM_ALLOW_TOOLS | no | 以逗号分隔的工具名称、list_* 前缀,或用于精选预设的 essential |
OSM_DENY_TOOLS | no | 语法相同;从 OSM_ALLOW_TOOLS 保留的工具中移除指定项 |
选择要加载的工具
OSM_ALLOW_TOOLS 和 OSM_DENY_TOOLS 接受以逗号分隔的工具名称;末尾的 * 可匹配整个系列。essential 是精选的 6 个工具预设:geocode、reverse_geocode、find_nearby_pois、poi_details、route、map_link。
OSM_ALLOW_TOOLS=essential
OSM_ALLOW_TOOLS=geocode,route,find_nearby_pois
OSM_DENY_TOOLS=isochrone,optimize_route
如果某个条目与任何工具都不匹配,启动就会中止并指出该条目,因此拼写错误不会悄悄隐藏工具——没有人会把缺失的工具追溯到环境变量。经过筛选的工具永远不会注册,因此它们既不会出现在 tools/list 中,也无法通过 tools/call 调用。
如果你同时运行多个此类服务,mcp-hub 是另一种解决方案——它的 /hub 端点会用 6 个元工具取代所有服务的工具。
安装
Claude Code
claude mcp add osm -- npx -y osm-mcp
Claude Desktop
claude_desktop_config.json:
{
"mcpServers": {
"osm": {
"command": "npx",
"args": ["-y", "osm-mcp"]
}
}
}
Codex
~/.codex/config.toml:
[mcp_servers.osm]
command = "npx"
args = ["-y", "osm-mcp"]
Docker
支持多架构,并包含 SBOM 和构建来源证明:
docker run -i --rm ghcr.io/ni-c/osm-mcp
必须使用 -i——协议通过 stdin 和 stdout 运行。无需发布端口。更多客户端配置示例请参阅客户端指南。
通过 mcp-hub
无法启动本地进程的客户端——ChatGPT connectors、Claude on the web、Cursor、LibreChat——可通过 mcp-hub 连接 osm-mcp:一个容器即可通过 Streamable HTTP 提供多个 stdio MCP 服务,并通过单个密码登录,使用 OAuth 2.1;对于无法使用 OAuth 的客户端,还可使用长期有效的令牌。它的 /hub 端点会将所有服务置于 6 个元工具之后,因此一个连接器就能访问所有服务,无需在模型上下文中放入 N×工具架构;它也支持两个协议修订版本——本服务提出的问题会经由它传递给另一端的用户。
它的 /config/mcp.json 使用 Claude Code 的格式,因此条目就是你已有的那一个:
{
"mcpServers": {
"osm": {
"command": "npx",
"args": ["-y", "osm-mcp"],
"env": { "OSM_ALLOW_TOOLS": "essential" },
"denyTools": ["isochrone"]
}
}
}
其中的 allowTools 和 denyTools 是 hub 自己针对各服务的筛选器,与 env 中的 *_ALLOW_TOOLS 并不相同——两者的区别及其容易引发的错误,详见客户端指南。
工具
| 工具 | 描述 |
|---|---|
geocode | 地名/地址 → 坐标(Nominatim 或 Photon) |
reverse_geocode | 坐标 → 最近的地址 |
route | 计算 2 个或更多途经点之间的距离和耗时,支持 foot/car/bike;可选提供逐向导航摘要 |
route_matrix | 一次调用即可计算每个出发点到每个目的地的行程时间/距离 |
optimize_route | 一组停靠点的最佳访问顺序(旅行商问题、OSRM trip) |
isochrone | 在给定时间或距离范围内可到达的区域(Valhalla,或使用密钥的 ORS) |
find_nearby_pois | 按类别或原始 OSM 标签查找位置周边的 POI,并按距离排序(Overpass) |
poi_details | 单个元素的完整 OSM 记录:营业时间、网站、电话等 |
suggest_meeting_point | 为 2–8 人推荐公平的会面地点(平衡行程时间) |
straight_line_distance | 离线计算的大圆距离 |
map_link | openstreetmap.org 标记/路线链接,离线计算 |
每个地点输入都可使用地名/地址(自动进行地理编码),也可直接使用 "lat,lon" 格式的坐标。
结构化输出
每个工具都声明了 outputSchema,并在文本块旁附带 structuredContent 作为答复,因此客户端无需解析散文即可使用结果:
{
"untrusted": true,
"source": "openstreetmap",
"profile": "foot",
"engine": "osrm",
"waypoints": ["Berlin Hauptbahnhof", "Brandenburger Tor"],
"distance": "2.3 km",
"distance_m": 2317,
"duration": "29 min",
"duration_s": 1740,
}
每个工具都带有 untrusted: true 和 source: "openstreetmap"——没有例外,因为任何人都能编辑 OpenStreetMap,而且这里没有任何工具会返回其他内容。否则,只读取结构化部分的客户端就会在完全没有说明的情况下收到地图编辑者的自由文本。
本服务计算的内容——距离、时长、坐标、运行的路由引擎——都有明确描述。来自 OSM 的内容虽有描述,但保持开放:标签命名空间没有架构,而且地图编辑者添加 payment:bitcoin 不应导致 poi_details 停止服务。SDK 会在每个结果发出前根据其架构进行验证,因此收紧数据形状只会造成这种后果。
本服务一直以来对文本执行的控制字符和双向文本清理,现在也会逐个键地应用于结构化值。过去,这项处理是在序列化后的 JSON 上进行,因此其中的每个字符串都会自动得到处理。
使用政策与署名
本服务会访问社区共享基础设施。它会在客户端执行已公布的限制,但运营方请求用户保持整体使用量较低,并仅用于非商业用途:
- 数据:© OpenStreetMap 贡献者,采用 ODbL 1.0 许可。
- **Nominatim:**最多每秒 1 个请求,必须使用可识别身份的 User-Agent,并缓存结果(政策)。
- **OSRM / Valhalla (FOSSGIS):**合理的非商业用途;最多每秒 1 个请求(关于)。
- **Overpass:**每个 IP 约有 2 个并发请求名额,每天少于 10 000 次查询(Wiki)。
- **Photon:**公平使用(photon.komoot.io)。
如需大量或商业用途,请自托管这些服务,并将 *_BASE_URL 变量指向你自己的实例。
有意不提供的功能
**不支持编辑。**所有 11 个工具对 OpenStreetMap 都是只读的;完全没有接入编辑 API,因此不存在可关闭的写入模式。
**不提供渲染和跟踪。**结果是结构化数据和链接,而非图像——map_link 会提供一个 URL,供你自行查看地图——且调用之间不会保留状态。
**不支持离线模式。**每个答复都来自公共 OpenStreetMap 服务,并受其使用政策约束。
安全
- 所有工具均为只读;本服务绝不会写入 OpenStreetMap。
- 不需要凭据;加载后,可选的
ORS_API_KEY会从进程环境中移除,并在错误消息中遮蔽。 - 工具结果会将来自 OSM 的内容(名称、地址、标签)标记为不可信数据,以便模型将其视为数据而非指令。
- 上游错误响应正文会被截断,HTML 错误页面会在到达模型上下文前被丢弃;读取响应正文前就会确定 HTTP 状态。
- 服务返回的每个值在到达结果前都会经过格式处理:数字须为有限值,字符串长度有上限;单个格式错误的元素会被丢弃,而非丢弃整个列表。
- 绝不会跟随重定向;所有请求都会超时。
文档
完整指南、工具参考和安全说明请见 osm-mcp.ni-c.de(源文件位于 docs/)。
开发
npm install
npm run lint # oxlint + prettier
npm test # unit tests (all upstream APIs mocked)
npm run test:coverage
npm run build
npm run smoke # opt-in LIVE test against the real public services
发布
由标签驱动,无需手动发布:
- 将
[Unreleased]中的条目移入CHANGELOG.md中新的## [x.y.z] - YYYY-MM-DD小节,并更新package.json中的版本号。 npm run lint && npm run build && npm run test:coverage。- 提交更改,然后创建带签名的附注标签:
git tag -s vx.y.z -m "vx.y.z"。 git push origin main vx.y.z。
随后,release.yml 会运行测试,通过 Trusted Publishing(无需令牌密钥)发布到 npm,根据 CHANGELOG 中的小节创建 GitHub 发布,并将其发布到 MCP registry,名称为 io.github.ni-c/osm-mcp。ci.yml 会在同一标签上将多架构镜像推送到 GHCR。
如果注册表步骤失败,请在 main 上修复问题,然后手动触发 Publish to MCP Registry 工作流——不要重新运行标签任务,否则它会检出旧版本的代码。
贡献
欢迎提交问题、参与讨论和发起拉取请求——请参阅 CONTRIBUTING.md。如需报告漏洞,请使用私下报告渠道,而非公开提交问题;相关政策见 SECURITY.md。
许可证
MIT © Willi Thiel
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。