mcpField
T
Traintrackr

Traintrackr

远程服务
traintrackr.live地图与出行02 天前更新

关于 Traintrackr

Traintrackr 是面向 Claude、ChatGPT 等 MCP 客户端的英国国家铁路查询服务,可查询实时站台信息、时刻表并规划行程。它结合实时数据与未来日期的计划时刻表。

主要功能

  1. 01查询实时出发、站台、延误和取消
  2. 02查看实时到达与出发牌
  3. 03查询未来日期的时刻表
  4. 04规划含换乘的行程
  5. 05查询列车停靠站和车站

适用场景

  1. 01查询车站的下一班列车
  2. 02查看列车是否延误或取消
  3. 03查询指定列车的站台
  4. 04规划两个车站之间的行程

MCP 相关

它向 MCP 客户端提供铁路数据工具,包括实时和计划服务查询、行程规划,以及出发牌 MCP App。托管端点为 https://traintrackr.live/mcp。

配置

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

服务地址https://traintrackr.live/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 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

Traintrackr

一个 MCP 服务,让 Claude 和 ChatGPT 能够回答有关英国(National Rail)列车的问题:“下一班去 Sudbury 的火车几点发车?”、“从 Liverpool Street 出发的 13:00 班次准点吗?”、“下周六早上从 Cambridge 到 Sudbury 怎么走?”

公共服务运行于 traintrackr.live。它免费使用,登录时使用电子邮件地址;无需密码。连接器地址为:

https://traintrackr.live/mcp

使用方法

Claude。 Traintrackr 已列入 Claude 的连接器目录:打开 claude.ai/directory/traintrackr,或者在 claude.ai 中打开 Customize → Connectors,选择 Connectors 旁边的 +,然后在目录中找到 Traintrackr。选择 Connect:Claude 会打开 Traintrackr 登录页面,你可以输入电子邮件地址,然后打开邮件中的链接,或输入邮件中发送的六位数代码。在 claude.ai 中添加的连接器也可在 Claude Desktop 和移动应用中使用。若要通过地址添加,请选择 Add custom connector,将其命名为 Traintrackr,并粘贴连接器地址。

ChatGPT。 ChatGPT 通过开发者模式添加连接器;该功能适用于网页版的 Plus、Pro、Business、Enterprise 和 Edu 计划。在工作区中,管理员可能需要先允许使用开发者模式。打开 Settings → Security and login → Developer mode,然后前往 chatgpt.com/plugins,选择 +,将其命名为 Traintrackr,粘贴连接器地址并选择 OAuth。按照上文所述,使用电子邮件地址登录。在新聊天中,选择 + → Developer mode,然后选择 Traintrackr。

接着询问列车相关问题。traintrackr.live/docs 介绍了每种回答包含的内容及其限制。隐私政策 和 使用条款 也可在网站上查看。该服务已在 MCP Registry 中登记,名称为 live.traintrackr/traintracker。

本 README 其余部分将介绍该服务的工作原理,以及如何运行自己的副本:通过 stdio 在本地运行,供 Claude 桌面应用使用;或通过 HTTP 托管(参见部署到 Render)。时刻表存储在 Postgres 中。

flowchart LR
    Claude[Claude] <-->|stdio or HTTP| TT[traintracker]

    subgraph Live["Live, next ~2 hours"]
        D[Darwin<br/>Rail Data Marketplace]
    end
    subgraph Timetable["Timetable, any future date"]
        NR[Network Rail<br/>SCHEDULE feed] -->|daily download| DB[(Postgres<br/>timetable schema)]
    end
    TT --> D
    TT --> DB

工具

工具回答的问题数据
find_station“哪个 Sudbury?”车站名称 ↔ CRS 代码内置车站列表
live_departures接下来发车的列车、预计时间、站台、延误、取消情况Darwin;如果 Darwin 两小时内的列车少于 rows,则补充时刻表中的列车;如果尚未配置,则使用时刻表时间;如果处于离线状态,则使用时刻表时间并附上说明
departure_platform“13:00 开往 Colchester 的列车在哪个站台?”一趟列车的站台,标记为 live 或 scheduledDarwin(分页);公布实时站台前,使用时刻表中的计划站台
platform_departures“7 号站台接下来有哪三趟列车?”与 departure_platform 相同
live_arrivals未来约 2 小时内到站的列车Darwin 到站信息;如果列车不足,则补充时刻表中的列车;如果尚未配置,则使用时刻表时间;如果处于离线状态,则使用时刻表时间并附上说明
show_board“显示 Liverpool Street 的出发信息板。”以出发信息板形式展示相同的实时出发或到站信息与 live_departures 和 live_arrivals 相同
timetable任意日期某车站的计划出发/到站信息本地时刻表
service_details一趟列车的所有停靠站提供该 ID 的数据来源
plan_journeyA 到 B 的行程及换乘(最多 max_changes 次,默认 4 次),包括伦敦跨区连接本地时刻表 + Darwin 实时信息覆盖层
data_status已配置的内容、时刻表的新旧程度、缺失项;设置 DJANGO_DEBUG=1(自行运行的服务)后,还会显示时刻表架构、上次刷新错误和已使用的 Darwin 配额—
privacy_policy“你保留了我的哪些信息?”以文本形式显示隐私政策及其页面地址/privacy 页面

每个工具都接受车站名称或 CRS 代码。有歧义的名称(“Sudbury”“Harrow”)会返回候选项,供 Claude 询问你指的是哪个。

出发信息板

show_board 附带一个 MCP App:支持 MCP Apps 的客户端会在答案旁以翻牌式出发信息板的形式绘制其结果。客户端会为所有提供信息板的工具调用绘制信息板,因此它被单独设为一个工具,并告知助手仅在有人要求查看信息板时使用。live_departures 和 live_arrivals 会返回相同的列车信息,但不会绘制任何内容。不支持 MCP Apps 的客户端会像处理其他工具一样处理 show_board 的结果。

信息板只有一个页面:apps/rail/ui/board.html,作为资源 ui://traintracker/board.html 提供。其样式和脚本均内嵌其中,且不会从任何位置加载内容。客户端会将工具的结果传给它;它最多显示 12 趟列车、车站公告和数据鸣谢。刷新会让客户端使用相同参数再次调用 show_board,与其他调用一样计入速率限制。对于在系统中启用了减少动态效果的用户,翻牌不会转动;屏幕阅读器则会将列车信息读作表格。

运行你自己的副本

从这里开始,内容均适用于自行运行服务。traintrackr.live 上的公共服务使用的就是这份代码,部署方式如部署到 Render 所述。

