返回市场
mcp马德里公共交通服务器

mcp马德里公共交通服务器

作者:dieguezz2 星标更新:2025-11-11

项目介绍

Madrid Transport MCP Server 🚇🚌🚆

提供西班牙马德里实时公共交通信息的Model Context Protocol (MCP)服务器。

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

✨ 特性

  • 🚇 马德里地铁 - 通过官方地铁API获取实时到站信息
  • 🚌 EMT公交 - 通过EMT OpenAPI获取实时到站信息
  • 🚆 近郊火车 - 通过Renfe GTFS实时数据源获取实时位置信息
  • 📊 GTFS集成 - 来自CRTM的静态时刻表数据
  • ⚡ 性能优化 - 使用SQLite缓存,响应时间小于一秒
  • 🔍 智能站点解析 - 对站点名称进行模糊匹配

🚀 快速开始

前提条件

  • Node.js >= 20.0.0
  • npm 或 yarn

安装

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

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

npm run setup:data

配置

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

# 仅用于EMT公交车
EMT_CLIENT_ID=your_client_id_here
EMT_PASS_KEY=your_pass_key_here

# 可选:调试日志
DEBUG=false
DEBUG_LEVEL=info  # error | warn | info | verbose | debug

# 可选:数据路径
GTFS_DATA_PATH=./transport-data

如何获取EMT凭证(免费):

  1. 访问 https://openapi.emtmadrid.es/
  2. 点击“注册”并创建账户
  3. 登录并进入“我的账户”>“我的应用”
  4. 创建一个新的应用
  5. 将您的Client IDPass Key复制到.env文件中

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

构建与运行

# 构建TypeScript
npm run build

# 启动MCP服务器
npm start

# 开发模式,自动重载
npm run dev

🔧 客户端配置

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

Claude Desktop

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

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %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

# 然后编辑文件以添加您的EMT凭证并更新路径

手动配置

