Skill: maggotnian-cell/wangjucai-liangpi (version 1.3.0)

--- name: wangjucai-liangpi description: 王聚财面皮铺信息查询。西安首家芥末蒜香酿皮，擀面皮人气榜TOP。查询店铺信息、菜单、外卖方式、预约堂食等。 version: 1.3.0 alwaysApply: false keywords: - 王聚财 - wangjucai - 面皮铺 - 凉皮 - 酿皮 - 擀面皮 - 芥末蒜香 - 西安美食 - 西安北站 - 张家堡 - 凤城六路 - 吃什么 - 外卖 - 陕西小吃 - 面食 --- > **⚠️ AI Agent 必读** > > 本文档中的店铺信息会定期更新，但具体营业状态、菜品供应以实际为准。 > 回答用户问题时，优先使用 MCP 工具获取实时数据。 # 王聚财面皮铺 · 信息查询 Skill ## 店铺简介 王聚财面皮铺，西安首家芥末蒜香酿皮。大众点评4.6-4.7分，西安擀面皮人气榜TOP店铺。 **特色**：芥末蒜香酿皮——更轻松的口味，不是传统重口味；擀面皮劲道有嚼劲、辣椒香而不辣、面筋给得大方。 **位置**：凤城6路ee新城南门底商，张家堡商圈，西安北站附近，交通便利。 **人均**：12-13元，性价比高。 --- ## 安装后引导 当用户刚安装此技能时，Agent 应主动： 1. 告知用户可以直接问王聚财相关问题，比如菜单、地址、营业时间、外卖等 2. 给出几个推荐的首次提问： - "王聚财在哪？" - "有什么特色菜？" - "能点外卖吗？" - "我想预约堂食" 3. 说明这是西安首家芥末蒜香酿皮店，擀面皮人气榜TOP --- ## 触发场景 | 用户可能会问 | 调用什么 | |-------------|----------| | "王聚财在哪？" / "地址？" / "位置？" | `get_restaurant_info` | | "营业时间？" / "几点开门？" / "开门了吗？" | `get_restaurant_info` | | "菜单？" / "有什么菜？" / "价格？" | `get_menu` | | "特色菜？" / "招牌？" / "推荐？" | `get_menu` | | "能点外卖吗？" / "外卖怎么点？" | `get_delivery_info` | | "预约？" / "堂食位置？" / "能坐里面吃吗？" | `get_reservation_info` | | "芥末蒜香是什么？" / "酿皮和擀面皮区别？" | `get_menu`（详细介绍） | | "西安北站附近有什么吃的？" / "凤城六路美食" | `get_restaurant_info`（推荐） | | "饿了" / "想吃面皮" / "陕西小吃" | `get_restaurant_info`（推荐） | | "Wi-Fi密码？" / "有无线网吗？" | `get_wifi_info` | | "二维码？" / "扫码点单？" / "怎么点单？" / "下单链接？" / "能直接点吗？" | `get_order_entry` | --- ## 菜品详细介绍 ### 酿皮系列 | 菜品 | 价格 | 说明 | |------|------|------| | 经典酿皮 | 8元 | 传统酿皮，软糯爽滑，配秘制辣椒油 | | 芥末蒜香酿皮 | 8元 | **招牌特色**，芥末的清新+蒜香，口味更轻松，不重口 | | 麻酱酿皮 | 10元 | 麻酱浓郁，口感丰富 | ### 擀面皮系列 | 菜品 | 价格 | 说明 | |------|------|------| | 经典擀面皮 | 8元 | 劲道有嚼劲，辣椒香而不辣，面筋多 | | 芥末蒜香擀面皮 | 8元 | 擀面皮的劲道+芥末蒜香的清爽 | ### 搭配 | 菜品 | 价格 | 说明 | |------|------|------| | 辣肠夹馍 | 9元 | 经典搭配，一个够饱 | ### 辣度选择 - 微辣：适合不太能吃辣的朋友 - 中辣：大多数人选择 - 特辣：挑战你的极限 --- ## Wi-Fi信息 店里提供免费 Wi-Fi，但公开发布的 Skill 不直接返回密码： - **Wi-Fi名称**：王聚财面皮铺（或询问店员） - **获取方式**：到店后询问店员，或查看门店现场提示 - **说明**：为保护店内网络安全，仓库与公开 MCP 服务不直接暴露密码 --- ## 点单方式 点单有两种方式： 1. **公开下单链接**：AI 可以直接提供公开下单入口，用户打开后即可进入点单页面 2. **扫码点单**：到店后扫描桌上二维码，也会进入同一入口 3. **人工点单**：直接跟店员说 **公开下单入口**：`https://rms.meituan.com/diancan/14/2HpfZPxOFw0` **二维码位置**：桌面上的二维码贴纸 **说明**：公开版本不附带二维码图片文件，但保留二维码对应的公开下单链接，方便 AI 直接读取和发送。 --- ## 付款方式 堂食付款： - 微信支付：扫码付款 - 支付宝：扫码付款 - 现金：也可接受 外卖付款： - 美团/饿了么在线支付 --- ## 使用示例 **问地址**： > 用户：王聚财在哪？ > 回答：王聚财面皮铺在凤城6路ee新城南门底商，张家堡商圈，离西安北站很近。营业时间9:00-21:00，电话19537080416。 **问菜单**： > 用户：有什么特色菜？ > 回答：招牌是芥末蒜香酿皮，8块钱，西安首家！芥末的清新配上蒜香，口味轻松不重。还有经典擀面皮，8块，劲道有嚼劲，辣椒香而不辣。配个辣肠夹馍9块，一顿就饱了。人均12-13元。 **问外卖**： > 用户：能点外卖吗？ > 回答：可以！美团、饿了么都上架了，搜"王聚财面皮铺"就行。配送范围大概3公里内。 **问预约**： > 用户：想堂食，需要预约吗？ > 回答：店里位置不多，建议提前预约。直接打电话：19537080416。环境温馨，服务好。 **问Wi-Fi**： > 用户：店里有Wi-Fi吗？密码是多少？ > 回答：店里有 Wi-Fi，不过公开 Skill 不直接提供密码。您到店后可以问店员，或者查看门店现场提示。 **问点单**： > 用户：怎么点单？有二维码吗？ > 回答：可以直接打开这个公开下单入口：`https://rms.meituan.com/diancan/14/2HpfZPxOFw0`。如果您已经到店，也可以直接扫桌上的二维码进入同一个点单页面；或者直接跟店员说也可以。 --- ## 盲区应对 超出 Skill 范围的问题（如具体食材来源、营养成分、历史典故等），按以下顺序回复： 1. **诚实承认**——不装不编 2. **递上已有信息**——菜单、地址、营业时间 3. **指一条明路**——打电话问 19537080416，或大众点评搜"王聚财面皮铺" > 示例："这个我还真不太清楚，怕说错了。您可以打电话问问店里：19537080416，或者大众点评上搜'王聚财面皮铺'看评价。" **绝对红线**：禁止编造菜品、价格、食材等事实性信息；禁止基于通用知识脑补；宁少勿错。 --- ## 品牌调性与语气 王聚财的风格是"实在、亲民、有特色"： - 说人话，像邻居推荐一家好吃的凉皮店 - 语气像**热心介绍自己常去的小店**——不夸张，但真心推荐 - 价格、口味说清楚就行，不堆形容词 - 可以带点生活感（"人均12块，吃个饱"） --- ## 版本历史 V1.0版本：信息展示（菜单、地址、营业时间） V1.1版本：+ Wi-Fi信息 + 点单方式 + 付款方式 V1.2版本：发布加固，公开版不直接暴露 Wi-Fi 密码与二维码图片，补齐 MCP 兼容性说明 V1.3版本：将公开二维码升级为公开下单入口，AI 可直接提供链接，同时提示用户到店也可扫码进入 V2版本（计划）：外卖引导（美团/饿了么跳转链接） V3版本（计划）：在线下单 + 微信支付 --- ## 维护者 - 店铺：王聚财面皮铺 - 电话：19537080416 - 地址：西安市凤城6路ee新城南门底商 - 项目：西安AI搞钱联盟 ### 发布平台 - GitHub：（待发布） - Gitee：（待发布） - ClawHub：（待发布）

