mcpField
A
amtsblatt-mcp

amtsblatt-mcp

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

关于 amtsblatt-mcp

amtsblatt-mcp 提供对瑞士官方公报中部分公告的只读访问,包括采购、规划和公共公告,适用于检索官方出版物。严格的允许列表会排除系统性公开自然人数据的类别。

主要功能

  1. 01搜索允许访问的公报公告
  2. 02获取公告全文
  3. 03搜索采购公告
  4. 04筛选多语言公告结果
  5. 05说明被阻止的类别

适用场景

  1. 01查找提契诺州发布的招标
  2. 02搜索苏黎世的规划变更
  3. 03获取官方公告全文
  4. 04查看哪些公告类别可查询

MCP 相关

向 MCP 客户端提供只读搜索、检索、类别列表和数据源状态工具。默认拒绝的允许列表限制可访问类别,并阻止涉及个人数据的类别。

配置

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

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

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

安装包
pypiamtsblatt-mcp0.23.0

工具

还没有获取到工具列表

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

详细介绍

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

📰 amtsblatt-mcp

版本 许可证:MIT Python 3.11+ MCP 无需身份验证 CI

面向 amtsblattportal.ch 的 MCP 服务——瑞士官方公报门户 (SHAB + 27 个州级公报)。提供公共采购和官方公告, 按设计排除涉及个人数据的栏目。

🇩🇪 德语版

概览

Amtsblattportal 发布了约 279 万 条官方公告:公共采购、州级和市级公告、法规、空间规划, 以及涉及自然人的破产、债务追讨、遗产公告和民事身份记录。

此服务仅开放前一类内容。涉及系统性自然人数据的栏目不可查询,任何工具都不接受个人姓名、 出生日期或地址。这是有意为之的数据保护决定,详见 数据保护与范围。

示例查询: “提契诺州本月发布了哪些公共招标?”

演示

演示:Claude 使用 gazette_search_procurement 和 gazette_get_publication → gazette_search_procurement(canton="TI", only_language=True, language="it") → gazette_get_publication(id=…)

如需查询其他州的采购信息(包括苏黎世、伯尔尼和巴塞尔城市州), 请使用 swiss-procurement-mcp; 参见 与 swiss-procurement-mcp 的边界。

功能

  • 默认拒绝的绿色允许列表——152 个栏目中开放 49 个;其余栏目默认一律阻止, 包括上游之后新增的栏目
  • 说明拒绝原因——被阻止的栏目会返回原因,不会静默返回空结果,也不会提供规避提示
  • 了解采购情况——知道目前只有 AR 和 TI 仍在此发布招标,BS 在 2024 年逐步停止发布, BL/VS 是历史档案,OB-ZG 在切换至 simap 后从未填充,而 ZH 则将所有内容都转至 simap.ch, 因而会作出说明,而非返回空结果。活动情况 通过测量得出,而不是根据栏目标签判断
  • 截止日期计算使用具有法律效力的时区 Europe/Zurich
  • 如实统计多语言内容——门户按语言发布记录,每种语言都有不同的出版编号;相同版本会合并, 翻译版本通过 language_mix 报告,而非猜测;only_language=True 可提供单一语言视图
  • 防御性 XML 解析——架构按子栏目定义;不对特定栏目硬编码路径,并会对经过实体转义的 HTML 正文进行反转义和清理
  • 出站流量允许列表、带退避机制的重试、结构化 JSON 日志
  • Markdown 或 JSON 输出,每个响应都附带来源归属和 provenance

前提条件

  • Python 3.11+
  • 无需 API 密钥。 amtsblattportal.ch 的读取 API 可免费访问。

安装

pip install amtsblatt-mcp
# or, without installing:
uvx amtsblatt-mcp

从源代码安装:

git clone https://github.com/malkreide/amtsblatt-mcp
cd amtsblatt-mcp
pip install -e ".[dev]"

配置

