mcpField
S
swiss-food-safety-mcp

swiss-food-safety-mcp

本地服务
github.com健康医疗05 周前更新

关于 swiss-food-safety-mcp

swiss-food-safety-mcp 是只读 MCP 服务,为 AI 助手提供瑞士 BLV 食品安全和兽医开放数据。工具涵盖最新警告,以及动物疾病、检查、抗生素、儿童营养和农药数据集。

主要功能

  1. 01食品召回与健康警告
  2. 02动物疾病及禽流感监测
  3. 03各州食品检查结果
  4. 04兽用抗生素使用统计
  5. 05儿童营养问卷计数
  6. 06农药登记查询与数据集发现

适用场景

  1. 01查看瑞士当前食品召回信息
  2. 02按州查看动物疾病报告
  3. 03检查食品检查及违规数据
  4. 04搜索获准农药或营养调查结果

MCP 相关

向 MCP 客户端提供 11 个只读 BLV 数据查询工具,并支持 stdio 和 Streamable HTTP 传输。无需身份验证。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"malkreide-swiss-food-safety": {
"command": "uvx",
"args": [
"swiss-food-safety-mcp"
]
}
}
}
启动命令uvx swiss-food-safety-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiswiss-food-safety-mcp1.2.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

🇨🇭 属于 瑞士公共数据 MCP 项目组合

swiss-food-safety-mcp

Version License: MIT Python 3.11+ MCP Data Source No Auth Required CI

🌐 English | Deutsch

将 AI 模型连接到瑞士联邦食品安全与兽医局(BLV)开放数据的 MCP 服务,涵盖食品召回、动物疾病监测、食品检查结果、抗生素使用情况、儿童营养调查和农药登记册。无需身份验证。


概述

swiss-food-safety-mcp 让 Claude 等 AI 助手能够直接访问瑞士联邦食品安全与兽医局(BLV / Bundesamt für Lebensmittelsicherheit und Veterinärwesen)的官方食品安全和兽医数据。它提供 11 个工具,涵盖食品召回、动物疾病监测、食品检查结果、兽医领域的抗生素使用情况、儿童营养调查以及农药登记册。

所有数据均来自瑞士官方联邦数据源(opendata.swiss、lindas.admin.ch、news.admin.ch)。无需 API 密钥或身份验证。

该服务遵循 No-Auth-First 理念,是瑞士公共部门 MCP 项目组合的一部分。

示例查询: “目前有哪些与苏黎世学校食堂相关的 BLV 食品警告?该州目前报告了哪些须通报的动物疾病?”

演示

演示:Claude 使用 blv_get_public_warnings 和 blv_search_animal_diseases → 按受众分类的更多用例 →


功能

  • 🚨 公共警告与召回 — 实时获取 BLV 产品召回和健康警告的 RSS 订阅
  • 🐄 动物疾病监测 — 通过 LINDAS SPARQL 立方体获取自 1991 年以来须通报的动物疾病(InfoSM)
  • 🐦 禽流感监测 — 包含地理数据的野生鸟类监测数据
  • 🥩 食品检查结果 — 各州食品检查结果和违规率
  • 💊 兽医抗生素使用情况 — ISABV 动物用药抗生素使用数据
  • 🧒 儿童营养调查 — menuCH-Kids 问卷统计(答案数量,不代表营养摄入量)
  • 🌿 农药登记册 — 瑞士批准使用的农药产品和活性成分
  • 📊 数据集发现 — 通过 CKAN API 浏览 opendata.swiss 上的全部 28 个 BLV 数据集
  • 🔗 双传输方式 — stdio(Claude Desktop)+ Streamable HTTP(云端/Render.com)
  • 🗣️ 双语 — 文档以英语为主,德语为辅

前置条件

  • Python 3.11+
  • uv 或 uvx(推荐)— 安装 uv

安装

使用 uvx(推荐——无需安装)
uvx swiss-food-safety-mcp
使用 uv
uv tool install swiss-food-safety-mcp
swiss-food-safety-mcp
从源代码安装
git clone https://github.com/malkreide/swiss-food-safety-mcp
cd swiss-food-safety-mcp
uv sync
uv run swiss-food-safety-mcp

快速开始

添加到 claude_desktop_config.json:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "swiss-food-safety": {
      "command": "uvx",
      "args": ["swiss-food-safety-mcp"]
    }
  }
}

在 Claude Desktop 中立即试用:

“目前有哪些 BLV 食品警告仍然有效?”
“今年苏黎世州是否报告了须通报的动物疾病?”

其他 MCP 客户端(Cursor、Windsurf、VS Code + Continue)
{
  "mcpServers": {
    "swiss-food-safety": {
      "command": "uvx",
      "args": ["swiss-food-safety-mcp"]
    }
  }
}
云端部署(Streamable HTTP)