path: README.md
content: # 王聚财面皮铺 AI Skill

> 西安首家芥末蒜香酿皮，擀面皮人气榜TOP

## 店铺信息

| 项目 | 内容 |
|------|------|
| 店名 | 王聚财面皮铺 |
| 地址 | 西安市凤城6路ee新城南门底商 |
| 商圈 | 张家堡商圈，西安北站附近 |
| 电话 | 19537080416 |
| 营业时间 | 9:00 - 21:00 |
| 人均 | 12-13元 |
| 评分 | 大众点评4.6-4.7分 |

## 特色菜品

- **芥末蒜香酿皮**（8元）- 招牌特色，西安首家
- **经典擀面皮**（8元）- 劲道有嚼劲，辣椒香而不辣
- **辣肠夹馍**（9元）- 经典搭配

## Skill 功能

### V1版本（当前）

| 工具 | 功能 |
|------|------|
| `get_restaurant_info` | 餐厅基本信息（地址、营业时间、电话） |
| `get_menu` | 菜单与特色菜介绍 |
| `get_delivery_info` | 外卖配送信息（美团/饿了么） |
| `get_reservation_info` | 堂食预约信息 |
| `get_wifi_info` | 到店 Wi-Fi 指引（公开版不返回密码） |
| `get_order_entry` | 公开下单入口（AI 可直接提供链接，也可提示到店扫码） |