Claude Desktop
{
  "mcpServers": {
    "amtsblatt": {
      "command": "uvx",
      "args": ["amtsblatt-mcp"]
    }
  }
}
云端部署(streamable-http)
export MCP_TRANSPORT=streamable-http
export MCP_API_KEY="$(openssl rand -hex 32)"   # mandatory — fails loud if unset
export PORT=8000
amtsblatt-mcp

端点为 /mcp。

从 SSE 迁移。 在 0.18.0 之前,此服务仅使用 SSE,路径为 /sse + /messages。MCP 规范 2026-07-28 将 HTTP+SSE 重新归类为 已弃用,并设定了十二个月的移除期限,同时移除了协议级会话,因此 streamable-http 现为默认方式。MCP_TRANSPORT=sse 仍然有效,且仍包含完整的 bearer 身份验证、速率限制和 CORS 机制——启动时会记录一条警告并注明截止日期。切换时请更新客户端 URL:路径变更才是会导致故障却不易察觉的部分。

变量默认值用途
MCP_TRANSPORTstdiostdio、streamable-http(别名 http)或已弃用的 sse
MCP_HOST127.0.0.1HTTP 绑定地址。默认为回环地址;设为 0.0.0.0 可在所有接口上公开访问(Docker 镜像有意这样设置)。
MCP_STATELESS(开启)streamable-http 完全不跟踪会话——这是规范 2026-07-28 的原生模式,该规范没有协议级会话。它不再试图回答会话劫持和会话亲和性问题,而是直接消除这些问题(SEC-009、SCALE-002)。设为 0 / false / no 可为握手时代的客户端恢复会话;其他任何值都会保留默认设置。在 sse 下忽略此项,因为它没有无状态模式。
MCP_CORS_ORIGINS(未设置)允许从浏览器调用端点的来源,以逗号分隔。未设置表示完全禁止跨源浏览器访问——不影响 stdio 和非浏览器客户端。对列出的来源会公开并接受 Mcp-Session-Id,因此浏览器客户端可以保持会话。* 会被接受,但会记录警告并禁用凭据,因为浏览器不允许通配符来源与凭据同时使用。
MCP_API_KEY—Bearer 令牌;每种 HTTP 传输方式都必须设置
MCP_RATE_LIMIT / MCP_RATE_WINDOW60 / 60滑动窗口速率限制
RUBRICS_TTL86400分类体系缓存 TTL(秒)
LOG_LEVELINFODEBUG | INFO | WARNING | ERROR。始终在 stderr 输出结构化 JSON,每行一个对象——stdio 传输时,stdout 用于传输 MCP 协议。
日志记录

基于 structlog 构建。工具调用期间发出的每条事件都带有该次调用的 correlation_id,通过 contextvars 绑定——因此,即使是在 HTTP 请求路径深处记录的重试或出站请求拒绝,也能与触发它的请求关联起来,无需在每个函数签名中传递上下文。

级别触发时机
DEBUG开始执行工具调用(tool_call_started)——可据此判断卡住的调用是否曾经启动
INFO工具调用顺利完成,并记录延迟
WARNING上游重试、出站请求被拒绝、身份验证失败、速率受限
ERROR工具调用引发异常

记录只包含异常的类型——绝不包含异常消息,也不包含上游响应正文。

{"event":"tool_call_started","tool":"gazette_search_procurement","correlation_id":"23221af26ae640c7","level":"debug","timestamp":"2026-07-27T22:20:07.494276Z"}
{"status":"ok","latency_ms":312,"event":"tool_call","tool":"gazette_search_procurement","correlation_id":"23221af26ae640c7","level":"info","timestamp":"2026-07-27T22:20:07.806Z"}

将这些记录发送到 SIEM,并针对 auth_failed、 rate_limited、egress_denied、green_gate_violation 和 blocked_publication_requested 设置告警—— 最后两项表示有请求试图访问此服务不提供的 rubric。

可用工具

