mcpField
O
onebusaway-mcp-server

onebusaway-mcp-server

远程服务
github.com/cyanheads地图与出行12 天前更新
代码仓库

关于 onebusaway-mcp-server

onebusaway-mcp-server 通过 OneBusAway API 提供公共交通线路、站点、实时到站和车辆信息,适用于普吉特海湾地区及兼容的 OneBusAway 实例。它还支持服务提醒和全天时刻表查询。

主要功能

  1. 01查找站点、线路与所属机构
  2. 02获取实时到站和车辆位置
  3. 03查询行程状态与服务提醒
  4. 04读取站点和线路全天时刻表
  5. 05提供站点与线路资源

适用场景

  1. 01查看某站点的实时到站信息
  2. 02追踪机构或线路上的车辆
  3. 03查询某线路当天的完整时刻表

MCP 相关

作为 MCP 服务,它通过 16 个工具提供 OneBusAway 的站点、线路、到站、车辆、提醒和时刻表数据,并提供站点与线路资源。支持 STDIO 与 Streamable HTTP。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://onebusaway.caseyjhand.com/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

安装包
npm@cyanheads/onebusaway-mcp-server0.3.0

工具

16

此工具无需参数。

详细介绍

@cyanheads/onebusaway-mcp-server

通过 MCP 查询 OneBusAway 公交 API 中的站点、线路、实时到站信息、车辆位置和时刻表。支持 STDIO 或 Streamable HTTP。

16 个工具 • 2 个资源

版本 许可证 Docker MCP SDK npm TypeScript Bun

在 Claude Desktop 中安装 在 Cursor 中安装 在 VS Code 中安装

框架


概览

OneBusAway 实时公交信息,默认适用于普吉特海湾地区(King County Metro、Sound Transit、Pierce Transit、Community Transit 等),也兼容任何 OneBusAway 实例。查找站点和线路,追踪实时到站信息和车辆位置,并获取时刻表和服务提醒。

工具
工具描述
onebusaway_list_agencies列出此实例上的公交机构,包括 ID、联系方式和服务覆盖区域
onebusaway_find_stops查找指定经纬度附近的站点,可选按站点代码筛选
onebusaway_search_stops将站点名称或代码解析为站点 ID
onebusaway_get_stop按 ID 获取一个站点
onebusaway_find_routes查找指定经纬度附近的线路,可选按名称或编号筛选
onebusaway_search_routes将线路名称或编号解析为线路 ID
onebusaway_get_route按 ID 获取一条线路
onebusaway_list_routes_for_agency列出某公交机构运营的所有线路
onebusaway_get_arrivals获取站点的实时到站和发车信息,包括时刻表偏差、车辆位置和有效提醒
onebusaway_get_stop_context通过一次上游请求获取站点详情、实时到站信息,以及该站点每条提醒的完整详情
onebusaway_get_alert按情况 ID 获取完整的服务提醒详情
onebusaway_get_trip获取一趟行程的实时状态和站点顺序
onebusaway_get_block按顺序列出一辆车在一个服务日内运行的所有行程及其站点时间
onebusaway_get_vehicles获取某公交机构正在运营车辆的实时位置,可选指定一条线路
onebusaway_get_schedule_for_stop按线路和方向获取某站点全天的发车时刻表
onebusaway_get_schedule_for_route获取某条线路的全天时刻表,包括每趟行程及其站点顺序
资源
资源描述
onebusaway://stop/{stopId}站点元数据:名称、坐标、服务线路、轮椅通行情况
onebusaway://route/{routeId}线路元数据:简称、描述、公交机构、时刻表 URL

仅支持工具的客户端也可通过 onebusaway_get_stop 和 onebusaway_get_route 获取相同数据。

功能参考

onebusaway_list_agencies tool
  • 无需输入;返回所有公交机构及其 id、联系方式、timezone 和 coverageCenter / coverageSpan
  • limitExceeded 表示上游返回的列表已达上限,且没有分页功能可获取剩余内容

onebusaway_find_stops tool
  • 必须提供 lat / lon;radius 的单位为米,默认值为 300,最大值为 1600;可选的 query 用于匹配站牌上印制的站点代码
  • 每个站点包含 id、code、direction、routeIds 和 wheelchairBoarding(ACCESSIBLE / NOT_ACCESSIBLE / UNKNOWN);limitExceeded 表示该半径范围内还有更多站点

onebusaway_search_stops tool
  • 必须提供 query(站点名称片段或站点代码);maxCount 最大为 100,默认值为 10
  • 返回的站点结构与 onebusaway_find_stops 相同;limitExceeded 表示匹配的站点数量超过 maxCount