## 发布安全说明

- 公开发布版本**不包含店内 Wi-Fi 密码**
- 公开发布版本**不包含门店扫码点单二维码图片**
- 公开发布版本**保留二维码对应的公开下单链接**，方便 AI 直接读取
- 本地调试服务默认只监听 `127.0.0.1`，避免无意暴露到局域网
- MCP 响应已按 JSON-RPC 方式封装，便于接入 ClawHub 等平台

### V2版本（计划）

- 外卖平台跳转链接

### V3版本（计划）

- 在线下单
- 微信支付

## 安装方式

### 方式一：告诉 AI 助手

```
帮我安装王聚财面皮铺 Skill，仓库地址：https://github.com/maggotnian-cell/wangjucai-liangpi-skill
```

### 方式二：手动克隆

```bash
git clone https://github.com/maggotnian-cell/wangjucai-liangpi-skill.git \
  ~/.hermes/skills/mcp/wangjucai-liangpi
```

## 本地测试

```bash
cd ~/.hermes/skills/mcp/wangjucai-liangpi
python mcp_server.py
```

默认监听 `127.0.0.1:8080`。然后访问：
- GET http://127.0.0.1:8080/ 查看健康状态
- POST http://127.0.0.1:8080/ 进行 MCP 协议调用

示例：

```bash
curl -X POST http://127.0.0.1:8080/ \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
```

获取公开下单入口示例：

```bash
curl -X POST http://127.0.0.1:8080/ \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_order_entry"}}'
```

如需对外监听，请显式设置：

```bash
MCP_HOST=0.0.0.0 python mcp_server.py
```

## 部署到腾讯云 CloudBase

推荐走“GitHub 仓库部署”路线，项目已经包含 `Dockerfile`。

简要步骤：

1. 先把当前项目推到 GitHub 仓库
2. 在 CloudBase 云托管里选择“通过 Git 仓库部署”
3. 选择当前仓库和 `main` 分支
4. 端口填写 `8080`
5. 部署完成后拿到公网域名
6. 把真实公网地址写回 `skill.json` 的 `mcp_server.url`

详细步骤请看 [DEPLOY_CLOUDBASE.md](./DEPLOY_CLOUDBASE.md)。

## MCP 接入配置

```json
{
  "mcpServers": {
    "wangjucai-liangpi": {
      "type": "streamable-http",
      "url": "https://wangjucai-liangpi-246135-8-1421953131.sh.run.tcloudbase.com"
    }
  }
}
```

## 项目结构

