mcpField
S
swiss-culture-mcp

swiss-culture-mcp

本地服务
github.com法律与政务15 周前更新

关于 swiss-culture-mcp

面向文化研究的 MCP 服务,提供瑞士联邦文化局的数据,包括受保护城镇景观、活态传统、文化奖项、新闻稿和数据集。它使用公开数据源,无需 API 密钥。

主要功能

  1. 01按地点搜索 ISOS 城镇景观
  2. 02按州或类别列出 ISOS 条目
  3. 03获取景观详情和统计数据
  4. 04浏览瑞士活态传统
  5. 05查询文化奖项及联邦文化局新闻稿
  6. 06查找 opendata.swiss 上的联邦文化局数据集

适用场景

  1. 01确认瑞士某处城镇景观是否受保护
  2. 02了解某州传承的活态传统
  3. 03查询瑞士文化奖项和公告
  4. 04查找 opendata.swiss 上的联邦文化局数据集

MCP 相关

提供十种工具和三个资源,用于查询文化遗产及相关公共数据。支持 stdio 和 Streamable HTTP 传输。

配置

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

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

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

安装包
pypiswiss-culture-mcp1.2.0

工具

还没有获取到工具列表

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

详细介绍

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

🏛️ swiss-culture-mcp

Version License: MIT Python 3.11+ MCP Data Source CI

瑞士文化遗产数据的 MCP 服务,数据来自瑞士联邦文化局(BAK)——ISOS 城镇景观、活态传统、文化奖项、新闻稿。无需 API 密钥。

🌐 English | Deutsch

演示:Claude 通过 MCP 工具调用查询 ISOS 城镇景观


概述

swiss-culture-mcp 让 AI 助手能够访问瑞士文化数据。该服务将 Claude 等大模型与瑞士的国家文化遗产相连接,涵盖受保护的城镇景观(ISOS)、非物质文化遗产活态传统以及当前文化奖项。

数据来源: geo.admin.ch REST API · news.admin.ch RSS · opendata.swiss CKAN · lebendige-traditionen.ch

无需 API 密钥。 所有数据来源均公开可用(开放政府数据)。

核心演示查询: “苏黎世市的学区内有哪些受保护的城镇景观,当地有哪些活态传统?”


功能

  • 🏘️ ISOS 搜索 – 按名称、州或聚落类型搜索瑞士受保护城镇景观联邦名录
  • 📜 活态传统 – 瑞士非物质文化遗产的 228 条记录
  • 🏆 文化奖项 – 瑞士电影奖、文学大奖、音乐奖等
  • 📰 BAK 新闻稿 – 瑞士联邦文化局的最新消息
  • 📦 开放数据目录 – opendata.swiss 上的 BAK 数据集
  • ☁️ 双重传输方式 – 面向 Claude Desktop 的 stdio,以及用于云部署的 Streamable HTTP
#工具说明
1bak_search_isos按地名搜索 ISOS 城镇景观
2bak_isos_by_kanton列出某个州的所有 ISOS 对象
3bak_get_isos_detail获取 ISOS 对象的完整详情
4bak_isos_by_kategorie按聚落类型筛选 ISOS(城市、村庄等)
5bak_isos_statisticsISOS 名录统计(按州抽样)
6bak_get_newsBAK 最新新闻稿
7bak_get_kulturpreise瑞士文化奖项(电影奖、文学大奖等)
8bak_get_opendataopendata.swiss 上的 BAK 数据集
9bak_list_traditions列出瑞士的活态传统
10bak_get_tradition_detail获取传统的详细说明

3 个资源: bak://isos/kantone · bak://isos/kategorien · bak://kulturpreise/uebersicht


数据来源

来源API 类型内容
geo.admin.chREST MapServerISOS(瑞士城镇景观联邦名录)
news.admin.chRSS FeedBAK 新闻稿、文化奖项
opendata.swissCKAN REST APIBAK 开放数据集
lebendige-traditionen.chHTML Fetch228 条非物质文化遗产记录

前提条件

  • Python 3.11+
  • uv 或 pip
  • 无需 API 密钥

安装

# Recommended: uvx (no install step needed)
uvx swiss-culture-mcp

# Alternative: pip
pip install swiss-culture-mcp

快速入门

# Start the server (stdio mode for Claude Desktop)
uvx swiss-culture-mcp

立即在 Claude Desktop 中试用:

“显示格劳宾登州所有受保护的城镇景观” “阿彭策尔州有哪些活态传统?” “2026 年颁发了哪些瑞士文化奖项?”


配置

