实时交通信息服务器

一个提供西班牙马德里实时公共交通信息的模型上下文协议(MCP)服务器,支持地铁、公交和火车数据查询。

  • by dieguezz
  • TypeScript
  • 本地部署
  • 6 星标
  • 更新于
在 GitHub 查看 dieguezz/mcp-madrid-public-transport

使用说明

马德里交通MCP服务器🚇🚌🚆

模型上下文协议(MCP)服务器提供 实时的 西班牙马德里的公共交通信息。

使用TypeScript构建,遵循干净架构原则(DDD+六边形架构)和函数式编程模式。

✨ 特性

  • 🚇 马德里地铁 -通过官方Metro API实时到达
  • 🚌 EMT公交车 -通过EMT OpenAPI实时到达
  • 🚆 通勤列车 -通过Renfe GTFS实时馈送实时位置
  • 📊 GTFS集成 -来自CRTM的静态进度数据
  • ⚡ 优化性能 -SQLite缓存,亚秒级响应时间
  • 🔍 智能站分辨率 -车站名称的模糊匹配

🚀 快速开始

先决条件

  • Node.js >= 20.0.0
  • npm 或纱线

安装

git clone <repository-url>
cd mcp-madrid-public-transport
npm install

备注:GTFS数据文件以压缩形式存储(.txt.zip)在存储库中减少大小。这 npm install 脚本通过以下方式自动解压缩它们 postinstall 钩子。如果需要手动解压缩:

npm run setup:data

配置

创建一个 .env 项目根目录中的文件:

# Required for EMT buses only
EMT_CLIENT_ID=your_client_id_here
EMT_PASS_KEY=your_pass_key_here

# Optional: Debug logging
DEBUG=false
DEBUG_LEVEL=info  # error | warn | info | verbose | debug

# Optional: Data paths
GTFS_DATA_PATH=./transport-data

如何获得EMT证书 (免费):

  1. 访问https://openapi.emtmadrid.es/
  2. 点击“注册”并创建帐户
  3. 登录并转到“我的帐户”>“我的应用程序”
  4. 创建新应用程序
  5. 复制您的 Client ID 和 Pass Key 到 .env 文件

备注:地铁和火车数据是公开的,不需要凭证。

构建与运行

# Build TypeScript
npm run build

# Start MCP server
npm start

# Development mode with auto-reload
npm run dev

🔧 客户端配置

此MCP服务器可以与任何兼容MCP的客户端一起使用。以下是针对最常见客户的说明。

克劳德桌面

将服务器添加到Claude Desktop配置文件中:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json 视窗: %APPDATA%/Claude/claude_desktop_config.json

配置

快速设置:复制并编辑示例配置文件:

# macOS
cp claude_desktop_config.example.json ~/Library/Application\ Support/Claude/claude_desktop_config.json

# Windows (PowerShell)
Copy-Item claude_desktop_config.example.json $env:APPDATA\Claude\claude_desktop_config.json

# Then edit the file to add your EMT credentials and update the path

手动配置:

{
  "mcpServers": {
    "madrid-transport": {
      "command": "node",
      "args": [
        "/absolute/path/to/mcp-madrid-public-transport/dist/index.js"
      ],
      "env": {
        "EMT_CLIENT_ID": "your_emt_client_id_here",
        "EMT_PASS_KEY": "your_emt_pass_key_here"
      }
    }
  }
}

重要:

  • 替换 /absolute/path/to/mcp-madrid-public-transport 使用克隆此存储库的实际路径
  • 添加您的EMT凭据(在以下网址免费获取https://openapi.emtmadrid.es/)
  • 确保你已经跑过了 npm install 和 npm run build 第一

Docker选项(备选)

如果你更喜欢使用Docker,首先构建镜像:

docker build -t mcp-madrid-transport .

然后配置Claude Desktop:

{
  "mcpServers": {
    "madrid-transport": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e", "EMT_CLIENT_ID=your_emt_client_id_here",
        "-e", "EMT_PASS_KEY=your_emt_pass_key_here",
        "mcp-madrid-transport"
      ]
    }
  }
}

配置后:

  1. 重新启动克劳德桌面
  2. 寻找🔨 右下角的锤子图标
  3. 单击查看可用工具: get_metro_arrivals, get_bus_arrivals, get_train_arrivals
  4. 开始询问有关马德里公共交通的问题!

查询示例

配置后,您可以询问Claude:

  • “乘地铁到哥伦比亚要多长时间?”
  • “什么公共汽车经过3000站?”
  • “下一班从阿托查开往丰拉夫拉达的火车什么时候开?”
  • “给我看看Sol站接下来的5次地铁到达时间”
  • “在接下来的10分钟内,有公共汽车到达卡斯蒂利亚广场吗?”

其他MCP客户端

对于其他MCP客户端(如 mcp-client-cli、自定义实现等),使用stdio传输:

node dist/index.js

服务器使用JSON-RPC 2.0协议通过stdin/stdout进行通信。

📡 MCP工具

get_metro_arrivals