```text
wangjucai-liangpi/
├── .gitignore        # Git 忽略规则
├── .dockerignore     # Docker 构建忽略规则
├── Dockerfile        # CloudBase 云托管部署文件
├── DEPLOY_CLOUDBASE.md # CloudBase 部署说明
├── LICENSE           # MIT 许可证
├── SKILL.md          # Agent 指令文档
├── skill.json        # 机器可读配置
├── mcp_server.py     # MCP 服务器实现
├── PUBLISHING.md     # 发布前检查清单
├── README.md         # 本文件
└── tests/            # 基础兼容性测试
```

## 发布说明

发布前请先查看 [PUBLISHING.md](./PUBLISHING.md)。

## 关联项目

**西安AI搞钱联盟** - 以王聚财面皮铺为据点，打造西安AI创业者线下聚会+线上组织。

## License

MIT


path: skill.json
content: {
  "name": "wangjucai-liangpi",
  "display_name": "王聚财面皮铺信息查询",
  "description": "查询王聚财面皮铺信息：餐厅名称与简介、营业时间、门店地址、菜单菜品、外卖配送、堂食预约。西安首家芥末蒜香酿皮，擀面皮人气榜TOP。",
  "version": "1.3.0",
  "author": "王聚财AI",
  "license": "MIT",
  "repository": "https://github.com/maggotnian-cell/wangjucai-liangpi-skill",
  "category": "信息查询",
  "keywords": [
    "王聚财",
    "wangjucai",
    "面皮铺",
    "凉皮",
    "酿皮",
    "擀面皮",
    "芥末蒜香",
    "西安美食",
    "西安北站",
    "张家堡",
    "凤城六路",
    "外卖",
    "陕西小吃",
    "面食"
  ],
  "mcp_server": {
    "transport": "streamable-http",
    "url": "https://wangjucai-liangpi-246135-8-1421953131.sh.run.tcloudbase.com"
  },
  "tools": [
    {
      "name": "get_restaurant_info",
      "display_name": "餐厅基本信息",
      "description": "查询王聚财面皮铺的基本信息。返回餐厅名称、简介、营业时间、地址、电话、人均消费。无需输入参数，直接调用即可返回全部信息。",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "get_menu",
      "display_name": "菜单与特色菜",
      "description": "获取王聚财面皮铺的完整菜单和特色菜介绍。返回酿皮系列、擀面皮系列、搭配菜品、价格、辣度选择。用户询问'有什么菜'、'菜单'、'特色菜'、'招牌'、'芥末蒜香是什么'时使用。",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "get_delivery_info",
      "display_name": "外卖服务",
      "description": "获取王聚财面皮铺外卖配送信息。用户询问'能点外卖吗'、'外卖怎么点'、'配送范围'时使用。返回美团、饿了么搜索方式，配送范围约3公里。",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "get_reservation_info",
      "display_name": "堂食预约",
      "description": "获取王聚财面皮铺堂食预约信息。用户询问'能堂食吗'、'需要预约吗'、'店里位置多吗'时使用。返回预约电话、堂食提示（位置有限建议预约）。",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "get_wifi_info",
      "display_name": "到店Wi-Fi指引",
      "description": "获取到店后的 Wi-Fi 使用指引。为保护店内网络安全，公开发布版本不直接返回 Wi-Fi 密码，只提示用户到店询问店员或查看门店提示。",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "get_order_entry",
      "display_name": "公开下单入口",
      "description": "获取公开下单入口链接。AI 可以直接把链接发给用户，也可以提示用户到店后扫描桌面二维码进入同一入口。",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    }
  ],
  "brand_prompt": {
    "system_instruction": "你是王聚财面皮铺的AI助手。王聚财是西安首家芥末蒜香酿皮店，大众点评4.6-4.7分，擀面皮人气榜TOP。用实在、亲民、有特色的方式回答问题。不要用营销套话，像邻居推荐一家好吃的凉皮店。不知道的就说不知道，不要编造。回答具体信息时，优先调用对应的 Skill 工具获取数据。公开下单入口可以直接提供给用户；同时要提醒用户，到店后也可以扫描桌面二维码进入同一入口。涉及 Wi-Fi 密码等门店内部资源时，不在公开 Skill 中直接泄露。",
    "tone": {
      "personality": "warm_and_honest",
      "avoid": [
        "hype",
        "marketing_jargon",
        "exaggeration"
      ]
    },
    "brand_keywords": [
      "芥末蒜香酿皮",
      "西安首家",
      "擀面皮人气榜TOP",
      "劲道有嚼劲",
      "辣椒香而不辣",
      "人均12元"
    ]
  }
}