用于通过浏览器中的 claude.ai 使用(例如,在未安装本地软件的受管工作站上):

# Loopback only (default) — safe for local testing:
swiss-food-safety-mcp --http
# Server runs on 127.0.0.1:8002

# External exposure (e.g. behind the Render TLS proxy):
swiss-food-safety-mcp --http --host 0.0.0.0

⚠️ HTTP 传输默认绑定到 127.0.0.1。仅当需要对外开放时,才传入 --host 0.0.0.0。 设置 BLV_MCP_ALLOWED_ORIGINS(以逗号分隔,不支持通配符)以允许浏览器客户端;默认值为 https://claude.ai。

Render.com(推荐):

  1. 将仓库推送到 GitHub,或在 GitHub 上复刻该仓库
  2. 在 render.com 上:新建 Web 服务 → 连接 GitHub 仓库
  3. 将启动命令设置为:swiss-food-safety-mcp --http --host 0.0.0.0
  4. 在 claude.ai 的“设置”→“MCP 服务”下,添加:https://your-app.onrender.com/mcp

Docker:

docker build -t swiss-food-safety-mcp .
docker run -p 8002:8002 swiss-food-safety-mcp
# or, with explicit CPU/memory limits:
docker compose up

该镜像采用非 root 用户和多阶段构建;容器已绑定 0.0.0.0,并包含健康检查。docker-compose.yml 还限制了 CPU 和内存。

💡 “开发者笔记本使用 stdio,浏览器使用 Streamable HTTP。”

🔧 配置 — 每项运行时设置均可通过 BLV_MCP_* 环境变量覆盖(BLV_MCP_HTTP_HOST、BLV_MCP_HTTP_PORT、 BLV_MCP_ALLOWED_ORIGINS、BLV_MCP_TIMEOUT、BLV_MCP_OTEL_ENDPOINT,等等)。 出站请求仅限瑞士联邦主机(*.admin.ch、 opendata.swiss)。如需启用 OpenTelemetry 跟踪:使用 pip install swiss-food-safety-mcp[otel] 安装,并设置 BLV_MCP_OTEL_ENDPOINT。


可用工具

工具描述数据来源
blv_get_public_warnings当前食品召回和健康警告news.admin.ch RSS
blv_list_datasets浏览全部 28 个 BLV 开放数据集opendata.swiss CKAN
blv_get_dataset_info数据集详情和资源 URLopendata.swiss CKAN
blv_search_animal_diseases自 1991 年以来须申报的动物疫病LINDAS SPARQL(/query)
blv_get_animal_health_stats年度动物健康统计数据opendata.swiss CSV/JSON
blv_get_food_control_results州级食品检查结果opendata.swiss CSV
blv_get_antibiotic_usage_vet兽用抗生素使用情况(ISABV)opendata.swiss CSV
blv_get_avian_influenza野生鸟类禽流感监测opendata.swiss CSV
blv_get_nutrition_data_childrenmenuCH-Kids:问卷统计数据(非营养素摄入量)opendata.swiss CSV
blv_search_pesticide_products瑞士批准的农药登记册opendata.swiss XML
blv_get_meat_inspection_stats屠宰场检查统计数据opendata.swiss CSV/JSON
示例查询
查询工具
“目前有哪些 BLV 食品警告?”blv_get_public_warnings
“2024 年苏黎世州有动物疫病吗?”blv_search_animal_diseases
“2024 年瑞士的禽流感情况如何?”blv_get_avian_influenza
“瑞士儿童实际吃些什么?”blv_get_nutrition_data_children
“瑞士批准了哪些铜基农药?”blv_search_pesticide_products

架构

┌─────────────────┐     ┌─────────────────────────────┐     ┌──────────────────────────────┐
│   Claude / AI   │────▶│   Swiss Food Safety MCP     │────▶│  Swiss Federal Open Data     │
│   (MCP Host)    │◀────│   (MCP Server)              │◀────│                              │
└─────────────────┘     │                             │     │  opendata.swiss (CKAN/CSV)   │
                        │  11 Tools · No Auth         │     │  lindas.admin.ch (SPARQL)    │
                        │  Stdio | Streamable HTTP    │     │  news.admin.ch (RSS/XML)     │
                        └─────────────────────────────┘     └──────────────────────────────┘

与相关 MCP 服务的协同