工具签名说明
gazette_search_publications(keyword?, rubric?, sub_rubric?, canton?, date_start?, date_end?, limit=20, page=0, language='de', only_language=False)强制执行绿色类别。未指定 rubric 时,会注入所有绿色类别,因此仅使用关键词的查询无法触及受限类别。
gazette_search_detailed相同筛选条件 + top_n=3聚合查询。 一次调用即可搜索,并并行获取排名前 top_n 条结果的全文。每份展开的文档都会经过相同的绿色类别检查;受限内容会被隐藏并计数,不会呈现。
gazette_search_procurement(keyword?, canton?, date_start?, date_end?, include_inactive=False, limit=20, page=0, language='de', only_language=False)OB-* 类别,以及公报原生子类别 AR-VS40、AR-OW40、BA-SH40。不含上述类别的州会返回 simap.ch 说明,且不会发起 HTTP 请求。没有 CPV——来源不包含该数据。
gazette_get_publication(id, response_format='markdown')从 XML 获取完整官方文本。获取后会再次检查类别;受限类别的内容会被丢弃。
gazette_list_rubrics(language='de', rubric_class='green', response_format='markdown')rubric_class='all' 会显示包含交通灯类别和原因的完整分类体系——列出 ≠ 可查询。
gazette_source_status(response_format='markdown')可访问性、延迟、缓存时长、范围指标。

所有工具均为 readOnlyHint=True。

示例用例
问题工具调用链
本季度提契诺州的招标gazette_search_procurement(canton="TI", only_language=True, language="it")
simap.ch 没有的采购信息gazette_search_procurement(canton="VS") — 瓦莱州有 150 项授标记录,simap 上均未收录
其他任何州的招标→ 使用 swiss-procurement-mcp
这里到底有哪些内容可查询?gazette_list_rubrics()
为什么我不能搜索破产信息?gazette_list_rubrics(rubric_class="all")
苏黎世的分区规划变更gazette_search_publications(rubric="RP-ZH")
某则公告的全文gazette_get_publication(id="fbf0ff9e-…")
某公司的所有发布信息→ 使用 register-mcp

数据保护与范围

Amtsblattportal 会系统地发布自然人的个人数据。这些发布内容是公开的——但通过 AI Agent 按姓名系统性地查询这些信息,是一种原发布目的未涵盖的二次利用,也会构成瑞士修订版《联邦数据保护法》(revDSG)所指的画像工具。

由此确立了四项规则,并且这些规则是在代码中强制执行的,而非仅写在文档里:

  1. 使用允许列表,绝不使用禁止列表。 未明确列为绿色 ⇒ 不可查询。 上游新增类别默认关闭。
  2. 任何工具签名中都不提供按个人搜索的入口。
  3. 不持久化。 发布内容有法定删除期限;缓存若超过该期限,将直接损害这些规定的效力。仅缓存分类体系。
  4. 受限 ⇒ 说明原因。 绝不静默返回空结果,也绝不暗示如何绕过限制。
不包含的内容

🔴 破产程序(KK)、债务追偿(SB)、债务催告(LS、SR)、 遗产延期(NA)、继承/遗嘱/身故(ES、TE-*、VA-*)、 家庭与民事身份(FZ-*、BV-*、BU-*)、法院传票 (UV、GB-*、GE-*、SJ-BE)、建筑申请(BP-*)、土地登记簿(GR-*)、 GR 公告目录(AA-GR)。

🟡 暂缓处理:税务、公告、许可、教育与教会事务,以及通用兜底类别。

完整的审计记录——包括对源规范所作的三项有文档记录的扩展——见 docs/rubric-classification.md。

每项决策覆盖多少内容,是经过测量的,而非估算的。 docs/coverage-matrix.md 列出了源数据自身的 类别轴,并标示本服务对其的覆盖范围:2 804 063 条公告中,84.2 % 可访问,12.6 % 因决策而受限,3.3 % 尚未分类。仅破产类别就有 321 704 条公告—— 这些公告存在于源数据中,但我们有意不提供访问。若没有这个数字,在审查中,“超出范围” 和“源数据中不存在”看起来并无区别,而本仓库此前就犯过这样的错误(见 SECURITY.md 中的 ARCH-003)。