环境变量
变量默认值描述
MCP_TRANSPORTstdio传输方式:stdio 或 streamable_http(也接受 streamable-http)。只有通过 HTTP 传输方式才能访问 2026-07-28 年代的数据。
MCP_HOST127.0.0.1HTTP 传输方式的绑定主机(默认仅限本地回环)
MCP_PORT8000HTTP 传输方式的端口
MCP_ALLOW_PUBLIC_BINDfalse若为 true,则允许在未进行身份验证的情况下绑定 0.0.0.0。仅在经过身份验证的反向代理(例如 Cloudflare Access、oauth2-proxy)之后使用此设置。
MCP_ALLOWED_HOSTS(空)此服务响应的主机名,以逗号分隔,不包含协议(mcp.example.ch)。用于 HTTP 传输方式的 Host/Origin 检查。所有非本地回环部署都必须设置此项——请参阅下方警告。无论如何都会允许本地回环,因此容器健康检查仍能正常运行。
ALLOWED_ORIGINS(空)以逗号分隔的 CORS 来源,包含协议(https://claude.ai)。留空表示不允许基于浏览器的 MCP 客户端;stdio 和非浏览器客户端不受影响。* 可用,但会记录为警告。
LOG_LEVELINFODEBUG、INFO、WARNING、ERROR——以结构化 JSON 格式向 stderr 输出日志
Claude Desktop 配置
{
  "mcpServers": {
    "swiss-culture": {
      "command": "uvx",
      "args": ["swiss-culture-mcp"]
    }
  }
}

配置文件位置:

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

重启 Claude Desktop 后,即可使用所有工具。示例查询:

  • “请列出格劳宾登州所有受保护的城镇景观”
  • “什么是阿尔卑斯长号和 Büchelspiel 传统?”
  • “2026 年颁发了哪些瑞士文化奖项?”
  • “施泰因阿姆莱茵老城是否列入 ISOS 名录?”
  • “阿彭策尔州有哪些活态传统?”
云端部署(Streamable HTTP)

通过浏览器中的 claude.ai 使用(例如在没有本地软件的托管工作站上):

连接器 URL 始终是部署主机加传输路径: https://<host>/mcp。在 claude.ai 的 Settings → MCP Servers 下添加。

Render.com(推荐):

  1. 将仓库推送到 GitHub,或在 GitHub 上复刻仓库
  2. 在 render.com:New Web Service → 连接 GitHub 仓库
  3. 在 Render 控制面板中设置环境变量,包括 MCP_ALLOWED_HOSTS=your-app.onrender.com,以及浏览器客户端所需的 ALLOWED_ORIGINS=https://claude.ai
  4. 在 claude.ai 的 Settings → MCP Servers 下添加:https://your-app.onrender.com/mcp

Docker。 仓库提供了多阶段 Dockerfile (python:3.13-slim、非 root 用户、TCP 健康检查)。它预设了传输方式、 0.0.0.0 绑定和 MCP_ALLOW_PUBLIC_BIND=true,因为在容器内部,平台的边缘代理是唯一的入口。镜像中有意不设置 MCP_ALLOWED_HOSTS——主机名取决于部署位置,猜测一个主机名会导致所有真实请求都被拒绝并返回 HTTP 421:

docker build -t swiss-culture-mcp .
docker run -p 8000:8000 \
    -e MCP_ALLOWED_HOSTS=mcp.example.ch \
    -e ALLOWED_ORIGINS=https://claude.ai \
    swiss-culture-mcp

这两个变量负责防护不同的内容,不能互相替代。 在 0.0.0.0 绑定下对本服务进行测试,且请求携带 Origin: https://claude.ai 时:

MCP_ALLOWED_HOSTSALLOWED_ORIGINSHost/Origin 检查POST预检请求
已设置已设置已启用200允许
已设置—已启用403拒绝
—已设置已关闭200允许
——已关闭200拒绝

请逐列阅读,因为这两种失败的类型并不相同。 ALLOWED_ORIGINS 决定浏览器客户端能否正常工作:未设置时,请求会被拒绝(Host 允许列表启用时,传输层会返回 403——即 Origin 被拒绝;若 Host 被拒绝,则会返回 421),或者浏览器无法读取响应。MCP_ALLOWED_HOSTS 决定部署是否安全:未设置时,build_transport_security() 会返回 None,完全不检查 Host 和 Origin 标头。第三行就是陷阱——浏览器客户端可以连接,一切看起来正常,但部署却容易遭受 DNS 重绑定攻击。在公共绑定上同时设置这两个变量;仅当不打算让浏览器客户端访问服务时,才不设置 ALLOWED_ORIGINS,并且绝不要在公共绑定上不设置 MCP_ALLOWED_HOSTS。

# Local HTTP mode (loopback only — safe default, no allow-list needed)
MCP_TRANSPORT=streamable_http MCP_PORT=8000 python -m swiss_culture_mcp.server

# Public bind (DANGEROUS — only behind an authenticating reverse proxy)
MCP_TRANSPORT=streamable_http MCP_HOST=0.0.0.0 MCP_ALLOW_PUBLIC_BIND=true \
    MCP_ALLOWED_HOSTS=mcp.example.ch python -m swiss_culture_mcp.server

⚠️ 安全: 服务本身没有身份验证。在没有上游身份验证层的情况下绑定到公共接口,会使其成为访问联邦数据源的开放代理。对于 0.0.0.0 部署,务必在前置位置运行经过身份验证的反向代理(Cloudflare Access、oauth2-proxy、nginx + auth_request)。

⚠️ 在公共绑定上设置 MCP_ALLOWED_HOSTS。 未设置时,完全不会检查 Host 和 Origin 标头,服务因此容易遭受 DNS 重绑定攻击:攻击者将受害者的浏览器指向该服务,并通过伪造的 Host 与其通信。每次以这种方式启动时,服务都会记录 dns_rebinding_protection_off——这条日志是问题的征兆,并非走个形式。回环绑定不需要允许列表;SDK 会根据绑定主机自动生成允许列表。


架构

┌─────────────────┐     ┌──────────────────────────┐     ┌──────────────────────────┐
│   Claude / AI   │────▶│   Swiss Culture MCP      │────▶│  geo.admin.ch REST       │
│   (MCP Host)    │◀────│   (MCP Server)           │◀────│  news.admin.ch RSS       │
└─────────────────┘     │                          │     │  opendata.swiss CKAN     │
                        │  10 Tools · 3 Resources  │     │  lebendige-traditionen   │
                        │  Stdio | Streamable HTTP  │     └──────────────────────────┘
                        └──────────────────────────┘

项目结构

swiss-culture-mcp/
├── src/
│   └── swiss_culture_mcp/
│       ├── __init__.py
│       └── server.py          # All 10 tools, 3 resources
├── tests/
│   ├── conftest.py            # pytest configuration
│   └── test_server.py         # 36 tests (unit + live)
├── pyproject.toml
├── CHANGELOG.md
├── CONTRIBUTING.md            # Contribution guide (English)
├── CONTRIBUTING.de.md         # Contribution guide (German)
├── SECURITY.md               # Security policy & posture (English)
├── SECURITY.de.md            # Security policy & posture (German)
├── LICENSE
├── README.md                  # This file (English)
└── README.de.md               # German version

MCP 协议版本

此服务通过同一端点支持两个协议时代。客户端在连接上的第一个请求决定使用哪一个;之后若声称属于另一个时代,则会被拒绝。

时代修订版本适用对象
initialize 握手2024-11-05 … 2025-11-25当今客户端使用的协议。服务会以请求指定的修订版本作答;如果请求指定了更新的版本,则使用 2025-11-25 这一上限。
每请求信封2026-07-28携带 2026-07-28 _meta 信封的请求会建立现代连接。

这两个修订版本都固定在 tests/test_protocol_version.py 中,并通过已安装的 SDK 进行断言,因此 Dependabot 更新 mcp 时不会在不知不觉中改变任一版本。

请注意,SDK 的 LATEST_PROTOCOL_VERSION 是现代时代的别名,而非握手时代的别名——仅以此为基准固定版本,会让当前客户端实际协商的时代任其漂移。

现代时代是通过测量得出的,而非推断出来的。 tests/test_modern_era.py 会构建服务实际使用的 ASGI 应用,并通过它发送请求:2026-07-28 信封、initialize 握手以及每种格式错误的变体。它会断言现代请求能够得到应答,两个时代彼此独立(现代线路上没有 initialize 方法;握手的版本上限是 2025-11-25,而不会提供 2026-07-28),server/discover 指定的正是固定的修订版本;与之不匹配的修订版本会被拒绝,并返回 -32022,同时指出请求版本和受支持版本;ttlMs/cacheScope 和 serverInfo 会作为线路字段传递。

这一点很重要,因为现代时代只存在于 streamable-HTTP 入口——stdio 和进程内客户端只使用 initialize 握手,不使用其他协议。通过进程内客户端测试规范,测试到的是处理程序,而非协议时代。这一测试盲区掩盖了一个字符级错误:main() 将 HTTP 传输启动为 streamable_http,而 SDK 的 run() 使用的是 streamable-http,因此传输因 ValueError 中止,服务根本没有提供该规范。所有测试仍然通过,因为它们模拟了 mcp.run,并将字符串与手动抄写的相同错字进行比较。

服务身份。 规范 2026-07-28 会在每个响应的 _meta 中携带 serverInfo,而不是像握手时代那样每个会话只携带一次。此服务会使用软件包元数据中的名称、标题、描述、网站 URL 和版本来填充该字段(使用 importlib.metadata,与出站 User-Agent 的数据来源相同);手动维护的字面值会被 scripts/check_version_sync.py 拒绝。

名称为 swiss-culture-mcp——与发行包、控制台脚本、注册表条目和出站 User-Agent 的拼写一致。直到 2026-09-20,它的名称还是 swiss_culture_mcp;如果同一身份在不同位置拼写各异,那它就不是同一个身份。tests/test_servername.py 会将这些来源关联起来,而不是拿字面值与自身比较。Python 日志记录器会刻意保留下划线:那是日志记录器名称,不是服务身份;重命名它只会破坏每位运维人员的日志配置,却无法让任何内容保持一致。

更新策略。 门禁检查失败时,不要盲目修改常量:请阅读这两个修订版本之间的规范更新日志,验证服务行为仍然正确,然后一并更新常量、本节、README.de.md 和 CHANGELOG.md。


测试

# Unit tests (no API key required)
PYTHONPATH=src pytest tests/ -m "not live"

# Integration tests (live API calls)
PYTHONPATH=src pytest tests/ -m "live"

使用示例

学校 / 教育
"Which protected townscapes are there in the school districts of the city of Zurich?"
→ bak_isos_by_kanton(kanton="ZH") + bak_get_isos_detail(...)

"Find living traditions for a project week on the theme of cultural heritage"
→ bak_list_traditions() + bak_get_tradition_detail(slug="...")

"Which UNESCO World Heritage Sites are also in ISOS?"
→ bak_search_isos(query="...") + bak_get_opendata(query="UNESCO")
市政管理 / 空间规划
"Is the building at address X within an ISOS perimeter?"
→ bak_search_isos(query="community/place name")

"Which BAK datasets are available for GIS integration?"
→ bak_get_opendata() → WMS/WFS URLs for GIS software
AI 工作组 / 演示
"Show current cultural policy of the federal government"
→ bak_get_news() + bak_get_kulturpreise()
→ More use cases by audience →

安全性与限制

方面详情
访问权限只读 — 服务无法修改或删除任何数据
个人数据不涉及个人数据 — 所有来源均为汇总后的公共文化遗产数据
速率限制内置每次查询上限(例如,最多 100 条 ISOS 结果、50 条新闻和 200 个类别条目)
超时每次 API 调用 20 秒
身份验证无需 API 密钥 — 所有 4 个数据源均可公开访问
许可证所有数据均采用开放许可证(Open Government Data):geo.admin.ch、opendata.swiss、news.admin.ch
服务条款受各数据源的服务条款约束:geo.admin.ch、opendata.swiss、news.admin.ch、lebendige-traditionen.ch

已知限制

  • ISOS 统计数据: 按州抽样,并非涵盖所有州
  • 活态传统: 通过 HTML 抓取——如果 lebendige-traditionen.ch 更改结构,可能会失效
  • BAK 新闻/奖项: RSS 源仅包含最新条目
  • opendata.swiss CKAN: 全文搜索可能会返回其他发布方的结果
  • 此服务分发的地址均经过实测,而非推测。 scripts/record_fixtures.py 会在每次运行时重新检查每个地址,并同时检查四个对照项(虚构的 geo.admin.ch 服务、虚构的 BAK 路径、虚构的新闻机构编号、虚构的传统标识)。2026-08-08,其中一个地址已失效:bak_isos_overview 将 .../home/kulturerbe/baukultur.html 作为其 BAK 来源发布——HTTP 404,整个 kulturerbe 分支也都如此。它已替换为可确认返回 200 的 BAK 根地址,而不是一个猜测的替代 URL。
  • 其他所有项均正常。 geo.admin.ch、opendata.swiss、gisos、isos、带有 org-nr=314 的新闻源以及传统页面都返回真实内容。这个空结果也会被记录:没有它,下次检查就只能从零开始。

与其他 MCP 服务的协同

swiss-culture-mcp 可与产品组合中的其他服务搭配使用:

组合使用场景
+ swiss-transport-mcp文化旅游:乘坐公共交通前往传统文化目的地进行一日游
+ zurich-opendata-mcp本地文化地图集:ISOS + 苏黎世市活动
+ global-education-mcp国际比较中的文化教育
+ fedlex-mcp文化财产转让法 + BAK 执法实践
+ swiss-statistics-mcp各州文化支出(BFS 数据)

更新日志

请参阅 CHANGELOG.md


参与贡献

欢迎贡献 — 请参阅 CONTRIBUTING.md。


安全

安全状况、加固详情和负责任披露流程记录在 SECURITY.md 中。


许可证

MIT 许可证 — 请参阅 LICENSE


作者

Hayal Oezkan · malkreide


致谢与相关项目

安装

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

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

评论

支持 Markdown

第一次接触 MCP?

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

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