组合用例
swiss-food-safety-mcp + zurich-opendata-mcp绘制学校附近动物疫病风险的地理分布
swiss-food-safety-mcp + fedlex-mcp将召回信息关联到食品法(Lebensmittelgesetz)
swiss-food-safety-mcp + swiss-statistics-mcp按学区关联营养数据与社会经济数据
swiss-food-safety-mcp + global-education-mcp将瑞士儿童营养情况与 OECD 基准进行比较

项目结构

swiss-food-safety-mcp/
├── src/
│   └── swiss_food_safety_mcp/
│       ├── __init__.py        # Package metadata
│       └── server.py          # All tools, resources, prompts
├── tests/
│   ├── __init__.py
│   └── test_server.py         # Unit tests (no live API calls)
├── .github/
│   └── workflows/
│       └── ci.yml             # Python 3.11–3.13 matrix
├── pyproject.toml             # hatchling build, uv-compatible
├── CHANGELOG.md
├── CONTRIBUTING.md            # Contribution guide (English)
├── CONTRIBUTING.de.md        # Contribution guide (German)
├── SECURITY.md               # Security policy (English)
├── SECURITY.de.md            # Security policy (German)
├── LICENSE                    # MIT
├── README.md                  # This file (English)
└── README.de.md               # German version

数据源

来源描述格式
opendata.swiss/BLV28 个开放数据集CSV, JSON, Parquet, SPARQL, XML
lindas.admin.ch/sparql瑞士关联数据 SPARQL 端点RDF/SPARQL
news.admin.ch RSSBLV 公共警告与召回信息RSS/XML
blv.admin.chBLV 网站(DE/FR/IT/EN)HTML

所有数据均为开放政府数据(OGD),采用 Creative Commons 许可,并要求注明出处。


已知限制

  • RSS 源: 仅包含 BLV 最近发布的内容;没有历史存档
  • 农药登记册: 对返回大量结果的查询,XML 解析可能较慢
  • CKAN 数据集: 高负载使用时会受到 opendata.swiss 速率限制
  • 动物疾病数据: 按州筛选取决于源数据的完整性
  • 数据集已固定,而非通过搜索确定: 每个数据工具都会指定其数据集 slug 和承载数据的资源(参见 server.py 中的 DATENQUELLEN)。关键词搜索会采用第一个命中项,因此可能悄无声息地退回到某个看似合理的数据集——这就是 blv_get_animal_health_stats 会返回抗生素数据,以及 blv_get_food_control_results 会从一个包含 26 个资源(其中 18 个是代码列表)的数据集中返回代码列表的原因。scripts/record_fixtures.py 每次运行都会重新测量固定的数据集与资源配对;如果数据集被重命名,现在会明确报错。
  • 儿童营养数据是问卷统计,而非营养素摄入量: opendata.swiss 上唯一发布的 menuCH-Kids 数据集包含答案数量(Geschlecht, Sprachregion, Altersgruppe, Frage, Antwort, Anzahl)。此前的文档字符串错误地承诺提供与膳食建议对照的营养素摄入量,并提供“Energie”“Zucker”“Eisen”作为筛选示例——这些条件都无法匹配,因而返回空列表。成人膳食摄入数据属于单独的数据集,本服务不涵盖。
  • SPARQL 到 CSV 的回退机制已移除。 它从来就无法正常工作:回退数据集唯一的 CSV 资源实际上是一个标记为 format: CSV 的 ZIP 文件。修正端点后,回退机制也已没有必要——而掩盖错误查询的回退机制,还不如没有。

安全与限制

  • 只读: 所有工具仅执行 HTTP GET 请求——不会写入、修改或删除任何数据。
  • 不涉及个人数据: API 返回的是汇总后的公共卫生和食品安全统计数据。本服务不会处理或存储任何可识别个人身份的信息。
  • 速率限制: opendata.swiss CKAN 和 lindas.admin.ch SPARQL 均为公共 API;请谨慎使用 limit 和筛选参数。本服务会为每个请求设置 30 秒超时。
  • 数据时效性: RSS 警告反映查询时最新发布的 BLV 内容。统计数据集(动物疾病、食品管控、抗生素)由 BLV 定期更新。本服务不会进行缓存。
  • 服务条款: 数据受各来源的服务条款约束——opendata.swiss、lindas.admin.ch、news.admin.ch。BLV 数据采用 Creative Commons 许可发布,并要求注明出处。
  • 不作保证: 本服务是社区项目,与 BLV 或瑞士联邦政府无关联。服务是否可用取决于上游 API。

部署与扩展

此服务处于 Phase 1 — 只读 阶段(参见 ROADMAP.md):全部 11 个工具都是只读查询,没有写入功能。

