内容
# 🏛️ 公开数据观察 - 游说观察 MCP 服务器
[](https://github.com/malkreide/lobbywatch-mcp/actions/workflows/ci.yml)
[](https://badge.fury.io/py/lobbywatch-mcp)
[](https://www.python.org)
[](LICENSE)
[](https://creativecommons.org/licenses/by-sa/4.0/)
[](https://github.com/malkreide)
> 一个 MCP 服务器,连接 AI 模型到 **Lobbywatch.ch**,瑞士联邦议会最大的游说数据库 —— 利益冲突、游说团体、访问权限和透明度评分。
[🇩🇪 德语版本](README.de.md)
> **瑞士公共数据 MCP 产品组合的一部分** —— 连接 AI 模型到瑞士公共数据源。
---
## 🎯 锚点演示查询
> *"哪些 WBK-N 成员与教育出版社或私人教育提供商有利益冲突,他们的透明度评估如何?"*
哪些国民议会教育委员会成员申报了与教育出版社或私人教育提供商的利益冲突,他们的补偿透明度评分如何?
[→ 更多示例按受众分类 →](EXAMPLES.md)
---
## 概述
Lobbywatch.ch 维护着瑞士联邦议会议员及其与游说组织的最大公共数据库:245 名议员,约 7,800 个利益冲突(已申报的授权),139 个游说团体,368 个访问权限持有者,每周更新,许可证 CC BY-SA 4.0。
`lobbywatch-mcp` 通过模型上下文协议将这些数据公开给大型语言模型。它旨在与 [`parlament-mcp`](https://github.com/malkreide/parlament-mcp) (官方瑞士议会 Curia Vista 数据)一起使用:这对组合使得在一次对话中可以询问议员的官方行为和他们的关联对象。
## 功能
- **先转储后 API 的架构。** 每周 JSON 转储是主要来源(稳定,在生产中验证);仅在返回可靠数据时使用实时 `dataIF` REST API(游说团体,搜索)。
- **七种第一阶段工具** - 议员查找、利益冲突列表、行业搜索、游说团体获取、排名、透明度配额、缓存控制。
- **CC BY-SA 4.0 署名** 通过 Pydantic 信封嵌入每个响应中。
- **双重传输** - `stdio` 用于 Claude Desktop,`streamable-http` / `sse` 用于云部署。
- **模糊名称匹配** 通过 rapidfuzz 实现自然 LLM 输入,如 "Jositsch" 或 "Wehrli"。
- **无需身份验证** (第一阶段 - 无身份验证优先)。
## 架构
```
┌─────────────────────────────┐
LLM 客户端 │ Lobbywatch 客户端 │
(Claude Desktop, │ │
Inspector, …) │ ┌───────────────────┐ │
│ │ │ 转储缓存 │ │ cms.lobbywatch.ch
│ MCP │ │ (24 小时 TTL, │ │ ┌──────────────────┐
▼ stdio / │ │ ~80 MB 驻留) ├─────┼─────►│ 每周 JSON │
┌─────────┐ HTTP │ └───────────────────┘ │ │ 导出(~17 MB) │
│ FastMCP │◄────►│ │ └──────────────────┘
│ 服务器 │ │ ┌───────────────────┐ │ ┌──────────────────┐
└─────────┘ │ │ dataIF REST ├─────┼─────►│ /interface/v1/ │
│ │ (实时备用) │ │ │ json/… │
│ └───────────────────┘ │ └──────────────────┘
└─────────────────────────────┘
```
出站 HTTP 请求通过单个 `httpx.AsyncClient` 运行,`follow_redirects=False`,一个 SSRF 守护进程阻止 RFC1918 / 本地链接 / 元数据 IP,以及一个 httpx 事件钩子,在每个请求上重新解析。转储路径是议员查询的主要真实来源;`dataIF` 仅用于游说团体查找和搜索端点。
## 先决条件
- Python 3.11 或更新版本
- 可以下载每周 Lobbywatch JSON 导出文件(~17 MB 压缩)
## 安装
从 PyPI(首次发布后):
```bash
pip install lobbywatch-mcp
```
从源代码:
```bash
git clone https://github.com/malkreide/lobbywatch-mcp.git
cd lobbywatch-mcp
pip install -e ".[dev]"
```
## 用法
### 独立运行
```bash
lobbywatch-mcp
```
这会在 `stdio` 模式下启动服务器。对于 HTTP:
```bash
LOBBYWATCH_MCP_TRANSPORT=http LOBBYWATCH_MCP_PORT=8000 lobbywatch-mcp
```
### 容器
一个加固的多阶段 `Dockerfile` 与存储库一起提供(非 root,read-only-rootfs 兼容)。参见 [`docs/deployment.md`](docs/deployment.md)
和 [`deploy/docker-compose.example.yml`](deploy/docker-compose.example.yml)
获取资源限制、粘性负载均衡指导和出口加固。
```bash
docker build -t lobbywatch-mcp:0.2.0 .
docker run --rm -p 127.0.0.1:8000:8000 lobbywatch-mcp:0.2.0
```
### Claude Desktop
添加到您的 `claude_desktop_config.json`:
```json
{
"mcpServers": {
"lobbywatch": {
"command": "uvx",
"args": ["lobbywatch-mcp"]
}
}
}
```
完整示例在 [`claude_desktop_config.json`](claude_desktop_config.json) 中提供。
### 示例查询
连接后,尝试以下提示:
- *"给我按利益冲突数量排名前 10 位的 SP 党议员。*"
- *"哪些 WBK-N 成员在出版或教育行业有授权?*"
- *"查找游说团体 'economiesuisse' 并列出其关联议员。*"
- *"FK-N(金融委员会)的补偿透明度评分分布如何?*"
## 工具
所有工具名称都使用 `lobbywatch_` 命名空间前缀(自 0.2.0 起)以避免与 sibling 产品组合服务器发生冲突。
| 工具 | 目的 | 来源 |
|---|---|---|
| `lobbywatch_get_parlamentarier(name_or_id)` | 完整个人资料 + 所有利益冲突 | 转储 |
| `lobbywatch_list_interessenbindungen(name_or_id, nur_hauptberuflich, nur_aktiv)` | 过滤后的授权列表 | 转储 |
| `lobbywatch_search_parlamentarier_nach_branche(branche_query, kommission, limit)` | 按行业和委员会交叉过滤 | 转储 |
| `lobbywatch_get_lobbygruppe(name_or_id)` | 游说团体与关联议员和组织 | 实时 dataIF |
| `lobbywatch_get_ranking(kriterium, kommission, partei, limit)` | 按条件排名前 N 名 | 转储 |
| `lobbywatch_get_transparenzquote(kommission)` | 补偿透明度标签分布 | 转储 |
| `lobbywatch_refresh_dump()` / `lobbywatch_dump_status()` | 缓存控制 | 转储 |
## 配置
所有行为均通过环境变量控制:
| 变量 | 默认值 | 目的 |
|---|---|---|
| `LOBBYWATCH_MCP_TRANSPORT` | `stdio` | 传输(`stdio`、`http`、`sse`) |
| `LOBBYWATCH_MCP_HOST` | `127.0.0.1` | HTTP 绑定主机(仅在身份验证网关后设置为 `0.0.0.0`) |
| `LOBBYWATCH_MCP_PORT` | `8000` | HTTP 绑定端口 |
| `LOBBYWATCH_MCP_CACHE_DIR` | `~/.cache/lobbywatch-mcp` | 转储缓存位置 |
| `LOBBYWATCH_MCP_CACHE_TTL` | `86400`(24 小时) | 缓存生存时间(秒) |
| `LOBBYWATCH_MCP_HTTP_TIMEOUT` | `60` | HTTP 超时(秒) |
| `LOBBYWATCH_MCP_CORS_ORIGINS` | _(未设置)_ | HTTP/SSE 的逗号分隔源允许列表;设置后,向浏览器公开 `Mcp-Session-Id` |
| `LOBBYWATCH_MCP_LOG_FORMAT` | `text` | `text`(标准库格式化器)或 `json`(通过 structlog 结构化) |
| `LOBBYWATCH_MCP_LOG_LEVEL` | `INFO` | `DEBUG` / `INFO` / `WARNING` / `ERROR` |
| `LOBBYWATCH_MCP_OTEL_ENABLED` | `0` | 设置为 `1` 以启用 OpenTelemetry 跟踪(需要 `pip install 'lobbywatch-mcp[obs]'`) |
| `LOBBYWATCH_MCP_OTEL_ENDPOINT` | _(未设置)_ | OTLP/HTTP 收集器端点(例如 `http://localhost:4318/v1/traces`) |
## 项目结构
```
lobbywatch-mcp/
├── src/lobbywatch_mcp/
│ ├── __init__.py
│ ├── __main__.py # CLI + 传输选择
│ ├── config.py # URL、缓存路径、署名
│ ├── client.py # 转储下载 + dataIF 客户端
│ ├── models.py # Pydantic v2 响应信封
│ └── server.py # FastMCP 工具注册
├── tests/
│ ├── conftest.py # 固定装置议员
│ ├── test_client.py # Respx 模拟单元测试
│ ├── test_server.py # 工具集成测试
│ └── test_live.py # @pytest.mark.live — 排除在 CI 之外
├── .github/workflows/
│ ├── ci.yml # 测试矩阵 + ruff
│ └── publish.yml # PyPI OIDC 受信任发布者
├── claude_desktop_config.json
├── pyproject.toml
└── ...
```
## 数据许可和署名
**代码** 在 MIT 许可下发布。
**数据** 由 Lobbywatch.ch 提供,并根据 [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) 许可。每个响应信封都包含署名字符串。下游用户必须:
1. 将 Lobbywatch.ch 作为数据源注明。
2. 在相同的 CC BY-SA 4.0 条款下共享派生数据集。
3. 了解 Lobbywatch 是一个 **社区研究的数据库** — 不是官方注册。它对透明度研究具有权威性,但不应与联邦议会的官方声明混淆。
## 已知限制
- 上游 `/table/parlamentarier/...` `dataIF` REST 端点当前返回空结果集。服务器通过使用每周 JSON 转储来解决这个问题。
- `zutrittsberechtigungen` (访问权限)未填充在此使用的“基本”转储变体中。未来版本将添加一个使用非基本转储的专用工具。
## 贡献
参见 [CONTRIBUTING.md](CONTRIBUTING.md)。
## 安全
参见 [SECURITY.md](SECURITY.md) 获取安全态势、接受风险的决策以及如何报告漏洞。
## 更新日志
参见 [CHANGELOG.md](CHANGELOG.md)。
## 许可
MIT 许可 - 参见 [LICENSE](LICENSE)。 数据 CC BY-SA 4.0 - 参见 [LICENSE](LICENSE) § 数据通知。
## 作者
**malkreide** · [GitHub](https://github.com/malkreide)
---
*瑞士公共数据 MCP 产品组合的一部分。*
<!-- mcp-name: io.github.malkreide/lobbywatch-mcp -->
<!-- BEGIN GENERATED: install -->
## 安装
通过 [`uv`](https://docs.astral.sh/uv/) 的 `uvx` 运行 - 无需克隆或手动安装。 将以下内容添加到您的 MCP 客户端配置(Claude Desktop 的 `mcpServers`,Cursor 和 Windsurf;VS Code 在 `.vscode/mcp.json` 中使用顶级 `servers` 键):
```json
{
"mcpServers": {
"lobbywatch-mcp": {
"command": "uvx",
"args": [
"lobbywatch-mcp"
]
}
}
}
```
<!-- END GENERATED: install -->