mcpField
P
parlament-mcp

parlament-mcp

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

关于 parlament-mcp

parlament-mcp 通过 Curia Vista API 将瑞士联邦议会数据接入 AI 应用。它支持搜索议会事务,并提供带引文的辩论摘录或全文,无需 API 密钥。

主要功能

  1. 01搜索议会事务
  2. 02获取议案详情
  3. 03查找议员与投票
  4. 04列出议会会议
  5. 05搜索并获取辩论记录

适用场景

  1. 01按主题和状态查找待处理动议
  2. 02按州或党派查找议员
  3. 03获取议会发言的带引文原文

MCP 相关

向 MCP 客户端提供只读工具,用于搜索和获取联邦议会事务、议员、投票、会议及辩论记录。

配置

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

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

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

安装包
pypiparlament-mcp0.4.1

工具

还没有获取到工具列表

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

详细介绍

🇩🇪 德语版

🏛️ parlament-mcp

CI PyPI version License: MIT Swiss Public Data MCP Portfolio

属于 Swiss Public Data MCP Portfolio – 将 AI 模型连接到瑞士公共数据源。

注意:此服务覆盖联邦层面(Curia Vista)。本仓库还包含一个独立的子项目 openparldata-mcp/——面向 26 个州和约 70 个市级议会的州及市级对应项目(OpenParlData.ch)。这两个项目是独立的服务。

一个通过 Curia Vista OData API(ws.parlament.ch)将 AI 模型连接到瑞士联邦议会的 MCP 服务。无需 API 密钥即可访问动议、质询、投票、议员、会议,以及《官方公报》(Amtliches Bulletin)的辩论逐字记录(第一阶段——优先免认证)。


🎯 标杆示例查询

元数据层:

“哪些关于学校 AI 的动议仍在处理中?” → parlament_search_business(keyword="KI", keyword2="Schule", status="Eingereicht")

逐字记录(《官方公报》):

“Munz 国民议会议员在 2024 年春季会议上对 Volksschule 说了什么?请提供准确原文和正确的 AB 引用。” → parlament_search_transcripts(speaker_name="Munz", session_id=5202, keyword="Volksschule") → 然后调用 parlament_get_transcript(transcript_id=…) 获取完整原文。

返回简短、可引用的摘录(AB 2024 N, 2024-03-13, Munz Martina),并附带稳定的来源 URL;逐字文本按需获取,绝不批量获取。

→ 按受众查看更多用例 →

非常适合苏黎世市政府 AI 专家组:查找有关教育领域 AI 的待处理动议,或即时引用议事厅里实际说过的话。

演示:Claude 通过 MCP 工具调用查询待处理的 AI 动议


🔧 工具

工具描述
parlament_search_business按关键词、类型、状态、议院和日期搜索动议
parlament_get_business获取单个议案的完整详情(文本、FC 答复)
parlament_search_members按州(例如 ZH)、政党和议院查找议员
parlament_get_votes获取议会投票及 Ja/Nein 含义
parlament_get_sessions列出近期会议及其 ID,供后续查询使用
parlament_search_transcripts搜索辩论记录 → 可引用的摘录,附 AB 引用和来源 URL(可按发言者 / 会议 / 议案 / 日期筛选)
parlament_get_transcript按 ID 获取单篇发言的完整逐字文本(设有上限、分页,并标记 is_excerpt)

🏗️ 架构

┌──────────────────────────────────┐
│     MCP Host (Claude Desktop /    │
│     Claude API / IDE)             │
└─────────────┬─────────────────────┘
              │ MCP Protocol (JSON-RPC 2.0)
              │ Transport: stdio (local) / SSE (cloud)
┌─────────────▼─────────────────────┐
│          parlament-mcp            │
│   FastMCP · Python · Pydantic v2  │
│                                   │
│  ┌── metadata layer (server.py) ──┐
│  │  search_business · get_business │
│  │  search_members · get_votes     │
│  │  get_sessions                   │
│  └─────────────────────────────────┘
│  ┌── transcript layer ────────────┐  ← separate module (transcripts.py)
│  │  search_transcripts (excerpts) │    · Language='DE' dedups editions
│  │  get_transcript (verbatim)     │    · Type=1 = real speeches only
│  └─────────────────────────────────┘    · retry + 45s read timeout
└─────────────┬─────────────────────┘
              │ HTTPS / OData v3
┌─────────────▼─────────────────────┐
│  ws.parlament.ch / odata.svc      │
│  Curia Vista – No Auth Required   │
│                                   │
│  Business · Vote · MemberCouncil  │   metadata path
│  Session ─< Meeting ─< Subject ─< Transcript   transcript path
└───────────────────────────────────┘