以单实例方式运行。Streamable HTTP 传输会保留每个会话的状态,因此横向扩展需要在负载均衡器上进行 Mcp-Session-Id 粘性路由,并配备共享会话存储——出于此类服务的规模考虑,我们有意不实现这两项功能。支持的部署方式是使用单个 Render 实例(或一个容器);docker-compose.yml 为可自托管部署设置了明确的 CPU/内存限制。


测试

# Unit + contract tests (no network) — this is what CI runs
PYTHONPATH=src pytest tests/ -m "not live"

# All tests including live API checks
PYTHONPATH=src pytest tests/

# Re-measure which dataset and resource each tool hits
PYTHONPATH=src python scripts/record_fixtures.py

54 项测试——53 项离线测试,1 项实时测试。

为什么要记录测试固件,而不是手动编写

手写的模拟数据编码了作者的假设,因此无法反驳作者的假设:生产代码和测试固件来自同一个提交、同一个小时,也来自对文档的同一种解读。如果两者都错了,就会一起出错——测试套件却依然全部通过。

这个仓库就有一个典型例子。每个模拟的 CKAN 资源都被命名为 "name": "CSV"。在 opendata.swiss 上,同一个字段的值却是 Food establishments 2025 或 Food establishments codelist administrative measures——仅这一差异,就决定了工具返回的是检查结果还是代码图例。模拟数据无法表达这种区别,因此没有测试能因此失败。

因此,我们记录的是选择结果:对每个工具,记录固定的数据集 slug、被访问的资源,以及该文件的表头行。表头正是验证的重点——它能区分数据与图例,也能显示 BOM 和分隔符是否得到正确处理。PROVENANCE.md 列出了每个文件的来源、日期、选择规则和 SHA-256 值。

记录的测量结果中有两项是对照项:在 lindas.admin.ch 下构造一条虚假路径(POST 返回 404,因此 /sparql 上的 404 确实存在),以及在 fsvo 命名空间中构造一个虚假类(实例数为 0,因此此前查询的 foag 类确实不存在)。没有这些对照项,每项测量只能说明我们收到了什么。如果对照项不再具有区分效果、固定资源消失、表头行为空或以 BOM 开头,或者某项发现已被更新,记录器就会中止。


MCP 协议版本

此服务原生支持规范 2026-07-28。它运行 fastmcp 4.x,该版本固定使用 mcp 2.x,而该 SDK 通过同一个服务对象支持两个协议时代:

时代版本客户端如何连接
现代2026-07-28server/discover,元数据位于 _meta.io.modelcontextprotocol/*
握手(旧版)2025-11-25经典的 initialize 交换

当前客户端会使用 2026-07-28;尚未升级的客户端会回退到握手流程,并且仍能获取所有工具。此服务不会选择版本——SDK 负责协商,而版本固定项记录了协商允许产生的版本组合。

现代时代不仅仅是版本号更高。它没有 initialize 握手,也没有 InitializeResult:在此模式下,Client.initialize() 会报错,服务元数据改由 server/discover 提供。因此,仍在检查 initialize_result.protocolVersion 的测试实际上只测了旧版,却会报告两个版本都通过。

tests/test_protocol_version.py 分别通过各自的路径测量两个时代,而不是互相比较常量:它将两个版本都固定为 LATEST_MODERN_VERSION / LATEST_HANDSHAKE_VERSION,在每种模式下连接真实客户端,断言现代版本中结构上不存在 InitializeResult,并检查两个时代列出的工具是否相同。test_das_sdk_fuehrt_weiterhin_zwei_aeren 则防止反向回退——否则降级回 mcp 1.x 会让一半断言变成无人留意的导入错误。

传输允许列表也随 SDK 更新:Mcp-Method、Mcp-Name 和 MCP-Protocol-Version 是规范 2026-07-28 映射到 HTTP 的路由标头,mcp.shared.inbound 现在会读取这些标头,因此 CORS 会将它们列入允许范围。Mcp-Param-* 则有意不在其中——规范只会为标记了 x-mcp-header 的工具参数生成这些标头,而此处没有任何工具这样做。


更新日志

请参阅 CHANGELOG.md


贡献

请参阅 CONTRIBUTING.md


安全

请参阅 SECURITY.md,了解安全政策以及如何报告漏洞。


许可证

MIT License — 请参阅 LICENSE


作者

Hayal Oezkan · github.com/malkreide


致谢与相关项目

安装

通过 uv 的 uvx 运行——无需克隆或手动安装。将其添加到 MCP 客户端配置中(Claude Desktop、Cursor 和 Windsurf 使用 mcpServers;VS Code 在 .vscode/mcp.json 中使用顶层 servers 键):

{
  "mcpServers": {
    "swiss-food-safety-mcp": {
      "command": "uvx",
      "args": [
        "swiss-food-safety-mcp"
      ]
    }
  }
}

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。