使用说明
🚌 DART MCP 服务器(因为您喜欢等公交)
一个承诺会告诉你相关信息的模型上下文协议(MCP)服务器 确切地 当询问下一趟DART公交车何时到达……结果反正也会晚10分钟。使用的是真实的GTFS数据,所以至少这种失望是官方的!
特性(或:“我们为何开发这个产品”)
- 🚌 公交车 “实时”公交时刻表 - 获取任意两个站点之间的下一班发车信息(实际到达时间可能无限变化)
- 📍(定位标记,常用于地图或指示位置) 停止查找 - 因为显然64个停靠站太多了,记不住🤷♀️
- 🕐 时钟,表示一个小时的时间单位或提醒时间。 特定时间查询 - 以手术般的精准度规划你的通勤路线,然后看着一切计划崩塌
- ✨(闪闪发光的符号,常用于表示兴奋、喜悦或特别的时刻) 智能搜索 - 这里大家都很懒,所以输入“dart”缩写而不是全名
- 📊 表格/数据图表 基于GTFS的 - 我们使用的数据与DART相同,所以当出现问题时,我们可以一起追究它们的责任
设置(有趣的部分🙄)
-
安装依赖项 (又名“更多要出问题的东西”):
# Install uv if you haven't already (because pip is apparently too mainstream now) curl -LsSf https://astral.sh/uv/install.sh | sh # Install dependencies using uv (fingers crossed it actually works) uv sync -
获取那份甜美、宝贵的GTFS数据: 服务器期望接收DART GTFS数据格式
src/dart_mcp/data/dart-tx-us/目录。因为显然我们不能礼貌地问问火车它们在哪里。uv run python scripts/fetch_gtfs.py这个神奇的脚本会下载包含以下内容的文件:
stops.txt- 所有火车假装停靠的地方trips.txt- 穿越时空的理论之旅stop_times.txt- 当火车在 理应;据说是 到达(剧透:他们并没有)calendar.txt- 工作日与周末的时刻表(因为火车也需要工作与生活的平衡)
使用方法(祝你好运!)
本地MCP服务器(真家伙)
这台服务器是设计为与MCP客户端(如Claude Desktop)一起使用的,而不是直接由人类运行(因为那样就太简单了)。以下是实际使用方法:
使用 Claude Desktop
将此添加到您的Claude Desktop MCP配置文件中:
{
"mcpServers": {
"dart": {
"command": "uvx",
"args": ["dart-mcp"]
}
}
}
这将自动从PyPI安装并运行最新版本。
然后重启Claude桌面应用,您就可以直接在对话中访问DART时刻表了!
与其他MCP客户端一起
任何兼容MCP的客户端都可以通过以下方式启动此服务器来使用它:
uvx dart-mcp
该服务器通过stdin/stdout使用MCP协议进行通信。直接运行时,它不会执行任何特别的操作——只是静静地等待接收正确的MCP消息。
远程HTTP服务器(用于CustomGPT.ai及Web客户端)
对于像CustomGPT.ai这样的需要远程MCP服务器URL的服务,我们已经提供了一个基于FastAPI的HTTP服务器:
快速入门
# Start the remote server locally
dart-mcp-server
# or
uvicorn dart_mcp.remote_server:app --host 0.0.0.0 --port 8000
部署到云端
# Railway (recommended)
railway init && railway up
# Render
# Push to GitHub and connect to Render
# Fly.io
flyctl launch && flyctl deploy
可用的终端节点
GET /- 服务器信息GET /health- 健康检查GET /mcp/tools- 列出可用工具POST /mcp/next_trains- 获取下一班公交车发车时间GET /mcp/stations- 列出所有公交车站GET /mcp/routes- 列出所有公交线路
示例API用法
# Get next buses
curl -X POST http://localhost:8000/mcp/next_trains \
-H "Content-Type: application/json" \
-d '{"origin": "DART", "destination": "UNIVERSITY"}'
# List all routes
curl http://localhost:8000/mcp/routes
📋 一个清单或待办事项的符号,可翻译为“清单”或“待办事项”。 看 `DEPLOYMENT.md` 翻译为中文是:“部署指南.md” 或 “部署说明.md”。这里,“DEPLOYMENT”指的是“部署”,而“.md”是Markdown文件格式的后缀,通常用于编写技术文档、说明文件等 以获取详细的部署说明。
测试服务器(用于开发)
你可以通过直接导入它来测试这个东西是否真的有效:
from dart_mcp.server import next_trains, list_stations
# Test next buses functionality (prepare for disappointment)
result = await next_trains('DART Central Station', 'University')
print(result) # Spoiler: there are no buses
# Test stops list (all 64 of them, because apparently that's manageable)
stations = await list_stations()
print(stations)
可用工具(你的新好伙伴)
next_trains(origin, destination, when_iso=None)
礼貌地询问下一趟火车何时到达。服务员会查看它的“水晶球”(GTFS数据),然后告诉你预计的时间 从技术上讲 准确。
参数:
origin(字符串):你现在所在的地方(可能正为自己的人生选择感到后悔)destination(字符串):你想去的地方(可能除了这里,任何地方都行)when_iso(字符串,可选):当你想要出行时(好像在公共交通中时间有什么意义似的)
示例:
# Next buses from current time (aka "right now would be nice")
next_trains('DART Central Station', 'University')
# Buses at a specific time (for the optimists who think schedules matter)
next_trains('University', 'DART Central Station', '2025-05-23T06:00:00')
# Using abbreviations (because typing is hard)
next_trains('dart', 'university')
list_stations()
获取所有64个DART公交站点的列表,因为显然要求记住它们太过困难。
返回值: 一个格式化的列表,会让你意识到这辆公交车到底要去多少个地方。
车站名称识别(我们不是心灵感应者,但我们会尽力)
服务器支持多种方式来简化输入站名的过程:
- 全名“DART中央车站”(专为追求完美者设计)
- 简称“大学”(对于稍不那么追求完美主义者而言)
- 缩写“dart” → “DART中央车站”(为真正懒人准备)
- 部分匹配“university”与“University”匹配(当你懒得区分大小写时)
可用站点(全部64个辉煌站点)
我们的服务器涵盖了每一个DART公交站点,因为我们追求完美:
DART铁路系统 (主赛事)
-
红线达拉斯市中心、珍珠/艺术区、城市广场/上城、嘲鸫(Mockingbird,此处为地名,直译保留)、公园大道、胡桃山/登顿、森林大道、林登·B·约翰逊/中央区、春谷、阿拉帕霍中心、加拉廷公园、布什高速公路、帕克路、普兰诺市中心、第15街/普兰诺、卡罗尔顿市中心、三一磨坊、环城公路、春谷(重复项,翻译时可略去或注明重复)、森林大道(重复项,翻译时可略去或注明重复)、胡桃山/登顿(重复项,翻译时可略去或注明重复)、公园大道(重复项,翻译时可略去或注明重复)、嘲鸫(重复项,翻译时可略去或注明重复)、城市广场/上城(重复项,翻译时可略去或注明重复)、珍珠/艺术区(重复项,翻译时可略去或注明重复)、达拉斯市中心(重复项,翻译时可略去或注明重复)
-
蓝线达拉斯市中心、珍珠/艺术区、城市广场/上城、嘲鸫(Mockingbird,此处可能指达拉斯的一个社区或区域)、公园大道、胡桃山/登顿、森林大道、林登·B·约翰逊/中央区、春谷、阿拉帕霍中心、加拉廷公园、布什高速公路、帕克路、普莱诺市中心、第15街/普莱诺、卡罗尔顿市中心、三一磨坊、环城公路、春谷(重复)、森林大道(重复)、胡桃山/登顿(重复)、公园大道(重复)、嘲鸫(重复)、城市广场/上城(重复)、珍珠/艺术区(重复)、达拉斯市中心(重复)
-
绿线达拉斯市中心、珍珠/艺术区、城市广场/上城区、嘲鸫大道、公园大道、胡桃山/登顿、森林大道、林登·贝恩斯·约翰逊/中央区、斯普林瓦利、阿拉帕霍中心、加拉廷公园、布什收费公路、帕克路、普莱诺市中心、第15街/普莱诺、卡罗尔顿市中心、特里尼蒂米尔斯、环城大道、斯普林瓦利、森林大道、胡桃山/登顿、公园大道、嘲鸫大道、城市广场/上城区、珍珠/艺术区、达拉斯市中心
-
橙线达拉斯市中心、珍珠/艺术区、城市广场/上城、嘲鸫区、公园大道、胡桃山/登顿、森林大道、林登·B·约翰逊/中央区、斯普林瓦利、阿拉帕霍中心、加拉廷公园、布什高速公路、帕克路、普兰诺市中心、第15街/普兰诺、卡罗尔顿市中心、三一磨坊、环城路、斯普林瓦利、森林大道、胡桃山/登顿、公园大道、嘲鸫区、城市广场/上城、珍珠/艺术区、达拉斯市中心
样本输出(准备被惊艳到)
🚌 Next DART bus departures from DART Central Station to University on Thursday, May 22, 2025:
• Bus 153: 17:58:00 → 19:16:00 (to University)
• Bus 527: 18:22:00 → 19:22:00 (to University)
• Bus 155: 18:28:00 → 19:46:00 (to University)
• Bus 429: 18:43:00 → 19:53:00 (to University)
• Bus 157: 18:58:00 → 20:16:00 (to University)
实际到达时间可能会有所不同。副作用可能包括对存在的恐惧以及对远程工作的深深喜爱。
技术细节(给技术爱好者看的)
- GTFS处理我们自动处理车站与其站台之间的关系(因为显然列车系统很复杂)
- 服务日历遵守工作日/周末时间表(火车也需要休息呢)
- 数据类型处理GTFS文件中混合整数/字符串格式的混乱情况
- 时间解析支持24+小时格式,满足那些传奇般的深夜服务需求
- 错误处理当你输入“Narnia”作为电台名称时,系统会优雅地处理(即不会报错或崩溃)
项目结构(有序的混乱)
dart-mcp/
├── .github/workflows/ # GitHub Actions (the CI/CD overlords)
│ ├── ci.yml # Main CI pipeline (linting, testing, the works)
│ └── update-gtfs.yml # Automated GTFS data updates
├── src/dart_mcp/ # Main package (because modern Python demands structure)
│ ├── data/dart-tx-us/ # GTFS data storage (where CSV files go to retire)
│ ├── __init__.py # Package initialization (the ceremony of Python)
│ ├── __main__.py # Entry point for python -m dart_mcp
│ ├── server.py # MCP server implementation (where the magic happens)
│ └── gtfs.py # GTFS data processing (aka "CSV wrestling")
├── scripts/ # Utility scripts (the supporting cast)
│ ├── __init__.py # Makes scripts a proper Python package
│ ├── fetch_gtfs.py # Downloads the latest disappointment data
│ └── lint.py # Run all CI checks locally (before embarrassment)
├── tests/ # Test suite (because trust but verify)
│ ├── conftest.py # Shared test fixtures (the common ground)
│ ├── test_gtfs.py # GTFS functionality tests (8 tests of data wrangling)
│ ├── test_server.py # Server functionality tests (4 tests of MCP protocol)
│ └── test_fetch_gtfs.py # Data fetching tests (7 tests of download chaos)
├── .pre-commit-config.yaml # Pre-commit hooks configuration
├── pyproject.toml # Modern Python config (because setup.py is so 2020)
└── README.md # This literary masterpiece
开发与测试(应对不可避免的故障情况)
代码质量与持续集成/持续交付(CI/CD)
这个项目使用现代的Python工具来保持代码的简洁和可维护性:
- “Ruff”可以翻译为“粗糙”或“粗犷”,具体含义取决于上下文。在描述物体或表面时,它可能指不光滑、有凹凸不平的质感;在描述人的性格或行为时,它可能指粗鲁、不拘小节的特点闪电般的快速代码检查和格式化(因为生命太短暂,不能浪费在慢工具上)
- MyPy类型检查(因为猜测类型是业余人士的做法)
- Pytest带有覆盖率报告的测试框架
发布流程(自动化精彩体验)
这个项目采用自动化版本管理和发布:
- 语义化版本控制版本号是根据提交信息自动生成的,使用 规范提交(或:约定式提交)
- 自动标记当你推送至
mainsemantic-release 会自动创建版本标签 - PyPI 发布带标签的发布版本会通过 GitHub Actions 自动构建并发布到 PyPI
- 可信出版使用PyPI进行OIDC认证(无需API令牌!)
发布版本
只需使用标准的提交格式进行提交,然后推送到主分支:
# For bug fixes (patch version bump: 1.0.0 → 1.0.1)
git commit -m "fix: correct station name lookup bug"
# For new features (minor version bump: 1.0.0 → 1.1.0)
git commit -m "feat: add support for weekend schedules"
# For breaking changes (major version bump: 1.0.0 → 2.0.0)
git commit -m "feat!: redesign API structure"
# or
git commit -m "feat: major API changes
BREAKING CHANGE: This changes the function signatures"
语义化发布(semantic-release)的工作流程将:
- 分析你的提交信息
- 确定适当的版本升级
- 创建一个 Git 标签(例如。,
v1.2.3) - 生成更改日志
- 触发发布工作流以发布到PyPI
本地测试
在推送之前,先在本地测试构建过程:
# Build packages locally
uv run python -m build --sdist --wheel
# Validate packages
uv run twine check dist/*
# Test upload to Test PyPI (optional)
uv run twine upload --repository testpypi dist/*
GitHub Actions CI(持续集成)
每次拉取请求(PR)和向主分支的推送都会触发自动检查:
- ✅ **代码检查(或代码格式化、代码规范检查)**粗略检查代码质量问题
- ✅ 格式化确保代码风格一致
- ✅ 类型检查MyPy 验证类型注解
- ✅ 测试完整的测试套件,附带覆盖率报告
- ✅ 覆盖范围在CI日志中生成测试覆盖率报告
如果任何检查失败,持续集成(CI)系统将会礼貌地拒绝您的拉取请求(PR),因为标准很重要。
MCP集成(用于AI统治者)
此服务器实现了模型上下文协议(MCP),这意味着它旨在与AI助手和其他MCP客户端无缝协作。一旦配置完成:
- **Claude Desktop(可译为“Claude桌面版”或保持原样,若“Desktop”在此处作为品牌或产品系列名称,则无需直译)**直接在对话中询问克劳德火车时刻表
- 其他MCP客户端任何兼容MCP的工具都可以访问DART数据
- 实时集成您的AI可以查看日程、建议路线,并帮助规划旅行
- 自然语言无需记住站点名称或命令语法
服务器提供了两个主要工具:
next_trains- 获取各站点之间的即将发车信息list_stations- 浏览所有可用的DART站点
所以,你的AI助手现在就像真人一样,可能会让你对火车时刻表感到失望!未来真的已经到来。
许可证(法律条款)
这个项目使用的是官方的DART GTFS数据。如果出现问题,请责怪他们,而不是我们。我们只是传递信息的媒介。
在达拉斯,这里公共交通既是必需品,也是无尽烦恼的源头,我怀着满腔热忱(❤️)并摄入了相当多的咖啡因,完成了这个作品。
