模组通 API v1 开发文档
模组通对外提供 RESTful API,允许外部应用程序通过 API 密钥调用 AI 对话功能。API 支持模组兼容性检测、光影推荐、崩溃诊断等全部平台能力。
| 基础 URL | https://aimod.xrstudio.cn/api/v1 |
| 数据格式 | JSON |
| 字符编码 | UTF-8 |
| 认证方式 | Authorization: Bearer mt_xxx |
| CORS | 已开放,浏览器可直接调用 |
获取 API 密钥
三种登录模式,专门适配桌面/移动端 App 场景:
| Action | 行为 | 适用场景 |
|---|---|---|
login | 智能复用:有密钥就复用,没有就自动创建 | App 默认使用 |
login_reuse | 仅复用:绝不创建新密钥 | App 启动时本地已有密钥,验证并取回 |
login_new | 强制新建:总是创建新密钥 | 新设备登录、多应用隔离 |
App 端登录
首次登录(本地无密钥):
POST /api/v1/auth.php
{
"action": "login",
"email": "user@example.com",
"password": "your_password"
}
可选请求头 X-App-Name: ModAnalyzer 自动设置密钥名称。
再次启动(本地有密钥,验证并复用):
POST /api/v1/auth.php
{
"action": "login_reuse",
"email": "user@example.com",
"password": "your_password"
}
返回 reused: true,密钥与之前相同。如果密钥被删则返回 404,提示改用 login。
响应格式
{
"api_key": "mt_a1b2c3d4e5f6...",
"key_name": "ModAnalyzer",
"created_at": "2026-08-07 19:12:03",
"reused": false,
"user": {
"id": 7,
"nickname": "玩家名",
"email": "user@example.com"
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| api_key | string | API 密钥(mt_ 前缀,64 位 hex) |
| key_name | string | 密钥名称 |
| reused | bool | true=复用已有密钥,false=新创建的 |
| user | object | 用户信息 |
Web 端获取
登录模组通 → 用户中心 → API 密钥 → 创建密钥。
App 集成流程
推荐流程
App 启动逻辑
App 启动
├── 本地存储有 api_key?
│ ├── 是 → login_reuse 验证
│ │ ├── 200 成功 → 直接使用
│ │ └── 404 失败 → 提示重新 login
│ └── 否 → 显示登录界面
│ └── login → 获取新密钥 → 持久化保存到本地
Python 集成示例
modtong_client.py
import json, os, requests
BASE = "https://aimod.xrstudio.cn/api/v1"
KEY_FILE = ".modtong_key"
def get_api_key(email, password):
"""登录并获取密钥"""
# 先尝试复用已有密钥
resp = requests.post(f"{BASE}/auth.php", json={
"action": "login_reuse",
"email": email, "password": password,
})
if resp.status_code == 200:
data = resp.json()
save_key(data["api_key"])
return data["api_key"]
# 没有密钥,创建新的
resp = requests.post(f"{BASE}/auth.php", json={
"action": "login",
"email": email, "password": password,
}, headers={"X-App-Name": "ModAnalyzer"})
if resp.status_code == 200:
data = resp.json()
save_key(data["api_key"])
return data["api_key"]
raise Exception(resp.json().get("error", "登录失败"))
def save_key(key):
with open(KEY_FILE, "w") as f:
f.write(key)
def load_key():
if os.path.exists(KEY_FILE):
with open(KEY_FILE) as f:
return f.read().strip()
return None
def check_key(key):
"""验证密钥有效性"""
resp = requests.get(f"{BASE}/auth.php",
headers={"Authorization": f"Bearer {key}"})
return resp.status_code == 200
def mod_analysis(key, mod_list):
"""调用模组分析"""
resp = requests.post(f"{BASE}/chat.php", json={
"message": f"检测以下模组的兼容性:\n{mod_list}"
}, headers={"Authorization": f"Bearer {key}"})
return resp.json()
# ── App 主流程 ──
key = load_key()
if key and check_key(key):
print("自动登录成功")
else:
email = input("邮箱: ")
password = input("密码: ")
key = get_api_key(email, password)
print("登录成功")
# 调用模组分析
result = mod_analysis(key,
"Sodium 0.5.8\nIris 1.7.2\nCreate 0.5.1\nJEI 15.3")
print(result["reply"])
验证 API 密钥
GET /api/v1/auth.php
Authorization: Bearer mt_xxx
成功 (200):{"valid": true, "user": {"id": 1, "nickname": "玩家名", "email": "..."}}
失败 (401):{"valid": false, "error": "无效的 API 密钥"}
AI 对话
核心接口,调用模组通 AI。
POST /api/v1/chat.php
Authorization: Bearer mt_xxx
Content-Type: application/json
请求体
{
"message": "帮我检测 Sodium 和 Iris 的兼容性",
"history": [],
"conversation_id": 0,
"files": []
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| message | string | 是 | 用户问题 / 模组列表 / 崩溃日志 |
| history | array | 否 | 历史对话,格式 [{"role":"user","content":"..."}] |
| conversation_id | int | 否 | 继续已有对话时传入 ID,0 或省略则创建新对话 |
| files | array | 否 | 附件 [{"name":"文件名","content":"内容"}] |
成功响应
{
"reply": "检测完成。Sodium 与 Iris **完全兼容**...",
"cards": [],
"conversation_id": 42
}
| 字段 | 类型 | 说明 |
|---|---|---|
| reply | string | AI 回复文本(Markdown 格式) |
| cards | array | 结构化卡片数据,包含 compat_result / shader_result / diagnose_result 等 |
| conversation_id | int | 对话 ID,用于后续继续对话 |
AI 能力列表
| 功能 | 触发方式 | 说明 |
|---|---|---|
| 模组兼容检测 | 提供模组列表 | 检测冲突、缺失前置、版本不匹配 |
| 光影推荐 | 提供硬件配置 | 根据 GPU/CPU/内存匹配光影 |
| 崩溃诊断 | 粘贴崩溃日志 | 分析 crash-report 定位原因 |
| 模组搜索 | 描述需求 | 实时查询 Modrinth 平台 |
| 内存计算 | 告知模组数量 | 推荐 JVM 参数 |
| Java 选择 | 告知 MC 版本 | 推荐对应 Java 版本 |
| BUG 查询 | 询问已知问题 | 查询收录的模组 BUG 知识库 |
错误码
| 400 | 请求体格式错误 |
| 401 | API 密钥无效或已删除 |
| 405 | 仅支持 POST 方法 |
| 500 | AI 服务不可用(返回友好提示文本) |
密钥管理
用户在 Web 端登录后管理自己的密钥(需 Session 认证)。
列出密钥
GET /api/v1/keys.php
Cookie: PHPSESSID=xxx
返回密钥列表(api_key 脱敏显示为 mt_b73edfad****8f7a)。
创建密钥
POST /api/v1/keys.php
Cookie: PHPSESSID=xxx
{ "name": "新应用" }
⚠ 密钥仅返回这一次,请立即保存。关闭后无法再次查看完整密钥。
删除密钥
DELETE /api/v1/keys.php?id=3
Cookie: PHPSESSID=xxx
→ { "success": true }
调用示例
cURL
curl -X POST "https://aimod.xrstudio.cn/api/v1/chat.php" \
-H "Authorization: Bearer mt_your_api_key" \
-H "Content-Type: application/json" \
-d '{"message": "Minecraft 1.20.1 Forge 装80个模组该分多少内存?"}'
JavaScript / Node.js
const BASE = "https://aimod.xrstudio.cn/api/v1";
const API_KEY = "mt_your_api_key_here";
async function chat(message, history = [], conversationId = 0) {
const resp = await fetch(`${BASE}/chat.php`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ message, history, conversation_id: conversationId }),
});
return resp.json();
}
const result = await chat("RTX 4070 + i5-13600K + 32GB 推荐写实光影");
console.log(result.reply);
Python
import requests
BASE = "https://aimod.xrstudio.cn/api/v1"
API_KEY = "mt_your_api_key_here"
def chat(message, history=None, conversation_id=0):
resp = requests.post(f"{BASE}/chat.php", json={
"message": message,
"history": history or [],
"conversation_id": conversation_id,
}, headers={"Authorization": f"Bearer {API_KEY}"})
return resp.json()
result = chat("Minecraft 1.20.1 应该用哪个 Java 版本?")
print(result["reply"])