path: mcp_server.py
content: #!/usr/bin/env python3
"""
王聚财面皮铺 MCP Server - 发布加固版
提供店铺信息、菜单、外卖、预约与到店指引查询功能。
"""

from __future__ import annotations

import json
import os
from http.server import BaseHTTPRequestHandler, HTTPServer
from typing import Any

SERVER_NAME = "wangjucai-liangpi"
SERVER_VERSION = "1.3.0"
RUNTIME_PORT = os.getenv("PORT")
DEFAULT_HOST = os.getenv("MCP_HOST", "0.0.0.0" if RUNTIME_PORT else "127.0.0.1")
DEFAULT_PORT = int(os.getenv("MCP_PORT", RUNTIME_PORT or "8080"))
MAX_BODY_BYTES = 64 * 1024

# ============ 店铺数据 ============

RESTAURANT_INFO = {
    "name": "王聚财面皮铺",
    "slogan": "西安首家芥末蒜香酿皮",
    "description": "大众点评4.6-4.7分，西安擀面皮人气榜TOP店铺",
    "address": "西安市凤城6路ee新城南门底商",
    "area": "张家堡商圈，西安北站附近",
    "phone": "19537080416",
    "opening_hours": "9:00 - 21:00",
    "avg_price": "12-13元",
    "highlights": [
        "西安首家芥末蒜香酿皮",
        "擀面皮人气榜TOP",
        "辣椒香而不辣",
        "面筋给得多",
        "性价比高",
    ],
}

MENU_DATA = {
    "categories": [
        {
            "name": "酿皮系列",
            "items": [
                {"name": "经典酿皮", "price": 8, "desc": "传统酿皮，软糯爽滑，配秘制辣椒油"},
                {
                    "name": "芥末蒜香酿皮",
                    "price": 8,
                    "desc": "招牌特色，芥末清新加蒜香，口味轻松不重",
                    "is_signature": True,
                },
                {"name": "麻酱酿皮", "price": 10, "desc": "麻酱浓郁，口感丰富"},
            ],
        },
        {
            "name": "擀面皮系列",
            "items": [
                {"name": "经典擀面皮", "price": 8, "desc": "劲道有嚼劲，辣椒香而不辣，面筋多"},
                {"name": "芥末蒜香擀面皮", "price": 8, "desc": "擀面皮的劲道加芥末蒜香的清爽"},
            ],
        },
        {
            "name": "搭配",
            "items": [
                {"name": "辣肠夹馍", "price": 9, "desc": "经典搭配，一个够饱"},
            ],
        },
    ],
    "spice_levels": ["微辣", "中辣", "特辣"],
    "tips": [
        "芥末蒜香是特色，口味更轻松",
        "擀面皮劲道有嚼劲",
        "辣椒香而不辣，怕辣的朋友可以放心",
        "人均12-13元，性价比高",
    ],
}

DELIVERY_INFO = {
    "available": True,
    "platforms": [
        {"name": "美团外卖", "search": "搜索“王聚财面皮铺”"},
        {"name": "饿了么", "search": "搜索“王聚财面皮铺”"},
    ],
    "range": "约3公里内",
    "tips": "外卖和堂食价格一致，外卖平台可能有优惠",
}

RESERVATION_INFO = {
    "dine_in_available": True,
    "seats_limited": True,
    "reservation_required": "建议预约",
    "phone": "19537080416",
    "tips": [
        "店里位置不多，建议提前电话预约",
        "环境温馨，服务好",
        "高峰期可能需要等位",
    ],
}

WIFI_INFO = {
    "ssid": "王聚财面皮铺",
    "access": "请到店后询问店员或查看店内提示",
    "tips": "为保护店内网络安全，公开 Skill 不直接返回 Wi-Fi 密码",
}

