内容
# OpenHammer API
Warhammer 40,000 单位数据的 REST API — 同时也作为 **MCP 服务器**,Claude(或任何 MCP 客户端)可以直接查询,而无需您手动进行 HTTP 调用。版本命名空间 — 目前提供第 10 版(35 个派系中的 1,380 个单位)和第 11 版(35 个派系中的 1,368 个单位)。
**在线 API**:https://openhammer-api-production.up.railway.app
**交互式文档**:https://openhammer-api-production.up.railway.app/docs
**在线 MCP 服务器**:https://openhammer-mcp-production.up.railway.app/mcp
## 目录
- [用法](#用法)
- [快速入门(本地)](#快速入门本地)
- [测试](#测试)
- [MCP 服务器](#mcp-服务器)
- [API 概述](#api-概述)
- [数据覆盖](#数据覆盖)
- [API 端点](#api-端点)
- [JSON 结构](#json-结构)
---
## 用法
所有端点都按版本命名:`/v1/{edition}/resource`。根端点列出了所有可用的版本。
API 在 **https://openhammer-api-production.up.railway.app**
### Python
```python
import requests
BASE = 'https://openhammer-api-production.up.railway.app'
edition = '10e'
# 获取所有派系
factions = requests.get(f'{BASE}/v1/{edition}/factions').json()
# 搜索 Space Marine 单位
units = requests.get(f'{BASE}/v1/{edition}/units?name=Marine&limit=10').json()
# 获取一个随机单位
random_unit = requests.get(f'{BASE}/v1/{edition}/units/random').json()
```
### JavaScript
```javascript
const BASE = 'https://openhammer-api-production.up.railway.app';
const edition = '10e';
// 获取 API 统计信息
const stats = await fetch(`${BASE}/v1/${edition}/stats`).then(r => r.json());
// 搜索 Necrons 单位
const units = await fetch(`${BASE}/v1/${edition}/units?faction=Necrons`).then(r => r.json());
```
### curl
```bash
BASE="https://openhammer-api-production.up.railway.app"
EDITION="10e"
# 获取所有派系
curl "$BASE/v1/$EDITION/factions"
# 搜索 Terminator 单位
curl "$BASE/v1/$EDITION/units?name=Terminator"
# 获取派系详情
curl "$BASE/v1/$EDITION/factions/Necrons/details"
```
### 交互式测试
访问 **https://openhammer-api-production.up.railway.app/docs**:
- 浏览所有 29 个端点
- 直接在浏览器中尝试请求
- 查看示例响应
- 查看请求/响应模式
---
## 快速入门(本地)
**使用 Python:**
```bash
git clone https://github.com/EshanPrakash/openhammer-api.git
cd openhammer-api
pip install -r requirements.txt
uvicorn api.main:app --reload
```
**使用 Docker:**
```bash
git clone https://github.com/EshanPrakash/openhammer-api.git
cd openhammer-api
docker build -t openhammer-api .
docker run -p 8000:8000 openhammer-api
```
访问 http://localhost:8000/docs 获取交互式文档。
---
## 测试
```bash
pip install -r requirements-dev.txt
pytest
```
测试完全在进程中运行,针对两个版本(无需实时服务器或网络访问),并覆盖搜索/过滤/排序行为、分页、错误情况以及所有 29 个端点上的版本一致性。
---
## MCP 服务器
`api/mcp_server.py` 向 MCP 工具公开相同的单位/派系/武器数据,因此 MCP 客户端(Claude Code、Claude Desktop、claude.ai)可以直接查询,而无需进行手动 HTTP 调用。工具直接调用进程内数据存储,而不是 REST API。
### 连接到托管服务器
MCP 服务器在线于 **https://openhammer-mcp-production.up.railway.app/mcp** — 无需安装。
```bash
claude mcp add --transport http openhammer https://openhammer-mcp-production.up.railway.app/mcp
```
Claude Desktop 和 claude.ai 支持相同的 URL 作为 HTTP/Streamable HTTP 连接器。这为您提供了 9 个工具:`list_editions`、`list_factions`、`search_units`、`get_unit`、`compare_units`、`random_unit`、`faction_details`、`search_weapons`、`search_abilities_or_rules`。
### 自己运行
其依赖项单独锁定在 `requirements-mcp.txt` 中,因为 `mcp` 需要比 `requirements.txt` 中固定的 `fastapi==0.104.1` 更新的 starlette/anyio 版本。
**使用 Python:**
```bash
python3 -m venv venv-mcp
source venv-mcp/bin/activate
pip install -r requirements-mcp.txt
python -m api.mcp_server
```
**使用 Docker:**
```bash
docker build -f Dockerfile.mcp -t openhammer-mcp .
docker run -p 8001:8001 openhammer-mcp
```
两者都在端口 8001(或 `$PORT`,如果设置)上提供 Streamable HTTP 服务,位于 `/mcp`。
### 测试
```bash
source venv-mcp/bin/activate
pip install -r requirements-mcp-dev.txt
pytest -c pytest-mcp.ini
```
完全在进程中运行,针对 FastMCP 实例通过内存客户端/服务器会话(无需实时服务器,无需网络),并覆盖两个版本上的所有 9 个工具。保留为单独的测试套件,从 `pytest`(运行 `tests/`)中分离出来,因为它需要 `mcp` 包。
---
## API 概述
### 您可以使用
OpenHammer API 提供 **29 个端点** 用于访问 Warhammer 40K 单位数据:
- **搜索和过滤**:按名称、派系、成本、关键词、能力查找单位
- **派系分析**:获取任何派系的详细统计数据、细分和洞察力
- **武器查找**:搜索武器并查找哪些单位拥有它们
- **批量操作**:查找多个单位、导出数据、聚合统计数据
- **关键词/能力搜索**:查找具有特定关键词或特殊规则的所有单位
### 性能
- **启动时间**:启动时约 1 秒
- **内存使用**:每个版本约 10-15MB(所有单位都加载到内存中)
- **响应时间**:对于大多数查询 <10ms
### 功能
- **MCP 服务器** — 通过 Claude 查询数据,而不是编写 HTTP 调用(参见 [MCP 服务器](#mcp-服务器))
- 版本命名空间 URL — 无需任何代码更改即可添加新版本
- 通过 GitHub Actions 自动进行每月数据同步(拉取最新的 BSData/wh40k-10e 和 BSData/wh40k-11e)
- 内存存储,响应时间 <10ms
- HTTP 缓存(1 小时)
- 速率限制(每 IP 100 请求/分钟)
- `/docs` 处的交互式 Swagger 文档
- 跨 11+ 个参数进行排序和过滤
- 批量操作和派系分析
- 启用 CORS
- Docker 化以便于部署
---
## 数据覆盖
**当前版本:** `10e`、`11e`
两个版本都涵盖了相同的 35 个派系:
- **帝国**: 19 个派系
- **混沌**: 7 个派系
- **异族**: 7 个派系
- **未对齐**: 2 个群体
### 派系列表
#### 帝国 (19 个派系)
Adepta Sororitas, Adeptus Custodes, Adeptus Mechanicus, Agents of the Imperium, Astra Militarum, Black Templars, Blood Angels, Dark Angels, Deathwatch, Grey Knights, Imperial Fists, Imperial Knights, Iron Hands, Raven Guard, Salamanders, Space Marines, Space Wolves, Ultramarines, White Scars
#### 混沌 (7 个派系)
Daemons, Chaos Knights, Chaos Space Marines, Death Guard, Emperor's Children, Thousand Sons, World Eaters
#### 异族 (7 个派系)
Aeldari, Genestealer Cults, Leagues of Votann, Necrons, Orks, Tyranids, T'au Empire
#### 未对齐 (2 个群体)
Titans, Unaligned Forces
### 版本总数
| 版本 | 单位 | 派系 |
|---------|-------|----------|
| `10e` (第 10 版) | 1,380 | 35 |
| `11e` (第 11 版) | 1,368 | 35 |
---
## API 端点
### 快速参考
**根目录**
- `GET /` - API 信息和可用版本列表
**统计信息和信息**
- `GET /v1/{edition}/stats` - 总单位、派系、类型分布
**派系** (5 个端点)
- `GET /v1/{edition}/factions` - 列出所有派系
- `GET /v1/{edition}/factions/{faction_name}/units` - 获取派系单位
- `GET /v1/{edition}/factions/{faction_name}/details` - 全面的派系详情
- `GET /v1/{edition}/factions/{faction_name}/stats` - 统计分布
- `GET /v1/{edition}/factions/{faction_name}/keywords` - 派系关键词及其计数
**单位** (8 个端点)
- `GET /v1/{edition}/units` - 搜索/过滤单位(11 个查询参数)
- `GET /v1/{edition}/units/{unit_id}` - 按 ID 获取特定单位
- `GET /v1/{edition}/units/search/name/{name}` - 按名称搜索
- `GET /v1/{edition}/units/random` - 随机单位
- `GET /v1/{edition}/units/expensive` - 按积分计算最昂贵的单位
- `GET /v1/{edition}/units/cheap` - 按积分计算最便宜的单位
- `GET /v1/{edition}/units/count` - 统计匹配单位,无需返回数据
- `GET /v1/{edition}/units/compare` - 按 ID 比较多个单位
**武器** (3 个端点)
- `GET /v1/{edition}/weapons/stats` - 武器统计数据
- `GET /v1/{edition}/weapons/list` - 列出所有武器名称
- `GET /v1/{edition}/weapons/search/{name}` - 搜索武器,查找拥有它们的单位
**能力和关键词** (5 个端点)
- `GET /v1/{edition}/abilities/search/{term}` - 按名称或描述搜索能力
- `GET /v1/{edition}/abilities/keywords/list` - 列出所有关键词
- `GET /v1/{edition}/abilities/keywords/search/{keyword}` - 按关键词查找单位
- `GET /v1/{edition}/abilities/special-rules/list` - 列出所有特殊规则
- `GET /v1/{edition}/abilities/special-rules/search/{rule}` - 按特殊规则查找单位
**批量操作** (6 个端点)
- `GET /v1/{edition}/bulk/units/by-ids` - 按 ID 批量查找
- `GET /v1/{edition}/bulk/units/by-names` - 按名称批量查找
- `GET /v1/{edition}/bulk/stats/by-keyword` - 按关键词聚合统计数据
- `GET /v1/{edition}/bulk/stats/by-faction-type` - 按派系类型聚合统计数据
- `GET /v1/{edition}/bulk/stats/by-faction` - 按派系聚合统计数据
- `GET /v1/{edition}/bulk/export/all-units-summary` - 导出所有单位摘要
### 示例查询
```bash
BASE="https://openhammer-api-production.up.railway.app"
EDITION="10e"
# 获取所有混沌单位,带有坚韧不拔的单位
curl "$BASE/v1/$EDITION/units?faction_type=Chaos&has_invuln=true"
# 获取最昂贵的单位
curl "$BASE/v1/$EDITION/units?sort_by=-points&limit=10"
# 获取最便宜的帝国单位
curl "$BASE/v1/$EDITION/units?faction_type=Imperium&sort_by=points&limit=20"
# 搜索 bolt 武器
curl "$BASE/v1/$EDITION/weapons/search/bolter"
# 获取 Necrons 派系详情
curl "$BASE/v1/$EDITION/factions/Necrons/details"
# 获取所有步兵单位的统计数据
curl "$BASE/v1/$EDITION/bulk/stats/by-keyword?keyword=Infantry"
# 获取综合的帝国统计数据
curl "$BASE/v1/$EDITION/bulk/stats/by-faction-type?faction_type=Imperium"
```
### 主搜索端点
`GET /v1/{edition}/units` 支持 11 个过滤和排序参数:
| 参数 | 类型 | 描述 | 示例 |
|-----------|------|-------------|---------|
| `limit` | int | 最大结果数(1-500,默认:100) | `limit=50` |
| `offset` | int | 跳过结果数(分页) | `offset=100` |
| `name` | string | 按名称过滤(部分匹配) | `name=guard` |
| `faction` | string | 按派系过滤 | `faction=Necrons` |
| `faction_type` | string | 按类型过滤 | `faction_type=Imperium` |
| `type` | string | 按单位/模型过滤 | `type=unit` |
| `has_invuln` | bool | 是否具有坚韧不拔 | `has_invuln=true` |
| `has_transport` | bool | 是否为运输单位 | `has_transport=true` |
| `keyword` | string | 按关键词过滤 | `keyword=Infantry` |
| `points_min` | int | 最小积分成本 | `points_min=100` |
| `points_max` | int | 最大积分成本 | `points_max=200` |
| `sort_by` | string | 排序字段(名称/积分/派系) | `sort_by=points` 或 `sort_by=-points` |
**排序**:`sort_by=field` 表示升序,`sort_by=-field` 表示降序。
---
## JSON 结构
数据存储在 `data/json/{edition}/` 中,每个派系一个 JSON 文件:
- `Imperium_-_[Faction_Name].json`
- `Chaos_-_[Faction_Name].json`
- `Xenos_-_[Faction_Name].json`
- `Unaligned_-_[Faction_Name].json`
添加新版本只需添加一个新子目录 — API 在启动时自动拾取。
### 单位对象模式
```json
{
"name": "string",
"id": "string",
"type": "string",
"faction": "string",
"faction_type": "string",
"points": {
"base": number,
"variants": [{ "name": "string", "cost": number }]
},
"composition": {
"min_models": number,
"max_models": number
},
"stats": {
"M": "string",
"T": "string",
"SV": "string",
"W": "string",
"LD": "string",
"OC": "string"
},
"invuln_save": "string|null",
"transport": "string|null",
"weapons": {
"ranged": [
{
"name": "string",
"Range": "string",
"A": "string",
"BS": "string",
"S": "string",
"AP": "string",
"D": "string",
"Keywords": "string|null"
}
],
"melee": [
{
"name": "string",
"Range": "Melee",
"A": "string",
"WS": "string",
"S": "string",
"AP": "string",
"D": "string",
"Keywords": "string|null"
}
]
},
"abilities": [{ "name": "string", "description": "string" }],
"special_rules": ["string"],
"keywords": ["string"]
}
```
---
## 许可证
MIT 许可证 - 请参阅 LICENSE 文件。
所有 Warhammer 40,000 内容均为 Games Workshop 的财产。
单位数据来源于 [BSData/wh40k-10e](https://github.com/BSData/wh40k-10e) 和 [BSData/wh40k-11e](https://github.com/BSData/wh40k-11e)。