huoli — 火力同城需求检索(独立 Skill · Pay Skill 范式)
火力同城是 独立 skill:act 的活动(频道)/ 行程(需求)工具契约以 内联副本形式拆分在 references/ 分目录(act-*.json),huoli 自包含、不跨 skill 引用 ../act。huoli 专属的付费闸(get_huoli_needs / payChannel)与支付逻辑独立实现。
与 act 的关系:act 文件与后端保持不变;huoli 这边把 act 工具契约完整复制到
references/act-*.json分文件,并在其上叠加「火力频道标记 + ¥1 付费解锁 + X402 支付闸」。两边是独立维护的副本关系,非运行期依赖。
Description
火力把本地生活 O2O 组织为「频道(活动)+ 需求(行程推荐)」两层,并支持用户自主运营(act 工具内联在 references/ 分目录):
- 频道检索与选择:搜/选火力频道(
activity.huoli_channel==true),调用内联的search_activities/get_activity_detail(见 references/act-*.json)。 - 无结果引导创建频道:当没有匹配频道时,引导用户创建——调用内联的
create_activity,约束type=ai(沿用默认)+fee=100(¥1 付费解锁)+ 打huoli_channel=true标记(见 references/act-create.json)。 - 组织推送需求(行程推荐):频道内需求 = 行程(
schedule表),调用内联的list_activity_schedules查询;发布需求走 act 的创建行程接口(见 references/act-schedules.json)。 - 付费解锁(支付子级):付费频道(¥1 / 100 分)解锁后,可读取该频道内全部需求;付费经微信支付 Agent Pay X402 协议触发,返回
WeixinPay-Required支付码,由调用方代理用户支付授权。
⚠️ 付费范围说明(计费边界)
- C 端用户(小程序 / H5):经
pages/huoli/needs.vue→payChannel()走微信 Native 扫码付(¥1),付费真实生效,是唯一强制计费的路径。- Agent / MCP 调用方:需求数据等同于 act 的
schedule,亦可通过list_activity_schedules(/act/schedules,同X-API-Key、无付费校验)直接读取——即get_huoli_needs的 ¥1 闸对 Agent 侧不强制(属运营 / 组织视角,不触发计费)。- 因此 huoli 作为 Pay Skill 的付费价值锚定「C 端用户侧」;X402 付费范式(Agent 代付)协议已在
huoli云对象对齐 SkillHub A2M 规范(402 响应体WeixinPay.{WeixinPay-Required}+ 重试头X-Out-Trade-No=payment_code + order.payment_code 回查解锁)。剩余阻塞为 SkillHub 入驻:skillIdhuoli未在 SkillHub 后台注册 + 绑定微信商户号前,preorder 端点返回 302(6a 验签失败),故needs(付费)暂返回402 + blocked + PAY_NOT_READY;入驻完成后即闭环。C 端用户付费(payChannel)不受影响。
🔒 隐私红线(仅约束 Agent/MCP 面):需求列表的 Agent/MCP 面(
get_huoli_needs/ 云对象queryNeeds())不返回联系方式类字段(contact/phone/mobile/wxid),仅展示content/price/images/start_time等非隐私信息;过滤以.field()投影实现,覆盖免费与已解锁两路径。联系方式属发布者隐私,第三方 Agent 不应获取。 C 端needs.vue例外:该页是小程序/H5 消费者面,直接经 clientDB 读schedule并有意展示联系方式(「联系发布者」是本地生活撮合的产品价值),不套用 Agent 面红线;其数据可见性由schedule的 clientDB 权限兜底。
解决的问题:让 Agent 生态能按次计费检索/运营本地生活需求,企业侧无需重构 act 业务逻辑,仅在原服务上叠加开发者签名 + X402 预下单 + 支付触发返回。
局限性:
- 所有写操作(创建频道、发布需求)的实际后端由
act承担,huoli 只规定调用约束,不另起云对象。 - 频道列表 MCP 端点(
list_huoli_channels)当前为规划项,前端频道列表pages/huoli/channel.vue直读activity集合。
Usage
步骤 1 — 频道检索与选择(复用 act)
// 工具:search_activities(来自 act)
// 端点:POST https://mcp.fore.vip/act/search
// 入参:{ keyword?, type?, latitude?, longitude?, page?, pageSize? }
// 火力视角:keyword 匹配本地生活需求语义;结果中筛 huoli_channel==true 即为火力频道
选择某频道后取 activity._id,进入步骤 2 / 3。
步骤 2 — 无结果 → 引导创建频道(复用 act create_activity)
当搜索无匹配火力频道时,引导用户创建。调用 act 的 create_activity,火力约束三件套:
// 工具:create_activity(来自 act,X-API-Key 鉴权)
// 端点:POST https://mcp.fore.vip/act/create
create_activity({
content: "南山科技园午休好去处", // 必填 ≤500 字
address: "深圳南山区科技园", // 必填 ≤128 字
cover: "https://...", // 必填,后端自动转存
tags: ["午休", "本地生活"],
latitude: 22.54, longitude: 113.95,
fee: 100, // ⭐ 火力强制:¥1=100分 付费解锁频道
// ⭐ 火力标记:火力 SKILL 创建时显式传 huoli_channel=true,后端原样透传持久化(非 schema 字段,写入即存;type 沿用 act 默认 ai,不改)
})
// 返回 { _id, url, pay_required: true } → 即新建火力频道
火力频道识别约定:
activity.huoli_channel == true(fee=100即付费频道)。type沿用 act 默认ai,不改后端 enum。
步骤 3 — 组织推送需求(行程推荐,复用 act)
频道内需求 = act 的行程(schedule)。查询复用 list_activity_schedules;发布需求走 act 创建行程接口(同 act 用法,仅 activity_id 填火力频道 _id)。
// 工具:list_activity_schedules(来自 act)
// 端点:POST https://mcp.fore.vip/act/schedules
// 入参:{ activity_id: "<火力频道 _id>", page?, pageSize? }
// → 返回该频道内全部需求(行程推荐)列表
步骤 4 — 付费解锁(支付子级,huoli 专属 X402)
状态:以下为 X402 付费闸的目标态(协议层已落地)。剩余阻塞为 SkillHub 入驻(skillId 注册 + 微信商户号绑定)未完成时,preorder 端点 302(
needs(付费)暂返402 + blocked + PAY_NOT_READY);入驻后即闭环。C 端用户付费不受影响。
付费频道未解锁时,huoli 的 get_huoli_needs 以集成响应模式返回真实 HTTP 402,并通过响应头 WeixinPay-Required 注入 payment_code(uniCloud URL化默认 200,自定义非 200 状态码必须走集成响应 mpserverlessComposedResponse: true):
{
"mpserverlessComposedResponse": true,
"statusCode": 402,
"headers": {
"content-type": "application/json",
"WeixinPay-Required": "<payment_code>"
},
"body": "{\"errCode\":402,\"pay_required\":true,\"unlocked\":false,\"out_trade_no\":\"<payment_code>\",\"amount\":100,\"currency\":\"CNY\",\"prompt\":\"本次查询火力频道需求需要付费(¥1 解锁全部需求)。请将 WeixinPay-Required 的值作为 paymentCode 交给 weixinpay_pay,以向用户申请支付授权。\"}"
}
调用方将 WeixinPay-Required 的值作为 paymentCode 交给微信支付 Agent(weixinpay_pay),由 Agent 向用户申请支付授权。支付成功后,用该笔账单的 payment_code(= WeixinPay-Required 的值)作为 X-Out-Trade-No 头重请求即可解锁(SkillHub A2M 规范;前端路径的 orderId 来自 payChannel() 返回值、以 X-Unlocked 头兼容):
const res = await fetch('https://mcp.fore.vip/huoli/needs', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': '<your-api-key>',
'X-Out-Trade-No': '<payment_code>' // SkillHub A2M 标准重试头,值=402 响应的 WeixinPay-Required(payment_code)
},
body: JSON.stringify({ channel_id: 'act_xxxx' })
})
前端直付(小程序 / H5,huoli 专属)
前端页面 pages/huoli/needs.vue 走 payChannel() 直接拿微信 Native code_url 扫码付,不经 X402(X402 仅对 MCP / Agent 调用方生效):
// 云对象方法:huoli.payChannel({ channel_id })
// 返回:{ errCode: 0, unlocked: false, orderId, codeUrl, amount: 100 }
const r = await uniCloud.importObject('huoli').payChannel({ channel_id: 'act_xxxx' })
// r.codeUrl → vk-uni-qrcode 展示扫码付 → 轮询 order.pay 自动解锁
Configuration
| 项 | 说明 |
|---|---|
X-API-Key |
get_huoli_needs 必须带;复用 ai-mcp 动态 Key 体系,与 act 一致。无 Key 返回 403。 |
X-Out-Trade-No |
SkillHub A2M 标准重试头,值=preorder 返回的 payment_code;云对象按 payment_code 回查 order 已支付解锁。 |
X-Unlocked |
C 端遗留兼容头,值=订单 _id;非 SkillHub 标准重试头。 |
activity.huoli_channel |
火力频道标记(布尔)。非 schema 声明字段,写入即存,不触碰既有 activity 模型。 |
create_activity 火力约束 |
type 沿用 act 默认 ai;fee=100(¥1 付费解锁);火力 SKILL 显式传 huoli_channel=true,后端原样透传(非 schema 字段,写入即存)。 |
order.type=5 |
火力解锁订单固定值;oid=频道 ID,price=100(分)。 |
精确字段定义(act 工具原始契约 + huoli 扩展)一律读 references/mcp.json,需要精确字段时再读取,不要凭记忆。
Examples
例 1:搜火力频道
POST /act/search { keyword: "午休去处", latitude, longitude }
→ 结果中筛 huoli_channel==true 的即为火力频道
例 2:无结果 → 创建火力频道
用户:"火力没有合适的频道,帮我建一个"
→ 引导收集 content/address/cover(同 act 必填)
→ POST /act/create { content, address, cover, fee:100, huoli_channel:true }(火力显式传,后端透传)
→ 返回 { _id, pay_required:true } = 新火力频道
例 3:组织推送需求(行程推荐)
POST /act/schedules { activity_id: "<火力频道 _id>" }
→ 返回该频道内全部需求(行程推荐)列表 total=N
例 4:付费解锁
以下为目标态;当前实际返回
402 + blocked + PAY_NOT_READY(SkillHub 入驻未完成导致 preorder 302,见步骤 4 说明)。
POST /huoli/needs { channel_id: "act_pay_xxx" } + X-API-Key
→ 402 + WeixinPay-Required(payment_code) # 入驻完成后;当前为 PAY_NOT_READY(302)
→ 交 weixinpay_pay 代理支付
→ 再次 POST /huoli/needs + X-Out-Trade-No: <payment_code>
→ { errCode: 0, unlocked: true, list: [...] }
Requirements
- 复用 act MCP 服务端:
https://mcp.fore.vip/act/{search,detail,create,schedules}(URL 化云对象,act 保持不变)。 - huoli 专属 MCP 服务端:
https://mcp.fore.vip/huoli/needs(付费闸)+https://mcp.fore.vip/http/uni-skill-pay-notify(支付回调)。 - 微信支付 V3 凭证:
uni-config-center/uni-skill-pay/config.json的wxpayV3段(uni-config-center 官方 config.json 范式)。 - SkillHub 开发者凭证:同
config.json的skillhub段(X402 预下单签名)。 - 依赖云对象:
huoli(needs / payChannel)、uni-skill-pay-notify(回调验签 + AES-256-GCM 解密置单)。 - 前端页面:
pages/huoli/channel.vue、pages/huoli/needs.vue(uni-app 主包)。
Troubleshooting
| 现象 | 原因 | 处理 |
|---|---|---|
403 Invalid or missing X-API-Key |
未带 / Key 无效 | 检查 X-API-Key 头,复用 ai-mcp 动态 Key |
402 + WeixinPay-Required |
付费频道未解锁(X402 目标态;当前因端点故障改为返回 PAY_NOT_READY) | 按范式交 weixinpay_pay 代理支付,再带 X-Unlocked 重请求 |
402 + blocked: true + PAY_NOT_READY |
X402 预下单端点故障(payapp.weixin.qq.com/.../preorder 被微信网关 302 拦截;非 V3 凭证问题,V3 Native 正常) |
属平台侧事项,需回 SkillHub 官方文档核实端点;C 端用户付费(payChannel)不受影响 |
| 创建的频道不在火力列表 | 未打 huoli_channel=true / fee≠100 |
确认创建时 fee=100,后端自动标记 huoli_channel |
Channel not found |
channel_id 错 / 非 huoli 频道 |
确认 activity._id 且 huoli_channel==true |
| 解锁后仍返回 402 | X-Out-Trade-No/payment_code 订单校验失败 |
确认 order.payment_code == X-Out-Trade-No 且 pay==true(C 端 X-Unlocked 路径:确认 oid==频道ID && type==5 && pay==true) |
References
| 项 | 路径 / 链接 |
|---|---|
| 工具契约总入口 | references/mcp.json(聚合以下分文件) |
| ├ act 搜索(内联副本) | references/act-search.json |
| ├ act 详情(内联副本) | references/act-detail.json |
| ├ act 创建频道(内联副本 + huoli 约束) | references/act-create.json |
| ├ act 行程列表(内联副本) | references/act-schedules.json |
| └ huoli 付费闸(专属) | references/huoli-needs.json |
| 外部 client 配置 | mcp-standard.json(根) |
| MCP 服务地址 | https://mcp.fore.vip |
| 频道列表页(前端) | pages/huoli/channel.vue |
| 需求页(前端) | pages/huoli/needs.vue |
| 部署与联调 | doc/HUOLI_DEPLOY.md |
| SkillHub Pay Skill 范式 | https://skillhub.cn/tutorials#agent-pay-upgrade |
Changelog
1.2.5
- 付费闸返回真实 HTTP 402(集成响应模式):此前因不了解 uniCloud URL化自定义状态码机制,付费未解锁态以
errCode:402普通 JSON 体(被框架包裹为 200)兜底。现改为mpserverlessComposedResponse: true+statusCode: 402+ 响应头WeixinPay-Required: <payment_code>,严格对齐 SkillHub A2M 规范(Agent 识别 HTTP 402 + WeixinPay-Required 头即触发weixinpay_pay)。body同时含out_trade_no/amount/prompt便捷字段。 - 错误分支(
PAY_NOT_READY/V3_ERROR)保持普通 JSON 返回(框架包裹为 200),不再误用 402,避免 Agent 误判为「可支付」态。 - 文档(
SKILL.md/references/huoli-needs.json)同步:402 标注为真实 HTTP 状态码、WeixinPay-Required为响应头(非 body 字段)。版本升 1.2.5。
1.2.4
- 对齐 SkillHub A2M 付费协议(修复「体验不全」真根因):此前
needs()读取X-Unlocked头解锁,但 SkillHub 官方规范 Agent 支付后重试携带的是X-Out-Trade-No(值=preorder 返回的payment_code),导致 Agent 面付费闭环永远无法解锁。修正:checkUnlocked改读X-Out-Trade-No(payment_code→order回查已支付解锁),保留X-Unlocked作 C 端兼容。needs()付费流程 preorder 成功后把payment_code落库(order.payment_code),并在 402 响应体补齐out_trade_no/amount(遵循 SkillHub 最佳实践体结构)。orderschema 新增payment_code字段。SKILL.md全部X-Unlocked协议描述改为X-Out-Trade-No(值=payment_code),与官方逐字对齐。
- 剩余阻塞(非代码死结):
skillId huoli未在 SkillHub 后台注册 + 绑定微信商户号前,preorder 返回 302(6a 验签失败),needs(付费)暂返PAY_NOT_READY;入驻后即闭环。C 端payChannel直付已真验可用。
1.2.3
- 品牌/标识归一:
huoli关键字统一改为「火力」(huoli);支付能力抽离为通用底座uni-skill-pay(含uni-skill-pay-notify通用回调),凭证统一单份uni-config-center/uni-skill-pay/config.json,支撑多 SKILL 子模块共用支付。前端pages/huoli/*→pages/huoli/*;activity.huoli_channel→huoli_channel(需数据迁移)。
1.2.2
- 隐私红线:huoli 云对象
queryNeeds()以.field()投影过滤联系方式类字段(contact/phone/mobile/wechat/wxid),需求列表(免费 + 已解锁两路径)不再泄露发布者隐私。对应references/huoli-needs.json列表字段说明同步更新,并在正文新增「隐私红线」段落。
1.2.1
- 文档/声明层收敛(不动后端):
- 增补「付费范围说明」:明确 ¥1 付费仅对 C 端用户(needs.vue + payChannel)强制生效;Agent/MCP 侧经
act/schedules读需求不触发计费(运营视角)。 - X402 付费闸标注为「目标态」,当前因 SkillHub 预下单端点被微信网关 302 拦截返回
PAY_NOT_READY,Agent 代付闭环暂不可用。 - 修正 Troubleshooting:
PAY_NOT_READY归因由「V3 凭证未配置」改为「X402 端点故障(非 V3 问题)」。 - 补全
X-Unlocked流程中orderId来源说明。 - frontmatter:
tags移除过时act-submodule、改act-compatible;negative_triggers收紧为「非火力/本地生活类」;版本升 1.2.1。
- 增补「付费范围说明」:明确 ¥1 付费仅对 C 端用户(needs.vue + payChannel)强制生效;Agent/MCP 侧经
1.2.0
- 重构为独立 skill:移除对
../act的引用,act 工具契约以内联副本拆分进references/act-*.json(search/detail/create/schedules),huoli 自包含。 references/mcp.json改为聚合本地分文件($ref: ./act-*.json),不再跨 skill 引用。- act 文件/后端保持不变,两边为独立维护的副本关系。
1.1.0
- 重构为 act 子级模块:明确复用 act 后端(search/detail/create/schedules),huoli 仅叠加频道标记 + 付费闸。
- 业务流写入正文:频道检索/选择 → 无结果引导创建(复用 create_activity,type=ai + fee=100 + huoli_channel=true)→ 组织推送需求(行程推荐)→ 支付逻辑子级(X402)。
- act 文件与后端保持不变。
1.0.0
- 初版:huoli 云对象
needs()(付费闸 X402)+payChannel()(前端直付);uni-skill-pay-notify 回调验签解密。 - 前端频道列表 / 需求页(主包)+ 「我的」页入口。
- SKILL 声明三件套(SKILL.md / references/mcp.json / mcp-standard.json)对齐 act 分层。
- 按 SkillHub 官方规范补齐 frontmatter 与标准章节结构。