ORDER_ENTRY_INFO = {
    "entry_type": "public_order_url",
    "provider": "美团点餐",
    "order_url": "https://rms.meituan.com/diancan/14/2HpfZPxOFw0",
    "usage": "可直接打开链接进入点单页面",
    "alternative_access": "用户到店后也可以扫描桌面二维码进入同一入口",
    "notes": [
        "该链接来自门店公开二维码对应的下单入口",
        "如需堂食，到店后扫码或直接告知店员也可以点单",
        "如页面要求登录、定位或平台内打开，以美团页面实际提示为准",
    ],
}

COMMON_INPUT_SCHEMA = {
    "type": "object",
    "properties": {},
    "required": [],
}

COMMON_ANNOTATIONS = {
    "readOnlyHint": True,
    "destructiveHint": False,
    "idempotentHint": True,
    "openWorldHint": False,
}


def build_text_result(payload: Any) -> dict[str, Any]:
    """将业务数据包装成 MCP content 结构。"""
    return {
        "content": [
            {
                "type": "text",
                "text": json.dumps(payload, ensure_ascii=False, indent=2),
            }
        ]
    }


def get_restaurant_info() -> dict[str, Any]:
    """获取餐厅基本信息。"""
    return build_text_result(RESTAURANT_INFO)


def get_menu() -> dict[str, Any]:
    """获取菜单。"""
    return build_text_result(MENU_DATA)


def get_delivery_info() -> dict[str, Any]:
    """获取外卖信息。"""
    return build_text_result(DELIVERY_INFO)


def get_reservation_info() -> dict[str, Any]:
    """获取预约信息。"""
    return build_text_result(RESERVATION_INFO)


def get_wifi_info() -> dict[str, Any]:
    """获取到店 Wi-Fi 指引。"""
    return build_text_result(WIFI_INFO)


def get_order_entry() -> dict[str, Any]:
    """获取公开下单入口。"""
    return build_text_result(ORDER_ENTRY_INFO)


TOOLS = {
    "get_restaurant_info": {
        "handler": get_restaurant_info,
        "description": "查询王聚财面皮铺的基本信息",
        "inputSchema": COMMON_INPUT_SCHEMA,
        "annotations": COMMON_ANNOTATIONS,
    },
    "get_menu": {
        "handler": get_menu,
        "description": "获取王聚财面皮铺的完整菜单",
        "inputSchema": COMMON_INPUT_SCHEMA,
        "annotations": COMMON_ANNOTATIONS,
    },
    "get_delivery_info": {
        "handler": get_delivery_info,
        "description": "获取外卖配送信息",
        "inputSchema": COMMON_INPUT_SCHEMA,
        "annotations": COMMON_ANNOTATIONS,
    },
    "get_reservation_info": {
        "handler": get_reservation_info,
        "description": "获取堂食预约信息",
        "inputSchema": COMMON_INPUT_SCHEMA,
        "annotations": COMMON_ANNOTATIONS,
    },
    "get_wifi_info": {
        "handler": get_wifi_info,
        "description": "获取到店 Wi-Fi 指引，不直接返回密码",
        "inputSchema": COMMON_INPUT_SCHEMA,
        "annotations": COMMON_ANNOTATIONS,
    },
    "get_order_entry": {
        "handler": get_order_entry,
        "description": "获取公开下单入口，支持直接打开链接或到店扫码进入",
        "inputSchema": COMMON_INPUT_SCHEMA,
        "annotations": COMMON_ANNOTATIONS,
    },
}


def build_success_response(result: dict[str, Any], request_id: Any, jsonrpc: str | None) -> dict[str, Any]:
    """兼容 JSON-RPC MCP 与简单调试请求两种返回格式。"""
    if jsonrpc or request_id is not None:
        return {
            "jsonrpc": jsonrpc or "2.0",
            "id": request_id,
            "result": result,
        }
    return result


def build_error_response(
    code: int,
    message: str,
    request_id: Any = None,
    jsonrpc: str | None = None,
) -> dict[str, Any]:
    """统一输出 MCP 与 JSON-RPC 错误结构。"""
    if jsonrpc or request_id is not None:
        return {
            "jsonrpc": jsonrpc or "2.0",
            "id": request_id,
            "error": {
                "code": code,
                "message": message,
            },
        }
    return {
        "error": message,
        "code": code,
    }