{
  "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 installnpm 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. 重启Claude Desktop
  2. 查看右下角的🔨锤子图标
  3. 点击查看可用工具:get_metro_arrivalsget_bus_arrivalsget_train_arrivals
  4. 开始询问关于马德里公共交通的问题!

示例查询

配置完成后,您可以向Claude提问:

  • "地铁到达哥伦比亚站还需要多久?"
  • "3000号站台有哪些公交车经过?"
  • "从阿托查出发前往富恩拉布拉达的下一班火车什么时候开?"
  • "显示Sol站接下来5个地铁到站时间"
  • "接下来10分钟内是否有公交车到达卡斯蒂利亚广场?"

其他MCP客户端

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

node dist/index.js

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

📡 MCP工具

get_metro_arrivals

获取地铁站的实时到站信息。

参数:

{
  station: string;      // 站点名称或代码(例如:"Colombia","par_4_211")
  line?: string;       // 可选:线路编号(例如:"8","L8")
  direction?: string;  // 可选:方向/目的地
  count?: number;      // 到站次数(默认:2,最大:10)
}

示例:

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

响应:

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

get_bus_arrivals

获取公交站的实时到站信息。

参数:

{
  stop: string;        // 站点名称或编号(例如:"Plaza de Castilla","3000")
  line?: string;      // 可选:线路编号(例如:"27")
  direction?: string; // 可选:方向/目的地
  count?: number;     // 到站次数(默认:2)
}

示例:

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

响应:

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

get_train_arrivals

获取近郊火车的实时位置和到站信息。

参数:

{
  station: string;     // 站点名称或代码(例如:"Atocha","10100")
  line?: string;      // 可选:线路(例如:"C-2")
  direction?: string; // 可选:目的地
  count?: number;     // 到站次数(默认:2)
}

示例:

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

响应:

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

🗂️ 数据来源

Metro de Madrid

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

EMT (Empresa Municipal de Transportes)

  • API:EMT OpenAPI v2
  • 端点https://openapi.emtmadrid.es
  • 认证:OAuth(Client ID + Pass Key)🔑
  • 数据:实时到站、距离、事件
  • 更新频率:约10秒
  • 覆盖范围:马德里市内的城市公交

Renfe Cercanías

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

CRTM(静态数据)

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

🏗️ 架构

该项目遵循Clean Architecture原则,采用领域驱动设计(DDD)六边形架构模式。

src/
├── index.ts                 # 应用程序入口点及MCP服务器设置
│
├── transport/               # 🚇🚌🚆 交通运输领域(有界上下文)
│   ├── metro/              # 地铁子域
│   │   ├── domain/         # 实体、值对象、接口
│   │   ├── application/    # 用例(GetMetroArrivalsUseCase)
│   │   └── infrastructure/ # API适配器、仓库
│   │
│   ├── bus/                # 公交子域
│   │   ├── domain/
│   │   ├── application/    # 用例(GetBusArrivalsUseCase)
│   │   └── infrastructure/ # EMT API适配器、认证
│   │
│   ├── train/              # 火车子域
│   │   ├── domain/
│   │   ├── application/    # 用例(GetTrainArrivalsUseCase)
│   │   └── infrastructure/ # Renfe GTFS-RT适配器
│   │
│   └── shared/             # 共享领域类型
│       └── domain/         # 坐标、交通运输方式等
│
├── mcp/                    # 🔌 MCP工具
│   ├── tools/             # 工具实现
│   │   ├── get-metro-arrivals.ts
│   │   ├── get-bus-arrivals.ts
│   │   └── get-train-arrivals.ts
│   ├── formatters/        # 输出格式化
│   └── validators/        # 输入验证
│
├── gtfs/                  # 📊 GTFS数据管理
│   ├── domain/           # GTFS实体(站点、路线、行程)
│   └── infrastructure/   # 文件加载器、SQLite仓库
│
├── cache/                # 💾 缓存层
│   ├── domain/
│   └── infrastructure/   # 内存缓存实现
│
└── common/               # 🔧 共享实用工具
    ├── http/            # HTTP客户端、重试策略
    ├── logger/          # 日志记录(控制台、文件、组合)
    ├── functional/      # Either、Option、管道工具
    └── config/          # 环境配置

关键设计模式

  • 领域驱动设计(DDD):每个交通工具类型的清晰领域边界
  • 六边形架构:领域独立于基础设施
  • 函数式编程:使用Either单子处理错误,纯函数
  • SOLID原则:单一职责、依赖倒置
  • 仓库模式:抽象数据访问
  • 适配器模式:外部API → 领域模型

⚡ 性能优化

第一阶段优化(已完成 ✅)

  • SQLite持久数据库:启动时加载GTFS数据一次(~8毫秒查询 vs 之前4500毫秒)
  • GTFS-RT缓存:全局60秒缓存Renfe数据源(0毫秒 vs 之前200毫秒每次请求)
  • LRU缓存:行程目的地查询缓存(2毫秒 vs 之前1000毫秒)
  • 站点映射器:预加载所有111个近郊火车站(<1毫秒查找)

结果:约1000倍性能提升(端到端3毫秒 vs 之前3750毫秒)

🛠️ 开发

运行测试

# 类型检查
npx tsc --noEmit

# 代码检查
npm run lint

# 格式化代码
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)以压缩形式存储:

# 将所有大型GTFS文件压缩为.txt.zip
npm run compress:data

# 解压所有.txt.zip文件
npm run setup:data

自动解压

  • npm install:自动运行postinstall钩子 → 解压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-dataGTFS数据路径
METRO_API_URL不必官方URL覆盖地铁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许可证 - 详情见LICENSE文件。

🙏 致谢与致谢

数据提供商

  • Metro de Madrid - 实时地铁API和静态数据
  • EMT Madrid - 实时公交到站API
  • Renfe - GTFS实时数据源(开放数据CC-BY-4.0)
  • CRTM (Consorcio Regional de Transportes de Madrid) - 所有运输方式的GTFS静态数据
  • xBaank/MadridTransporte-Backup - GTFS数据仓库

开发

  • 由Claude构建 🤖 - 本项目在Claude(Anthropic)的帮助下开发,Claude是一个AI助手,帮助了:
    • 架构设计(DDD + 六边形架构)
    • TypeScript