onebusaway_get_stop tool
  • 提供单个 stopId;返回 name、code、坐标、direction、routeIds 和 wheelchairBoarding
  • 未知 ID 会返回 stop_not_found 错误,可通过 onebusaway_find_stops 或 onebusaway_search_stops 进行恢复

onebusaway_find_routes tool
  • 必须提供 lat / lon;radius 的单位为米,默认值为 500,最大值为 1600;也可改用 latSpan + lonSpan 矩形框(两者都必须设置);可选的 query 用于按线路名称或编号搜索
  • 每条线路包含 shortName、longName、agencyId、GTFS type(0=有轨电车 … 5=缆车)、color 和时刻表 url;limitExceeded 表示该区域内还有更多线路

onebusaway_search_routes tool
  • 必须提供 query(线路名称或编号);maxCount 最大为 100,默认值为 10
  • 返回 shortName、longName、agencyId 和 GTFS type;limitExceeded 表示匹配的线路数量超过 maxCount
  • 在线路搜索端点返回 404 的实例上会返回 endpoint_unavailable 错误,其中包括 Puget Sound;请改用 onebusaway_find_routes 或 onebusaway_list_routes_for_agency

onebusaway_get_route 工具
  • 单个 routeId;返回 shortName、longName、description、agency、GTFS type、color 和班次 url
  • 未知 ID 会报错 route_not_found,可通过 onebusaway_find_routes 或 onebusaway_search_routes 查找

onebusaway_list_routes_for_agency 工具
  • 必须提供 agencyId;未知 agency 会报错 agency_not_found
  • 返回所有路线及其 shortName、longName、GTFS type、color 和 url;limitExceeded 表示上游限制了列表且不支持分页

onebusaway_get_arrivals 工具
  • 必须提供 stopId;查询时间窗口为 minutesBefore(整数,0–60,默认 5)/ minutesAfter(整数,0–240,默认 35),更长的时间范围请使用 onebusaway_get_schedule_for_stop;未知站点会报错 stop_not_found
  • 每条到站信息包含 predicted(false = 仅按时刻表)、以秒为单位的 scheduleDeviation(正值 = 晚点,仅在有预测时有意义)、predictedArrivalTime、vehiclePosition、stopsAway 和 tripId
  • 当前有效的警报会出现在 situations[] 中:包括该站点上的警报,以及每条到站信息通过 situationIds 关联的警报,每个警报仅出现一次

onebusaway_get_stop_context 工具
  • 输入与 onebusaway_get_arrivals 相同,失败类型也相同,为 stop_not_found / rate_limited;一次调用只会发出一个上游请求
  • 返回 stop(onebusaway_get_stop 的字段,但不含 routeIds)、符合 onebusaway_get_arrivals 格式的 arrivals,以及符合 onebusaway_get_alert 格式的 alerts——包括查询窗口内站点上的所有警报,以及到站信息上的所有警报;即使窗口内没有到站信息携带某个全站警报,该警报也会包含在内
  • 如果上游响应中缺少站点,stop 为 null;如果响应中缺少被引用的警报,则不返回该警报;无论哪种情况,都会通过 notice 指明用于获取它的工具

onebusaway_get_alert 工具
  • 单个 situationId,来自 onebusaway_get_arrivals(situations[].id 或 arrivals[].situationIds);未知 ID 会报错 situation_not_found
  • 返回 TPEG reason 代码、severity、consequenceMessage、affects(agency、路线、站点或行程范围)、包含改道站点 ID 的 consequences,以及 activeWindows

onebusaway_get_trip 工具
  • 必须提供 tripId;serviceDateMs(非负整数,按当地时间午夜计算)仅适用于前一个服务日的行程;includeSchedule(默认 true)会添加包含 GTFS 时间和 distanceAlongTripMeters 的站点顺序
  • status 包含 phase(例如 in_progress、layover_before)、predicted、position、scheduleDeviation 和 nextStop;blockId(行程没有对应区块时为 null)可用于调用 onebusaway_get_block
  • 如果该行程在指定服务日期内未处于活动状态,则报错 trip_not_found;已完成行程的时间信息来自 onebusaway_get_schedule_for_route