在车站实时获取地铁到达时间。

参数:

{
  station: string;      // Station name or code (e.g., "Colombia", "par_4_211")
  line?: string;       // Optional: Line number (e.g., "8", "L8")
  direction?: string;  // Optional: Direction/destination
  count?: number;      // Number of arrivals (default: 2, max: 10)
}

例子:

{
  "station": "Colombia",
  "line": "8",
  "count": 3
}

答复:

{
  "success": true,
  "station": "COLOMBIA",
  "stationCode": "par_4_156",
  "arrivals": [
    {
      "line": "8",
      "destination": "Nuevos Ministerios",
      "estimatedTime": "2 minutos",
      "platform": "1"
    }
  ]
}

get_bus_arrivals

在车站实时获取公交车到达情况。

参数:

{
  stop: string;        // Stop name or number (e.g., "Plaza de Castilla", "3000")
  line?: string;      // Optional: Line number (e.g., "27")
  direction?: string; // Optional: Direction/destination
  count?: number;     // Number of arrivals (default: 2)
}

例子:

{
  "stop": "3000",
  "line": "27",
  "count": 2
}

答复:

{
  "success": true,
  "stop": "Plaza de Castilla",
  "arrivals": [
    {
      "line": "27",
      "destination": "Embajadores",
      "estimatedTime": "5 minutos",
      "distance": 1200
    }
  ]
}

get_train_arrivals

获取实时Cercanías列车位置和到达时间。

参数:

{
  station: string;     // Station name or code (e.g., "Atocha", "10100")
  line?: string;      // Optional: Line (e.g., "C-2")
  direction?: string; // Optional: Destination
  count?: number;     // Number of arrivals (default: 2)
}

例子:

{
  "station": "Atocha",
  "line": "C-5",
  "count": 3
}

答复:

{
  "success": true,
  "station": "Atocha",
  "arrivals": [
    {
      "line": "C-5",
      "destination": "Fuenlabrada",
      "platform": "4",
      "departureTime": "14:35",
      "status": "on_time"
    }
  ]
}

🗂️ 数据源

马德里地铁

  • API:官方马德里地铁API
  • 端点: https://serviciosapp.metromadrid.es
  • 认证:无需✅
  • 数据:实时到达、平台、目的地
  • 更新频率:约30秒

EMT(市政运输公司)

  • API:EMT OpenAPI v2
  • 端点: https://openapi.emtmadrid.es
  • 认证:OAuth(客户端ID+密钥)🔑
  • 数据:实时到达、距离、事件
  • 更新频率:约10秒
  • 覆盖:马德里市的城市公交车

RENFE附近

  • API:Renfe GTFS实时(官方开放数据)
  • 端点: https://gtfsrt.renfe.com/vehicle_positions.json
  • 认证: ✅ 不需要(公共API)
  • 数据:实时车辆位置、行程信息、当前停车
  • 更新频率:约30秒
  • 许可证:CC-BY-4.0(开放数据)
  • 来源: https://data.renfe.com/dataset/ubicacion-vehiculos
  • 覆盖:全西班牙(按以“10”开头的行程ID过滤马德里)

CRTM(静态数据)

  • 格式:GTFS(通用运输馈电规范)
  • 数据:时刻表、路线、站点、车站映射
  • 更新频率:每月

🏗️ 建筑

项目如下 清洁建筑 原则与 领域驱动设计(DDD) 和 六边形架构 模式。

src/
├── index.ts                 # Application entry point & MCP server setup
│
├── transport/               # 🚇🚌🚆 TRANSPORT DOMAIN (Bounded Context)
│   ├── metro/              # Metro subdomain
│   │   ├── domain/         # Entities, value objects, interfaces
│   │   ├── application/    # Use cases (GetMetroArrivalsUseCase)
│   │   └── infrastructure/ # API adapters, repositories
│   │
│   ├── bus/                # Bus subdomain
│   │   ├── domain/
│   │   ├── application/    # Use cases (GetBusArrivalsUseCase)
│   │   └── infrastructure/ # EMT API adapter, auth
│   │
│   ├── train/              # Train subdomain
│   │   ├── domain/
│   │   ├── application/    # Use cases (GetTrainArrivalsUseCase)
│   │   └── infrastructure/ # Renfe GTFS-RT adapter
│   │
│   └── shared/             # Shared domain types
│       └── domain/         # Coordinates, TransportMode, etc.
│
├── mcp/                    # 🔌 MCP TOOLS
│   ├── tools/             # Tool implementations
│   │   ├── get-metro-arrivals.ts
│   │   ├── get-bus-arrivals.ts
│   │   └── get-train-arrivals.ts
│   ├── formatters/        # Output formatting
│   └── validators/        # Input validation
│
├── gtfs/                  # 📊 GTFS DATA MANAGEMENT
│   ├── domain/           # GTFS entities (Stop, Route, Trip)
│   └── infrastructure/   # File loaders, SQLite repository
│
├── cache/                # 💾 CACHING LAYER
│   ├── domain/
│   └── infrastructure/   # InMemoryCache implementation
│
└── common/               # 🔧 SHARED UTILITIES
    ├── http/            # HTTP client, retry policies
    ├── logger/          # Logging (Console, File, Combined)
    ├── functional/      # Either, Option, pipe utilities
    └── config/          # Environment configuration

