SNCF MCP服务器🚄
A. 模型上下文协议(MCP) 查询服务器 SNCF (法国国家铁路)使用官方Navitia API的列车时刻表。与Claude Desktop和其他MCP兼容客户端无缝集成。
  
✨ 特性
- 🔍 搜索火车 任何两个法国城市之间的实时数据
- 🚉 查找车站 在法国的任何一个城市
- 📅 灵活的日期解析 -接受ISO、欧洲和书面日期格式
- ⚡ 实时数据 -使用官方的SNCF Navitia API和实时时间表
- 🎯 智能出行规划 -显示接送、持续时间和路线详细信息
- 🌍 国际航线 -支持跨境旅行(如巴黎-慕尼黑)
- 🛠️ 克劳德桌面就绪 -与MCP客户端开箱即用
🚀 快速开始
先决条件
- Python 3.12或更高版本
- 紫外线 (推荐)或pip
- SNCF API密钥(免费注册)
安装
- 克隆存储库
git clone https://github.com/belgrano9/sncf_mcp_server.git
cd sncf_mcp_server- 安装依赖项
uv sync- 获取您的SNCF API密钥
- 注册地址: SNCF数字API门户网站 - 请求访问Navitia API - 复制API密钥
- 配置环境变量
创建一个 .env 项目根目录中的文件:
SNCF_API=your-api-key-here⚠️ 重要:永远不要承诺你的 .env 文件!它已经在里面了 .gitignore.
- 测试服务器
uv run server.py📖 用法
独立测试
直接在Python中测试搜索功能:
from server import search_trains, find_station
# Search for trains
result = search_trains("Paris", "Lyon", "2025-11-20 14:00")
print(result)
# Find a station
stations = find_station("Paris")
print(stations)或者使用附带的Jupyter笔记本(test_notebook.ipynb)用于交互式测试。
Claude桌面集成
添加到您的Claude Desktop配置文件中:
视窗 (%APPDATA%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"sncf": {
"command": "uv",
"args": [
"--directory",
"C:\\Users\\YourName\\path\\to\\sncf_mcp_server",
"run",
"server.py"
]
}
}
}macOS (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"sncf": {
"command": "uv",
"args": [
"--directory",
"/path/to/sncf_mcp_server",
"run",
"server.py"
]
}
}
}Linux (~/.config/Claude/claude_desktop_config.json):
{
"mcpServers": {
"sncf": {
"command": "uv",
"args": [
"--directory",
"/path/to/sncf_mcp_server",
"run",
"server.py"
]
}
}
}重新启动Claude Desktop,您可以问:
- *“明天下午2点给我看从巴黎到里昂的火车”*
- *“明天从巴黎东站到慕尼黑最早的火车是几号?”*
- *“查找巴黎的所有火车站”*
- *“从波尔多到马赛需要多长时间?”*
🛠️ MCP工具
1. search_trains
使用实时数据查找两个车站之间的列车。
参数:
origin(string):始发站/城市名称(例如,“巴黎”、“里昂”、“巴黎东站”)destination(string):目的站/城市名称(例如,“慕尼黑Hbf”、“巴塞罗那”)departure_datetime(字符串,可选):灵活格式的旅行日期/时间:
- ISO: "2025-11-28 08:00" (推荐) - 欧洲的: "28/11/2025 08:00" - 书面: "November 28, 2025 8:00am" - 默认值:当前时间
输出示例:
═══════════════════════════════════
SNCF JOURNEY SEARCH
═══════════════════════════════════
🔍 Searched for 'Paris Est':
✓ Paris Gare de l'Est (ID: stop_area:SNCF:...)
Paris - Bercy (ID: stop_area:SNCF:...)
Paris Montparnasse (ID: stop_area:SNCF:...)
→ Selected: Paris Gare de l'Est
🔍 Searched for 'München Hbf':
✓ München Hauptbahnhof (ID: stop_area:OCE:...)
→ Selected: München Hauptbahnhof
📅 Searching for trains departing after: 2025-11-28 08:00
🔄 API datetime format: 20251128T080000
─────────────────────────────────
🚄 AVAILABLE TRAINS
─────────────────────────────────
Found 5 journey option(s):
1. Depart: 2025-11-28 08:55 → Arrive: 2025-11-28 14:54
Duration: 5h 59min | Direct
2. Depart: 2025-11-28 10:55 → Arrive: 2025-11-28 16:54
Duration: 5h 59min | Direct
3. Depart: 2025-11-28 12:55 → Arrive: 2025-11-28 19:18
Duration: 6h 23min | 1 change(s)
Route: Paris Gare de l'Est → Stuttgart Hbf | Stuttgart Hbf → München Hbf
═══════════════════════════════════2. find_station
搜索城市中的火车站或按名称搜索。
参数:
station_name(string):要搜索的车站/城市名称(例如,“巴黎”、“里昂Part-Dieu”)
输出示例:
═══════════════════════════════════
STATION SEARCH
═══════════════════════════════════
🔍 Searched for 'Paris':
✓ Paris Gare de Lyon (ID: stop_area:SNCF:87686006)
Paris Montparnasse (ID: stop_area:SNCF:87391003)
Paris Gare du Nord (ID: stop_area:SNCF:87271007)
→ Selected: Paris Gare de Lyon
✅ Best match: Paris Gare de Lyon
ID: stop_area:SNCF:87686006
═══════════════════════════════════3. get_train_prices ⚠️ 实验性
仅限于教育概念验证-可能不起作用
试图从SNCF的预订系统中抓取价格信息。
⚠️ 重要免责声明:
- 这是一个 实验特征 仅用于教育目的
- 可能违反SNCF的服务条款
- 可能被防刮擦措施阻止(403禁止)
- 不建议用于生产
- 要获得真实定价,请使用商业API(Lyko、Trainline)或SNCF Connect网站
参数:
origin(string):始发站/城市名称destination(string):目的站/城市名称departure_datetime(字符串,可选):旅行日期/时间(格式与search_trains相同)page(整数,可选):页码(默认值:1)per_page(整数,可选):每页结果数(默认值:5,最大值:20)
示例输出(如果有效):
═══════════════════════════════════
SNCF PRICE CHECK (EXPERIMENTAL)
═══════════════════════════════════
⚠️ WARNING: Experimental feature
May not work due to anti-scraping measures
For educational purposes only
📍 Route: Paris Gare de Lyon → Marseille Saint-Charles
📅 Date: 2025-11-17
─────────────────────────────────
Attempting to fetch prices...
─────────────────────────────────
❌ Price check failed: Access forbidden - anti-scraping measures detected
This feature is experimental and may not work.
For real pricing, please visit:
- SNCF Connect: https://www.sncf-connect.com
- Or use commercial API providers为什么这可能行不通:
- SNCF采用防刮擦措施(403禁止)
- 要求对其预订API进行反向工程
- API结构是专有的且未记录
- 可能违反服务条款
推荐的生产替代方案:
- Lyko SNCF Connect API公司 -商业供应商
- API列车线 -多运营商预订
- SNCF官方合作计划
看 sncf_scraper/README.md 技术细节和伦理考虑。
🏗️ 建筑
sncf_mcp_server/
├── server.py # FastMCP server implementation
├── price_checker.py # Price scraping wrapper (experimental)
├── pyproject.toml # Dependencies & project config
├── .env # API key (not committed)
├── .gitignore # Git ignore rules
├── README.md # This file
├── test_notebook.ipynb # Jupyter notebook for testing
├── sncf_scraper/ # Price scraper module (experimental)
│ ├── __init__.py # Module exports
│ ├── models.py # TrainOffer, PriceSearchResult models
│ ├── scraper.py # SNCFPriceScraper implementation
│ └── README.md # Scraper documentation & disclaimers
└── tests/ # Test suite
├── test_simple.py # Simple train search test
├── test_pagination.py # Pagination feature test
├── test_search.py # MCP wrapper test
├── test_price_scraper.py # Price scraper tests (experimental)
├── debug_*.py # Debug/diagnostic scripts
├── run_all_tests.py # Test runner
└── README.md # Test documentation运作原理
- 车站搜索:查询Navitia API的
/places模糊匹配端点 - 行程规划:用途
/journeys带有起点、终点和日期时间的端点 - 日期解析:灵活的解析器处理多种日期/时间格式
- 响应格式:返回人类可读的行程信息,包括:
- 出发和到达时间 - 行程持续时间 - 转账次数 - 多航段旅行路线详情
关键实施细节
- ✅ 实时数据(无需本地数据库)
- ✅ 灵活的日期解析
python-dateutil - ✅ 欧洲日期格式支持(日优先解析)
- ✅ 根据城市名称自动解析车站ID
- ✅ 显示透明度最高的3个电台匹配
- ✅ 处理国内和国际航线
- ✅ 传输带有路线细分的信息
- ✅ 分页支持 -每页返回10个结果(最多100个行程)
- ✅ 全面的测试套件 -请参阅 测试/README.md
🌍 支持的路线
服务器支持 任何路线 在SNCF/Navitia网络中:
- 高速(TGV):巴黎里昂、巴黎马赛、巴黎波尔多、巴黎斯特拉斯堡
- 国际的:巴黎-伦敦(欧洲之星)、巴黎-慕尼黑、巴黎-巴塞罗那、巴黎-布鲁塞尔
- 长途(城际):法国各地的区域联系
- TER(区域快递):当地服务
- 跨境:与德国、意大利、西班牙、瑞士、比利时的连接
主要城市:
- 巴黎(多站:北站、里昂站、蒙帕纳斯、东站、奥斯特利茨站、圣拉扎尔站、贝尔西站)
- 里昂、马赛、波尔多、图卢兹
- 斯特拉斯堡、南特、尼斯、里尔
- 国际:伦敦、慕尼黑、巴塞罗那、布鲁塞尔、日内瓦、米兰
- 1000+个车站 横跨法国和欧洲!
使用 find_station 发现任何城市的可用车站。
🔧 发展
项目设置
# Clone and install
git clone https://github.com/belgrano9/sncf_mcp_server.git
cd sncf_mcp_server
uv sync
# Set up your API key in .env
echo "SNCF_API=your-api-key-here" > .env
# Run the server
uv run server.py
# Or use FastMCP dev mode
fastmcp dev server.py依赖项
- fastmcp -MCP服务器框架
- 请求: (>=2.32.5)-API调用的HTTP客户端
- python dotenv (>=1.2.1)-环境变量管理
- python日期工具 -灵活的日期/时间解析
- httpx (>=0.28.1)-异步HTTP客户端
- 卢古鲁 (>=0.7.3)-记录
- 富有的 (>=14.2.0)-终端格式化
文件结构
server.py-主MCP服务器search_trains和find_station工具.env-API密钥配置(从不提交!)test_notebook.ipynb-交互式测试笔记本tests/-测试套件(见 测试/README.md)
测试
运行测试套件以验证一切正常:
# Run all tests
uv run tests/run_all_tests.py
# Run individual tests
uv run tests/test_simple.py # Simple train search
uv run tests/test_pagination.py # Pagination feature
uv run tests/debug_env2.py # Environment check看 测试/README.md 获取详细的测试文档。
📝 数据源
实时数据来自 法国国营铁路公司Navitia API:
- API基本URL:
https://api.sncf.com/v1 - 认证:HTTP基本身份验证(API密钥作为用户名)
- 覆盖:法国国营铁路公司遍布法国的网络和国际联系
- 更新频率:实时(无需手动更新)
- 格式:JSON响应
- 文档: Navitia API文档
获取API密钥
- 访问 SNCF数字
- 创建账户
- 请求访问Navitia API
- 将API密钥复制到
.env
🐛 已知问题
- Windows控制台可能显示Unicode字符的编码错误(功能不受影响)
- 站名匹配使用第一个结果-use
find_station对于不明确的名称 - 国际航线的可用性可能有限,具体取决于API覆盖范围
🤝 贡献
欢迎投稿!拜托:
- 分叉存储库
- 创建要素分支(
git checkout -b feature/amazing-feature) - 提交您的更改(
git commit -m 'Add amazing feature') - 推到分支(
git push origin feature/amazing-feature) - 打开拉取请求
贡献的想法
- \[\]添加价格信息(如果API中提供)
- \[\]支持列车状态/实时延误
- \[\]多段行程优化
- \[\]地图上路线的可视化
- \[\]其他查询过滤器(列车类型、最大换乘次数等)
- \[\]支持往返查询
- \[\]保存喜爱的路线
📄 许可证
此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。
🙏 致谢
📮 支持
- 问题:
- API 文档: Navitia API文档
- MCP文件: 模型上下文协议
🔗 相关项目
- Renfe MCP服务器 -西班牙铁路的类似服务器
- FastMCP -支持此服务器的框架
- MCP服务器 -官方MCP服务器实施
______________________________________________________________________
*Voyagez智能,火车上的Voyagez! 🚄*