与 register-mcp 的边界

对于特定公司的公告,请使用 register-mcp。它保留完整的 类别访问权限——包括公司的自身破产记录——但查询始终以公司的 UID 为依据。 公司的破产属于企业数据,而非自然人画像;按 UID 限定范围可杜绝按名称枚举。

amtsblatt-mcp 则恰好相反:搜索范围广,类别范围窄。它完全不提供上游的 uids 参数。

与 swiss-procurement-mcp 的边界

simap.ch 是瑞士公共采购的主要来源——涵盖全部 26 个州和联邦,提供 CPV 和 BKP 代码、 授标信息及公告历史。采购相关问题请使用 swiss-procurement-mcp。

amtsblattportal.ch 是官方公告的主要来源——包括商业登记、空间规划、法规、州级和市镇公告。 本服务正是用于此类信息;采购仅占其已发布 49 个类别中的 6 个。

此处的采购信息大多是相同招标的二次发布,如今这一点已有数据衡量,而非仅凭假设。 公告的 XML 在内容源自 simap.ch 时会包含 <simapPublicationNumber>,可据此精确关联两个数据集。 在完整的 2026 年 OB-TI 数据集中,546 条记录中有 503 条(92.1%) 包含该字段;六个 OB-* 类别中有三个在自身标签中明确说明了这一点 (OB-BL——“über Simap importiert (I N A K T I V)”)。

例外范围很小且界限明确:AR-VS40(瓦莱州,150 项授标)、 AR-OW40(上瓦尔登州,7 项)、BA-SH40(沙夫豪森州,2 项)以及提契诺的子类别 OB-TI65(“Avvisi di gara non CIAP”)完全不含 simap 引用。这是本门户的采购覆盖范围中 swiss-procurement-mcp 无法访问的部分;即使 VS、OW 和 SH 没有启用的 OB-* 类别, gazette_search_procurement 仍可提供这些内容。数据和方法见 docs/simap-overlap.md。

这两个服务有意保持独立:来源不同、再利用条款不同,而且只有在覆盖服务中的每个工具时, 失效关闭的类别闸门才有意义。数据见 docs/procurement-coverage.md。

成熟度与阶段

阶段 1 — 只读。 六个工具均为只读;没有写入路径,也没有计划添加。请参阅 ROADMAP.md,了解各阶段的待办事项、明确不计划实现的内容,以及阶段转换所需条件。

这里最重要的范围限制不是阶段,而是绿色允许列表——包含系统性自然人数据的分类不可查询,且这一限制由代码强制执行,并在每次抓取后重新检查。阶段变化不会影响这一点。请参阅数据保护与范围。

SDK 和依赖项更新会通过 Dependabot PR 提交,因此对协议或 SDK 的破坏性变更会经过审慎审查,而不会悄然引入。


架构

   Claude / MCP client
            │
      amtsblatt-mcp
            │
   ┌────────┴────────┐
   │  green gate     │  ← rubrics.py: fail-closed allow-list
   └────────┬────────┘     (checked at the tool AND at the query builder)
            │
   ┌────────┴────────┐
   │  param allow-   │  ← Silent Ignore guard
   │  list + quirks  │  ← Silent Empty guard (taxonomy validation)
   └────────┬────────┘  ← plausibility guard (corpus-size check)
            │
   ┌────────┴────────┐
   │ egress allow-   │
   │ list (httpx)    │
   └────────┬────────┘
            │
  amtsblattportal.ch/api/v1
   /publications · /publications/{id}/xml · /rubrics · /tenants

架构 A(仅使用实时 API)。 这些端点无需身份验证即可稳定响应,因此不维护批量数据转储。