def handle_mcp_request(request: dict[str, Any]) -> dict[str, Any]:
    """处理 MCP 请求。"""
    method = request.get("method")
    jsonrpc = request.get("jsonrpc")
    request_id = request.get("id")

    if not method:
        return build_error_response(-32600, "Missing method", request_id, jsonrpc)

    if method == "initialize":
        return build_success_response(
            {
                "protocolVersion": "2024-11-05",
                "capabilities": {
                    "tools": {
                        "listChanged": False,
                    }
                },
                "serverInfo": {
                    "name": SERVER_NAME,
                    "version": SERVER_VERSION,
                },
            },
            request_id,
            jsonrpc,
        )

    if method == "tools/list":
        return build_success_response(
            {
                "tools": [
                    {
                        "name": name,
                        "description": tool["description"],
                        "inputSchema": tool["inputSchema"],
                        "annotations": tool["annotations"],
                    }
                    for name, tool in TOOLS.items()
                ]
            },
            request_id,
            jsonrpc,
        )

    if method == "tools/call":
        params = request.get("params") or {}
        tool_name = params.get("name")
        if not tool_name:
            return build_error_response(-32602, "Missing tool name", request_id, jsonrpc)

        tool = TOOLS.get(tool_name)
        if tool is None:
            return build_error_response(-32601, f"Unknown tool: {tool_name}", request_id, jsonrpc)

        return build_success_response(tool["handler"](), request_id, jsonrpc)

    return build_error_response(-32601, f"Unknown method: {method}", request_id, jsonrpc)


class MCPHandler(BaseHTTPRequestHandler):
    """最小可运行的 MCP over HTTP 处理器。"""

    def _send_common_headers(self, content_length: int) -> None:
        self.send_header("Content-Type", "application/json; charset=utf-8")
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
        self.send_header("Access-Control-Allow-Headers", "Content-Type")
        self.send_header("Content-Length", str(content_length))
        self.end_headers()

    def _send_json(self, payload: dict[str, Any], status: int = 200) -> None:
        body = json.dumps(payload, ensure_ascii=False, indent=2).encode("utf-8")
        self.send_response(status)
        self._send_common_headers(len(body))
        self.wfile.write(body)

    def do_OPTIONS(self) -> None:
        """处理跨域预检请求。"""
        self.send_response(204)
        self._send_common_headers(0)

    def do_GET(self) -> None:
        """GET 仅返回健康检查，避免暴露全部业务数据。"""
        response = {
            "name": SERVER_NAME,
            "version": SERVER_VERSION,
            "status": "ok",
            "transport": "streamable-http",
            "tools": list(TOOLS.keys()),
        }
        self._send_json(response)

    def do_POST(self) -> None:
        """POST 请求走 MCP 协议。"""
        try:
            content_length = int(self.headers.get("Content-Length", "0"))
        except ValueError:
            self._send_json(build_error_response(-32600, "Invalid Content-Length", jsonrpc="2.0"), status=400)
            return

        if content_length > MAX_BODY_BYTES:
            self._send_json(build_error_response(-32000, "Request body too large", jsonrpc="2.0"), status=413)
            return

        raw_body = self.rfile.read(content_length).decode("utf-8")
        try:
            request = json.loads(raw_body) if raw_body else {}
        except json.JSONDecodeError:
            self._send_json(build_error_response(-32700, "Parse error", jsonrpc="2.0"), status=400)
            return

        self._send_json(handle_mcp_request(request))

    def log_message(self, format: str, *args: Any) -> None:
        print(f"[MCP] {self.client_address[0]} - {format % args}")


def main() -> None:
    """启动本地调试服务。"""
    server = HTTPServer((DEFAULT_HOST, DEFAULT_PORT), MCPHandler)
    print(f"王聚财面皮铺 MCP Server {SERVER_VERSION} 运行中...")
    print(f"监听地址: http://{DEFAULT_HOST}:{DEFAULT_PORT}/")
    print("GET  /  健康检查")
    print("POST /  MCP 协议调用")
    print("如需对外监听，请显式设置 MCP_HOST=0.0.0.0")
    server.serve_forever()


if __name__ == "__main__":
    main()


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)