onebusaway_get_block 工具
  • 单个 blockId,来自 onebusaway_get_trip;未知 ID 会报错 block_not_found
  • 顶层的 trips、activeServiceIds 和 inactiveServiceIds 描述首个返回的配置;alternateConfigurations 按顺序保留其余所有配置。服务 ID 表示日历条件,并不意味着某个配置今天会运行
  • 每条行程包含 distanceAlongBlock、accumulatedSlackTime(停站时间,单位为秒)和 blockStopTimes。可选的精确 tripId 或 departureFromSec / departureBeforeSec 会分别在每个配置中筛选完整行程,并保留空配置项
  • 使用筛选条件时,selection.total / returned 统计所有配置中的行程实例;configurationCounts[0] 描述顶层配置,之后每项对应一个备选配置

示例:{"blockId":"<blockId from onebusaway_get_trip>","departureFromSec":86400,"departureBeforeSec":90000} 会筛选出发时间在 24:00(含)至 25:00(不含)之间的行程,并保留其完整站点顺序。


onebusaway_get_vehicles 工具
  • 必填 agencyId;未知的机构会返回 agency_not_found 错误。可选的 routeId 会在获取该机构的所有车辆后由客户端筛选
  • 每辆车包含 position、orientation、phase、scheduleDeviation、tripId、nextStop 和 predicted(表示正在报告实时 GPS 数据);limitExceeded 表示上游返回的列表已达上限且不支持分页
  • tripId 优先使用当前行程;路线和目的地标牌元数据仅从该行程解析。orientation 保留从东开始逆时针计算的角度(0=东,90=北,180=西,270=南),而非罗盘方位角
  • 缺少纬度或经度的记录会被跳过:omittedWithoutPosition 统计整个机构中此类记录的数量;按路线筛选时,omittedWithoutPositionOnRoute 统计已解析匹配项中的此类记录数量。这些计数不受上游截断影响

onebusaway_get_schedule_for_stop 工具
  • 必填 stopId;可选 date,须为真实的 YYYY-MM-DD 日历日期;默认(省略或留空时)为机构时区的当天;未知站点会返回 stop_not_found 错误
  • 按路线和方向对出发班次分组,每项包含 scheduledDepartureTime 和 tripId
  • serviceDateMs 保留上游的时刻表日期标记:省略或留空日期时为查询时间;指定日期时为实例本地午夜;不会取整到服务日边界
  • 可选的 routeId、departureFromMs 和 departureBeforeMs 条件以 AND 组合;时间边界为非负整数 Unix 毫秒,下限包含,上限不包含。筛选后的结果会省略空方向和路线;selection.total / returned 分别统计筛选前后的出发班次数
  • 仅提供静态时刻表;实时预测请使用 onebusaway_get_arrivals

示例:{"stopId":"1_75403","routeId":"1_100259","departureFromMs":1792882800000,"departureBeforeMs":1792886400000} 会筛选该路线在给定 Unix 时间区间内的出发班次。


onebusaway_get_schedule_for_route 工具
  • 必填 routeId;可选 date,须为真实的 YYYY-MM-DD 日历日期;默认(省略或留空)为今天;未知路线会报错 route_not_found
  • 返回当天的每趟行程,包含 tripId、tripHeadsign、serviceId 和停靠站序列
  • serviceDateMs 保留上游路线的 scheduleDate,用于标识时刻表对应的服务日期
  • 路线、停靠站、行程终点标牌和服务元数据优先从引用中解析;引用字段缺失或为空时,保留旧版元数据和分组回退逻辑
  • 可选的精确 tripId 或 departureFromSec / departureBeforeSec,用于选择在时间区间内有任意一次发车的完整行程。边界值必须是非负整数形式的 GTFS 午夜起算秒数,可超过 86400;下界包含在内,上界不包含在内。selection.total / returned 分别统计选择前后的行程数
  • 仅提供静态时刻表;实时预测请通过停靠站上的 onebusaway_get_arrivals 获取

示例:{"routeId":"1_100259","departureFromSec":28800,"departureBeforeSec":32400} 会选出 08:00(含)至 09:00(不含)之间有任意一次发车的行程。

对于路线和区块时刻表,非空白的 tripId 不能与发车时间边界同时使用。空白的可选 ID 视为省略;任一边界都可以省略,但同时提供的两个边界必须递增。未指定选择条件时,三个工具都会返回完整映射结果,不包含选择元数据或默认上限。选择计数仅描述该上游响应,不包括上游服务中未包含的内容;匹配数为零时,结果仍然成功,但会附带提示。