关键设计模式

  • 领域驱动设计(DDD):为每种传输类型明确域边界
  • 六边形架构:独立于基础设施的域
  • 函数式编程:用于错误处理的monad,纯函数
  • 坚实的原则:单一责任,依赖倒置
  • 存储库模式:抽象数据访问
  • 适配器模式:外部API→ 领域模型

⚡ 性能优化

Sprint 1优化(已完成✅)

  • SQLite持久数据库:启动时加载一次GTFS数据(约8ms查询,而之前为4500ms)
  • GTFS-RT缓存:Renfe提要的全局60秒缓存(每次请求0毫秒vs 200毫秒)
  • LRU缓存:缓存行程目的地查询(2ms vs 1000ms)
  • 站点映射器:所有111个Cercanías站都已预加载(<1ms查找)

结果:性能提高了约1000倍(端到端3ms,之前为3750ms)

🛠️ 发展

运行测试

# Type check
npx tsc --noEmit

# Lint
npm run lint

# Format code
npm run format

调试模式

启用详细日志记录:

DEBUG=true DEBUG_LEVEL=debug npm start

日志级别: error | warn | info | verbose | debug

项目结构

  • src/ -TypeScript源代码
  • dist/ -编译的JavaScript(生成)
  • transport-data/ -GTFS静态数据文件(压缩为 .txt.zip)
  • *.db -SQLite数据库(首次运行时生成,约246MB)

GTFS数据管理

压缩工作流程

为了减小存储库大小,大型GTFS数据文件(>100KB)被压缩存储:

# Compress all large GTFS files to .txt.zip
npm run compress:data

# Decompress all .txt.zip files
npm run setup:data

自动解压

  • npm 安装:自动运行 postinstall hook → 解压缩GTFS文件和SQLite数据库
  • Docker构建:Dockerfile在映像构建期间运行解压缩脚本
  • 首次运行:应用程序使用解压缩的 gtfs-static.db 数据库

文件大小

  • 未压缩的GTFS数据:~1.2GB
  • 压缩GTFS(.txt.zip):~150MB(存储在Git中)
  • 未压缩的SQLite数据库:~246MB
  • 压缩数据库(gtfs-static.db.zip):~51MB(存储在Git中)
  • Git中压缩总量:约200MB
  • 本地未压缩总量:~1.4GB

Git配置

  • .gitignore 排除 *.txt 文件(未压缩的GTFS)
  • .gitignore 允许 *.txt.zip 文件(压缩的GTFS)
  • .gitignore 排除 *.db 文件(未压缩的SQLite数据库)
  • .gitignore 允许 *.db.zip 文件(压缩数据库)
  • .dockerignore 为Docker构建正确配置

📝 环境变量

变量 必填 默认 描述
EMT_CLIENT_ID 对于总线 - EMT API客户端ID
EMT_PASS_KEY 对于总线 - EMT API传递密钥
DEBUG 没有 false 启用调试日志记录
DEBUG_LEVEL 没有 info 日志级别
GTFS_DATA_PATH 没有 ./transport-data GTFS数据路径
METRO_API_URL 否 官方URL 覆盖Metro API URL
EMT_API_URL 否 官方URL 覆盖EMT API URL
CACHE_TTL_METRO 没有 30 高速缓存TTL(秒)
CACHE_TTL_BUS 没有 10 总线缓存TTL(秒)
CACHE_TTL_TRAIN 没有 10 列车缓存TTL(秒)

📄 许可证

MIT许可证-请参阅 许可证 文件以获取详细信息。

🙏 致谢与致谢

数据提供程序

  • 马德里地铁 -实时Metro API和静态数据
  • 马德里EMT -实时公交车到达API
  • Renfe -GTFS实时馈送(开放数据CC-BY-4.0)
  • CRTM(马德里地区运输联盟) -所有运输方式的GTFS静态数据
  • Xbaak/madrid运输备份 -GTFS数据存储库

发展

  • 与克劳德一起建造 🤖 - 该项目是在人工智能助理Claude(Anthropic)的大力协助下开发的,他帮助:
    • 建筑设计(DDD+六边形建筑)
    • TypeScript实现和函数式编程模式
    • API集成(Metro、EMT、Renfe GTFS-RT)
    • 性能优化(1000倍加速)
    • 代码审查和最佳实践
    • 文档

技术

  • TypeScript -类型安全的JavaScript
  • Node.js -运行时环境
  • MCP-SDK (@modelcontextprotocol/sdk)-模型上下文协议
  • fp-ts -函数式编程实用程序
  • 更好平方3 -快速SQLite3绑定
  • csv解析 -GTFS CSV解析
  • 黄道带 -运行时类型验证

由以下材料制成❤️ 在马德里,为马德里

触手可及的实时公共交通数据