内容
# 🇫🇮 芬兰开放代理
芬兰开放数据和公共服务API的代理工具包。它是开源的、便携的、且对代理友好 —— 一个代码库,提供三种使用方式:
1. **人类CLI** — `芬兰开放代理 调用 <工具> 键=值 ...` 从终端运行任何工具。
2. **AI工具的JSON输出** — 添加 `--json`(或 `response_format=json`)以获取机器可读的输出。
3. **代理的MCP服务器** — `芬兰服务MCP` 向Claude Desktop、Claude Code或任何MCP客户端公开每个工具;且**技能**(Markdown剧本)教导代理在没有运行服务器时使用纯`curl`路径。
每个工具都自动以这三种模式提供。 大多数服务**无需API密钥** —— 这里的一切都是公开的、开放的数据。
## 领域(v0.10 — 40个工具)
完整的、始终最新的工具参考: [`文档/工具.md`](./docs/TOOLS.md) (自动生成)。
| 领域 | 来源 | 工具 |
| --- | --- | --- |
| ⚡️ 能源 | porssisahko.net, spot-hinta.fi, Fingrid | 现货价格,现在的价格,最便宜的小时,Fingrid数据 |
| 🌦️ 天气 | FMI, HSY, STUK | 预报,观测,空气质量,海平面和波浪,太阳辐射,国家辐射(STUK),闪电 |
| 🚆 交通 | Fintraffic Digitraffic, Digitransit | 车站和实时列车,交通消息,天气摄像头,道路天气状况,道路维护,船舶(AIS),港口调用,行程路由 |
| 🏢 注册 | PRH/YTJ, avoindata.fi, 统计芬兰, Suomi.fi | 公司搜索和详情,开放数据集搜索和详情,StatFin浏览和数据,公共服务搜索和详情 |
| 🏛️ 公民 | 议会(芬兰议会) | 议员搜索,席位组成,最近的投票,投票明细 |
| 🎭 文化 | Finna | 文化遗产搜索和记录详情 |
| 🗺️ 地点 | 国家土地调查局(MML) | 地理编码 |
| 📚 图书馆 | Kirjastot.fi | 公共图书馆搜索和开放时间 |
| 🩺 健康 | THL Sotkanet | 健康和福利指标搜索和值 |
| 🎫 事件 | LinkedEvents | 搜索芬兰的事件(音乐会,展览等) |
三个工具需要一个免费的密钥(参见配置):`transport_plan_route`(Digitransit),`energy_fingrid_latest`(Fingrid),和`places_geocode`(国家土地调查局)。 其他一切都是无密钥的。
### 服务和数据源
本仓库集成的每个芬兰服务,它提供的内容,以及是否需要密钥:
| 服务(提供者) | 提供 | 密钥 | 领域 |
| --- | --- | --- | --- |
| porssisahko.net / spot-hinta.fi | 小时电力现货价格(Nord Pool FI),c/kWh 含增值税 | 否 | 能源 |
| Fingrid开放数据 | 电网负载,生产组合,风/核/水力时间序列 | 免费密钥 | 能源 |
| FMI — 芬兰气象研究所 | 预报,站点观测,海平面和波浪 | 否 | 天气 |
| HSY(通过FMI `urban::`) | 赫尔辛基地区空气质量 | 否 | 天气 |
| STUK(通过FMI) | 国家外部(背景)辐射剂量率 | 否 | 天气 |
| Fintraffic Digitraffic — 铁路 | VR实时列车,时刻表,车站元数据 | 否 | 交通 |
| Fintraffic Digitraffic — 道路 | 交通消息,天气摄像头,道路天气站点 | 否 | 交通 |
| Fintraffic Digitraffic — 海事 | AIS实时船舶位置,港口调用 | 否 | 交通 |
| Digitransit | 全国公共交通行程规划 + 地理编码 | 免费密钥 | 交通 |
| PRH / YTJ | 商业登记 — 公司,商业ID(Y-tunnus) | 否 | 注册 |
| avoindata.fi(DVV) | 国家开放数据目录(数据集发现) | 否 | 注册 |
| 统计芬兰(Tilastokeskus) | StatFin统计数据库(PxWeb) | 否 | 注册 |
| Suomi.fi PTV | 芬兰服务目录 — 公共服务和渠道 | 否 | 注册 |
| 议会(芬兰议会) | 议会 — 议员,席位组成,投票和明细 | 否 | 公民 |
| Finna(国家图书馆) | 图书馆,博物馆和档案搜索 | 否 | 文化 |
| Maanmittauslaitos(NLS) | 地理编码 — 地点/地址 → 坐标 | 免费密钥 | 地点 |
| Kirjastot.fi | 公共图书馆 — 目录和开放时间 | 否 | 图书馆 |
| THL Sotkanet | 按地区/年份划分的健康和福利统计指标 | 否 | 健康 |
| LinkedEvents | 芬兰的事件(音乐会,展览等) | 否 | 事件 |
所有数据都是公开和开放的;每个来源都有自己的许可(大多是CC BY 4.0 — 注明出处)。 查看 [工具参考](./docs/TOOLS.md) 以获取每个工具的构建信息。
查看 [`PLAN.md`](./PLAN.md) 以获取架构,[`AGENTS.md`](./AGENTS.md) 以获取代码映射, 以及 [`skills/`](./skills) 以获取每个领域的CLI剧本。
## 快速开始
需要Python 3.11+ 和 [uv](https://docs.astral.sh/uv/)。 无需克隆 — `uvx` 直接从GitHub运行(像 `npx` 一样):
```bash
# 列出所有工具
uvx --from git+https://github.com/mikahanninen/finnish-open-agent finnish-open-agent list
# 1) 人类CLI
uvx --from git+https://github.com/mikahanninen/finnish-open-agent finnish-open-agent \
call energy_cheapest_hours count=3
# 2) AI/脚本的JSON输出 — 添加 --json
uvx --from git+https://github.com/mikahanninen/finnish-open-agent finnish-open-agent \
call weather_get_forecast place=Helsinki hours=6 --json
```
提示:为其设置别名 — `alias foa='uvx --from git+https://github.com/mikahanninen/finnish-open-agent finnish-open-agent'` — 然后直接使用 `foa list`,`foa call library_search query=Oodi`。
### 开发(克隆)
```bash
git clone https://github.com/mikahanninen/finnish-open-agent.git
cd finnish-open-agent
uv venv && uv pip install -e ".[dev]"
uv run finnish-open-agent list
```
### 从Claude Desktop / Claude Code使用
添加到您的MCP配置(例如 `claude_desktop_config.json`)。 此表单不需要本地路径:
```json
{
"mcpServers": {
"finnish-open-agent": {
"command": "uvx",
"args": [
"--from", "git+https://github.com/mikahanninen/finnish-open-agent",
"finnish-open-agent"
],
"env": { "FOA_APP_ID": "your-name/finnish-open-agent" }
}
}
}
```
如果您克隆了仓库,请将 `uv` 指向它:`"command": "uv"`,`"args": ["--directory", "/path/to/finnish-open-agent", "run", "finnish-open-agent"]`。
然后询问类似的问题:
- “芬兰今晚最便宜的三个小时的电力是什么?”
- “给我罗瓦涅米的12小时天气预报和赫尔辛基的空气质量。”
- “下一班从坦佩雷开往哪里,帮我规划从赫尔辛基到奥塔涅米的路线。”
- “查找公司Supercell及其商业ID。”
- “2025年底芬兰的人口是多少?”(统计芬兰)
- “芬兰议会当前的席位分布是怎样的,绿党的议员是谁?”
- “在芬兰博物馆中查找Tove Jansson的档案照片。”(Finna)
## 配置
所有配置都通过环境变量(参见 [`.env.example`](./.env.example)):
| 变量 | 默认值 | 目的 |
| --- | --- | --- |
| `FOA_APP_ID` | `finnish-open-agent` | 作为 `Digitraffic-User` 头部发送的标识符(Fintraffic要求调用者标识自己) |
| `FOA_HTTP_TIMEOUT` | `30` | 每个请求的超时时间(秒) |
| `FOA_CACHE_TTL` | `120` | 慢速移动元数据的进程内缓存TTL(秒;0禁用) |
| `FINGRID_API_KEY` | — | 来自data.fingrid.fi的免费密钥(仅限`energy_fingrid_latest`) |
| `DIGITRANSIT_API_KEY` | — | 来自portal-api.digitransit.fi的免费密钥(`transport_plan_route`需要) |
| `NLS_API_KEY` | — | 免费的国家土地调查密钥(`places_geocode`需要) |
| `FOA_TRANSPORT` | `stdio` | `stdio`(本地)或 `http`(远程流式HTTP) |
| `FOA_HOST` / `FOA_PORT` | `127.0.0.1` / `8000` | HTTP传输的绑定地址 |
## 🇫🇮 社区收藏
除了仓库自己的工具外,`finnish-open-agent` 还策划了 **其他人** 的芬兰技能,MCP服务器和代理工具的目录。 它是仅限链接的 — 每个项目都由其作者在其自己的许可下拥有;这里不复制任何内容。 浏览 [`ecosystem/CATALOG.md`](./ecosystem/CATALOG.md) (从 [`ecosystem/registry.yaml`](./ecosystem/registry.yaml) 自动生成)。
精选社区条目:
- **[WilmAI](https://github.com/aikarjal/wilmai)** by `aikarjal` ([wilm.ai](https://www.wilm.ai/)) — 一个开源CLI,读取Wilma学校系统(时间表,作业,成绩,出勤...)为干净的JSON,具有AI代理友好模式。
- **[maiklubi](https://github.com/jannemakela/maiklubi)** by Janne Mäkelä — 一个AI友好CLI,用于myc lubi.fi,整合家庭体育俱乐部活动,RSVP,发票和通知从终端或AI代理。
想让您的项目被列出吗? 在注册表中添加一个条目并打开一个PR — 参见 [CONTRIBUTING.md](./CONTRIBUTING.md)。 要重新生成目录和站点的社区表格:
```bash
uv run python scripts/render_catalog.py
uv run python scripts/render_community_table.py
```
## CLI / 技能方法
不喜欢运行服务器? [`skills/finnish-open-data`](./skills/finnish-open-data) 技能文档提供了针对上述每个源的现成 `curl` 配方。 将任意或所有11种技能安装到您的代理中,使用 [`skills` CLI](https://github.com/vercel-labs/skills) (支持Claude Code,Cursor,Codex和70多种其他):
```bash
npx skills add mikahanninen/finnish-open-agent # 所有11种技能
npx skills add mikahanninen/finnish-open-agent -s finnish-weather # 仅一种
npx skills add mikahanninen/finnish-open-agent -s finnish-weather,finnish-transport # 几种
```
以相同的方式删除它们:
```bash
npx skills remove -s finnish-weather # 仅一种
npx skills remove --all # 此CLI安装的所有内容
```
或者,将技能文件夹手动拖入代理的技能目录(例如 `~/.claude/skills/`)。
## 测试和CI
```bash
uv run python -m pytest -m "not live" # 离线单元测试(解析,文档新鲜度)
uv run python -m pytest -m live # 可选的实时烟雾测试,对抗真实API
uv run ruff check src tests scripts
uv run python scripts/render_tools.py # 重新生成docs/TOOLS.md
uv run python scripts/render_catalog.py # 重新生成ecosystem/CATALOG.md
```
GitHub Actions( [.github/workflows/ci.yml](./.github/workflows/ci.yml) )运行lint,离线测试和 **文档新鲜度检查** — PR更改工具或注册表但未重新生成 `docs/TOOLS.md` / `ecosystem/CATALOG.md` 将失败CI,因此生成的markdown永远不会偏离同步。
## 数据源和许可
本项目仅调用 **公共、开放** 接口。 每个源都有自己的条款;大多数是CC BY 4.0,并要求注明出处。 在发布派生数据时,请注明出处(Fintraffic / Digitraffic,芬兰气象研究所,PRH,统计芬兰,avoindata.fi / DVV)。 本仓库使用MIT许可;数据不是。
## 许可
MIT — 参见 [`LICENSE`](./LICENSE)。