到达信息、停靠站上下文、行程、车辆、时刻表和警报都包含经过验证的 IANA timezone;纪元时间和日期标题会明确标注时区。停靠站工具使用所查询停靠站的机构命名空间,车辆使用所请求的机构,行程/路线时刻表使用所引用路线的机构。每条警报都会解析各自的机构、路线、行程和停靠站范围;只有在所有范围均解析成功且时区一致时,才会使用这些范围的时区。时区缺失、无效、无法解析或互相冲突时,将使用 UTC,不会额外发起请求。纪元数值和 GTFS 秒数保持不变,包括超过 24:00 的时刻表时间。


onebusaway://stop/{stopId} 资源
  • 以 application/json 格式返回停靠站记录,结构与 onebusaway_get_stop 返回的相同
  • stopId 来自 onebusaway_find_stops 或 onebusaway_search_stops

onebusaway://route/{routeId} 资源
  • 以 application/json 格式返回路线记录,结构与 onebusaway_get_route 返回的相同
  • routeId 来自 onebusaway_find_routes 或 onebusaway_search_routes

功能

基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔认证(none / jwt / oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及支持可选 OpenTelemetry 跟踪的结构化日志记录。

OneBusAway 专属功能:

  • 使用类型化错误分类封装 onebusaway-sdk(NotFound、RateLimited、上游返回 400 时的 ValidationError、ServiceUnavailable)
  • 默认使用 Puget Sound 实例(api.pugetsound.onebusaway.org),开发时可使用 ONEBUSAWAY_API_KEY=TEST;ONEBUSAWAY_BASE_URL 可将其指向任意其他 OneBusAway 实例
  • 站点和路线 ID 带有机构前缀,格式为 {agencyId}_{localId}(站点为 1_75403,路线为 1_100259);机构 ID 是不带修饰的前缀(Metro Transit 为 1,Sound Transit 为 40)
  • 所有上游请求共用一个限速器,其容量由 ONEBUSAWAY_RATE_LIMIT_* 设置;它会根据 API 密钥的配额对请求排队。如果调用在等待时限内未获得请求名额,则会在任何工具上返回可重试的 rate_limited 错误,并附带 data.retryAfter
  • 仅提供公交数据,不提供行程规划;服务级说明会引导 Agent 了解 ID 格式和常见查询链

便于 Agent 使用的输出:

  • 每条到站信息、每个行程和每辆车辆都包含 predicted,用于区分 GPS 跟踪数据和仅基于时刻表的预测
  • 机器可读时间:scheduleDeviation 以秒为单位;到站、站点时刻表和更新的时间戳以 Unix 毫秒为单位;行程、路线时刻表和班次的站点时间采用从午夜起算的 GTFS 秒数
  • 可串联的 ID:站点工具返回的 stopId 可用于查询到站信息,tripId 可用于调用 onebusaway_get_trip,blockId 可用于调用 onebusaway_get_block,situationIds 可用于调用 onebusaway_get_alert,agencyId 可用于查询车辆和路线列表
  • 类型化错误约定中的恢复提示会指出下一步要调用的工具;结果为空或被截断时会附带 notice

开始使用

公共托管实例

公共实例地址为 https://onebusaway.caseyjhand.com/mcp,无需安装。通过 Streamable HTTP 将任意 MCP 客户端连接到该实例:

{
  "mcpServers": {
    "onebusaway-mcp-server": {
      "type": "streamable-http",
      "url": "https://onebusaway.caseyjhand.com/mcp"
    }
  }
}
自托管 / 本地运行

将以下内容添加到 MCP 客户端配置文件中。在 Puget Sound 实例上,无需注册即可使用 ONEBUSAWAY_API_KEY=TEST。

{
  "mcpServers": {
    "onebusaway-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/onebusaway-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info",
        "ONEBUSAWAY_API_KEY": "TEST"
      }
    }
  }
}

也可以使用 npx(无需 Bun):

{
  "mcpServers": {
    "onebusaway-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/onebusaway-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info",
        "ONEBUSAWAY_API_KEY": "TEST"
      }
    }
  }
}

也可以使用 Docker:

{
  "mcpServers": {
    "onebusaway-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "-e", "ONEBUSAWAY_API_KEY=TEST",
        "ghcr.io/cyanheads/onebusaway-mcp-server:latest"
      ]
    }
  }
}

使用 Streamable HTTP 时,设置传输方式并启动服务:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 ONEBUSAWAY_API_KEY=TEST bun run start:http
# Server listens at http://localhost:3010/mcp
先决条件
  • Bun v1.4.0 或更高版本(或 Node.js v24+)。
  • OneBusAway API 密钥。开发时可在 Puget Sound 实例上使用 TEST;用于生产环境或其他实例时,请到相应机构的开发者门户注册。
