马来西亚过境MCP
马来西亚公共交通系统的MCP(模型上下文协议)服务器,提供马来西亚10多个城市的实时公共汽车和火车信息。
MCP端点: https://mcp.techmavie.digital/malaysiatransit/mcp
分析仪表板: https://mcp.techmavie.digital/malaysiatransit/analytics/dashboard
数据来源: 马来西亚中转中间件
目录
特性
- 11个运营服务区+1个维护中+1个即将推出 马来西亚各地
- 巴生谷(吉隆坡快速铁路、吉隆坡快速巴士、地铁接驳线) - 槟城(Rapid Penang, Penang Ferry, KTM Komuter North) - Ipoh (BAS.MY Ipoh, KTM Komuter 北) - 芙蓉(BASE.MY芙蓉,KTM城际) - 康加(BAS.MY康加,北卡穆特KTM) - Alor Setar(BAS.MY Alor Setar,KTM Komuter Nord) - 巴鲁市 (BAS.MY 巴鲁市, KTM Intercity) - Kuala Terengganu, Melaka, Kuching (仅限BAS.MY) - 柔佛州(BAS.MY柔佛新山+柔佛下摩法卡特-通过PAJ适配器的41条BMJ路线) - 关丹(维修中) - 亚庇(即将推出)
- 实时车辆跟踪 -公共汽车和火车的实时位置
- 停止搜索和信息 -按名称或位置查找站点
- 路由发现 -浏览带目的地的可用路线
- 到达预测 -获取站点的实时到达时间(基于形状,准确率提高40-60%)
- 调度信息 -获取出发时间、路线安排和运营状态
- 票价计算器 -计算BAS.MY和Rapid Penang路线的巴士票价
- 多模式支持 -巴士、铁路和渡轮服务
- 提供商状态监控 -检查公交服务提供商的运营状态
- 位置检测 -使用地理编码自动检测服务区域
- 🆕 KTM 北 通讯 -从巴东勿刹到怡保的23个车站,包括票价计算
- 🆕 KTM城际 -SH和ERT路线(图姆帕特-杰玛斯-JB中央车站)
- 🆕 槟城渡轮 -巴特沃斯到乔治敦的渡轮信息
- 🆕 API分析 -查看API使用情况统计、端点指标和客户端跟踪
- 🆕 分析仪表板 -带有图表的可视化仪表板,用于监控MCP服务器的使用情况
- 🆕 客户端标识 -MCP向中间件标识自己以进行分析跟踪
- 🆕 自动部署 -自动VPS部署的GitHub操作工作流
- 🆕 多模式行程规划器(测试版) -
plan_journey组成横跨马来西亚的巴士+铁路+渡轮+步行路线(谷歌方向引擎,按路线本地计算票价,AA1跨境,免费CAT路线) - 🆕 服务器端位置自动完成 -
places_autocomplete+place_details通过过境感知机场覆盖来解决马来西亚地名问题 - 🆕 票价元数据 -
get_fare_structures公开BAS.MY/Peang/免费CAT模型,以便代理商解释票价是如何计算的
建筑
该MCP服务器充当人工智能助手和马来西亚运输中间件API之间的桥梁:
AI Assistant (Claude, GPT, etc.)
↓
Malaysia Transit MCP Server (identifies as "Malaysia-Transit-MCP")
↓
Malaysia Transit Middleware API (tracks usage via X-App-Name header)
↓
Malaysia Open Data Portal (GTFS Static & Realtime)客户身份: 此MCP自动发送 X-App-Name: Malaysia-Transit-MCP 每个API请求的头,允许中间件在其分析仪表板中单独跟踪此MCP的使用情况。
快速开始
连接到MCP服务器
将此配置添加到您的MCP客户端(Claude Desktop、Cursor、Windsurf等):
{
"mcpServers": {
"malaysia-transit": {
"transport": "streamable-http",
"url": "https://mcp.techmavie.digital/malaysiatransit/mcp"
}
}
}使用MCP检查员进行测试
npx @modelcontextprotocol/inspector
# Select "Streamable HTTP"
# Enter URL: https://mcp.techmavie.digital/malaysiatransit/mcp卷曲测试
# List all available tools
curl -X POST https://mcp.techmavie.digital/malaysiatransit/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# Call the hello tool
curl -X POST https://mcp.techmavie.digital/malaysiatransit/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"hello","arguments":{}}}'安装
npm install配置
环境变量
MCP服务器使用环境变量进行配置:
MIDDLEWARE_URL(必需):马来西亚Transit中间件API URL
- 违约: https://malaysiatransit.techmavie.digital
INTERNAL_AUTH_TOKEN(生产需要):中间件API身份验证的共享机密
- 必须匹配 INTERNAL_APP_AUTH_TOKEN 在中间件环境中 - 生成方式: openssl rand -hex 32
GOOGLE_MAPS_API_KEY(可选):用于位置检测的Google Maps API密钥
- 如果没有提供,则退回提名(免费但不太准确) - 从获取API密钥 谷歌云控制台
ANALYTICS_RESET_KEY(可选):管理员密钥POST /analytics/reset
- 如果未设置,则禁用重置端点(返回403)
ANALYTICS_IMPORT_KEY(可选):管理员密钥POST /analytics/import
- 如果未设置,则禁用导入终结点(返回403)
发展
要在开发模式下运行MCP服务器:
npm run dev构建
要构建用于部署的MCP服务器,请执行以下操作:
npm run build可用工具
服务区域发现
list_service_areas
列出马来西亚所有可用的过境区。
参数: 无
退货: 服务区域及其ID、名称和功能的列表。
例子:
const areas = await tools.list_service_areas();get_area_info
获取特定区域的详细信息。
参数:
areaId(string):服务区域ID(例如“penang”、“klang valley”)
例子:
const info = await tools.get_area_info({ areaId: "penang" });位置检测
detect_location_area ⭐
使用地理编码自动检测某个位置属于哪个公交服务区域。
参数:
location(string):地点名称或地点(例如,“KTM Alor Setar”、“Komtar”、“KLCC”)
退货: 检测到的区域ID、置信度和位置详细信息。
例子:
const result = await tools.detect_location_area({ location: "KTM Alor Setar" });
// Returns: { area: "alor-setar", confidence: "high" }停止信息
search_stops
按名称搜索站点。使用 detect_location_area 首先,如果不确定该地区。
参数:
area(string):服务区域IDquery(string):搜索查询(例如,“Komtar”、“KLCC”)
例子:
const stops = await tools.search_stops({
area: "penang",
query: "Komtar"
});get_stop_details
获取有关站点的详细信息。
参数:
area(string):服务区域IDstopId(string):停止搜索结果中的ID
get_stop_arrivals ⭐
在车站获得实时到达预测。
参数:
area(string):服务区域IDstopId(string):停止搜索结果中的ID
退货: 包括一份关于预测方法的全面免责声明,后面是到货数据,包括:
- 计算方法(基于形状或直线)
- 置信水平(高、中或低)
- 预计到达时间(分钟)
- 车辆信息
预测方法:
- 基于形状的距离 (首选):使用实际路线几何形状,在±2-4分钟内准确
- 直线距离 (回退):保守估计,乘数为1.4倍
- 包括GPS速度验证、时间调整和停车停留时间
- 保守派偏见:早到总比错过公交车好
例子:
const arrivals = await tools.get_stop_arrivals({
area: "penang",
stopId: "stop_123"
});
// Returns disclaimer + arrival data with confidence levelsfind_nearby_stops
找到附近的车站和为他们服务的路线。
参数:
area(string):服务区域IDlocation(字符串,可选):要进行地理编码的地名(例如“KLCC”、“Komtar”)lat(数字,可选):纬度坐标(如果是必需的location未提供)lon(数字,可选):经度坐标(如果是必需的location未提供)radius(数字,可选):搜索半径,单位为米(默认值:500)
find_nearby_stops_with_arrivals ⭐
查找附近的站点,并在一次通话中获得实时到达信息。
参数:
area(string):服务区域IDlocation(字符串,可选):要进行地理编码的地名lat(数字,可选):纬度坐标(如果是必需的location未提供)lon(数字,可选):经度坐标(如果是必需的location未提供)radius(数字,可选):搜索半径,单位为米(默认值:500)routeFilter(字符串,可选):按路线编号过滤到达信息(例如,“302”、“101”)
find_nearby_stops_with_routes
查找附近的站点,并在一次通话中获取服务于这些站点的所有路线。
参数:
area(string):服务区域IDlocation(字符串,可选):要进行地理编码的地名lat(数字,可选):纬度坐标(如果是必需的location未提供)lon(数字,可选):经度坐标(如果是必需的location未提供)radius(数字,可选):搜索半径,单位为米(默认值:500)
路线信息
list_routes
列出一个区域中的所有路线。
参数:
area(string):服务区域ID
get_route_stops
让所有站点都由特定路线服务。
参数:
area(string):服务区域IDrouteId(string):来自的路由IDlist_routes
get_route_details
获取详细的路线信息。
参数:
area(string):服务区域IDrouteId(string):来自list_routes的路由ID
get_route_geometry
获取路线路径以进行地图可视化。
参数:
area(string):服务区域IDrouteId(string):来自list_routes的路由ID
实时数据
get_live_vehicles ⭐
获取实时车辆位置。
参数:
area(string):服务区域IDtype(枚举,可选):按类型筛选(“bus”或“rail”)
例子:
const vehicles = await tools.get_live_vehicles({ area: "penang" });get_provider_status
检查提供商的运行状态。
参数:
area(string):服务区域ID
日程信息(新)
get_route_departures
获取特定路线(双向)的下一个N次出发。
参数:
area(string):服务区域ID(例如,“ipoh”、“seremban”、“penang”)routeId(string):来自list_routes的路由IDcount(数字,可选):返回的出发次数(默认值:5)
例子:
const departures = await tools.get_route_departures({
area: "ipoh",
routeId: "A32",
count: 5
});get_next_departure
获取特定方向路线的下一个出发点。
参数:
area(string):服务区域IDrouteId(string):来自list_routes的路由IDdirection(枚举,可选):“出站”、“入站”或“循环”
get_stop_routes
获取服务于特定站点的所有路线及其下一次出发。
参数:
area(string):服务区域IDstopId(string):停止search_stops中的IDcount(数字,可选):每条路线的出发次数(默认值:3)
get_route_schedule
获取路线的完整每日时间表。
参数:
area(string):服务区域IDrouteId(string):来自list_routes的路由ID
get_route_origin
获取特定方向上路线的起点站名称。
参数:
area(string):服务区域IDrouteId(string):来自list_routes的路由IDdirection(枚举,可选):“出站”或“入站”
get_route_status
检查路线当前是否按照其时间表运行。
参数:
area(string):服务区域IDrouteId(string):来自list_routes的路由ID
票价计算器(新)
get_fare_routes
获取特定区域内可用于票价计算的所有路线。
参数:
area(string):服务区域ID(例如,“ipoh”、“seremban”、“penang”、“kangar”)
支持区域: 制动辅助系统。MY地区(怡保、芙蓉、康加、亚罗士打、哥打巴鲁、瓜拉丁加奴、马六甲、柔佛、古晋)和槟城拉皮德。
get_route_stops_for_fare
获取路线上的所有站点及其距离,以便计算票价。
参数:
area(string):服务区域IDrouteId(string):来自get_fare_routes的路由ID
calculate_fare ⭐
计算路线上两站之间的公共汽车票价。
参数:
area(string):服务区域IDrouteId(string):来自get_fare_routes的路由IDfromStop(字符串):起始站IDtoStop(string):目的站ID
退货: 成人、优惠和儿童票价以马来西亚令吉计算,并附有免责声明。
例子:
const fare = await tools.calculate_fare({
area: "ipoh",
routeId: "A32",
fromStop: "stop_001",
toStop: "stop_015"
});
// Returns: { adult: "1.50", concession: "0.75", child: "FREE" }calculate_journey_fare
计算有巴士接送的多段旅程的总票价。
参数:
area(string):基础服务区域IDlegs(array):行程航段数组(最多5条),每条航段包含:
- routeId (string):此航段的路线ID - fromStop (字符串):起始站ID - toStop (string):目的站ID - areaId (字符串,可选):此航段的区域ID(用于跨区域旅行)
注: 每次巴士换乘都需要单独支付车费(BAS.MY没有集成接送服务)。
get_route_directions_for_fare
计算票价时获取路线的可用方向。
参数:
area(string):服务区域IDrouteId(string):来自get_fare_routes的路由ID
KTM北通道工具 (新)
get_ktm_komuter_stations
获得所有23个KTM北Komuter站(巴东Besar-巴特沃斯-怡保线)。
参数: 无
退货: 站点代码、名称和坐标。
例子:
const stations = await tools.get_ktm_komuter_stations();
// Returns: [{ code: "PB", name: "Padang Besar", ... }, ...]calculate_ktm_komuter_fare ⭐
计算两站之间的北通勤者KTM票价。
参数:
from(字符串):始发站代码(例如,巴特沃斯的“BU”)to(string):目的站代码(例如,怡保的“IP”)
例子:
const fare = await tools.calculate_ktm_komuter_fare({
from: "BU",
to: "IP"
});
// Returns: { adult: "12.00", child: "6.00", currency: "MYR" }get_ktm_komuter_fare_matrix
获取显示所有车站对之间票价的完整KTM Komuter Utara票价矩阵。
参数: 无
get_ktm_station_departures ⭐
获取特定KTM车站的出发时间。
参数:
stationName(string):车站名称(例如“巴特沃斯”、“怡保”)type(枚举):计划类型-ktm-komuter-utara或ktm-intercity
例子:
const departures = await tools.get_ktm_station_departures({
stationName: "Butterworth",
type: "ktm-komuter-utara"
});get_ktm_stations
获取特定时间表类型的所有KTM电台。
参数:
type(枚举):ktm-komuter-utara或ktm-intercity
get_ktm_schedules
获取特定计划类型的完整KTM计划数据。
参数:
type(枚举):ktm-komuter-utara或ktm-intercity
find_nearby_ktm_stations
查找特定位置附近的KTM车站。
参数:
lat(数字):纬度坐标lon(数字):经度坐标radius(数字,可选):搜索半径,单位为公里(默认值:10)type(枚举):ktm-komuter-utara或ktm-intercity
槟城渡轮工具(新)
get_penang_ferry_overview ⭐
获取槟城渡轮服务概述,包括路线、运营商和一般信息。
参数: 无
get_penang_ferry_schedule
获取槟城渡轮的完整时刻表,包括运营时间和频率。
参数: 无
get_penang_ferry_next_departure
搭乘下一班从两个码头出发的槟城渡轮。
参数: 无
get_penang_ferry_terminals
获取槟城渡轮码头信息,包括位置和设施。
参数: 无
get_penang_ferry_fare
获取槟城渡轮票价信息和付款方式。
参数: 无
例子:
const fare = await tools.get_penang_ferry_fare();
// Returns: { adult: "1.40", child: "0.70", ... }系统工具
get_system_health
检查Malaysia Transit中间件服务的运行状况。
参数: 无
get_debug_info
获取有关中间件服务的全面调试信息。
参数: 无
分析工具(新)
get_api_analytics
从中间件获取API使用分析和统计数据。
参数:
type(枚举,可选):要检索的分析类型:
- summary (默认):概述请求/小时、错误率、正常运行时间 - endpoints:每个端点统计 - areas:按服务区域统计 - cumulative:所有时间总计 - clients:应用程序/网站使用情况细分
例子:
// Get summary analytics
const summary = await tools.get_api_analytics({ type: "summary" });
// Get client usage (see which apps use the API)
const clients = await tools.get_api_analytics({ type: "clients" });get_area_analytics
获取特定服务领域的详细API使用分析。
参数:
area(string):服务区域ID(例如“penang”、“klang valley”)
例子:
const penangStats = await tools.get_area_analytics({ area: "penang" });旅程规划器(新,测试版)
plan_journey ⭐
规划马来西亚的多式联运公共交通之旅。在交通模式下,通过谷歌方向组合公共汽车、铁路、渡轮和步行路线,然后在本地计算每条路线的票价。
参数:
originText(字符串,可选):地名(例如,“Komtar”、“Penang Airport”、“KL Sentral”)originLat/originLng(数字,可选):坐标(使用文本或lat+lng)destinationText/destinationLat/destinationLng:形状与原点相同modeBus/modeRail/modeFerry(布尔值,可选):过滤传输模式language(字符串,可选):en,ms,th
退货: 一系列旅行选择,每种选择都有 summary (持续时间、步行距离、换乘次数、票价估算 hasMissingFare 旗), legs[] (模式、路线、往返车站、时间、每程票价),以及 walkOnly 旗帜。
错误: invalid-origin (400), invalid-destination (400), invalid-modes (400), unsupported-inter-area (400), area-out-of-coverage (400), engine-unavailable (503), routing-failed (503).直接向用户显示这些消息;不要递归重试。
例子:
const plan = await tools.plan_journey({
originText: "Penang Airport",
destinationText: "Komtar",
});Beta警告: ETA是预定时间(使用 get_stop_arrivals 在登机口实时查看预计到达时间)。部分航段可能缺少票价(hasMissingFare: true).
get_journey_areas
列出行程计划器支持的服务区域,以及发动机名称和步行/交通配置。
参数: 无
places_autocomplete
服务器端的Google Places自动完成马来西亚地名的代理。返回排名建议,包括交通感知覆盖(机场快速到达规范公交车站)。
参数:
input(字符串,2-120个字符):搜索输入sessiontoken(字符串,可选):在自动补全+详细信息调用中重复使用相同的令牌,用于Google Places计费language(字符串,可选):en,ms,th
使用案例: 当用户给出了一个模糊的地名,而你希望他们在调用之前消除歧义时 plan_journey.
place_details
解决a placeId 从 places_autocomplete 转换为坐标和格式化地址。
参数:
placeId(string):来自places_autocomplete(谷歌place_id或override:*合成ID)sessiontoken(字符串,可选):与自动补全中使用的会话令牌相同language(字符串,可选)
票价元数据(新)
get_fare_structures
获取中间件使用的票价结构定义。返回基于BAS.MY距离的定价、快速槟城分段区和免费槟城CAT路线(CAT、CT13、C13A/B/C、CT14、CT15)。
参数: 无
使用案例: 向用户解释 *怎么* 打电话前会计算车费 calculate_fare.
get_ktm_intercity_fare
查询KTM城际(SH和ERT路线)票价。 注: 目前返回HTTP 501,因为城际票价数据尚未集成。响应包括指向相关端点的指针和KTMB官方网站的链接。调用此工具,向用户诚实地显示差距,而不是猜测票价。
参数: 无
测试
hello
验证服务器是否正常工作的简单测试工具。
使用示例
查找您的巴士何时到达
// 1. Detect area from location
const areaResult = await tools.detect_location_area({
location: "KTM Alor Setar"
});
// 2. Search for your stop
const stops = await tools.search_stops({
area: areaResult.area,
query: "KTM Alor Setar"
});
// 3. Get real-time arrivals
const arrivals = await tools.get_stop_arrivals({
area: areaResult.area,
stopId: stops[0].id
});
// Returns: "Bus K100(I) arrives in 1 minute, Bus K100(O) in 2 minutes"轨道直播巴士
// Get all live vehicles in Penang
const vehicles = await tools.get_live_vehicles({
area: "penang"
});
// Filter by bus only
const buses = await tools.get_live_vehicles({
area: "klang-valley",
type: "bus"
});发现路径
// List all routes in Klang Valley
const routes = await tools.list_routes({
area: "klang-valley"
});
// Get detailed route information
const routeDetails = await tools.get_route_details({
area: "klang-valley",
routeId: "LRT-KJ"
});AI集成指南
关键用例
1.“我的公共汽车什么时候来?”⭐
这是主要用例。用户想知道他们的下一班公共汽车/火车什么时候到达。
工作流程:
1. User asks: "When is the next bus at Komtar?"
2. AI uses: detect_location_area({ location: "Komtar" })
3. AI uses: search_stops({ area: "penang", query: "Komtar" })
4. AI uses: get_stop_arrivals({ area: "penang", stopId: "..." })
5. AI responds: "Bus T101 arrives in 5 minutes, Bus T201 in 12 minutes"2.“我的公共汽车现在在哪里?”
用户希望实时跟踪他们的公交车。
工作流程:
1. User asks: "Where is bus T101 right now?"
2. AI uses: detect_location_area({ location: "Penang" })
3. AI uses: get_live_vehicles({ area: "penang" })
4. AI filters for route T101
5. AI responds: "Bus T101 is currently at [location], heading towards Airport"工具使用模式
始终从位置检测开始
当用户提到一个位置而没有指定区域时,使用位置检测:
// User: "When is the next bus at KTM Alor Setar?"
const areaResult = await tools.detect_location_area({
location: "KTM Alor Setar"
});
// Returns: { area: "alor-setar", confidence: "high" }详细信息前搜索
在请求详细信息之前,始终搜索站点/路线:
// ✅ CORRECT
const stops = await tools.search_stops({ area: "penang", query: "Komtar" });
const arrivals = await tools.get_stop_arrivals({
area: "penang",
stopId: stops[0].id
});
// ❌ WRONG - Don't guess stop IDs
const arrivals = await tools.get_stop_arrivals({
area: "penang",
stopId: "random_id"
});响应格式
到达时间
以用户友好的方式设置到达时间:
// ✅ GOOD
"Bus T101 arrives in 5 minutes"
"Train LRT-KJ arrives in 2 minutes"
"Next bus: T201 in 12 minutes"
// ❌ BAD
"Arrival time: 2025-01-07T14:30:00Z"
"ETA: 1736258400000"多次到达
清晰地呈现多次到达:
"Upcoming arrivals at Komtar:
• T101 → Airport: 5 minutes
• T201 → Bayan Lepas: 12 minutes
• T102 → Gurney: 18 minutes"错误处理
提供商不可用
try {
const arrivals = await tools.get_stop_arrivals({ ... });
} catch (error) {
// Check provider status
const status = await tools.get_provider_status({ area: "penang" });
if (status.providers[0].status !== "active") {
"The transit provider is currently unavailable.
Please try again later or check the official transit app."
}
}最佳实践
- 使用位置检测 当用户提到地名时
- 始终指定区域 每种工具(除
list_service_areas和detect_location_area) - 在详细信息之前搜索 -不要猜ID
- 优雅地处理错误 -提供商可能会出现临时中断
- 清晰地格式化响应 -使用分钟,而不是时间戳
- 不缓存实时数据 -它每30秒更新一次
支持的服务区域
| 区域ID | 名称 | 提供商 | 交通类型 | 票价计算器 |
|---|---|---|---|---|
klang-valley | 巴生谷 | 吉隆坡快速铁路、吉隆坡快速巴士、地铁支线 | 巴士、铁路 | ❌ (吉隆坡快速票价未建模) |
penang | 槟城 | 快速槟城(包括免费CAT路线-RM 0),槟城渡轮,北通勤者KTM | 巴士,渡轮,铁路 | ✅ |
kuantan | 关丹 | 维修中 | 巴士 | ❌ |
ipoh | 怡保 | BAS.MY怡保,KTM北通勤者 | 巴士,铁路 | ✅ |
seremban | 芙蓉 | BASE.MY芙蓉,KTM城际 | 巴士、铁路 | ✅ |
kangar | Kangar | BAS.MY Kangar,KTM北通勤者 | 巴士、铁路 | ✅ |
alor-setar | Alor Setar | BAS.MY Alor Setar, KTM Komuter Nord | 巴士, 铁路 | ✅ |
kota-bharu | 哥打巴鲁 | BAS.MY哥打巴茹,KTM城际 | 巴士、铁路 | ✅ |
kuala-terengganu | Kuala Terengganu | BAS.MY Kuala Terengganu | 巴士 | ✅ |
melaka | 马六甲 | BAS.MY 马六甲 | 巴士 | ✅ |
johor | 柔佛州新山 | BAS.MY柔佛新山+柔佛州下摩法卡特(BMJ-41路) | 巴士 | ✅ |
kuching | 古晋 | BAS.MY古晋 | 巴士 | ✅ |
kota-kinabalu | 亚庇 | 即将推出 | - | ❌ |
KTM服务
| 服务 | 路线 | 车站 | 票价计算器 |
|---|---|---|---|
| KTM 北方通勤 | 大竞技场↔ 巴特沃斯↔ 伊波 | 23 站 | ✅ |
| KTM城际(SH) | JB Sentral↔ 宝石↔ 图姆帕特 | 多个 | ❌ (即将推出) |
| KTM城际(ERT) | JB Sentral↔ 宝石↔ 图姆帕特 | 多个 | ❌ (即将推出) |
位置到区域映射
这 detect_location_area 工具自动将公共位置映射到服务区域:
| 用户说 | 区域ID |
|---|---|
| Ipoh,Bercham,头发尖端,Kidd Field | ipoh |
| 芙蓉、尼莱、波德申 | seremban |
| 乔治敦、巴特沃斯、巴彦乐帕斯、槟城中央车站 | penang |
| 布城Shah Alam KLCC | klang-valley |
关东,周,皇冠城市。 kuantan | |
Kangar,Arau,Kuala Perlis,Padang Besar。 kangar | |
Alor Setar,农民河,Pendang,Jitra alor-setar | |
| Kota Bharu, 长区, Bachok, Machang, 果冻 | kota-bharu |
红色,红色,忠诚。 kuala-terengganu | |
马六甲,坦平,贾辛,土地清真寺 melaka | |
| Johor Bahru, Iskandar Puteri, Sandir Gudang, Kulai | johor |
| 古晋、包、斯里安、巴科、西尼瓦湾、马塘 | kuching |
部署
生产服务器
MCP服务器部署在:
- 端点:
https://mcp.techmavie.digital/malaysiatransit/mcp - 健康检查:
https://mcp.techmavie.digital/malaysiatransit/health - 分析仪表板:
https://mcp.techmavie.digital/malaysiatransit/analytics/dashboard - 分析API:
https://mcp.techmavie.digital/malaysiatransit/analytics - 运输: 流式HTTP
分析仪表板
MCP服务器包括一个内置的分析仪表板,用于跟踪:
- 请求和工具调用总数
- 工具使用分布 (甜甜圈图)
- 每小时请求趋势 (过去24小时)
- 按端点请求 (柱状图)
- 按用户代理列出的顶级客户
- 最近的工具调用提要
仪表板每30秒自动刷新一次。
自我寄宿
要部署自己的实例,请参阅 部署指南.
# Using Docker
docker compose up -d --build
# Or run directly
npm run build
npm run start:http自动部署
此存储库包括用于自动VPS部署的GitHub Actions工作流。当你推 main,服务器会自动重新部署。
要设置自动部署,请将以下机密添加到您的GitHub存储库中:
VPS_HOST-您的VPS IP地址VPS_USERNAME-SSH用户名(例如。,root)VPS_PORT-SSH端口(例如。,22)VPS_SSH_KEY-用于身份验证的专用SSH密钥GOOGLE_MAPS_API_KEY-用于地理编码的Google Maps API密钥INTERNAL_AUTH_TOKEN-共享身份验证令牌(必须与中间件的INTERNAL_APP_AUTH_TOKEN)ANALYTICS_RESET_KEY(可选)-启用/analytics/reset管理员端点ANALYTICS_IMPORT_KEY(可选)-启用/analytics/import管理员端点
故障排除
连接问题
如果您无法连接到中间件:
- 验证您的
MIDDLEWARE_URL是正确的 - 确保中间件正在运行且可访问
- 检查网络连接
- 验证
INTERNAL_AUTH_TOKEN匹配中间件INTERNAL_APP_AUTH_TOKEN(如果启用了中间件身份验证) - 直接测试中间件:
curl https://your-middleware-url/api/areas
未返回数据
如果工具返回空数据:
- 使用以下工具检查服务区域是否正常运行
get_provider_status - 使用验证区域ID是否正确
list_service_areas - 检查中间件日志是否有错误
实时数据不可用
实时数据取决于上游GTFS提供商:
- 使用
get_provider_status检查提供者的健康状况 - 一些提供商可能会出现临时中断
- 检查中间件日志以了解API问题
位置检测不起作用
如果位置检测返回不正确的结果:
- 确保
GOOGLE_MAPS_API_KEY在环境变量中设置 - 查看Google云控制台了解API配额限制
- 验证API密钥是否已启用地理编码API
- 如果谷歌地图失败,将回归提名
需求
- Node.js: >= 18.0.0
- 马来西亚中转中间件:正在运行的实例(本地或已部署)
- 谷歌地图API密钥:可选,用于增强位置检测
项目结构
malaysiatransit-mcp/
├── src/
│ ├── index.ts # Main MCP server entry point
│ ├── http-server.ts # Streamable HTTP server with analytics
│ ├── transit.tools.ts # Transit tool implementations
│ ├── geocoding.utils.ts # Location detection utilities
│ ├── inspector.ts # MCP Inspector entry point
│ └── server.ts # HTTP server for testing
├── deploy/
│ ├── DEPLOYMENT.md # VPS deployment guide
│ └── nginx-mcp.conf # Nginx reverse proxy config
├── .github/
│ └── workflows/
│ └── deploy-vps.yml # GitHub Actions auto-deploy
├── docker-compose.yml # Docker deployment config
├── Dockerfile # Container build config
├── package.json # Project dependencies
├── tsconfig.json # TypeScript configuration
├── .env.sample # Environment variables template
├── README.md # This file
└── LICENSE # MIT License相关项目
- 马来西亚开放数据MCP -马来西亚开放数据门户MCP
贡献
欢迎投稿!请随时提交拉取请求或未决问题。
许可证
麻省理工学院-参见 许可证 文件以获取详细信息。
致谢
- 马来西亚开放数据门户 对于GTFS数据
- 马来西亚 空间 Rapid KL服务
- 制动辅助系统。我的 区域巴士服务
- 模型上下文协议 对于MCP框架
- 谷歌地图平台 用于地理编码服务
- OpenStreetMap提名 用于回退地理编码
______________________________________________________________________
制作❤️ 通过 Aliff