已验证的上游特性(2026-07-20 实时检查)
特性行为防护措施
静默忽略未知参数名称会返回 HTTP 200 和完整语料库。canton=ZH(单数拼写错误)会被静默忽略,筛选条件也随之失效。查询参数仅使用 ALLOWED_GAZETTE_PARAMS 构建;合理性检查会拒绝结果超过 2 000 000 条的情况。
静默返回空结果未知分类值会返回 HTTP 200 和 total: 0,无法与确实没有匹配项的情况区分。每个代码都会在调用前根据分类体系进行验证。
仅返回元数据列表端点和 GET /publications/{id} 均会返回 content: null。只能通过 /publications/{id}/xml 获取全文。
忽略排序pageRequest.sortOrders 会被接受并返回 200,但不起作用;返回的 sortOrders 为 []。在客户端排序。
缺少 publicationStates返回 401,而不是 400——这并不表示需要凭据。始终注入该参数;401 消息会说明这一点。
没有页面大小上限pageRequest.size=2000 会返回 2000 条项目。客户端上限为 100。
复数形式不一致rubrics/cantons/subRubrics 为复数,keyword/tenant 为单数。编码时使用精确拼写,不采用复数化规则。

已知限制

  • 各州覆盖不均。 29 个类别中,只有 16 个提供了自己的分类体系;AG、FR、GE、GL、JU、LU、NE、UR 仍不完整。

  • 删除时限。 公告会随时间从 API 中消失,因此仅透传。

  • 采购边界。 包括 Zürich 在内的大多数州都通过 simap.ch 发布招标,不在本门户范围内。这里没有 OB-ZH,也没有 CPV 分类。此门户提供而 simap 不提供的内容列于 docs/simap-overlap.md;gazette_get_publication 会报告 simap_publication_number,以便区分镜像与原始公告。

  • 实测采购覆盖率(publicationStates=PUBLISHED,2026-07-27,按日历年统计记录数——可通过 python scripts/measure_procurement_coverage.py 复现):

    分类20222023202420252026最新记录状态
    OB-TI5174916256075462026-07-27活跃
    OB-AR95857956402026-05-22活跃
    OB-BS1 1491 0583191522026-05-202024 年期间逐步停止发布
    OB-VS01 0521002024-01-05存档 — 导入 simap 的数据截至 2023 年底
    OB-BL0740002023-03-30存档 — 标记为 «I N A K T I V»
    OB-ZG00000—从未填充

    目前只有 TI 和 AR 仍在持续发布。 OB-BS 是一个很有说明性的案例: 它的标签只是普通的“Öffentliches Beschaffungswesen”,没有停用标记, 因此只有数据量能反映迁移情况——这也是 active 需要实测而不能直接读取的原因。使用 include_inactive=True 可访问 BS、BL 和 VS 的存档。 详情见 docs/procurement-coverage.md。

  • 不支持推送。 仅支持轮询;没有订阅或 webhook 机制。

  • 具有法律效力的文本是签署后的 PDF,而不是此 API。

MCP 协议版本

通过 initialize 握手提供2024-11-05 … 2025-11-25 — 握手支持的上限
通过逐请求封套提供2026-07-28
选择方式使用 HTTP 时,每个请求的 MCP-Protocol-Version 标头决定版本:2026-07-28 会作为不需要握手且没有会话的独立请求提供;握手时期的版本值或未提供标头时,则走 initialize 路径。使用 stdio 时,由客户端的首个请求决定:server/discover 探测会建立现代连接。
serverInfo名称为 amtsblatt_mcp,并包含软件包版本;该信息会写入每个现代结果的 _meta
固定在_app.py 中的 MCP_PROTOCOL_VERSION,并由 server.py 重新导出
SDKmcp[cli]>=2.0.0,<3
缓存提示tools/list 和 server/discover:ttlMs 为 300000,cacheScope 为 public