安装
  1. 克隆仓库:
git clone https://github.com/cyanheads/onebusaway-mcp-server.git
  1. 进入目录:
cd onebusaway-mcp-server
  1. 安装依赖:
bun install
  1. 配置环境:
cp .env.example .env
# edit .env — set ONEBUSAWAY_API_KEY if needed

配置

变量描述默认值
ONEBUSAWAY_API_KEYOneBusAway API 密钥。在 Puget Sound 实例上,TEST 可用。TEST
ONEBUSAWAY_BASE_URLOneBusAway 实例的基础 URL。https://api.pugetsound.onebusaway.org
ONEBUSAWAY_RATE_LIMIT_REQUESTS每个时间窗口允许的上游请求数,由所有调用方共享。20
ONEBUSAWAY_RATE_LIMIT_WINDOW_MS滑动速率限制窗口的时长,单位为毫秒。60000
ONEBUSAWAY_RATE_LIMIT_MAX_WAIT_MS调用等待可用名额的最长时间,超时后将以 rate_limited 失败,单位为毫秒。请设置为低于 SDK 的 60 秒请求超时时间。45000
MCP_TRANSPORT_TYPE传输方式:stdio 或 http。stdio
MCP_HTTP_PORTHTTP 服务端口。3010
MCP_SESSION_MODEHTTP 会话模式:stateless、stateful 或 auto。stateless
MCP_AUTH_MODE身份验证方式:none、jwt 或 oauth。none
MCP_LOG_LEVEL日志级别(debug、info、notice、warning、error)。info
LOGS_DIR日志文件目录(仅限 Node.js)。<project-root>/logs
STORAGE_PROVIDER_TYPE存储后端:in-memory、filesystem、supabase、cloudflare-kv/r2/d1。in-memory
OTEL_ENABLED启用 OpenTelemetry。false

完整的可选覆盖项列表请参阅 .env.example。

运行服务

本地开发
  • 构建并运行生产版本:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:http
    # or
    bun run start:stdio
    
  • 运行检查和测试:

    bun run devcheck       # Lint, format, typecheck, security, changelog sync
    bun run test           # Vitest test suite
    bun run test:coverage  # Test suite with coverage, held to the framework thresholds
    bun run lint:mcp       # Validate MCP definitions against spec
    
Docker
docker build -t onebusaway-mcp-server .
docker run --rm -e ONEBUSAWAY_API_KEY=TEST -p 3010:3010 onebusaway-mcp-server

Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/onebusaway-mcp-server。默认会安装 OpenTelemetry 对等依赖;构建时使用 --build-arg OTEL_ENABLED=false 可省略这些依赖。

项目结构

目录用途
src/index.tscreateApp() 入口点:注册工具和资源、设置服务说明,并初始化 OneBusAway 服务。
src/config使用 Zod 解析和验证服务专属环境变量。
src/mcp-server/tools工具定义(*.tool.ts)及其共用的架构和格式辅助函数。
src/mcp-server/resources站点和路线资源定义(*.resource.ts)。
src/services/onebusawayOneBusAway 服务:封装 onebusaway-sdk、控制上游请求频率、对错误分类;包含领域类型。
tests/针对工具、资源、服务和配置的 Vitest 测试。

开发指南

开发指南和架构规则请参阅 CLAUDE.md。简要说明如下:

  • 处理程序抛出异常,框架负责捕获——工具逻辑中不要使用 try/catch
  • 使用 ctx.log 记录请求范围内的日志,使用 ctx.state 存储租户范围内的数据
  • 在 src/index.ts 的 createApp() 数组中注册新工具和资源
  • 封装外部 API 调用:验证原始数据 → 规范化为领域类型 → 返回输出架构;绝不伪造缺失字段

贡献

欢迎提交问题。提交前请运行检查和测试:

bun run devcheck
bun run test

许可证

Apache-2.0 — 详情请参阅 LICENSE。

来自默认 Puget Sound OneBusAway API 的公交数据由 Sound Transit 和 King County Metro 运营,受 Sound Transit Transit Data Terms of Use 约束;托管端点的用户也需遵守这些条款。主要义务如下:

  • 第 2 条:可按要求提供使用指标。
  • 第 3 条:数据从 OneBusAway API 实时获取,不会被修改,也不会在请求周期之外缓存。
  • 第 4 条:您同意向您提供这些数据的任何用户传递实质上相似的条款。
  • 第 7 条:本服务的名称或品牌不得使用 Sound Transit 商标。

评论

支持 Markdown

第一次接触 MCP?

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

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