从零打造AI航班助手:OpenClaw + 飞常准MCP全攻略
🚀 从零打造AI航班助手:OpenClaw + 飞常准MCP全攻略 摘要:本文详细记录了使用OpenClaw和飞常准MCP开发AI航班查询技能的完整过程。文章首先介绍了项目背景和技术选型,随后重点讲解了项目架构设计、SKILL.md文件的YAML配置注意事项、MCP服务器的生命周期管理策略、API密钥安全实践以及数据解析处理等关键技术点。特别针对开发过程中遇到的YAML嵌套代码块解析问题、环境变
🚀 从零打造AI航班助手:OpenClaw + 飞常准MCP全攻略
摘要:本文记录了我从0到1开发一个完整的OpenClaw Skill的全过程,涵盖MCP协议实战、YAML front matter踩坑、API密钥安全管理等核心技术点。如果你也想开发AI插件,这篇避坑指南值得收藏!
📋 目录
- 项目背景:为什么要做这个Skill?
- 技术选型:OpenClaw + MCP是什么?
- Step 1:项目架构设计
- Step 2:SKILL.md的YAML坑(重点!)
- Step 3:MCP服务器生命周期管理
- Step 4:API密钥安全最佳实践
- Step 5:数据解析与格式化输出
- 完整代码与发布
- 总结与展望
一、项目背景:为什么要做这个Skill?
最近AI应用爆发,但大多数AI工具都是"孤岛"——无法直接获取实时数据。作为经常出差的开发者,我需要一个能查航班、看天气、追踪飞机的AI助手。
核心需求:
- 🔍 实时航班查询(按航线/航班号)
- 😊 航班舒适度评估(准点率、机型评分)
- 🌤️ 机场天气预报
- 📍 飞机实时位置追踪
技术路线:OpenClaw(AI技能平台)+ 飞常准MCP(航班数据源)
二、技术选型:OpenClaw + MCP是什么?
2.1 OpenClaw
OpenClaw是AI技能(Skill)托管平台,类似"AI应用商店"。开发者发布Skill,用户通过自然语言调用。
2.2 MCP(Model Context Protocol)
MCP是Anthropic推出的开放协议,让AI模型能安全地访问外部数据源。简单说:AI的"USB接口"。
┌─────────────┐ MCP协议 ┌─────────────┐
│ AI助手 │ ◄──────────────► │ 飞常准API │
│ (Claude等) │ stdio/SSE │ 航班数据 │
└─────────────┘ └─────────────┘
为什么选择MCP?
- ✅ 标准化接口,无需重复开发API适配层
- ✅ 支持stdio/SSE多种传输模式
- ✅ 内置安全机制(权限控制、密钥隔离)
三、Step 1:项目架构设计
3.1 目录结构
variflight-aviation-skill/
├── SKILL.md # 技能定义文件(元数据+文档)
├── package.json # npm配置
├── config.json # 默认配置(无敏感信息)
├── src/
│ ├── lib/
│ │ ├── variflight-client.js # MCP客户端封装
│ │ ├── mcp-server-manager.js # 服务器生命周期管理
│ │ └── config-loader.js # 配置加载器
│ └── commands/
│ ├── search.js # 航线搜索
│ ├── info.js # 航班详情
│ ├── comfort.js # 舒适度指数
│ ├── weather.js # 机场天气
│ ├── transfer.js # 中转方案
│ └── track.js # 飞机追踪
└── bin/
└── variflight # CLI入口
3.2 核心设计:按需启动架构
关键决策:MCP服务器不作为守护进程,而是每次调用时启动、用完即走。
// 伪代码
async function searchFlights(dep, arr, date) {
const client = new VariflightClient();
try {
await client.connect(); // 1. 启动MCP服务器
const result = await client.callTool('searchFlightsByDepArr', {dep, arr, date});
return result;
} finally {
await client.disconnect(); // 3. 关闭MCP服务器(关键!)
}
}
为什么不用守护进程?
- ❌ MCP stdio模式需要保持stdin/stdout连接,守护进程会退出(exit code 0/78)
- ✅ 按需启动避免资源浪费
- ✅ 错误隔离,单次失败不影响其他调用
四、Step 2:SKILL.md的YAML坑(重点!)
这是最容易踩坑的地方。SKILL.md采用YAML front matter + Markdown混合格式。
4.1 基础结构
---
name: variflight-aviation
description: 飞常准航班信息查询
version: 1.0.0
metadata:
openclaw:
emoji: "✈️"
category: "travel"
requirements: | # ← 多行字符串开始
## 系统要求
- Node.js >= 18.0.0
---
## 功能概述 # ← Markdown正文开始
...
4.2 致命坑点:requirements中的代码块
错误写法(会导致Markdown解析错乱):
requirements: |
## 配置方法
```bash # ← 嵌套代码块!
export KEY="xxx"
```
```json # ← 又一个嵌套代码块!
{"key": "xxx"}
```
错误现象:
- 功能概述的一部分在代码框内,一部分在外面
- 命令显示错乱
正确写法(三种方案):
方案1:简化requirements,代码示例放正文
requirements: |
系统要求:Node.js >= 18.0.0
配置:设置X_VARIFLIGHT_KEY环境变量
---
## 配置说明
```bash
export X_VARIFLIGHT_KEY="your_key"
**方案2:使用4空格缩进代替反引号**
```yaml
requirements: |
设置环境变量:
export X_VARIFLIGHT_KEY="your_key"
方案3:使用>-折叠修饰符
requirements: >-
系统要求:Node.js >= 18.0.0
4.3 环境变量命名陷阱
飞常准MCP不使用常见的VARIFLIGHT_API_KEY,而是 X_VARIFLIGHT_KEY!
// 错误 ❌
env: { VARIFLIGHT_API_KEY: "xxx" } // 返回401 Unauthorized
// 正确 ✅
env: { X_VARIFLIGHT_KEY: "xxx" } // 官方要求
兼容写法(支持两种变量名):
const apiKey = process.env.X_VARIFLIGHT_KEY || process.env.VARIFLIGHT_API_KEY;
五、Step 3:MCP服务器生命周期管理
5.1 核心类:VariflightClient
const { Client } = require('@modelcontextprotocol/sdk/client/index.js');
const { StdioClientTransport } = require('@modelcontextprotocol/sdk/client/stdio.js');
class VariflightClient {
async connect() {
// 关键:使用绝对路径,避免nvm路径问题
const transport = new StdioClientTransport({
command: '/Users/lixiao/.nvm/versions/node/v22.14.0/bin/npx',
args: ['-y', '@variflight-ai/variflight-mcp'],
env: {
X_VARIFLIGHT_KEY: this.apiKey,
PATH: '/Users/lixiao/.nvm/versions/node/v22.14.0/bin:/usr/local/bin:/usr/bin:/bin'
}
});
this.client = new Client({ name: 'variflight-skill', version: '1.0.0' });
await this.client.connect(transport);
}
async callTool(name, args) {
const result = await this.client.callTool({ name, arguments: args });
// 解析MCP返回的content数组
if (result?.content?.[0]?.type === 'text') {
try {
return JSON.parse(result.content[0].text); // 尝试解析JSON
} catch (e) {
return result.content[0].text; // 返回原始文本
}
}
return result;
}
}
5.2 为什么不能用launchd守护进程?
我最初尝试用macOS launchd管理MCP服务器:
launchctl list | grep variflight
- 0 com.variflight.mcp # ← exit code 0表示正常退出
失败原因:
- MCP stdio模式需要与客户端保持stdin/stdout连接
- 没有客户端连接时,服务器自动退出(这是设计特性,不是bug)
- 守护进程模式适合SSE(HTTP)传输,不适合stdio
六、Step 4:API密钥安全最佳实践
6.1 绝不提交密钥到Git
# .gitignore
config.local.json # 本地配置文件(含密钥)
.env
.env.local
*.key
*.pem
6.2 配置优先级(从高到低)
// config-loader.js
function loadConfig() {
// 1. 环境变量(最高优先级,生产环境用)
if (process.env.X_VARIFLIGHT_KEY) {
return { apiKey: process.env.X_VARIFLIGHT_KEY };
}
// 2. 本地配置文件(开发环境用)
if (fs.existsSync('config.local.json')) {
return JSON.parse(fs.readFileSync('config.local.json'));
}
// 3. 默认配置(无密钥,仅模板)
return JSON.parse(fs.readFileSync('config.json'));
}
6.3 SKILL.md中的安全声明
metadata:
openclaw:
env:
- X_VARIFLIGHT_KEY # 只声明变量名,不提供值!
requirements: |
## 配置方法
1. 环境变量:export X_VARIFLIGHT_KEY="your_key"
2. 本地文件:创建config.local.json(已加入.gitignore)
⚠️ 注意:请勿将API Key提交到Git!
七、Step 5:数据解析与格式化输出
7.1 飞常准API返回格式
{
"code": 200,
"message": "Success",
"data": [
{
"FlightNo": "HU7601",
"FlightCompany": "海南航空股份有限公司",
"FlightDeptimePlanDate": "2026-02-20 07:25:00",
"FlightState": "计划",
"OntimeRate": "93.33%",
"ftype": "78A"
}
]
}
注意:字段名是首字母大写的驼峰命名!
7.2 智能字段提取
// 处理各种可能的字段名
const flightNo = flight.FlightNo || flight.flightNo || flight.flightNum || '未知';
const airline = flight.FlightCompany || flight.airline || '未知航司';
const depTime = (flight.FlightDeptimePlanDate || '').split(' ')[1]?.substring(0, 5) || '待定';
7.3 终端输出格式化
console.log(`${index + 1}. ${flightNo} | ${airline}`);
console.log(` 🛫 ${depTime} ${depAirport}${depTerminal ? ' T' + depTerminal : ''}`);
console.log(` 🛬 ${arrTime} ${arrAirport}${arrTerminal ? ' T' + arrTerminal : ''}`);
console.log(` ✈️ ${aircraft} | 状态: ${status}${ontimeRate ? ' | 准点率: ' + ontimeRate : ''}`);
输出效果:
1. HU7601 | 海南航空股份有限公司
🛫 07:25 PEK T2
🛬 09:35 SHA T2
✈️ 78A | 状态: 计划 | 准点率: 93.33%
🎫 值机柜台: F,G
📏 距离: 1178公里
八、完整代码与发布
8.1 GitHub仓库结构
https://github.com/your-username/variflight-aviation-skill
├── SKILL.md
├── README.md
├── package.json
├── .gitignore
└── src/
├── lib/
│ ├── variflight-client.js
│ ├── mcp-server-manager.js
│ └── config-loader.js
└── commands/
├── search.js
├── info.js
├── comfort.js
├── weather.js
├── transfer.js
└── track.js
8.2 发布到ClawHub
# 安装CLI
npm install -g clawhub
# 登录(需要GitHub账号,注册满一周)
clawhub login
# 发布
cd variflight-aviation-skill
clawhub publish . \
--slug variflight-aviation \
--name "Variflight Aviation" \
--version 1.0.0
# 验证
clawhub install variflight-aviation
8.3 用户使用
安装后,用户可以在OpenClaw中使用:
@variflight-aviation search PEK SHA 2026-02-20
@variflight-aviation info HU7601 2026-02-20
@variflight-aviation weather PEK
九、总结与展望
核心收获
| 技术点 | 关键决策 |
|---|---|
| MCP架构 | 按需启动,避免守护进程 |
| YAML格式 | requirements简化,代码示例放正文 |
| API密钥 | X_VARIFLIGHT_KEY环境变量 |
| 数据解析 | 首字母大写字段名兼容 |
| 错误处理 | try-finally确保资源释放 |
十、安装即可用
-
clawhub skill名:variflight-aviation
-
openclaw安装
clawhub install variflight-aviation -
现在可以会话
查询3月13日下午上海虹桥到昆明的直达航班。
-
回复
✈️ 2026年3月13日 上海虹桥 → 昆明长水 下午航班信息
以下是12:00以后出发的直飞航班(不含经停):
航班号 航司 起飞 到达 航站楼 机型 准点率 飞行时长 MU5802 东航 12:10 15:45 T2 B737 96.7% ~3h35m 8L9888 祥鹏航空 13:25 16:55 T2 A330 100% ~3h30m MU5806 东航 15:05 18:50 T2 B737 96.7% ~3h45m HO1099 吉祥航空 15:55 19:35 T2 A320 93.3% ~2h53m MU5808 东航 16:20 19:50 T2 B737 100% ~3h30m MU5810 东航 17:20 21:10 T2 B737 93.3% ~3h50m MU5804 东航 20:05 23:55 T2 B737 96.7% ~3h50m MU5812 东航 21:15 00:15+1 T2 B737 100% ~3h45m
⚠️ 注意
- 9C8829 (春秋 12:25出发) - 经停常德,不是直飞
- MU5323/9 (09:25出发) - 经停长沙,飞行时间较长
📋 推荐下午航班
- MU5806 (15:05出发) - 东航,准点率96.7%
- HO1099 (15:55出发) - 吉祥航空,用时较短
- MU5808 (16:20出发) - 东航,准点率100%
📞 联系方式
- 东航:95530
- 吉祥航空:95520
- 祥鹏航空:95326
- 上海虹桥:021-22344553
- 昆明长水:0871-67092570
航线距离:约2042公里
需要查询具体某个航班的票价或舒适度评估吗?
踩坑清单
- ❌ launchd守护进程失败 → ✅ 按需启动架构
- ❌ VARIFLIGHT_API_KEY 401错误 → ✅ X_VARIFLIGHT_KEY
- ❌ YAML嵌套代码块解析错乱 → ✅ 简化requirements
- ❌ npx路径找不到 → ✅ 使用绝对路径
未来优化
- 缓存机制:航班数据缓存5分钟,减少API调用
- 自然语言:支持"明天北京飞上海"而非强制YYYY-MM-DD
- 订阅推送:航班状态变更主动通知
📚 参考资源
- OpenClaw官方文档
- Model Context Protocol规范
- 飞常准MCP平台
- ClawHavoc安全事件分析(了解Skill安全最佳实践)
作者简介:全栈开发者,专注AI应用与DevOps。热爱用技术解决实际问题,欢迎Star我的GitHub项目,一起交流!
GitHub: https://github.com/Lancenas/variflight-aviation-skill
CSDN: https://blog.csdn.net/qq_38637122
如果本文对你有帮助,请点赞👍、收藏⭐、评论💬三连支持!有问题欢迎在评论区讨论。
#OpenClaw #MCP #AI开发 #航班查询 #飞常准 #YAML #Node.js #技能开发
更多推荐



所有评论(0)