关于 mcp-bbc-goodfood
mcp-bbc-goodfood 将 BBC Good Food 食谱接入聊天客户端,适合查找和阅读食谱的人。它支持按网站筛选条件搜索、调整份量和公制或美制单位,且无需 API 密钥或账户。
主要功能
- 01查询可用筛选项
- 02按条件搜索食谱
- 03读取并调整食谱份量
- 04切换公制与美制单位
- 05缩放任意食材清单
适用场景
- 01查找符合饮食或烹饪时间要求的食谱
- 02按用餐人数缩放食材数量
- 03将食谱数量转换为美制单位
MCP 相关
这是一个 MCP 服务,向聊天客户端提供筛选项查询、食谱搜索、食谱读取和食材缩放工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
4收录的工具列表 · 更新于 今天
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| query | string | 否 | 用于统计范围内数量的搜索条件。网站会在搜索返回的行中统计 facet,因此不传 query 时,统计的是整个列表。 |
详细介绍
mcp-bbc-goodfood
BBC Good Food 是一个英国烹饪网站,也是同名杂志的线上平台。其食谱由网站自己的厨师撰写并测试,每份食谱都会列出食材、做法、准备和烹饪时间、难度、适合的饮食类型、每份的营养信息,以及读者给出的星级评分。网站按照自己的分类维度筛选食谱:饮食类型、菜系、餐食类型和难度。部分内容需要订阅才能查看。
此服务可将聊天客户端连接到该网站。你可以查看各个分类维度的可选值,按这些维度搜索食谱,查看一份食谱并根据用餐人数调整食材用量,还可以在公制和美制单位之间切换。无需 API 密钥或账号。
安装
一键安装
Claude Code
claude mcp add bbc-goodfood -- npx -y mcp-bbc-goodfood
Claude Desktop、Cursor 以及任何使用标准配置格式的客户端
{
"mcpServers": {
"bbc-goodfood": {
"command": "npx",
"args": ["-y", "mcp-bbc-goodfood"]
}
}
}
需要 Node 24 或更高版本,无需设置任何环境变量。
使用 Docker
{
"mcpServers": {
"bbc-goodfood": {
"command": "docker",
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-bbc-goodfood:1.1.0"]
}
}
}
-i 会保持 stdin 打开,协议通过它传输;不使用 -t,因为 TTY 会改写数据流。容器需要能够通过 HTTPS 访问 www.bbcgoodfood.com,仅此而已:无需卷、端口或凭据。
使用 Bundle,无需 npm
从最新版本下载
mcp-bbc-goodfood-1.1.0.mcpb 并打开。支持 MCP bundle 的客户端会自动安装,无需 npm,也无需编辑配置文件。Bundle 包含其依赖项,因此安装时不会下载任何内容。
你可以询问的内容
- “给我找一道用时不到 40 分钟的素食咖喱。”
- “我可以按哪些饮食类型筛选?”
- “用美制杯量单位,把那道食谱按 6 人份读给我听。”
- “这些食谱中,哪些评分至少有 4 星?”
- “把杂志上的这份配料清单按 1.5 倍调整。”
常规流程会先运行 list_filters,然后运行 search_recipes,最后沿着结果行携带的路径运行 get_recipe。
工具
| 工具 | 功能 |
|---|---|
list_filters | 读取网站各个筛选维度接受的值。 |
search_recipes | 沿这些维度缩小范围,查找食谱。 |
get_recipe | 读取一道食谱,并根据请求调整份量或改用其他单位。 |
scale_ingredients | 调整任意配料清单的份量,无需向网站发出请求。 |
缩小搜索范围前,请先调用 list_filters。 网站接受某个维度上的任意值;对于它不认识的值,网站会返回总数为 0 的结果。因此,猜错拼写时,网站不会拒绝请求,而是会肯定地返回没有结果。
list_filters
读取网站用于缩小范围的筛选维度,以及每个维度接受的值。
| 参数 | 类型 | 必填 | 功能 |
|---|---|---|---|
query | 字符串,1 至 80 个字符 | 否 | 统计单次搜索中的各项值,而不是整个列表中的值。 |
返回内容: filters,每个筛选维度对应一项,其中包含网站自己的措辞 name 和 label、用于指定 search_recipes 对应参数的 argument,以及包含各项 value、其 label 和 count 的 options。如果网站没有提供某项的 count,该值为 null。option_count 表示此处列出的选项数量;该数量少于网站接受的选项数:返回的值是出现频率最高的值,未列出的选项仍可使用。计数范围取决于所选范围:传入 query 会统计单次搜索中的值,不传入则会统计整个列表中的值;两者回答的是不同问题。
search_recipes
搜索食谱,并按网站自身的筛选维度以及此服务应用于已读取行的限制进行缩小范围。
| 参数 | 类型 | 必填 | 作用 |
|---|---|---|---|
query | 字符串,1 至 80 个字符 | 是 | 菜肴、食材或烹饪技巧。 |
limit | 整数,1 至 30,默认值为 30 | 否 | 返回的行数。 |
page | 整数,1 至 334,默认值为 1 | 否 | 返回哪一页的行。 |
sort | relevant、rating、published 或 quickest,默认值为 relevant | 否 | 网站对行进行排序的方式。 |
diet | 字符串,1 至 60 个字符 | 否 | list_filters 提供的值。 |
cuisine | 字符串,1 至 60 个字符 | 否 | list_filters 提供的值。 |
meal_type | 字符串,1 至 60 个字符 | 否 | list_filters 提供的值。 |
difficulty | 字符串,1 至 60 个字符 | 否 | list_filters 提供的值。 |
max_total_minutes | 整数,1 至 1440 | 否 | 整道食谱所需的分钟数。 |
max_calories | 整数,1 至 10000 | 否 | 每份的热量。 |
min_servings | 整数,1 至 50 | 否 | 至少达到此份数。 |
min_rating | 数字,1 至 5 | 否 | 至少达到此星级。 |
exclude_premium | 布尔值 | 否 | 排除网站订阅内容对应的行。 |
返回内容: 包含 id(可供 get_recipe 使用)、title、url、image_url 和 rating 的行;如果网站未提供评分,则 rating 为 null。此外还会返回 result_count、网站在剔除任何内容之前提供的行数 rows_seen,以及 total_available。标记为 total_is_ceiling 的总数表示单次搜索最多会提供的行数,因此它表示的是下限,而非确切数量。restrictions_lifted 列出因缩小范围导致搜索失败而被取消的限制,premium_dropped 则统计被移除的订阅内容行。网站不提供筛选订阅内容行的限制,因此 exclude_premium 会在页面返回后再移除这些行:此时返回的页面可能少于请求的数量,而较短的页面并不代表结果已全部返回。
get_recipe
读取一份食谱,并按指定的份数和计量单位系统重新缩放。
| 参数 | 类型 | 必填 | 作用 |
|---|---|---|---|
id | 字符串,1 到 200 个字符 | 是 | 页面自身的路径,search_recipes 返回的行中会包含此路径。 |
servings | 整数,1 到 100 | 否 | 将食材缩放至此份数。 |
unit_system | metric 或 us | 否 | 数量所用的计量单位。 |
返回内容:title、url、premium、网站原文中的 yield_text,例如 Serves 4 - 6、yield_count、prep_minutes、cook_minutes、total_minutes、difficulty、diets、author、rating、rating_count、description、ingredients、steps、nutrition(其中 nutrition_per 用于标明其描述的份量)以及 unit_system。页面未说明的数值为 null。**订阅内容中的食谱会返回 premium 为 true,且不含食材和步骤:**请引导读者前往该页面,不要自行补全。每种食材都带有 scaling,其值为 scaled、rounded 或 unscaled。
scale_ingredients
对任意食材行应用相同的计算,不向网站发出请求。
| 参数 | 类型 | 必填 | 作用 |
|---|---|---|---|
ingredients | 字符串数组,1 到 100 项,每项 1 到 300 个字符 | 是 | 按食谱写法提供要缩放的行。 |
factor | 数值,0.001 到 1000 | 两者之一 | 每个数量的乘数。 |
from_servings | 整数,1 到 100 | 两者之一 | 按原写法,这份食材清单可供多少人食用。 |
to_servings | 整数,1 到 100 | 两者之一 | 目标供餐人数。 |
传入 factor,或者同时传入 from_servings 和 to_servings。
**返回内容:**按 get_recipe 的返回格式缩放后的食材行,每行都包含 original、text、amount、amount_max、unit 和 scaling。
缩放数量
数量采用适合该食材的单位,因此某一行返回的单位可能与食谱原文不同:200 g 乘以 20 后为 4 kg,2 g 除以 10 后为 200 mg。
食材可以细分到什么程度,取决于食材本身。面包可以切成两份、三份或四份;鸡蛋则无法分着用。若计算结果落在两种可行份量之间,就会进行取整,缩放后的食谱与原食谱的比例也会略有偏差。该行会标记为 rounded,备注会说明处理方式。
这些数值是此服务计算得出的,因此展示时请说明它们是重新计算的。若食谱页面未注明份数,就无法将其换算为指定人数的用量,结果也会说明这一点。
配置
所有变量均为可选项。在客户端配置的 env 块中设置。
| 变量 | 默认值 | 作用 |
|---|---|---|
BGF_USER_AGENT | 项目标识 | 向网站标识你的应用,并提供可以联系到相关人员的地址。 |
BGF_MIN_INTERVAL_MS | 1500 | 两次请求之间的间隔,范围为 1000 至 60000。 |
BGF_TIMEOUT_MS | 20000 | 单次请求的截止时间,范围为 1000 至 120000。 |
BGF_MAX_RETRIES | 3 | 临时故障后的重试次数,范围为 0 至 8。 |
BGF_CACHE_TTL_MS | 900000 | 页面在内存中的保留时间,范围为 0 至 86400000。 |
BGF_CACHE_MAX_ENTRIES | 200 | 同时保存在内存中的页面数,范围为 1 至 5000。 |
BGF_MAX_BODY_BYTES | 8000000 | 读取页面的最大大小,单位为字节,范围为 100000 至 64000000。 |
BGF_LOG_LEVEL | error | silent、error、info 或 debug,输出到 stderr。 |
超出范围的值将回退为默认值,原因会写入 stderr。
错误
每种失败都会附带六种代码之一、一条消息,以及在有帮助时说明下一步操作的提示。
| 代码 | 发生了什么 | 该怎么做 |
|---|---|---|
not_found | 网站已响应,但没有该食谱。 | 使用 search_recipes 检查路径。 |
invalid_input | 在发出请求前,参数已被拒绝。 | 阅读消息,其中会指出相关参数。 |
rate_limited | 网站要求此客户端降低请求频率。 | 等待提示中所示的秒数,然后使用相同参数再次调用。食谱仍然存在。 |
parse_failure | 页面已加载,但缺少预期内容。 | 在问题跟踪器中报告。 |
network_error | 请求未能完成。 | 稍后重试。 |
timeout | 请求超出截止时间。 | 提高 BGF_TIMEOUT_MS,或减少请求的行数。 |
作为库使用
读取网站的层已独立发布,带有自己的请求间隔控制、缓存和错误处理,且不绑定任何协议。
import { BbcGoodFoodClient } from "mcp-bbc-goodfood/client";
const client = new BbcGoodFoodClient();
const { data, cached } = await client.searchRecipes({ query: "lasagne" });
console.log(data.rows.length, cached);
listFilters、searchRecipes 和 getRecipe 各自返回 { data, cached },并在出错时抛出一个携带六种代码之一的错误。这里同样会确保两次请求之间至少间隔规定的时间。
请求节奏与归属
请求逐个发出,间隔至少 1.5 秒;无论服务如何配置,间隔都不会短于 1 秒。User-Agent
始终以项目标识和可联系到真人的地址结尾。
每条结果都包含读取页面的地址,source 则标明网站。食谱归 BBC Good Food
及撰写食谱的厨师所有。
此 MCP 服务是一个非官方项目,与 BBC Good Food 无关联。
隐私
此服务不会收集任何关于你的信息,也不会向作者发送任何信息。它在你的机器上运行,
只连接 www.bbcgoodfood.com,运行期间将结果保存在内存中,
不会写入磁盘。
PRIVACY.md 说明请求会携带哪些信息,以及哪些设置会影响这些信息。
开发
npm install
npm run build:fixtures
npm test
npm run check
测试使用生成的 fixture 运行,不会发出网络请求。在线测试套件
npm run test:live 会针对每个路由发出一个请求,并每晚直接对网站运行。
贡献
漏洞、问题和想法请提交到 问题跟踪器。欢迎提交 拉取请求;先提出问题有助于就更改方案达成一致。请参阅 CONTRIBUTING.md。
许可证
MIT,详见 LICENSE。食谱归 BBC Good Food 及其 作者所有。
mcp-bbc-goodfood(法语版)
BBC Good Food 是一个英国烹饪网站,也是同名杂志的在线平台。 其食谱由自家厨师撰写并测试,每道食谱都列出食材、做法、准备和烹饪时间、 难度、适用的饮食方式、每份的营养成分,以及读者给出的星级评分。网站 按自身设定的类别筛选食谱:饮食方式、菜系、餐食类型、难度。部分 食谱仅对订阅用户开放。
此服务将对话客户端连接到该网站。你可以查看每个类别下的选项,按这些类别 搜索食谱,查看食谱及按用餐人数调整后的食材用量,还可以在公制与美制单位 之间切换用量。无需 API 密钥,也无需账户。
安装
一键安装
Claude Code
claude mcp add bbc-goodfood -- npx -y mcp-bbc-goodfood
Claude Desktop、Cursor 及所有采用标准配置格式的客户端
{
"mcpServers": {
"bbc-goodfood": {
"command": "npx",
"args": ["-y", "mcp-bbc-goodfood"]
}
}
}
需要 Node 24 或更高版本,无需设置任何环境变量。
使用 Docker
{
"mcpServers": {
"bbc-goodfood": {
"command": "docker",
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-bbc-goodfood:1.1.0"]
}
}
}
-i 用于保持标准输入打开,它是协议通道;省略 -t,因为 TTY 会重写数据流。
容器需要能够通过 HTTPS 访问 www.bbcgoodfood.com,除此之外不需要其他条件:
无需挂载卷、开放端口或提供凭据。
Bundle,无需 npm
从
最新发布版本
下载 mcp-bbc-goodfood-1.1.0.mcpb 并打开。支持 MCP bundle 的客户端会自动安装,
无需 npm,也无需修改配置文件。Bundle 包含其依赖项,因此安装时不会下载任何内容。
可以询问什么
- “帮我找一道制作时间少于 40 分钟的素食咖喱。”
- “我可以按哪些饮食类型筛选?”
- “用美制杯量单位,把这道适合六人份的食谱念给我听。”
- “哪些食谱的评分达到四星或以上?”
- “把从杂志上摘录的这份食材清单按 1.5 倍调整。”
常规流程是先调用 list_filters,再调用 search_recipes,然后根据某一行所带的路径调用 get_recipe。
工具
| 工具 | 功能 |
|---|---|
list_filters | 读取网站各筛选维度可用的值。 |
search_recipes | 根据这些维度筛选并查找食谱。 |
get_recipe | 读取食谱,并按需调整份量或换算为其他单位。 |
scale_ingredients | 调整任意食材清单,无需查询网站。 |
缩小搜索范围前,请先调用 list_filters。 网站接受任意筛选维度的值;对于不认识的值,它会返回零条结果。因此,猜测拼写会让你确信结果不存在,而不是收到拒绝。
list_filters
读取网站用于缩小搜索范围的筛选维度,以及每个维度可用的值。
| 参数 | 类型 | 必需 | 功能 |
|---|---|---|---|
query | 字符串,1 到 80 个字符 | 否 | 统计搜索结果中的值,而不是整个列表中的值。 |
返回内容: filters,每个筛选维度对应一项,包含网站使用的术语 name 和 label、用于指定 search_recipes 中对应筛选参数的 argument,以及包含每个选项的 value、label 和 count 的 options。如果网站未公布某个 count,则其值为 null。option_count 表示此处列出的选项数量;这个数量少于网站实际接受的选项数量:返回的值是最常用的值,未列出的选项仍然可用。计数会根据范围统计,因此传入 query 时统计搜索结果中的值,省略它时则统计整个列表中的值;两者回答的是不同的问题。
search_recipes
搜索食谱,并根据网站提供的筛选条件及此服务端对读取到的条目应用的限制进行筛选。
| 参数 | 类型 | 必填 | 作用 |
|---|---|---|---|
query | 字符串,1 至 80 个字符 | 是 | 一道菜、一种食材或一种烹饪技巧。 |
limit | 整数,1 至 30,默认值为 30 | 否 | 返回的条目数。 |
page | 整数,1 至 334,默认值为 1 | 否 | 条目所在的页码。 |
sort | relevant、rating、published 或 quickest,默认值为 relevant | 否 | 网站排列条目的顺序。 |
diet | 字符串,1 至 60 个字符 | 否 | list_filters 提供的一个值。 |
cuisine | 字符串,1 至 60 个字符 | 否 | list_filters 提供的一个值。 |
meal_type | 字符串,1 至 60 个字符 | 否 | list_filters 提供的一个值。 |
difficulty | 字符串,1 至 60 个字符 | 否 | list_filters 提供的一个值。 |
max_total_minutes | 整数,1 至 1440 | 否 | 整道食谱的用时上限,单位为分钟。 |
max_calories | 整数,1 至 10000 | 否 | 每份热量上限。 |
min_servings | 整数,1 至 50 | 否 | 最少份数。 |
min_rating | 数值,1 至 5 | 否 | 最低星级。 |
exclude_premium | 布尔值 | 否 | 排除仅限订阅用户查看的条目。 |
返回内容: 带有 id 的条目,可供 get_recipe 使用;还包括 title、
url、image_url,以及 rating;如果网站未提供评分,则值为 null。
此外还会返回 result_count、网站在任何筛除操作之前提供的条目数 rows_seen,
以及 total_available。标记为 total_is_ceiling 的总数表示搜索最多会返回的
条目数,因此它表示的是下限,而不是确切数量。restrictions_lifted 列出因筛选条件
导致搜索失败而被放宽的限制,premium_dropped 则统计被排除的订阅用户专享条目。
网站不会对订阅用户专享条目应用任何限制,因此 exclude_premium 会在页面返回后
将其移除:此时返回的页面可能少于请求的条目数,而较短的页面并不表示结果已结束。
get_recipe
读取一份食谱,并根据所需份数和单位制进行调整。
| Argument | Type | Requis | Ce qu'il fait |
|---|---|---|---|
id | chaîne, 1 à 200 caractères | oui | 页面路径,按网页中的原样填写。 |
servings | entier, 1 à 100 | non | 将食材调整为指定份数。 |
unit_system | metric ou us | non | 数量所使用的单位。 |
返回内容: title、url、premium、yield_text(采用网站上的表述,例如
Serves 4 - 6)、yield_count、prep_minutes、cook_minutes、
total_minutes、difficulty、diets、author、rating、rating_count、
description、ingredients、steps、nutrition(含有说明所述份量的
nutrition_per),以及 unit_system。网页未注明的数值为
null。仅限订阅者的食谱会以 premium 为真返回,且不包含食材和步骤:
请将读者引导至食谱页面,不要尝试还原这些内容。每种食材都带有
scaling,其值为 scaled、rounded 或 unscaled。
scale_ingredients
对任意食材列表应用相同的计算方式,无需请求网站。
| Argument | Type | Requis | Ce qu'il fait |
|---|---|---|---|
ingredients | tableau de 1 à 100 chaînes, 1 à 300 caractères | oui | 要调整的行,格式与食谱中的写法相同。 |
factor | nombre, 0.001 à 1000 | l'un des deux | 每个数量要乘以的数值。 |
from_servings | entier, 1 à 100 | l'un des deux | 原始列表对应的份数。 |
to_servings | entier, 1 à 100 | l'un des deux | 所需的份数。 |
传入 factor,或同时传入 from_servings 和 to_servings。
返回内容: 以 get_recipe 返回的格式提供调整后的各行,每行包含
original、text、amount、amount_max、unit 和
scaling。
数量调整方式
数量采用适合该食材的单位表示。因此,调整后的一行可能使用与食谱中
不同的单位:200 g 乘以二十会变成 4 kg,而 2 g 除以十会变成
200 mg。
食材可分割的精细程度取决于其性质。面包可以切成两份、三份或四份;
鸡蛋则无法分割。因此,无法精确分割的数量会进行四舍五入,调整后的
食谱与原始比例会略有偏差。该行会标记为 rounded,其说明会注明
所做的处理。
这些数字是本服务计算得出的,因此展示时请说明它们是重新计算的。如果 食谱页面没有注明份数,就无法按就餐人数调整;响应中会说明这一点。
配置
每个变量都是可选的。将它们放在客户端配置的 env 块中。
| 变量 | 默认值 | 作用 |
|---|---|---|
BGF_USER_AGENT | 项目标识 | 向网站标识您的应用,并提供可联系到相关人员的地址。 |
BGF_MIN_INTERVAL_MS | 1500 | 两次请求之间的间隔,范围为 1000 至 60000。 |
BGF_TIMEOUT_MS | 20000 | 单次请求的超时时间,范围为 1000 至 120000。 |
BGF_MAX_RETRIES | 3 | 临时失败后的重试次数,范围为 0 至 8。 |
BGF_CACHE_TTL_MS | 900000 | 页面在内存中的保留时间,范围为 0 至 86400000。 |
BGF_CACHE_MAX_ENTRIES | 200 | 同时保留在内存中的页面数,范围为 1 至 5000。 |
BGF_MAX_BODY_BYTES | 8000000 | 读取页面的最大大小,单位为字节,范围为 100000 至 64000000。 |
BGF_LOG_LEVEL | error | silent、error、info 或 debug,写入错误输出。 |
超出范围的值会恢复为默认值,原因会写入错误输出。
错误
每次失败都会带有六种代码之一和一条消息,并在有帮助时提供下一步操作建议。
| 代码 | 发生的情况 | 处理方法 |
|---|---|---|
not_found | 网站已响应,但没有这道菜谱。 | 使用 search_recipes 检查路径。 |
invalid_input | 在发出任何请求前,参数已被拒绝。 | 阅读消息,其中会指出相关参数。 |
rate_limited | 网站要求此客户端放慢速度。 | 等待指定的秒数,然后使用相同的参数重试。这道菜谱仍然存在。 |
parse_failure | 页面已加载,但缺少预期内容。 | 在问题跟踪页面上报告。 |
network_error | 请求未能完成。 | 稍后重试。 |
timeout | 请求超时。 | 增大 BGF_TIMEOUT_MS,或减少请求的行数。 |
作为库使用
读取网站的这一层单独发布,包含请求间隔、缓存和错误处理,不绑定任何协议。
import { BbcGoodFoodClient } from "mcp-bbc-goodfood/client";
const client = new BbcGoodFoodClient();
const { data, cached } = await client.searchRecipes({ query: "lasagne" });
console.log(data.rows.length, cached);
listFilters、searchRecipes 和 getRecipe 各自返回 { data, cached },并会抛出带有六种代码之一的错误。两次请求之间的最短间隔在这里同样适用。
请求间隔与署名
请求会逐个发出,间隔至少为 1.5 秒;无论如何配置,间隔都不会短于 1 秒。User-Agent 始终以项目标识和可联系到相关人员的地址结尾。
每个结果都附有读取来源页面的地址,source 则标明网站。菜谱归 BBC Good Food 及其撰写者所有。
此 MCP 是一个非官方项目,与 BBC Good Food 无关。
隐私
此服务不会收集您的任何信息,也不会向作者发送任何信息。它在您的
计算机上运行,只会连接到 www.bbcgoodfood.com,会在运行期间将响应保存在
内存中,也不会向磁盘写入任何内容。PRIVACY.md 说明了请求会携带哪些信息,以及哪些设置会改变这些情况。
开发
npm install
npm run build:fixtures
npm test
npm run check
测试使用生成的固定数据运行,不会发出任何请求。
实时测试套件 npm run test:live 会针对每个路由发出一个请求,并且
每晚直接针对网站运行。
贡献
问题、疑问和想法都可以提交到 问题跟踪。欢迎提出修改建议;先提交工单有助于 就修改方案达成一致。请参阅 CONTRIBUTING.md。
许可证
MIT,详见 LICENSE。食谱归 BBC Good Food 及其作者所有。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。