MCP Python SDK 会在会话层协商协议版本,且不提供用于设置版本的构造函数参数,因此无法通过配置固定版本。版本是通过声明常量固定的,并通过检测强制执行:

  • **运行时,**版本不匹配会以 WARNING 级别记录 protocol_version_drift 事件。 服务会继续运行。
  • 在 CI 中,tests/test_protocol_version.py 会失败。

SDK 升级应该导致我们的构建失败,而不是导致某人在自己的环境中升级 mcp 后无法运行。

tests/test_modern_era.py 会验证这两个时期的协议是否确实可用——经过 bearer 验证、速率限制和 CORS,而不只是出现在常量中:它测试带有路由标头的原始 2026-07-28 请求、在 HTTP 和 stdio 上以 auto 模式运行的 mcp.Client,以及作为负向对照的旧式握手。

更新策略
  • Dependabot 每月都会创建 SDK 更新 PR(.github/dependabot.yml)。
  • 当更新改变协议版本时,CI 测试会失败。修复方法不是盲目编辑常量:应阅读规范变更日志,确认服务仍按预期运行——尤其是绿色允许列表的不变量——然后在同一个提交中更新常量、本节和 CHANGELOG.md。
  • 协议版本更新会在 CHANGELOG.md 中明确说明,不会并入依赖更新条目。
缓存提示

规范 2026-07-28 为每个可缓存结果提供 ttlMs 和 cacheScope。 SDK 默认将两者设为“立即过期,绝不共享”,因此,不传入 cache_hints 的服务并非中立——它会要求每个客户端在每次连接时重新列出。此服务的工具列表在导入时注册,对每个调用者都相同,因此会声明其可缓存五分钟,并可在授权上下文之间共享(_app.py 中的 CACHE_HINTS)。

public 依据的是后一项属性,而非便利性:绿色允许列表在工具内部按请求执行,绝不会通过对调用者隐藏工具来实现。工具列表一旦开始因调用者而异,就必须在同一个提交中将范围改为 private。


基元:仅工具

此服务只公开工具,不公开资源或提示词。这是一个有意作出的决定,并非遗漏(ARCH-008)。

为什么不使用资源。 资源用于客户端可以枚举和缓存的、可识别且可列出的内容。此语料库包含 279 万份出版物,且每天都在增长;更重要的是,并非所有内容都可以提供。根据设计,包含系统性个人数据的分类标准会被排除,而这一排除会在两处执行:请求前对筛选条件进行绿色检查,以及获取后对返回文档进行检查。

资源 URI 会将出版物 ID 作为可枚举地址交给客户端。由于 ID 是不透明的,只有获取文档后才能知道它对应的分类标准——这正是设置获取后检查的原因。将出版物公开为资源,就意味着要么枚举尚未通过检查的 ID,要么仍然在获取时进行检查;此时资源抽象毫无益处,反而需要维护第二条内容路径,才能确保保证继续有效。这个仓库已经从中吸取过一次教训:之所以必须将聚合工具中的检查提取到共享辅助函数中,正是因为第二条内容路径最容易让这类保证悄然失效。

我们具体评估过一个候选项:

候选项保留为工具的原因
gazette_list_rubrics形式上确实很像资源——它是一个有限、变化缓慢的分类体系,并且已经使用 TTL 缓存。但它的全部用途,是传达“列出 ≠ 可查询”:它会呈现红绿灯分类,以及每个受限分类被限制的原因。若将其作为资源,这种说明就会变成模型可能读取也可能不读取的文档;作为工具,它则是对模型所提问题的回答。

为什么不使用提示词。 问题模板会在第二个可能与允许列表不同步的位置,重复工具文档字符串中已有的指导。既然文档字符串会告知模型哪些分类可访问,一个信息来源比两个更安全。

返回类型:渲染后的文本,而非模型

工具返回 str——默认使用 Markdown,也可以通过 response_format='json' 返回 JSON——而不是 Pydantic 模型。这是对 SDK-002 的明确记录的偏离,是有意为之,并非疏忽。