🚀 安装

Claude Desktop(stdio)

添加到 ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "parlament": {
      "command": "uvx",
      "args": ["parlament-mcp"]
    }
  }
}
本地开发
git clone https://github.com/malkreide/parlament-mcp
cd parlament-mcp
pip install -e .
python -m parlament_mcp.server
云端 / Railway(SSE)
MCP_TRANSPORT=sse MCP_HOST=0.0.0.0 PORT=8080 python -m parlament_mcp.server
# SSE endpoint: http://your-host:8080/sse
网络绑定

默认情况下,服务绑定到 127.0.0.1(仅限 localhost)。仅在容器 / 云环境(Docker、Railway、Render、Kubernetes)中设置 MCP_HOST=0.0.0.0。切勿在本地开发机器上绑定到 0.0.0.0,否则会将服务暴露给本地网络(存在 NeighborJack 风险);若在未检测到容器的环境中这样操作,服务会记录警告。

传输方式通过 MCP_TRANSPORT 选择(默认为 stdio,也可设为 sse / streamable-http);--http 仍作为 streamable-http 的别名保留。

身份验证(可选)

HTTP 传输默认开放(公开只读数据)。如需使用 bearer token,请通过 CORS/身份验证应用工厂提供服务,并设置 MCP_BEARER_TOKENS:

MCP_BEARER_TOKENS="alice:tok_abc,bob:tok_def" MCP_ALLOWED_ORIGINS="https://claude.ai" \
  uvicorn parlament_mcp.server:create_http_app --factory --host 0.0.0.0 --port 8080

此后,每个请求都需要 Authorization: Bearer <token>;身份信息来自经过验证的 token,而非会话标头(参见 docs/security.md)。

Docker
docker compose up --build          # binds 127.0.0.1:8080 only
# or build the hardened image directly (non-root, read-only FS):
docker build -t parlament-mcp .

Kubernetes 清单(加固的 securityContext、资源限制、出站 NetworkPolicy、Mcp-Session-Id 粘性路由)位于 deploy/k8s/;HAProxy 粘性表示例位于 deploy/haproxy.cfg。


🔗 协同组合

合作方服务组合方式
openparldata-mcp联邦 ↔ 次国家级 — 同一问题横跨各州和市镇
fedlex-mcp法律文本 ↔ 制定该法律的议会辩论
zurich-opendata-mcp城市政策 ↔ 州级/联邦动议
swiss-statistics-mcp数据依据 ↔ 引用统计数据的动议

强力查询示例:

"Zeige mir alle Zürcher Motionen zu KI in der Bildung
 und verlinke die relevanten Bundesgesetze aus fedlex-mcp."

📊 数据来源

  • API: ws.parlament.ch/odata.svc
  • 身份验证: 无(阶段 1——优先采用无身份验证方式)
  • 协议: OData v3 / JSON
  • 覆盖范围: 自 1978 年以来的所有议会事务;约自 2000 年以来的表决。 自 1999-12-06 起的结构化逐字记录(Amtliches Bulletin) (1891–1999 年的较早记录仅以档案扫描件形式存在——参见已知限制)。
  • 更新周期: 实时(官方政府数据)
版权——允许逐字引用

瑞士当局的官方记录不受版权保护,依据为 Art. 5 para. 1 lit. a URG(《瑞士版权法》)。因此,Amtliches Bulletin 中 议会辩论的逐字内容可以自由转载和引用——这正是记录工具返回的内容:原文 本身,而非代替原文的摘要。


📜 数据来源与许可证

来源许可证署名
Curia Vista (ws.parlament.ch)CC BY 4.0© Schweizer Parlament,CC BY 4.0

每个工具都会返回带类型的结构化响应(FastMCP 会公开输出架构),其中包含 source、license、provenance、match_type 和 count,以及带类型的 results。数据未经修改直接传递。

🧭 阶段

此服务处于阶段 1——只读封装器(所有工具均为 readOnlyHint: true, 不执行写入)。完整的阶段模型和转换标准见 docs/roadmap.md。

🔖 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 时,不会悄然更改其中任何一个。该文件还会测量协商情况:每个时期都使用一个真实客户端连接已注册的服务,并直接读取连接上的修订版本,而不是根据常量推断。

在 2026-07-28 时期,没有用于承载服务身份信息的握手;SDK 会将 io.modelcontextprotocol/serverInfo 写入结果的 _meta。服务会在其中传递自己的软件包版本 (tests/test_server_info.py),因此两个时期报告的版本相同。

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

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

🧱 MCP 原语

第 1 阶段仅使用工具——设计依据和第 2 阶段资源计划见 docs/adr/ADR-003-mcp-primitives.md。