无需账户即可试用(演示模式)

设置 TRAINTRACKER_DEMO=1,即可在账户获批前测试每个工具。此时服务会使用生成的示例数据,且不会发出网络请求:

  • **时刻表:**为东英格兰和伦敦的 25 个真实车站生成 SCHEDULE 数据源(包括 Liverpool Street、Stratford、Chelmsford、Colchester、Ipswich、Norwich、Marks Tey、Sudbury、Cambridge、Kings Cross 等),从今天起覆盖 90 天。周日的首班车时间较晚。数据存储在独立的架构 (timetable_demo) 中,与真实时刻表分开,并且每天重建。演示模式仍需要 DATABASE_URL。
  • **实时车站信息板:**Darwin 的出发、到达和服务详情响应会在进程内根据该时刻表生成。约五分之一的列车会晚点,约二十五分之一会取消,约十二分之一会变更站台;同一天的同一列车始终会得到相同结果。大型车站(Liverpool Street、Kings Cross、Cambridge 等)会在发车前 15 分钟公布站台,因此会触发使用时刻表站台作为备用方案的逻辑。

每块车站信息板和每项行程计划都会附注数据为生成数据,而 data_status 会报告 demo_mode。查询演示网络以外的车站时,会得到空车站信息板。

"env": { "TRAINTRACKER_DEMO": "1" }

将其添加到 Claude 桌面端配置中的 traintracker 条目(参见添加到 Claude 桌面应用),或将 TRAINTRACKER_DEMO=1 写入 .env。配置好密钥后,请将其移除。可以尝试询问:"Liverpool Street 的下一班列车是什么?"、"从 Cambridge 开往 Kings Cross 的下一班列车在哪个站台?"、"明天 9 点如何从 Cambridge 前往 Sudbury?"

需要的账户

#账户是否需要?费用提供内容用途
1Rail Data Marketplace — Live Departure Board 产品查询实时信息时需要免费Darwin:National Rail 的实时数据源。提供未来 2 小时的出发信息板,包括预计时间、站台、晚点/取消原因、停靠站和车站提醒。与车站屏幕上的数据相同。live_departures、plan_journey 中的实时信息叠加层
2Network Rail Open Data (NTROD) — SCHEDULE 数据源查询时刻表和规划时需要免费Network Rail 规划系统提供的 GB 完整客运时刻表,包括发布后的短期变更(工程施工、加开列车、取消)。每日刷新。timetable、plan_journey、针对 tt: ID 的 service_details,以及实时工具的离线备用数据
3Rail Data Marketplace — Service Details 产品可选免费Darwin 车站信息板上列车的完整实时停靠站信息。针对 darwin: ID 的 service_details
4Rail Data Marketplace — Live Arrival Board 产品可选免费Darwin 到达信息板。未订阅时,到达信息显示计划时间。live_arrivals
1. Rail Data Marketplace(Darwin)
  1. 在 raildata.org.uk 创建账户。
  2. 在产品目录中搜索 "Live Departure Board"(LDBWS 产品,不是 "Live Fastest Departure Boards")并订阅。免费层级的审批时间从即时到几天不等。
  3. 打开已订阅的产品 → Specification 标签页。复制 Consumer key(不是 secret)并填入 DARWIN_API_KEY。
  4. 检查该标签页上的基础 URL 是否与 .env.example 中的 DARWIN_DEPARTURES_URL 相符。若不相符,请将 DARWIN_DEPARTURES_URL 设置为你的值(即 /GetDepBoardWithDetails 之前的所有内容)。
  5. *(可选)*以相同方式订阅 Service Details 和 Live Arrival Board。每个产品都有各自的密钥和 URL:设置 DARWIN_SERVICE_API_KEY / DARWIN_SERVICE_URL 和 DARWIN_ARRIVALS_API_KEY / DARWIN_ARRIVALS_URL。
2. Network Rail 开放数据(SCHEDULE)
  1. 在 Network Rail 数据源门户注册。激活可能需要一些时间。
  2. 登录并确认 Static feeds 下方显示 SCHEDULE。
  3. 将门户用户名和密码填入 NR_USERNAME 和 NR_PASSWORD。
  4. 如果门户提供的 full daily extract, all operators, JSON 下载链接与 .env.example 中的 NR_SCHEDULE_URL 不同,请将 NR_SCHEDULE_URL 设置为该链接。

当时刻表缺失或超过 26 小时时,服务会在后台下载数据源。服务会在启动时以及每次工具调用时检查,因此即使服务连续运行数天,也能保持数据最新。如果下载失败,服务会继续提供旧时刻表,而 data_status 会显示错误。你也可以手动运行 manage.py refresh_timetable --commit(请参阅命令)。如果有单独的任务运行 refresh_timetable,例如在 Render 上运行,请设置 TIMETABLE_AUTO_REFRESH=0。

3. Postgres

时刻表位于 DATABASE_URL 所指定数据库的一个架构中(默认是 timetable)。该数据库中的角色需要具备创建架构的权限;数据库所有者具备此权限。在共享服务器上,请为 traintracker 分配专属数据库和角色:

CREATE ROLE traintracker LOGIN PASSWORD '…';
CREATE DATABASE traintracker OWNER traintracker;
REVOKE CONNECT ON DATABASE traintracker FROM PUBLIC;

请将该角色填入 DATABASE_URL,而不是使用服务器自身的用户。服务器用户拥有服务器上的每个数据库,因此 traintracker 中的故障可能会影响其他应用的数据;而 traintracker 角色只能访问自己的数据库。

完整的 GB 时刻表约占 475 MB(430 万个停靠点),刷新时构建新副本会占用约两倍空间。刷新耗时约 40 秒,另加下载时间。系统会在暂存架构中构建新时刻表,然后通过重命名切换,因此读取者不会看到未构建完成的时刻表;同时,顾问锁可防止两个刷新同时运行。

这些表是 UNLOGGED:每天都会根据数据源重新构建,因此不会写入预写日志,也不会增加服务器的 WAL 或时间点恢复存储。代价是 Postgres 会在崩溃后清空这些表;之后,工具会报告“尚无时刻表”,直到下一次刷新。

各数据源的用途