渲染后的输出不是内部对象的序列化结果,而是为读者编写的内容。它包含来源说明、范围声明(green_rubrics_only)、合并语言变体时的去重警告,以及被屏蔽的 rubric 返回的、用来代替数据的说明。这些内容能避免模型得出错误结论,而且它们是文字说明,不是字段。

返回模型要么会丢掉这些内容,要么会把它们塞回字符串字段中;本质上并无不同,只是形式更繁琐。对于需要机器可读结果的调用方,json 格式已经满足需求。

**可能改变这一做法的情况:**调用方需要对结果进行计算,而不是阅读结果。届时,正确的做法是仅在 JSON 路径上使用类型化模型,而不是彻底改变每个工具的返回方式。


测试

pip install -e ".[dev]"
PYTHONPATH=src pytest tests/ -m "not live"   # 75 tests, no network
PYTHONPATH=src pytest tests/ -m live         # hits the real API
ruff check src/ tests/ scripts/
ruff format --check src/ tests/ scripts/
python scripts/check_version_sync.py

这些检查与 CI 对相同目录运行的检查相同。dev extra 将 ruff 固定为 CI 安装的版本,因此本地运行结果与 CI 运行结果一致。

测试套件涵盖必需的组合:带来源 URL 的绿色 rubric 搜索、被屏蔽的 rubric → 返回说明且不发起 HTTP 调用、按州筛选、根据固定的“今天”计算 Europe/Zurich 截止日期、跨页分页、语言去重、布尔值规范化,以及 API 无法访问时的处理。测试数据是缩短后的真实响应,并统一做了匿名化处理——不含任何真实个人数据。

项目结构

amtsblatt-mcp/
├── src/amtsblatt_mcp/
│   ├── rubrics.py       # Fail-closed green allow-list — the scope decision
│   ├── server.py        # MCPServer, 5 tools, quirk guards, XML parsing
│   ├── _log.py          # Structured JSON logging + per-tool call events
│   ├── _middleware.py   # Bearer auth + sliding-window rate limit (SSE only)
│   └── _otel.py         # Optional OpenTelemetry wiring
├── tests/
│   ├── test_allowlist.py    # Data-protection invariants (own CI job)
│   ├── test_search.py       # Search, procurement, pagination, dedup, errors
│   ├── test_publication.py  # XML parsing, deadlines, egress allow-list
│   └── fixtures.py          # Anonymised real responses
├── docs/
│   ├── rubric-classification.md   # Why each of the 152 rubrics is open/closed
│   ├── procurement-coverage.md    # Measured OB-* volume; why `active` is measured
│   ├── coverage-matrix.md         # Measured reach: which part of the corpus the tools cover
│   └── simap-overlap.md           # Mirror vs. original, joined on simapPublicationNumber
├── scripts/
│   ├── measure_procurement_coverage.py
│   └── measure_coverage_matrix.py
├── Dockerfile · compose.yaml      # Hardened, non-root, read-only container
└── server.json                    # MCP registry manifest

更新日志

请参阅 CHANGELOG.md。

贡献

请参阅 CONTRIBUTING.md。对 src/amtsblatt_mcp/rubrics.py 的更改必须在 PR 描述中明确说明理由:发布 rubric 是一项数据保护决策,而非功能。

安全

有关报告问题和运营方加固说明,请参阅 SECURITY.md。

许可证

MIT——请参阅 LICENSE。数据源声明:NOTICE.md。

数据源:amtsblattportal.ch,由 SECO / 瑞士经济事务国务秘书处代表瑞士联邦运营。可自由使用,但不保证内容完整或准确。只有出版物的签署 PDF 具有法律约束力。

作者

Hayal Oezkan · malkreide

致谢与相关项目

属于 Swiss Public Data MCP Portfolio:

  • register-mcp — Zefix 商业登记册,可通过公司 UID 与官方公报关联

评论

支持 Markdown

第一次接触 MCP?

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

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