🏷️ 工具注解

所有工具都声明了与其行为一致的显式注解:

工具只读破坏性幂等开放世界
parlament_search_business✅—✅✅
parlament_get_business✅—✅✅
parlament_search_members✅—✅✅
parlament_get_votes✅—✅✅
parlament_get_sessions✅—✅✅
parlament_search_transcripts✅—✅✅
parlament_get_transcript✅—✅✅

📈 可观测性

结构化 JSON 日志会写入 stderr(stdout 保留给 stdio 协议使用)。OpenTelemetry 跟踪会包装每次工具调用,并自动检测发出的 HTTP 请求;设置 OTEL_EXPORTER_OTLP_ENDPOINT(并启用 otel-export extra)即可发送跟踪数据。完整的安全态势(Lethal-Trifecta 评估、出站流量允许列表、网关加固)请参阅 docs/security.md。


🛡️ 安全与限制

方面详情
访问权限只读(readOnlyHint: true)——服务无法修改或删除任何数据
个人数据根据法律(BGÖ),议会事务属于公开记录。不会访问或存储私人数据。
速率限制内置每次查询上限:最多 100 条结果(议会事务/议员)、50 条(投票)、30 条(会议记录搜索)、10 条(会议)。会议记录全文按次调用设有上限,并采用分页方式——不会意外拉取整场会议的内容。
超时每次元数据调用 20 秒;读取会议记录 45 秒(逐字搜索开销较大)
身份验证无需 API 密钥——Curia Vista 可公开访问
数据来源瑞士联邦政府官方数据(Schweizerische Parlamentsdienste)
服务条款受 ws.parlament.ch 的服务条款约束——Schweizerische Parlamentsdienste

已知限制

通用

  • OData substringof() 筛选器对某些字段区分大小写。
  • 对于非常近期的会话,API 中的会话名称可能为 null——请使用会话 ID。

记录稿(Amtliches Bulletin) — 已于 2026-07-19 在线验证:

  • 时间覆盖范围:仅从 1999-12-06 开始。 结构化的 Transcript 实体可追溯至 1999 年 12 月。1891–1999 年的辩论仅存在于扫描版档案文件中(Bundesarchiv / Amtsdruckschriften),未接入此处(OCR 不在范围内)。日期范围完全早于覆盖范围的查询会返回说明性错误,而非空结果。
  • 源数据中没有页码。 API 不包含页码或栏号字段,因此无法生成经典的 AB <year> N <page> 格式。我们提供稳定、可验证的替代格式——AB <year> <N|S>, <date>, <speaker>——以及权威的 source_url(SubjectId)和 transcript_id。这是有据可查且坦诚的权衡,并非遗漏。
  • 语言行为(重要)。 Language 表示的是版本,而非发言语言。工具筛选 Language eq 'DE' 仅用于去重,将三个字节完全相同的版本(DE/FR/IT)缩减为一份。每篇发言均以其原始措辞返回;法语或意大利语发言不会被隐藏,其实际语言会在 language 字段中标明(de/fr/it)。响应通过 language_note 说明了这一点。
  • 截断会明确标示,绝不静默处理。 搜索会返回较短的摘录(snippet,约 320 个字符),并附带 is_excerpt、total_length_chars 以及获取全文的提示。parlament_get_transcript 会将输出限制在 max_chars;发生截断时,会设置 is_excerpt=True,并返回可用于继续获取的 next_offset。
  • 仅提供逐字原文,绝不提供摘要。 措辞本身就是产品;工具绝不会用摘要替代实际文本。
  • 延迟: 将自由文本 keyword 与 speaker_name 结合使用是最慢的路径(约 40 秒)。添加 session_id、business_number 或日期范围,可将读取时间控制在约 1–2 秒。

🧪 测试

pip install -e ".[dev]"

# Unit + mocked integration tests (no network), as run in CI:
PYTHONPATH=src pytest tests/ -m "not live"

# Include live tests against the real ws.parlament.ch API:
PYTHONPATH=src pytest tests/ -m live

HTTP 请求使用 respx 模拟;依赖网络的测试标记为 @pytest.mark.live,并通过 -m "not live" 从 CI 中排除。工具定义固定在 tool-hashes.json 中(python -m parlament_mcp.tool_hashes --check)。


贡献

请参阅 CONTRIBUTING.md。


安全

安全政策和安全态势(漏洞报告、Lethal-Trifecta 评估、已接受的风险)请参阅 SECURITY.md。


许可证

MIT © Hayal Oezkan — 请参阅 LICENSE


作者

Hayal Oezkan · github.com/malkreide

安装

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

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

评论

支持 Markdown

第一次接触 MCP?

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

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