flowchart TD
    Q{What's being asked?}
    Q -->|next ~2 hours| L[live_departures / live_arrivals]
    Q -->|a future date| T[timetable]
    Q -->|A to B| P[plan_journey]
    Q -->|one train| S[service_details]

    L --> L1{Darwin key?}
    L1 -->|yes| Darwin
    Darwin -->|error or timeout:<br/>note says Darwin is offline| TT
    L1 -->|no| TT[(Timetable<br/>scheduled times, flagged)]

    T --> TT

    P --> CSA[Connection Scan<br/>over the day's timetable]
    CSA --> OV{Today, departing<br/>within 2 hours?}
    OV -->|yes| Darwin2[Darwin expected times<br/>+ tight-connection flag]
    Darwin2 -.->|offline| Note[Plan note: Darwin offline,<br/>times are scheduled]

    S --> ID{ID prefix}
    ID -->|darwin:| Darwin3[Darwin Service Details]
    ID -->|tt:| TT
数据源新鲜度覆盖范围缓存时间需要了解的限制
Darwin实时现在至 +2 小时20 秒Darwin 服务 ID 会在列车运行后很快过期
时刻表(Postgres)每日(Network Rail 约在 06:00 发布)前两天至已发布时刻表的末尾(通常为数月)直到下次重建仅含计划时间;临时变更会显示在 Darwin 中,而非此处
Trainline 链接

时刻表中的列车(timetable、plan_journey、带 tt: ID 的 service_details,以及在回退到计划时间时使用的实时工具)会附带 trainline_url:该列车在 Trainline 上的页面,显示其停靠站及运行情况。地址格式为 <TRAINLINE_LIVE_URL>/departures/<station>/<token>,其中 token 是 /callingPattern/<train UID>/<run date> 的 base64 编码。车站仅用于页面标题:可以是站台牌上的车站、某一段行程的上车站,或列车始发站。

  • Darwin 中的列车没有链接:Darwin 服务 ID 不包含列车 UID。
  • Trainline 使用自己的站名 slug 来命名车站。大多数 slug 可从车站列表中的名称推导;trainline_slugs.json 列出了不同的 slug,以及 Trainline 没有实时站台牌的车站对应的 null(大多是 2022 年之后开放的车站)。如果列车只停靠这些车站,则没有链接。
  • Trainline 未发布这些地址的规范。地址取自其实时站台牌,并于 2026 年 9 月根据其实时页面站点地图核对 slug。对于 Trainline 不认识的列车,它会显示该车站的站台牌。
  • 演示模式不会提供链接:其中的列车是虚构的。
Darwin 配额

免费 Darwin 访问额度为每个四周 Railway 周期 500 万次请求,所有用户共用一个服务器密钥。服务器会统计发送到 Darwin 的请求,并在 manage.py rail_status 中报告总数;当 DJANGO_DEBUG=1 时,也会在 data_status 中报告(托管服务器不会告诉每位登录用户还剩多少额度):

Darwin usage: 412,906 requests in the last 28 days, 8.26% of 5,000,000
  • 统计内容: 每个发送到 Darwin 的请求都会计入,包括失败的请求。通过 20 秒缓存响应的时刻表不会发送请求,也不会计入。演示模式下不计入。
  • 统计周期: 滚动 28 天。Railway 周期不容易简单推算(一年中首尾两个周期的长度各不相同),而滚动窗口的限制不会比它所重叠的周期更宽松。
  • 按产品统计: 每个 Rail Data Marketplace 产品(departures、arrivals、service)都会单独计数,百分比则按总数计算。如果你的配额是按产品计算的,这个百分比会高估你的用量。
  • 每日限制: 服务器在一个英国自然日内最多向 Darwin 发送 DARWIN_DAILY_LIMIT 次请求(默认值为 170,000 次;按配额计算,每天约为 178,000 次)。达到限制后,实时工具会改为返回计划时刻,并说明原因,直到午夜。服务器重启后会恢复当天的计数。设置为 0 可关闭此限制。
  • 警告: 用量超过配额的 70% 时,日志会发出警告;超过 90% 时会再次发出。每条警告只发出一次,只有用量降到相应阈值以下后再次超过,或服务器在用量已超过阈值时重启,才会再次发出。
  • 存储: 在独立架构(USAGE_SCHEMA)中使用一个小型表 darwin_requests,以便计数在重启和时刻表刷新后仍能保留。计数先累积在内存中,达到 50 条待写入记录或经过一分钟后写入;服务器关闭时也会写入。服务器被强制终止时,最多会丢失这些尚未写入的记录。写入失败会记入日志并重试,且不会导致工具调用失败。超过 60 天的记录会被删除。
时刻表保留的内容

SCHEDULE 数据源很大(包含所有列车,包括货运列车)。导入时,traintracker 只保留乘客所需的信息:

  • 仅保留客运类别(列车、替代列车或纳入时刻表的巴士、船舶)。货运和空载列车会被丢弃,但例外情况是覆盖记录和取消记录,它们可能导致客运列车在特定日期停运。
  • 仅保留有公开时刻的停靠站;交汇点和通过点会被丢弃。
  • 丢弃结束日期超过两天的时刻表。

因此,时刻表涵盖其生成日期之前两天起,直到任何时刻表的最后运行日期;如果工具被要求查询此范围以外的日期,就会说明这一点。

对于每个日期,时刻表会按列车应用 Network Rail 的优先级规则:取消(C)优先于新增(N),新增优先于覆盖(O),覆盖优先于永久(P);并遵循每份时刻表的运行日和日期范围。目前尚未应用银行假日运行标志,因此银行假日请查看实时看板。

行程规划

plan_journey 会按轮次扫描当天每一段列车行程:第 n 轮查找最多乘坐 n 趟列车时最早到达的路线。这样一次就能找出最快路线,以及换乘次数较少但较慢的选项,最多不超过 max_changes。它会从每次发车后的时间继续搜索,以找出接下来的几个选项,然后剔除那些在出发时间、到达时间和换乘次数上都被其他选项胜过的路线,因此不会让你不必要地提前出发。结果按到达时间排序,且始终包含换乘次数最少的选项。

  • 最短换乘时间: 默认列车之间至少留出 5 分钟(MIN_INTERCHANGE_MINUTES)。步行/地铁连接已包含进出车站所需的时间,因此经过这些连接后不会额外增加换乘时间。
  • 伦敦市内换乘: 地铁不在铁路时刻表中,因此伦敦各终点站(Kings Cross、Liverpool Street、Waterloo 等)之间的换乘时间为估算值:0.8 公里以内按步行速度计算,再加 5 分钟;否则按约 12 分钟的地铁时间计算,再加上每公里 3.5 分钟。这类换乘会标记为 tube (approx.)。
  • 实时信息叠加: 对于今天两小时内出发的路段,会添加 Darwin 预计时刻和站台信息;如果延误或取消导致换乘时间不足(包括通过步行/地铁连接的换乘),则会将 connection_at_risk 设为真。如果 Darwin 不可用,仍会返回行程规划,只是不含实时信息。
  • 搜索范围覆盖整个运营日(包括运行至凌晨的列车),不会延续到次日早晨。车站信息板会显示午夜后不久出发的列车。
  • 负载: 一次行程规划会多次扫描当天的列车;构建某个日期的路网需要几秒钟,且占用超过 100 MB 内存。内存中会保留两个日期的数据。时刻表读取和行程规划会在线程中运行,每次最多并行两个;等待轮到自己的时间超过 10 秒时,调用方会收到服务器繁忙的提示。

安装

需要 uv、Python 3.14(uv 会根据 .python-version 安装)和一个 Postgres 数据库(版本 13 或更高)。本地使用 Docker(或 OrbStack)是最快的启动方式:

docker run -d --name traintracker-pg --restart unless-stopped \
  -e POSTGRES_PASSWORD=postgres -p 127.0.0.1:55432:5432 postgres:17
git clone [email protected]:hugorodgerbrown/traintracker.git
cd traintracker
uv sync
cp .env.example .env          # fill in your keys and DATABASE_URL (.env is git-ignored)
uv run python manage.py migrate
uv run python manage.py refresh_timetable --commit   # first timetable download (a few minutes)
uv run python manage.py rail_status
uv run python manage.py runserver                    # the site, sign-in and /mcp at localhost:8000
添加到 Claude 桌面应用

编辑 ~/Library/Application Support/Claude/claude_desktop_config.json。请使用 uv 的完整路径(运行 which uv 获取),因为该应用不会使用 shell 的 PATH:

{
  "mcpServers": {
    "traintracker": {
      "command": "/Users/hugo/.local/bin/uv",
      "args": ["run", "--directory", "/Users/hugo/Projects/traintracker", "python", "manage.py", "serve_stdio"]
    }
  }
}

--directory 会将项目文件夹设为工作目录,因此服务器会从该目录的 .env 读取密钥。serve_stdio 只响应启动它的应用,因此无需登录,也没有速率限制。密钥也可以放在此文件的 "env" 块中;实际环境变量的优先级高于 .env。

重启 Claude 应用,然后询问 "what's the status of traintracker's data sources?",检查是否已连接所有数据源。

配置

所有配置都通过环境变量设置;如果项目文件夹中存在 .env,则会从中读取。请参阅 .env.example。本地开发无需任何 Django 设置;在 Render 上,titan 的环境变量组会设置这些变量(请参阅部署到 Render)。

Django 设置位于 config/settings.py:

变量默认值用途
DJANGO_DEBUG1设为 0 可启用生产环境加固,这是 manage.py check --deploy 的要求。设为 1 时,登录邮件会输出到控制台日志,data_status 会显示内部详情
DJANGO_SECRET_KEY开发密钥DJANGO_DEBUG=0 时必填。也用于生成每个登录码的哈希
ACCOUNTS_EMAIL_KEY固定的开发密钥DJANGO_DEBUG=0 时必填。用于生成查找每个账户的单向哈希,因此不会存储邮箱地址。切勿更改:否则所有账户都会丢失
DJANGO_ALLOWED_HOSTSlocalhost,127.0.0.1网站响应的主机名,以逗号分隔;Render 的 onrender.com 名称会自动添加
DJANGO_CSRF_TRUSTED_ORIGINS—受信任的表单提交来源,以逗号分隔
SITE_URLhttp://localhost:8000(在 Render 上为 onrender.com 名称)公共地址:邮件中的链接、通行密钥来源,以及网站显示的连接器地址(<SITE_URL>/mcp)
RATE_LIMIT_PROXY_COUNT0,或在 DJANGO_DEBUG=0 时为 1应用前方的代理数量;用于限制的客户端地址是从 X-Forwarded-For 末尾起向前数对应跳数的地址
EMAIL_HOST / EMAIL_PORTlocalhost / 587登录邮件的 SMTP 中继。对于 Resend:主机为 smtp.resend.com
EMAIL_HOST_USER / EMAIL_HOST_PASSWORD—SMTP 登录信息。对于 Resend:用户名为 resend,密码为 API 密钥
EMAIL_USE_TLS1使用 STARTTLS 连接中继
DEFAULT_FROM_EMAILTraintrackr <noreply@localhost>登录邮件的发件人;其中的域名必须通过中继验证
WEBAUTHN_RP_IDSITE_URL 的主机名通行密钥适用的范围(参见 docs/accounts.md)
FIVEBAR_DOMAIN—为该域名启用 fivebar 的无 Cookie 访客计数;为空时关闭
FIVEBAR_TOKEN—与 FIVEBAR_DOMAIN 配合使用时,在 fivebar 中将每次 MCP 工具调用计为 /mcp/<tool>:记录工具、是否成功响应、应用名称和账户的带密钥哈希,绝不记录参数或响应内容(相关决策)。此令牌需在 fivebar 中创建,并且仅启用 Send events;为空时关闭

列车工具的设置由 apps/rail/config.py 读取:

变量默认值用途
DARWIN_API_KEY—Live Departure Board 消费者密钥
DARWIN_DEPARTURES_URLRDM LDBWS URL如果你的 Specification 选项卡显示不同的地址,则覆盖此值
DARWIN_SERVICE_API_KEY / DARWIN_SERVICE_URLboard key / RDM URLService Details 产品
DARWIN_ARRIVALS_API_KEY / DARWIN_ARRIVALS_URL—Live Arrival Board 产品
NR_USERNAME / NR_PASSWORD—Network Rail 数据馈送登录凭据
NR_SCHEDULE_URL完整的每日 JSON 提取文件如果门户提供了不同的链接,则覆盖此值
DATABASE_URL—用于时刻表(必填)及 Django 自身表的 Postgres 数据库
TIMETABLE_SCHEMAtimetable时刻表所在的架构(演示模式会在末尾附加 _demo)
USAGE_SCHEMAtraintracker_usage记录发送到 Darwin 的请求数量的架构(见 Darwin 配额)
DARWIN_DAILY_LIMIT170000一个英国日内发送到 Darwin 的最多请求数;超过此数后,实时工具将返回计划时刻。设为 0 可关闭限制
TIMETABLE_AUTO_REFRESH1设为 0 可停止服务自行下载时刻表(请改用 cron 任务)
TIMETABLE_MAX_AGE_HOURS26数据超过此时长后重新下载
TRAINTRACKER_DATA_DIR若已设置则为 $XDG_DATA_HOME/traintracker,否则为 ~/.traintracker导入前馈送文件的下载位置
RATE_LIMIT_PER_MINUTE30/mcp 上每个账户每分钟的工具调用次数;设为 0 可关闭限制
RATE_LIMIT_BURST10每分钟速率限制生效前,一个账户可同时发起的工具调用次数
OPENAI_APPS_CHALLENGE—来自 OpenAI 插件门户的令牌。设置后,该令牌会通过 /.well-known/openai-apps-challenge 返回,供 OpenAI 获取以验证域名
MIN_INTERCHANGE_MINUTES5规划所需的最短换乘时间
TRAINLINE_LIVE_URLhttps://www.thetrainline.com/live时刻表服务中 Trainline 链接的基础地址
HTTP_TIMEOUT_SECONDS15上游请求超时时间
TRAINTRACKER_DEMO关闭设为 1 可使用生成的示例数据,而非任何账户数据(见无需账户即可试用:演示模式)
TRAINTRACKER_NO_DOTENV关闭设为 1 可阻止列车工具读取 .env(预览服务会设置此项)

命令

每条命令都是 Django 管理命令,通过 uv run python manage.py <command> 运行。更改数据的命令只会说明其将执行的操作,除非指定 --commit。

命令作用
runserver在本地运行网站、登录功能和 /mcp(生产环境使用 gunicorn;请参阅部署到 Render)
serve_stdio通过 stdio 运行 MCP 服务(Claude 桌面应用和 MCP Inspector 使用的方式)。无需登录,也没有速率限制
migrate创建或更新 Django 的数据表
refresh_timetable [--commit]下载 SCHEDULE 源并重建时刻表(在演示模式下,重建生成的时刻表)
import_timetable FILE [--commit]根据你自行下载的源文件构建时刻表(JSON,可压缩或不压缩)
rail_status显示已配置的来源、已使用的 Darwin 配额和时刻表详情
forget_account EMAIL [--commit]删除指定邮箱的账户及其通行密钥、已保存的站点信息、已连接应用的令牌和任何登录请求(即擦除请求)
block_account EMAIL [--commit]关闭指定地址的账户,或将其设为已关闭状态,使其无法登录,并停止其已连接的应用
purge_idle_accounts [--commit]删除 180 天内没有登录且没有新令牌的账户
purge_sign_in_requests [--commit]删除已过期的登录请求
purge_idempotency_records [--commit]删除超出 24 小时保留期限的幂等性记录(Titan 的记录)
cleartokens删除已过期的 OAuth 令牌(django-oauth-toolkit 的令牌)

账户命令的说明见 docs/accounts.md。使用 serve_stdio 时,日志会写入 stderr,stdout 则承载 MCP 协议。

部署到 Render

render.yaml 在法兰克福定义了三个服务:

服务类型用途环境
traintrackerWeb 服务,512 MB,traintrackr.livegunicorn,1 个 worker,8 个线程。构建时运行 collectstatic,每次部署上线前运行 migrate,健康检查路径为 /livez环境组 titan 和 traintracker;在服务上设置 DARWIN_API_KEY、OPENAI_APPS_CHALLENGE 和 TIMETABLE_AUTO_REFRESH=0
traintracker-refreshCron 作业,每天 UTC 时间 06:30manage.py refresh_timetable --commit环境组 titan 和 traintracker;在服务上设置 NR_USERNAME、NR_PASSWORD
traintracker-purgeCron 作业,每天 UTC 时间 03:17purge_idempotency_records、purge_sign_in_requests、cleartokens 和 purge_idle_accounts:隐私政策规定要删除的内容环境组 titan 和 traintracker

这两个环境组由 titan 创建。titan 是随 django-titan-template 提供的命令行工具。titan 由所有 Titan 应用共享(关闭调试、Python 版本、主机和来源、SMTP 中继);traintracker 是此应用专用的(DATABASE_URL、DJANGO_SECRET_KEY、ACCOUNTS_EMAIL_KEY、邮件密钥和发件人、SITE_URL、FIVEBAR_DOMAIN,以及手动添加的 FIVEBAR_TOKEN)。ACCOUNTS_EMAIL_KEY 用于生成查找每个账户的一次性哈希:请妥善保存副本,切勿更改它(文档)。Blueprint 会引用这些环境组,但不会声明它们,因此同步时不会覆盖它们;在服务上设置的值优先于环境组中的值。Web 服务只运行 1 个 worker,因为列车工具在每个进程中共用一个事件循环、一个 Darwin 配额和一个行程网络(决策说明)。它会在内存中保留一天的行程网络,以供 plan_journey 使用(约 200 MB),因此至少需要 512 MB。

  1. 运行 titan deploy traintracker。首次部署前,它会创建 Blueprint 所需的资源:共享的 titan 环境组、应用角色、共享 Postgres 实例上的数据库、仅用于发送邮件的 Resend 密钥,以及 traintracker 环境组。随后它会部署 Blueprint、将域名 traintracker.<parent domain> 添加到服务,并通过其 onrender.com 域名检查 /healthz。Render 提示输入时,请在相应服务上设置 DARWIN_API_KEY、OPENAI_APPS_CHALLENGE、NR_USERNAME 和 NR_PASSWORD。
  2. 手动运行一次 traintracker-refresh Cron 作业(Trigger Run),以加载首份时刻表。
  3. 为服务配置域名。titan 自带的 golive 会将应用指向 <slug>.<parent domain>;此部署使用的是目录列表、MCP Registry 和用户连接器所用的 traintrackr.live,因此需要手动配置:将域名添加到服务,在服务的 DJANGO_ALLOWED_HOSTS 中添加该域名(接在 titan 环境组的值之后),并在 traintracker 环境组中设置 SITE_URL=https://traintrackr.live 和 FIVEBAR_DOMAIN=traintrackr.live。titan 从不覆盖已设置的值,因此也可以在那里更改 DEFAULT_FROM_EMAIL。
  4. 将此服务添加为 claude.ai 连接器(见下文)。
添加为 claude.ai 连接器

/mcp 是 Titan 的 MCP 视图,位于 mcp-auth 之后;mcp-auth 是基于 django-oauth-toolkit 构建的模板 OAuth 服务,因此只需在 claude.ai 中添加一次,即可通过 claude.ai、Claude Desktop 和移动应用使用。ChatGPT 的连接方式相同。

  1. 在 claude.ai 中:Settings → Connectors → Add custom connector,将其命名为 traintracker,URL 填写 https://<your-service-host>/mcp。OAuth 客户端字段留空:Claude 会自行注册。
  2. Claude 会打开服务的登录页面。登录(参见登录)。

登录后,Claude 会获得一个有效期为一小时的访问令牌和一个有效期为 30 天的刷新令牌;每次刷新时,刷新令牌都会轮换。这里列出了 offline_access 作用域,ChatGPT 需要它来在访问令牌过期后保持连接。仅接受发往 Claude、ChatGPT 和回环地址(Claude Code 等桌面客户端)的回调(MCP_AUTH 位于 config/settings.py)。任何拥有有效账户的人都可以连接。/oauth/connected/ 会列出已连接到当前登录账户的应用。traintracker-purge cron 作业每晚删除过期令牌。

登录

登录使用 Titan 账户:先输入电子邮件地址,然后使用邮件中的链接或六位数验证码登录;也可以使用从账户页面添加的通行密钥。这里没有密码。docs/accounts.md 详细介绍了链接和验证码的有效时长、邮件发送和验证码尝试次数的限制、账户会保留哪些信息,以及如何关闭或删除账户。设置 DJANGO_DEBUG=1 时,登录邮件会写入控制台日志,而不是发送出去;不要在日志可能被他人读取的主机上使用此设置。

速率限制。 /mcp 的工具调用按账户限流:可同时发起 RATE_LIMIT_BURST 次调用,并按 RATE_LIMIT_PER_MINUTE 的速率补充额度。所有用户共用一个 Darwin 密钥,此限制可防止单个账户耗尽全部额度。每次调用会消耗一次 Darwin 请求;如果一次调用会发起更多请求(例如逐页读取较长的 board,或包含多个路段的行程),每个额外请求也会计费,因此该账户后续调用的等待时间会更长。行程规划计为三次调用。超出限制的调用会返回工具错误:请求过多。请在 N 秒后重试。,模型可以读取并转达此错误。计数保存在内存中,因此重启会清除计数。serve_stdio 不受限制。

站点

Django 应用还提供一个小型公开站点,因此只需部署一次、使用一个域名:

路径页面
/服务器的功能、带复制按钮的连接器地址、如何将其添加到 Claude 和 ChatGPT,以及三个示例提示词
/docs用通俗语言介绍每个工具,三个演示示例及其答案包含的内容、限制、数据来源和支持信息
/privacy隐私政策(UK GDPR):处理哪些数据、原因、保存时长及处理方
/terms使用条款:服务按现状提供、准确性、责任、公平使用、数据许可和适用法律
/board选择一个车站,并可选一个站台,查看实时信息板(参见可分享的信息板)

站点位于 apps/public/。页面使用 Django 模板:每页的内容片段位于 templates/public/pages/(index.html、docs.html、privacy.html、terms.html),并嵌入 templates/public/layout.html,由 views.py 渲染;pages.py 列出这些页面、生成页脚链接,并将隐私页面转换为 privacy_policy 工具返回的文本。可分享的信息板(信息板页面、选择器、嵌入视图、电视视图、JSON 数据源和车站建议)由 boards.py 按请求渲染;frame.html 仅显示信息板,用于嵌入或电视展示。静态文件位于 static/:一个样式表 css/site.css,以及两个脚本:js/site.js 用于复制按钮、出发信息板和车站选择器;js/saved_boards.js 用于保存你的上一个信息板和收藏。信息板是应用的视觉风格,由 site.js 根据 index.html 中的示例列车表绘制:apps/rail/ui/board.html 将样式和脚本内嵌,而站点的内容安全策略会拒绝这些内嵌内容,因此翻页显示效果会在 site.css 和 site.js 中重新实现。更改应用绘制翻页显示效果的方式时,两个文件都要修改。图标为 static/icons/icon.svg,并以其为源生成 32、180 和 512 像素的 PNG;上传到目录列表的是 icon-512.png,而 /favicon.ico 会重定向到 32 像素的 PNG。要更改图标,请编辑 SVG 并重新生成 PNG,例如 magick -background none -density 1200 icon.svg -resize 512x512 PNG32:icon-512.png。链接预览卡片是 static/img/share.png,尺寸为 1200 × 630,源自 static/img/share.svg:它展示了首页在出发信息板应用旁作出的承诺。渲染它需要浏览器:卡片使用系统的无衬线字体和粗体等宽字体,而 ImageMagick 自带的 SVG 渲染器无法选择这些字体。在浏览器中将 share.svg 绘制到 1200 × 630 的画布并保存为 PNG,或者设置设备像素比为 1 并截取该尺寸的屏幕截图;然后运行 magick saved.png -strip PNG24:share.png,移除 Alpha 通道,因为测试会拒绝带有 Alpha 通道的文件。在 share.svg 中,每个翻页片都是一个 <rect>,每个字母都是独立的 <text>,因此更改列车时,需要逐个修改字母。无需构建步骤。页面会显示服务器自身的配置值(来自 SITE_URL 的连接器地址,以及来自 RATE_LIMIT_PER_MINUTE 和 RATE_LIMIT_BURST 的公平使用限制),因此部署到其他位置时,页面描述的就是该部署本身。隐私政策和使用条款中写明了本仓库部署的信息及其运营方:部署你自己的版本时,请修改 privacy.html、terms.html 和支持地址。

样式表和脚本由 WhiteNoise 通过带有文件哈希的名称提供(collectstatic),因此浏览器会立即获取已更改的文件,并缓存未更改的文件。页面不会设置 Cookie,也不会从其他源加载内容,除非设置了 FIVEBAR_DOMAIN 时会加载 fivebar 的计数器;Content-Security-Policy 标头仅允许加载站点自身的样式表、脚本和请求。页面会遵循读者的浅色或深色设置,并适配手机屏幕宽度。

可分享的信息板

/board/LST 是一座车站的实时出发信息,单独占据一个页面;/board/LST/9 是一个站台的信息;/board/LST/COL 则是停靠科尔切斯特的列车(或者,对于接下来两小时内没有直达列车的车站,例如 /board/LST/SUY,显示每趟列车,以及换乘车站的接续信息)。这是首页的翻牌式列车显示屏,包含实时列车信息和车站时钟,可在屏幕上保持打开、分享链接或嵌入其他网站。无需登录。/board 是用于选择车站、目的地或站台的表单;输入车站名称时,车站字段会显示名称建议。

地址内容
/board/LST伦敦利物浦街站接下来 10 趟出发列车:未来两小时内显示实时信息;如果显示屏上的列车不足,则接着显示时刻表中的计划列车(见下文)
/board/LST/9仅显示 9 号站台的出发列车;若尚未公布列车的实时站台,则按计划站台匹配
/board/LST/COL显示停靠科尔切斯特的出发列车,无论终点站在哪里:也包括开往诺里奇的列车
/board/LST/COL?tv=1仅显示列车显示屏,铺满电视屏幕:见下文
/board/LST/9?embed=1仅显示同一列车显示屏,不含网站页眉或页脚,供 <iframe> 使用。这是唯一允许其他网站嵌入的页面
/api/board/LST/9以 JSON 格式提供列车显示屏数据;页面在显示期间每分钟获取一次
/api/boards已登录用户保存的列车显示屏:见下文

Darwin 只提供未来两小时的信息,因此,冷清的线路或夜间的任何车站都会让显示屏几乎空空如也。若显示屏上的列车不足 10 趟,就会接着显示时刻表中的计划列车,从 Darwin 两小时数据的截止时间开始,最多延伸至一天后,确保同一趟列车不会重复显示。计划列车的预计时间会以淡色字样标注为 Scheduled(琥珀色仍表示实时且准点),进入两小时范围后则会更新为实时信息。较晚日期的列车会归在该日期的标题下(MONDAY 19 OCTOBER),来源说明会标明两种数据来源。工具会将这些列车标记为 source: "timetable",并附上其运行日期 date。

车站代码后若跟着另一个三字母代码,表示目的地;其他内容则表示站台。一块显示屏只能按目的地或站台筛选,不能同时按两者筛选。每块显示屏都有一个固定地址:小写代码、名称(/board/cambridge、/board/LST/colchester)或写作 p9 或 platform-9 的站台地址,都会重定向至该地址,因此分享同一块显示屏时始终使用同一个链接。若名称对应多个车站,则会进入选择器,让用户选择车站。显示屏页面提供链接和 <iframe> 代码,各自配有复制按钮,还提供通往各站台显示屏的链接。

页面会将列车信息渲染为表格,因此无需 JavaScript 也能使用;site.js 会绘制翻牌,每次更新时,字母会从旧内容翻转为新内容。任何人都可以打开显示屏,而且嵌入繁忙页面的显示屏会被所有访客打开,因此发送给 Darwin 的请求是每块显示屏每分钟一次,而不是每位访客一次:答案(或失败结果)会缓存 60 秒,并由该显示屏的所有请求共享(board.py 中的 SharedBoards);获取数据期间到达的请求会等待并共用同一个答案。每个客户端地址可同时打开 30 块显示屏,并且每分钟最多打开 60 块(BOARD_LIMIT,见 apps/public/board.py);超过限制时会返回 429 响应,并附带 Retry-After。和其他请求一样,显示屏请求也计入 DARWIN_DAILY_LIMIT。 你的站点看板。 首页会实时显示你上次打开的看板,取代示例看板;下方会以链接形式列出你的收藏。看板页面上有 添加到收藏(最多 12 个;添加第 13 个时会移除最早添加的收藏)。退出登录时,浏览器会保存收藏(localStorage),不会向服务器发送任何内容。登录后,账户会保存收藏(SavedBoard、apps/public/saved.py 中的 /api/boards),浏览器则不保存,因此所有设备上的收藏都相同;登录时,浏览器保存的收藏会转移到账户中。嵌入视图和电视视图永远不会被记住。所有人的首页 HTML 都相同,因此可以保持缓存;static/js/saved_boards.js 和 site.js 会填入你的看板。原因:docs/decisions/saved-boards-live-in-the-browser-or-the-account.md。

在电视上。 ?tv=1 会单独显示看板,并调整翻牌的大小,让每列车次都能显示在屏幕内:宽屏上每列车次占一行,竖屏上占两行。该尺寸下屏幕剩余的列会拓宽目的地栏,让看板填满屏幕宽度,并容纳较长的名称。在看板页面上,在电视上显示会就地切换到相同视图并进入全屏,适用于拖到作为扩展显示器的电视上的窗口,或投屏的标签页;退出全屏后会返回原视图。电视上的屏幕会保持唤醒状态(浏览器支持时使用 Screen Wake Lock),光标在 3 秒不移动后会隐藏,页面每晚会在英国时间 03:10 至 03:50 之间自动重新加载一次,让持续运行数周的看板也能获取站点更新。它与该看板的其他所有视图共用数据请求,因此不会给 Darwin 增加额外负担。每个实时看板都会在“已更新”旁显示距离下次更新的倒计时;超过 5 分钟未更新的看板会变暗,并显示上次更新时间。

MCP Registry

server.json 描述了供官方 MCP Registry 使用的服务:名称 live.traintrackr/traintracker、版本,以及一个位于 https://traintrackr.live/mcp 的远程、可流式传输的 HTTP 服务。它遵循 Registry 的 2025-12-11 架构。有一项测试会确保其中的版本与 pyproject.toml 保持一致。

版本 0.1.0 已发布。CI 不负责发布:新版本需要手动发布,先运行 mcp-publisher login dns,再运行 mcp-publisher publish。live.traintrackr/ 名称需要证明你持有该域名,方法是在 traintrackr.live 的顶级域名上设置一条 TXT 记录,其中包含签名密钥的公钥部分。部署你自己的版本时,请将名称和 URL 改为你的域名。

限制

  • 过去的运行时间(“昨天 08:00 的车晚点了吗?”)不可用。Darwin 只涵盖现在到未来 2 小时;时刻表显示的是计划时间。
  • Darwin 宕机:Darwin 离线时,实时工具会显示计划时间,并说明 Darwin 离线;在其恢复之前,晚点、取消和实时站台信息均不可用。
  • 不包含票价。
  • 时刻表不包含地铁/公交/有轨电车,只有近似的伦敦终点站链接。
  • 工程施工会在 Network Rail 发布后出现在时刻表中(通常会提前很久),并会在当天出现在 Darwin 中。

开发

Traintrackr 是一个基于 Titan 的 Django 项目。Titan 是其同系列应用所用的项目模板。它分四步从独立的 Starlette 应用迁移到了 Titan(迁移决策);新开发内容应尽量贴近模板,以便 copier update --trust 能顺利合并。HTTP 由 Django 在 gunicorn 下提供服务,列车工具则在每个进程的单个事件循环上运行(相关决策)。

与 Titan 一样,tox 通过 tox-uv 插件使用 uv.lock 中的依赖,在 Python 3.14 上运行所有检查;docs/testing.md 说明了各项测试的运行位置。铁路测试(tests/rail/)需要一个可创建架构的 Postgres,地址由 TEST_DATABASE_URL 指定(默认值为 postgresql://postgres:[email protected]:55432/postgres;安装部分中的 docker run 命令会提供该数据库)。每项测试都使用自己的架构,并在结束后将其删除(tests/rail/conftest.py)。CI 将 Postgres 17 作为服务运行。

uvx --with tox-uv tox              # fmt, lint, types, checks, test, audit
uvx --with tox-uv tox -e test      # one environment
uvx --with tox-uv tox -e test -- -k platform   # arguments after -- go to the tool
uvx --with tox-uv tox -e sast      # semgrep (downloads its rule packs)

CI(.github/workflows/ci.yml)将每个环境作为独立作业运行,也会运行 sast 和 gitleaks 扫描;它使用工作流中指定版本的 uv、tox 和 tox-uv,并将 Actions 固定到某个提交。Dependabot(.github/dependabot.yml)每周为 uv.lock、package-lock.json 和 Actions 提交更新建议;uv 和 tox 的版本则手动升级,uv 也会在 render.yaml 中升级。uv run pre-commit install 会在每次提交前运行 ruff、gitleaks 和 mypy。

环境运行内容
fmtruff format --check
lintruff check:包含 Titan 的规则、文档字符串和 bandit,适用于所有代码。apps/rail/ 中的 SQL(及其测试)使用 f-string 拼接架构名称,因此不受 S608 检查
types使用 django-stubs 的 mypy;apps/rail/ 保持严格检查
checks使用生产设置运行 manage.py check --deploy,并检查是否有缺失的迁移
test使用 coverage 运行 pytest(覆盖率下限为 90%):tests/rail/ 测试导入器、STP 规则、规划器、下载、客户端、演示模式、工具、命令、速率限制和 Darwin 用量;tests/public/ 测试网站和站台;tests/mcp/ 测试 /mcp 端点及其工具;tests/accounts/ 测试登录、通行密钥和账户命令;tests/core/ 测试 Titan 的共享组件
js使用 Vitest 和 jsdom 测试 tests/js/:检查 static/js 在页面中的行为。Node 仅用于测试(package.json)
audit使用 pip-audit 审计生产依赖,使用 npm audit 审计测试工具
sastsemgrep(不在默认列表中:它会下载规则包)

测试使用 Network Rail JSON 格式的合成 SCHEDULE 源数据(tests/rail/feedgen.py),以及参照已发布 Darwin 架构构造的 API fixture。它们并非真实记录,因此首次针对实际服务运行测试才是最终检查。

预览服务器

.claude/launch.json 中配置了两个服务器,可通过 Claude Code 的预览面板启动。两者都在上述开发用 Postgres 上以演示模式运行,忽略 .env,且只监听 127.0.0.1。设置 PREVIEW_DATABASE_URL 可改用其他数据库。

名称运行内容用途
web运行 manage.py migrate,然后在端口 8000 上以 DJANGO_DEBUG=1 运行 manage.py runserver;若该端口已被占用,则使用空闲端口预览公开网站、登录页面和 /mcp。登录邮件会写入服务器控制台日志
mcp-inspector通过 npx 运行 MCP Inspector(版本 2),监听端口 6274,并以 manage.py serve_stdio 作为 stdio 目标手动调用工具。其 Apps 选项卡会显示工具的 MCP App(如果有)

Inspector 需要 Node 22.19 或更高版本。它会启动一个可运行命令的本地服务器,并由每次启动时生成的令牌保护;令牌会放入它提供的页面中。配置保留了该功能。

manage.py
config/          Settings (one module, from the environment), URLs, WSGI/ASGI
apps/
  core/          Titan's shared pieces: BaseModel, idempotency, rate limits, /livez, /healthz and /.well-known/security.txt
  accounts/      Sign-in by email link or code, passkeys, the account commands
  mcp/           /mcp: Titan's MCP view (mcp-auth), the tool list, ui:// resources
  public/        The site: pages (views.py, pages.py), boards (boards.py, board.py), saved boards (saved.py), templates
  pwa/           The app's name and identity, as Titan's templates use it
  rail/          The train tools and the data behind them
    server.py    MCP tools, source fallback, live overlay
    runtime.py   The tools' event loop, one per process
    timetable.py SCHEDULE importer and Postgres queries (STP resolution)
    planner.py   Connection Scan journey planner, London links
    darwin.py    Rail Data Marketplace LDBWS client
    usage.py     Count of requests sent to Darwin, against the allowance
    ratelimit.py Per-account limit on tool calls
    stations.py  Station search and name resolution
    trainline.py Links to a train's page on Trainline
    schemas.py   Output models shared by all sources
    demo.py      Demo mode: generated timetable and in-process Darwin
    config.py    The train tools' settings, from the environment
    ui/          MCP App: the departure board (ui://traintracker/board.html)
    data/        stations.json, trainline_slugs.json
    management/  serve_stdio, refresh_timetable, import_timetable, rail_status
templates/       Traintrackr's sign-in, account and connect pages
static/          site.css, site.js, the sign-in scripts, the icons and the share card
tests/           core, accounts, mcp, public, rail
docs/            accounts.md, testing.md, decisions/

数据与许可

Darwin 数据通过 Rail Data Marketplace 获取,Network Rail 数据馈送则按您订阅时接受的条款使用。重新分发任何输出前,请先查看这些条款。两者都要求注明来源:

数据署名措辞来源
Darwin(实时运行时间)“Powered by National Rail Enquiries”,并附上指向 nationalrail.co.uk 的链接,以及 NRE 品牌指南中的徽标NRE Developer Guidelines v06-01,第 4 节。若馈送数据与其他数据结合使用,可在署名页面注明来源
Network Rail SCHEDULE(时刻表)“Contains public sector information licensed under the Open Government Licence v3.0.”Network Rail 数据馈送许可依据开放政府许可 v3.0发布这些数据馈送,且未另行说明,因此适用该许可的默认条款
车站列表davwheat/uk-railway-stations,Open Database License (ODbL)该仓库的许可

署名信息位于 /docs 的“数据来源”部分。网站每个页面的页脚都注明 National Rail Enquiries,并提供指向该部分的“数据来源”链接。服务端指令中有一行列明了数据来源,因此助手在说明答案来源时可以注明;工具响应中不会重复添加这些信息。页脚包含文字和链接,但不含 NRE 徽标:Darwin 数据馈送页面上的品牌素材包规定,使用徽标须获得 National Rail 的许可。相关许可已于 2026-09-30 申请(layout.html 中的 TODO(hugo))。

代码:MIT。

评论

支持 Markdown

第一次接触 MCP?

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

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