Compare commits

..

1 Commits

Author SHA1 Message Date
papertager 0e39635a04 chore: ignore python bytecode 2026-05-26 23:33:26 +08:00
102 changed files with 613 additions and 9319 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
__pycache__/
*.py[cod]
*$py.class
.idea/
.opencode/

View File

@ -3,5 +3,4 @@
<component name="Black">
<option name="sdkName" value="loratest" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
</project>

View File

@ -14,24 +14,7 @@
"name": "MiniMax-M2.7"
}
}
},
"glm-5.1": {
"npm": "@ai-sdk/openai-compatible",
"name": "GLM-5.1 Self-hosted",
"options": {
"baseURL": "https://www.glmfast.ai4mats.com/v1",
"apiKey": "sk-glm-96de15fe331cd6955929bbd4469e641fe2541afa8e09758dea0c9cbce257e0c3 "
},
"models": {
"glm-5.1-fast": { "name": "GLM-5.1-fast",
"limit": {
"context": 30000,
"output": 512
}
}
}
}
}
},
"mcp": {
"bayesian-analysis": {

View File

@ -1,42 +0,0 @@
---
name: create-code
description: 当用户需要新增代码配置时,请使用此技能。
triggers:
- "新增代码配置"
- "创建代码配置"
metadata:
api-base: https://www.ai4mats.com
---
# 创建代码配置(调用接口)
## 何时使用
- 用户需要创建一个新的代码配置
- 用户提到“创建代码配置”“新建代码配置”“调用创建代码配置 API”
## 执行流程Agent 必须遵守)
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **输入参数**
- 代码仓库名称 `code_repo_name`
- Git 地址 `git_url`
- 代码分支/Tag `git_branch`
4. **创建代码配置**
- 调用`scripts/create_code_mcp_server.create_code`方法
- 参数:`token`(来自步骤2), `code_repo_name`(来自步骤3), `git_url`(来自步骤3), `git_branch`(来自步骤3)
5. **反馈结果**
- ✅ 成功:返回创建结果
- ❌ 失败:返回错误码和错误信息

View File

@ -1,68 +0,0 @@
import json
import os
import httpx
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
@mcp.tool()
async def create_code(
token: str,
code_repo_name: str,
git_url: str,
git_branch: str,
) -> str:
url = f"{API_BASE_URL}/api/mmp/codeConfig"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"code_repo_name": code_repo_name,
"is_public": True,
"git_url": git_url,
"git_branch": git_branch
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型版本失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,61 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,44 +0,0 @@
---
name: create-image
description: 当用户需要新增镜像时,请使用此技能。
triggers:
- "新增镜像"
- "创建镜像"
metadata:
api-base: https://www.ai4mats.com
---
# 创建镜像(调用接口)
## 何时使用
- 用户需要创建一个新的镜像
- 用户提到“创建镜像”“新建镜像”“调用创建镜像 API”
## 执行流程Agent 必须遵守)
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **输入参数**
- 镜像名称 `name`
- 版本名称 `tag_name`
- 镜像描述 `description`
- 版本描述 `version_description`
- 公网镜像地址 `path`
4. **创建镜像**
- 调用`scripts/create_image_mcp_server.create_image`方法
- 参数:`token`(来自步骤2), `name`(来自步骤3), `tag_name`(来自步骤3), `description`(来自步骤3), `version_description`(来自步骤3), `path`(来自步骤3)
5. **反馈结果**
- ✅ 成功:返回创建结果
- ❌ 失败:返回错误码和错误信息

View File

@ -1,71 +0,0 @@
import json
import os
import httpx
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
@mcp.tool()
async def create_image(
token: str,
name: str,
tag_name: str,
description: str,
version_description: str,
path: str,
) -> str:
url = f"{API_BASE_URL}/api/mmp/image/addImageAndVersion"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"upload_type": 0,
"is_public": False,
"tag_name": tag_name,
"description": description,
"name": name,
"version_description": version_description,
"path": path
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型版本失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,61 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,95 +0,0 @@
---
name: create-model
description: 当用户需要新增模型时,请使用此技能。
triggers:
- "新增模型"
- "创建模型"
metadata:
api-base: https://www.ai4mats.com
---
# 创建模型(调用接口)
## 何时使用
- 用户需要创建一个新的模型
- 用户提到“创建模型”“新建模型”“调用创建模型 API”
## 执行流程Agent 必须遵守)
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 模型名称 `name`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **查询模型类型列表**
- 调用`scripts/model_mcp_server.query_model_type_list`方法
- 结果中的二级目录`second_asset_icon_list`字段的`name`为所有的模型类型
4. **输入参数**
- 模型类型 `model_type` (范围来自于步骤3的结果不能超出范围)
- 模型标签 `model_tag`
5. **创建模型**
- 调用`scripts/model_mcp_server.create_model`方法
- 参数:`token`(来自步骤2), `name`(来自步骤1), `model_tag`(来自步骤4), `model_type`(来自步骤4)
6. **反馈结果**
- ✅ 成功:返回模型名称和创建结果
- ❌ 失败:返回错误码和错误信息
7. **询问是否创建模型版本**
- 如果创建模型成功,则继续询问用户是否需要创建模型版本
- 用户回答是则进行以下步骤,否则终止。
8. **输入版本描述**
- 输入版本描述version_desc
9. **上传文件**
- 调用`scripts/upload_file.upload_file`方法分片上传文件
- 参数:`token`(来自步骤2), file_path
10. **获取最新的版本号**
- 调用`scripts/model_mcp_server.query_next_version`方法获取最新的版本号
- 参数:`token`(来自步骤2), `identifier`(来自步骤6), `owner`:username
11. **创建模型版本**
- 调用`scripts/model_mcp_server.create_model_version`方法
- 参数:`token`(来自步骤2), `git_id`(来自步骤6), `id`(来自步骤6), `identifier`(来自步骤6), `file_path`(来自步骤9的输入), `file_data`(来自步骤9的结果), `name`:name, `owner`:username, `version`(来自步骤10), `version_desc`(来自步骤8)
12. **反馈结果**
- ✅ 成功:返回创建模型版本结果
- ❌ 失败:返回错误码和错误信息
---
## 示例对话
**用户:**
> 帮我创建一个模型,名字叫 material-filter-v1标签是 material,screening
**Agent 行为:**
1. 询问用户名和密码(如未知)
2. 调用登录接口获取token
3. 调用创建模型
4. 返回:
> ✅ 模型 `material-filter-v1` 创建成功
5. 询问是否创建模型版本
6. 输入版本描述
7. 上传文件
8. 获取最新的版本号
9. 创建模型版本
10. 反馈结果
---
## 注意事项
- Token 有效期由服务端控制,过期需重新登录
- 不建议将用户名、密码、Token 写入日志
- 创建失败时应明确提示是 **登录失败** 还是 **创建失败**

View File

@ -1,115 +0,0 @@
---
name: create-model
description: 当用户需要新增模型时,请使用此技能。
triggers:
- "新增模型"
- "创建模型"
metadata:
api-base: http://172.20.32.121:31213
---
# 创建模型(调用接口)
## 何时使用
- 用户需要创建一个新的模型
- 用户提到“创建模型”“新建模型”“调用创建模型 API”
## 接口信息
### 1. 登录获取access_token接口
- 方法POST
- 路径:/api/auth/login
- Content-Typeapplication/json; charset=UTF-8
- 请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | ✅ | 用户名 |
| password | string | ✅ | 密码 |
#### 示例请求
curl -X POST http://172.20.32.121:31213/api/auth/login \
-H "Content-Type: application/json; charset=UTF-8" \
-d '{"username": "fanshuai","password": "h1n2x3j4y5@"}'
#### 返回示例
{"code":200,"msg":null,"data":{"access_token":"eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX2tleSI6IjU1ZTdiOGIxLWFmNjYtNDQyYS1iMjgyLTM4YWVmMzhlODI3MyIsInVzZXJuYW1lIjoiZmFuc2h1YWkifQ.SCu4a85IKUY9OlFApDWVlEvHeuacf4FoW0agzIKrmR8a8uLdur3Rb8Y7_1tu71JEKT_pQBGSTDhtf7FobqdIrg","expires_in":1779433929217}}
### 2. 新增模型接口
- 方法POST
- 路径:/api/mmp/newmodel/addModel
- Headers
- `Authorization: Bearer <access_token>`
- `Content-Type: application/json; charset=UTF-8`
- 请求参数:
| 参数 | 类型 | 必填 | 默认值 |
|---|---|---|---|
| name | string | ✅ | — |
| model_type | string | ❌ | `"多模态模型"` |
| model_tag | string | ✅ | — |
| is_hot_stone | boolean | ❌ | `false` |
| is_public | boolean | ❌ | `false` |
| model_source | string | ❌ | `"add"` |
| preview_pic | string | ❌ | `http://172.20.32.121:31213/minio/data/mini-model-platform-data/temp/fanshuai/1761528061144/model/材料筛选.png` |
#### 示例请求
curl -X POST http://172.20.32.121:31213/api/mmp/newmodel/addModel \
-H "Authorization: Bearer $access_token" \
-H "Content-Type: application/json; charset=UTF-8" \
-d '{
"name": "material-filter-v1",
"model_type": "多模态模型",
"model_tag": "material,screening",
"is_hot_stone": false,
"is_public": false,
"model_source": "add",
"preview_pic": "http://172.20.32.121:31213/minio/data/mini-model-platform-data/temp/fanshuai/1761528061144/model/材料筛选.png"}'
#### 返回示例
{"code":200,"msg":"操作成功","data":{"id":23,"name":"material-filter-v1","create_by":"fanshuai","create_time":"2026-05-21 15:28:26","update_time":"2026-05-21 15:28:26","model_size":"0 B","model_source":"add","model_tag":"material,screening","model_type":"多模态模型","owner":"fanshuai","identifier":"fanshuai_model_20260521152825","is_public":false,"relative_paths":"fanshuai/model/128/fanshuai_model_20260521152825/origin/model","preview_pic":"http://172.20.32.121:31213/minio/data/mini-model-platform-data/temp/fanshuai/1761528061144/model/材料筛选.png","is_hot_stone":false,"git_id":128}}
## 执行流程Agent 必须遵守)
1. **确认参数**
- 是否已提供:
- 用户名
- 密码
- 模型名称 `name`
- 模型标签 `model_tag`
- 若缺失,必须先向用户询问
2. **调用登录接口**
- 获取 `access_token`
- 保存为临时变量 `access_token`
3. **构造创建模型请求**
- 使用默认值补齐未传参数
- 使用 `Bearer Token` 鉴权
4. **调用创建模型接口**
5. **反馈结果**
- ✅ 成功:返回模型名称和创建结果
- ❌ 失败:返回错误码和错误信息
---
## 示例对话
**用户:**
> 帮我创建一个模型,名字叫 material-filter-v1标签是 material,screening
**Agent 行为:**
1. 询问用户名和密码(如未知)
2. 调用登录接口
3. 调用创建模型接口
4. 返回:
> ✅ 模型 `material-filter-v1` 创建成功
---
## 注意事项
- Token 有效期由服务端控制,过期需重新登录
- 不建议将用户名、密码、Token 写入日志
- preview_pic 如用户未指定,必须使用默认图片地址
- 创建失败时应明确提示是 **登录失败** 还是 **创建失败**

View File

@ -1,47 +0,0 @@
import asyncio
import httpx
import json
import sys
sys.stdout.reconfigure(encoding='utf-8')
API_BASE_URL = "https://www.ai4mats.com"
async def create_model(token: str, name: str, model_tag: str, model_type: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/newmodel/addModel"
headers = {"Content-Type": "application/json; charset=UTF-8", "Authorization": f"Bearer {token}"}
payload = {
"name": name,
"model_type": model_type,
"model_tag": model_tag,
"is_hot_stone": False,
"is_public": False,
"model_source": "add",
"preview_pic": "https://www.ai4mats.com/minio/data/mini-model-platform-data/temp/fanshuai/1761528061144/model/材料筛选.png"
}
print(f"请求参数: {json.dumps(payload, ensure_ascii=False, indent=2)}")
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
async def main():
# Load state
with open("flow_state.json", "r", encoding="utf-8") as f:
state = json.load(f)
token = state.get("token")
name = "skill2"
model_tag = "123"
model_type = "模型材料筛选"
print("正在创建模型...")
result = await create_model(token, name, model_tag, model_type)
print(f"创建结果: {json.dumps(result, ensure_ascii=False, indent=2)}")
# Save result for next steps
with open("create_result.json", "w", encoding="utf-8") as f:
json.dump(result, f, ensure_ascii=False, indent=2)
if __name__ == "__main__":
asyncio.run(main())

View File

@ -1,67 +0,0 @@
import asyncio
import httpx
import json
import sys
sys.stdout.reconfigure(encoding='utf-8')
API_BASE_URL = "https://www.ai4mats.com"
async def login(username: str, password: str) -> dict:
url = f"{API_BASE_URL}/api/auth/login"
headers = {"Content-Type": "application/json; charset=UTF-8"}
payload = {"username": username, "password": password}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
async def query_model_type_list(token: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/assetIcon"
headers = {"Content-Type": "application/json; charset=UTF-8", "Authorization": f"Bearer {token}"}
params = {"category_id": 2}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
return response.json()
async def main():
username = "fanshuai"
password = "h1n2x3j4y5@"
print("正在登录...")
login_result = await login(username, password)
if login_result.get("code") != 200:
print(f"登录失败: {login_result}")
return
token = login_result.get("data", {}).get("access_token")
if not token:
print("获取token失败")
return
print("登录成功")
# Query model type list
print("\n正在查询模型类型列表...")
type_result = await query_model_type_list(token)
if type_result.get("code") == 200:
data = type_result.get("data", [])
print(f"{len(data)} 个一级分类:\n")
for item in data:
print(f"--- {item.get('name')} ---")
second_list = item.get("second_asset_icon_list", [])
for second in second_list:
print(f" - {second.get('name')}")
print()
# Save token and types for next steps
with open("flow_state.json", "w", encoding="utf-8") as f:
json.dump({"token": token, "types": type_result.get("data", [])}, f, ensure_ascii=False)
print("状态已保存到 flow_state.json")
else:
print(f"查询失败: {type_result}")
if __name__ == "__main__":
asyncio.run(main())

View File

@ -1,22 +0,0 @@
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 37,
"name": "skill2",
"create_by": "fanshuai",
"create_time": "2026-05-25 11:02:39",
"update_time": "2026-05-25 11:02:39",
"model_size": "0 B",
"model_source": "add",
"model_tag": "123",
"model_type": "模型材料筛选",
"owner": "fanshuai",
"identifier": "fanshuai_model_20260525110238",
"is_public": false,
"relative_paths": "fanshuai/model/143/fanshuai_model_20260525110238/origin/model",
"preview_pic": "https://www.ai4mats.com/minio/data/mini-model-platform-data/temp/fanshuai/1761528061144/model/材料筛选.png",
"is_hot_stone": false,
"git_id": 143
}
}

View File

@ -1,207 +0,0 @@
import asyncio
import httpx
import json
import sys
import os
sys.stdout.reconfigure(encoding='utf-8')
API_BASE_URL = "https://www.ai4mats.com"
DEFAULT_SIZE = 10 * 1024 * 1024 # 10MB
import hashlib
def compute_md5(file_path: str) -> str:
file_size = os.path.getsize(file_path)
chunk_size = min(DEFAULT_SIZE, file_size)
with open(file_path, "rb") as f:
data = f.read(chunk_size)
md5 = hashlib.md5(data).hexdigest()
filename = os.path.basename(file_path)
name_bytes = filename.encode('utf-8')
combined = md5.encode('utf-8') + name_bytes
return hashlib.md5(combined).hexdigest()
async def get_upload_task(token: str, params: dict) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/chunk"
headers = {"Authorization": f"Bearer {token}"}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
return response.json()
async def upload_chunk(token: str, file_path: str, part_number: int, total_chunks: int, identifier: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/chunk"
file_size = os.path.getsize(file_path)
filename = os.path.basename(file_path)
start = DEFAULT_SIZE * (part_number - 1)
end = min(start + DEFAULT_SIZE, file_size)
current_chunk_size = end - start
with open(file_path, "rb") as f:
f.seek(start)
blob_data = f.read(current_chunk_size)
data = {
"chunkNumber": str(part_number),
"chunkSize": str(DEFAULT_SIZE),
"currentChunkSize": str(current_chunk_size),
"filename": filename,
"relativePath": filename,
"identifier": identifier,
"totalChunks": str(total_chunks),
"totalSize": str(file_size),
}
files = {"upfile": (str(part_number), blob_data, "application/octet-stream")}
headers = {"Authorization": f"Bearer {token}"}
async with httpx.AsyncClient(timeout=600.0) as client:
response = await client.post(url, data=data, files=files, headers=headers)
response.raise_for_status()
return response.json()
async def merge_chunks(token: str, file_path: str, identifier: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/mergeFile"
file_size = os.path.getsize(file_path)
filename = os.path.basename(file_path)
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json; charset=UTF-8"}
payload = {
"fileType": "application/zip",
"name": filename,
"relativePath": filename,
"size": file_size,
"uniqueIdentifier": identifier,
"refProjectId": "123456789",
}
async with httpx.AsyncClient(timeout=600.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
async def get_merge_status(token: str, filename: str, identifier: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/selectFile"
headers = {"Authorization": f"Bearer {token}"}
params = {"filename": filename, "identifier": identifier}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
return response.json()
async def upload_file(token: str, file_path: str) -> dict:
file_size = os.path.getsize(file_path)
filename = os.path.basename(file_path)
total_chunks = max(1, (file_size + DEFAULT_SIZE - 1) // DEFAULT_SIZE)
identifier = compute_md5(file_path)
print(f"文件: {filename}, 大小: {file_size}, 分片数: {total_chunks}")
task_params = {
"chunkNumber": 1,
"chunkSize": DEFAULT_SIZE,
"currentChunkSize": min(DEFAULT_SIZE, file_size),
"totalSize": file_size,
"identifier": identifier,
"filename": filename,
"relativePath": filename,
"totalChunks": total_chunks,
}
task_result = await get_upload_task(token, task_params)
if task_result.get("code") != 200:
raise Exception(f"获取上传任务失败: {task_result}")
task = task_result.get("data", {})
if task.get("skip_upload"):
print("文件已存在,跳过上传")
return task
for part in range(1, total_chunks + 1):
print(f"上传分片 {part}/{total_chunks}...")
result = await upload_chunk(token, file_path, part, total_chunks, identifier)
print(f" 分片 {part} 完成")
print("合并分片中...")
merge_result = await merge_chunks(token, file_path, identifier)
if merge_result.get("code") != 200:
raise Exception(f"合并失败: {merge_result}")
merge_data = merge_result.get("data", {})
if merge_data.get("state") == "Succeeded":
print("合并成功!")
return merge_data
for i in range(30):
await asyncio.sleep(3)
status_result = await get_merge_status(token, filename, identifier)
status_data = status_result.get("data", {})
state = status_data.get("state")
print(f" 合并状态查询 #{i+1}: {state}")
if state == "Succeeded":
print("合并成功!")
return status_data
elif state == "Failed":
raise Exception(f"合并失败: {status_result}")
raise Exception("合并状态查询超时")
async def query_next_version(token: str, identifier: str, owner: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/newmodel/queryNextVersion"
headers = {"Content-Type": "application/json; charset=UTF-8", "Authorization": f"Bearer {token}"}
payload = {"identifier": identifier, "owner": owner}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
async def create_model_version(token: str, git_id: int, id: int, identifier: str, file_path: str, file_data: dict, name: str, owner: str, version: str, version_desc: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/newmodel/addVersion"
headers = {"Content-Type": "application/json; charset=UTF-8", "Authorization": f"Bearer {token}"}
model_version_vos = [{"file_name": os.path.basename(file_path), "file_size": os.path.getsize(file_path), "url": file_data.get("location")}]
payload = {
"git_id": git_id,
"id": id,
"identifier": identifier,
"is_public": False,
"model_source": "add",
"model_version_vos": model_version_vos,
"name": name,
"owner": owner,
"version": version,
"version_desc": version_desc,
}
print(f"创建版本请求: {json.dumps(payload, ensure_ascii=False, indent=2)}")
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
async def main():
# Load model create result
with open("create_result.json", "r", encoding="utf-8") as f:
create_result = json.load(f)
model_data = create_result.get("data", {})
git_id = model_data.get("git_id")
model_id = model_data.get("id")
identifier = model_data.get("identifier")
name = model_data.get("name")
owner = model_data.get("owner")
# Load token
with open("flow_state.json", "r", encoding="utf-8") as f:
state = json.load(f)
token = state.get("token")
file_path = "D:\\code\\nginx.zip"
version_desc = "skill2-v1"
# Step 1: Upload file
print("Step 1: 上传文件...")
file_data = await upload_file(token, file_path)
print(f"上传结果: {json.dumps(file_data, ensure_ascii=False, indent=2)}")
# Step 2: Get next version
print("\nStep 2: 获取最新版本号...")
version_result = await query_next_version(token, identifier, owner)
print(f"版本号查询结果: {json.dumps(version_result, ensure_ascii=False, indent=2)}")
if version_result.get("code") != 200:
print(f"查询版本号失败")
return
version = version_result.get("data")
print(f"最新版本号: {version}")
# Step 3: Create model version
print("\nStep 3: 创建模型版本...")
result = await create_model_version(token, git_id, model_id, identifier, file_path, file_data, name, owner, version, version_desc)
print(f"创建模型版本结果: {json.dumps(result, ensure_ascii=False, indent=2)}")
if __name__ == "__main__":
asyncio.run(main())

View File

@ -1,178 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("文件mcp server")
# 3. 定义工具(所有工具都增加 token 参数)
@mcp.tool()
async def chunk_get(
token: str,
chunkNumber: int,
chunkSize: int,
currentChunkSize: int,
filename: str,
relativePath: str,
identifier: str,
totalChunks: int,
totalSize: int,
) -> str:
url = f"{API_BASE_URL}/api/mmp/uploader/chunk"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"chunkNumber": chunkNumber,
"chunkSize": chunkSize,
"currentChunkSize": currentChunkSize,
"filename": filename,
"relativePath": relativePath,
"identifier": identifier,
"totalChunks": totalChunks,
"totalSize": totalSize
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 获取文件信息失败: {str(e)}"
@mcp.tool()
async def chunk_post(
token: str,
chunkNumber: int,
chunkSize: int,
currentChunkSize: int,
filename: str,
relativePath: str,
identifier: str,
totalChunks: int,
totalSize: int,
upfile: UploadFile
) -> str:
url = f"{API_BASE_URL}/api/mmp/uploader/chunk"
headers = {
"Content-Type": "multipart/form-data; application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"chunkNumber": chunkNumber,
"chunkSize": chunkSize,
"currentChunkSize": currentChunkSize,
"filename": filename,
"relativePath": relativePath,
"identifier": identifier,
"totalChunks": totalChunks,
"totalSize": totalSize,
"upfile": upfile
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 上传文件分片失败: {str(e)}"
@mcp.tool()
async def mergeFile(
token: str,
fileType: str,
name: str,
refProjectId: str,
relativePath: str,
size: int,
uniqueIdentifierstr,
) -> str:
url = f"{API_BASE_URL}/api/mmp/uploader/mergeFile"
headers = {
"Content-Type": "multipart/form-data; application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"fileType": fileType,
"name": name,
"refProjectId": refProjectId,
"relativePath": relativePath,
"size": size,
"uniqueIdentifierstr": uniqueIdentifierstr
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 聚合文件分片失败: {str(e)}"
@mcp.tool()
async def selectFile(token: str,
filename: str,
identifier: str) -> str:
url = f"{API_BASE_URL}/api/mmp/uploader/mergeFile"
headers = {
"Content-Type": "multipart/form-data; application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"filename": filename,
"identifier": identifier
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 查询文件信息失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

File diff suppressed because one or more lines are too long

View File

@ -1,62 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,165 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("模型mcp server")
# 3. 定义工具(所有工具都增加 token 参数)
@mcp.tool()
async def create_model(
token: str, # 新增:认证令牌
name: str,
model_tag: str,
model_type: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/newmodel/addModel"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"name": name,
"model_type": model_type,
"model_tag": model_tag,
"is_hot_stone": False,
"is_public": False,
"model_source": "add",
"preview_pic": "https://www.ai4mats.com/minio/data/mini-model-platform-data/temp/fanshuai/1761528061144/model/材料筛选.png"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
@mcp.tool()
async def query_next_version(
token: str,
identifier: str,
owner: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/newmodel/queryNextVersion"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"identifier": identifier,
"owner": owner
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 查询模型最新版本失败: {str(e)}"
@mcp.tool()
async def create_model_version(
token: str,
git_id: int,
id: int,
identifier: str,
file_path: str,
file_data: dict,
name: str,
owner: str,
version: str,
version_desc: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/newmodel/addVersion"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
model_version_vos = [{"file_name": os.path.basename(file_path), "file_size": os.path.getsize(file_path),
"url": file_data.get("location")}]
payload = {
"git_id": git_id,
"id": id,
"identifier": identifier,
"is_public": False,
"model_source": "add",
"model_version_vos": model_version_vos,
"name": name,
"owner": owner,
"version": version,
"version_desc": version_desc
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型版本失败: {str(e)}"
@mcp.tool()
async def query_model_type_list(
token: str
):
url = f"{API_BASE_URL}/api/mmp/assetIcon"
headers = { "Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"}
params = {
"category_id": 2,
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 查询模型类型列表失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,167 +0,0 @@
import asyncio
import hashlib
import json
import os
import sys
import time
import httpx
API_BASE_URL = "https://www.ai4mats.com"
DEFAULT_SIZE = 10 * 1024 * 1024 # 10MB
def compute_md5(file_path: str) -> str:
# Only compute MD5 of the first chunk for performance
file_size = os.path.getsize(file_path)
chunk_size = min(DEFAULT_SIZE, file_size)
with open(file_path, "rb") as f:
data = f.read(chunk_size)
md5 = hashlib.md5(data).hexdigest()
# Add filename to md5 like the frontend does
filename = os.path.basename(file_path)
name_bytes = filename.encode('utf-8')
combined = md5.encode('utf-8') + name_bytes
return hashlib.md5(combined).hexdigest()
async def get_upload_task(token: str, params: dict) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/chunk"
headers = {"Authorization": f"Bearer {token}"}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
return response.json()
async def upload_chunk(token: str, file_path: str, part_number: int, total_chunks: int, identifier: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/chunk"
file_size = os.path.getsize(file_path)
filename = os.path.basename(file_path)
start = DEFAULT_SIZE * (part_number - 1)
end = min(start + DEFAULT_SIZE, file_size)
current_chunk_size = end - start
with open(file_path, "rb") as f:
f.seek(start)
blob_data = f.read(current_chunk_size)
data = httpx.MultipartData(
chunkNumber=str(part_number),
chunkSize=str(DEFAULT_SIZE),
currentChunkSize=str(current_chunk_size),
filename=filename,
relativePath=filename,
identifier=identifier,
totalChunks=str(total_chunks),
totalSize=str(file_size),
upfile=(str(part_number), blob_data),
)
headers = {"Authorization": f"Bearer {token}"}
async with httpx.AsyncClient(timeout=600.0) as client:
response = await client.post(url, data=data, headers=headers)
response.raise_for_status()
return response.json()
async def merge_chunks(token: str, file_path: str, identifier: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/mergeFile"
file_size = os.path.getsize(file_path)
filename = os.path.basename(file_path)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json; charset=UTF-8",
}
payload = {
"fileType": "application/zip",
"name": filename,
"relativePath": filename,
"size": file_size,
"uniqueIdentifier": identifier,
"refProjectId": "123456789",
}
async with httpx.AsyncClient(timeout=600.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
async def get_merge_status(token: str, filename: str, identifier: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/selectFile"
headers = {"Authorization": f"Bearer {token}"}
params = {"filename": filename, "identifier": identifier}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
return response.json()
async def upload_file(token: str, file_path: str) -> dict:
file_size = os.path.getsize(file_path)
filename = os.path.basename(file_path)
total_chunks = max(1, (file_size + DEFAULT_SIZE - 1) // DEFAULT_SIZE)
identifier = compute_md5(file_path)
print(f"File: {filename}, Size: {file_size}, Chunks: {total_chunks}, MD5: {identifier}")
# Step 1: Get upload task
task_params = {
"chunkNumber": 1,
"chunkSize": DEFAULT_SIZE,
"currentChunkSize": min(DEFAULT_SIZE, file_size),
"totalSize": file_size,
"identifier": identifier,
"filename": filename,
"relativePath": filename,
"totalChunks": total_chunks,
}
task_result = await get_upload_task(token, task_params)
print(f"Task result: {json.dumps(task_result, ensure_ascii=False)}")
if task_result.get("code") != 200:
raise Exception(f"Get upload task failed: {task_result}")
task = task_result.get("data", {})
if task.get("skip_upload"):
print("File already uploaded, skipping upload")
return task
# Step 2: Upload chunks
for part in range(1, total_chunks + 1):
print(f"Uploading chunk {part}/{total_chunks}...")
result = await upload_chunk(token, file_path, part, total_chunks, identifier)
print(f" Chunk {part} result: {json.dumps(result, ensure_ascii=False)}")
# Step 3: Merge chunks
print("Merging chunks...")
merge_result = await merge_chunks(token, file_path, identifier)
print(f"Merge result: {json.dumps(merge_result, ensure_ascii=False)}")
if merge_result.get("code") != 200:
raise Exception(f"Merge failed: {merge_result}")
# Step 4: Poll merge status
merge_data = merge_result.get("data", {})
if merge_data.get("state") == "Succeeded":
print("Merge succeeded immediately!")
return merge_data
# Poll for status
for i in range(30):
await asyncio.sleep(3)
status_result = await get_merge_status(token, filename, identifier)
status_data = status_result.get("data", {})
state = status_data.get("state")
print(f" Merge status poll #{i+1}: {state}")
if state == "Succeeded":
print("Merge succeeded!")
return status_data
elif state == "Failed":
raise Exception(f"Merge failed: {status_result}")
raise Exception("Merge status polling timed out")
async def main():
token = sys.argv[1]
file_path = sys.argv[2]
result = await upload_file(token, file_path)
print(f"\nFinal result:\n{json.dumps(result, ensure_ascii=False, indent=2)}")
if __name__ == "__main__":
asyncio.run(main())

View File

@ -1,103 +0,0 @@
---
name: create-service
description: 当用户需要新增应用时,请使用此技能。
triggers:
- "创建应用"
- "新增应用"
- "创建智算应用"
- "新增智算应用"
metadata:
api-base: https://www.ai4mats.com
---
# 创建应用
## 何时使用
- 用户需要创建一个新的应用
- 用户提到“创建应用”“新建应用”“调用创建应用 API”“创建智算应用”
## 执行流程Agent 必须遵守)
1. **确认应用类型**
- 询问用户需要创建:常规应用 还是 智算应用
- 记录用户选择
2. **确认参数**
- 如果有token则跳过步骤2步骤3token过期则再从这一步开始执行
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
3. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
4. **查询应用类型列表**
- 调用`scripts/create_service_mcp_server.get_service_types`方法
- 结果中的`type`字段为所有的应用类型
5. **输入参数**
- 应用名称 `service_name`
- 应用类型 `service_type` (范围来自于步骤4的结果不能超出范围)
- 应用标签 `tag`
- 应用描述 `description`
6. **创建应用**
- 如果用户选择**常规应用**
- 调用`scripts/create_service_mcp_server.create_servive`方法
- 如果用户选择**智算应用**
- 调用`scripts/create_service_mcp_server.create_zs_service`方法
- 参数:`token`(来自步骤3), `service_name`(来自步骤5), `service_type`(来自步骤5), `tag`(来自步骤5), `description`(来自步骤5)
7. **反馈结果**
- ✅ 成功:返回应用名称和创建结果
- ❌ 失败:返回错误码和错误信息
7. **询问用户是否需要创建版本**
- 询问用户是否需要创建应用版本,如果需要则进行以下步骤,不需要则终止任务
8. **输入参数**
- 应用版本 `version`
- 版本描述 `description`
- 副本数量 `replicas`
9. **选择运行镜像**
- 输入参数:
- 查询公开镜像还是个人镜像 `is_public`(bool类型)
- `page`(默认0)
- `size`(默认20)
- 调用 `scripts/create_service_mcp_server.query_image`方法,参数:`token`(来自步骤2), `page`(来自步骤9), `size`(来自步骤9), `is_public`(来自步骤9)
- 询问用户是否需要查询下一页的数据如果需要则page参数加1再次查询。
- 用户选择了镜像之后,调用 `scripts/create_service_mcp_server.query_image_version`方法查询镜像版本
- 用户选择某一个镜像版本
10. **选择资源规格**
- 调用 `scripts/create_service_mcp_server.query_computing_resource`方法查询资源规格列表
- 用户选择某一个资源规格
11. **选择模型**
- 询问用户是否需要选择模型,如果是,则进行以下步骤,如果否,则跳过此环节,直接进入下一环节
- 调用 `scripts/create_service_mcp_server.query_models`方法查询模型列表
- 输入参数:
- 查询公开模型还是个人模型 `is_public`(bool类型)
- `page`(默认0)
- `size`(默认20)
- 询问用户是否需要查询下一页的数据如果需要则page参数加1再次查询。
- 用户选择了模型之后,调用 `scripts/create_service_mcp_server.query_model_version`方法查询模型版本,参数:`token`(来自步骤2),`owner`,`identifier`
- 用户选择某一个模型版本,调用`scripts/create_service_mcp_server.query_model_version_detail`方法查询模型版本详情,参数:`token`(来自步骤2), `id`(模型id), `name`(模型名称), `owner`,`identifier`, `version`(模型版本), `is_public`, `git_id`
- 并要求输入参数挂载路径:`mount_path`
12. **输入环境变量**
- 询问用户是否需要输入环境变量,如果是,则进行以下步骤,如果否,则跳过此环节,直接进入下一环节
- 用户可以输入多个key-value键值对key和value都是str类型然后存放在变量`env_variables`中
13. **创建应用版本**
- 调用 `scripts/create_service_mcp_server.create_service_version`方法
- 参数:`token`(来自步骤2), `service_id`(应用id来自步骤5的返回结果中的id字段), `service_name`(来自步骤4), `version`(来自步骤8), `description`(来自步骤8),
`replicas`(来自步骤8), `computing_resource_id`(来自步骤10中用户选择的结果中的id字段), `model`(来自步骤11用户选择的模型版本对象), `mount_path`(来自步骤11),
`image`(来自步骤9中选择的镜像版本对象), `env_variables`(来自步骤12)
14. **反馈结果**
- ✅ 成功:返回应用版本创建结果
- ❌ 失败:返回错误码和错误信息

View File

@ -1,316 +0,0 @@
import json
import os
import httpx
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("service mcp server")
@mcp.tool()
async def get_service_types(token: str):
url = f"{API_BASE_URL}/api/mmp/service/getServiceTypes"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询应用类型失败: {str(e)}"
@mcp.tool()
async def create_servive(
token: str,
service_name: str,
service_type: str,
description: str,
tag: str,
) -> str:
url = f"{API_BASE_URL}/api/mmp/service"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"service_name": service_name,
"service_type": service_type,
"description": description,
"tag": tag,
"source": 0,
"img_url": "https://www.minio.ai4mats.com/data/mini-model-platform-data/temp/fanshuai/1761528061144/app-1.png"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 创建模应用失败: {str(e)}"
@mcp.tool()
async def query_image(
token: str,
page: int,
size: int,
is_public: bool
):
url = f"{API_BASE_URL}/api/mmp/image"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": is_public
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询镜像列表失败: {str(e)}"
@mcp.tool()
async def query_image_version(token: str,
image_id: int):
url = f"{API_BASE_URL}/api/mmp/imageVersion"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": 0,
"size": 2000,
"image_id": image_id,
"status": "Available"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询镜像版本列表失败: {str(e)}"
@mcp.tool()
async def query_computing_resource(token: str):
url = f"{API_BASE_URL}/api/mmp/computingResource"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": 0,
"size": 1000}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询资源规格列表失败: {str(e)}"
@mcp.tool()
async def query_models(token: str,
page: int,
size: int,
is_public: bool):
url = f"{API_BASE_URL}/api/mmp/newmodel/queryModels"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": is_public,
"is_hot_stone": False
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询镜像列表失败: {str(e)}"
@mcp.tool()
async def query_model_version(
token: str,
owner: str,
identifier: str
):
url = f"{API_BASE_URL}/api/mmp/newmodel/getVersionList"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"owner": owner,
"identifier": identifier
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询镜像列表失败: {str(e)}"
@mcp.tool()
async def query_model_version_detail(token: str,
id: int,
name: str,
owner: str,
identifier: str,
version: str,
is_public: bool,
git_id: int
):
url = f"{API_BASE_URL}/api/mmp/newmodel/getModelDetail"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"owner": owner,
"identifier": identifier,
"id": id,
"name": name,
"version": version,
"is_public": is_public,
"git_id": git_id
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询镜像列表失败: {str(e)}"
@mcp.tool()
async def create_service_version(
token: str,
service_id: int,
service_name: str,
version: str,
description: str,
replicas: int,
computing_resource_id: int,
model: dict,
mount_path: str,
image: dict,
env_variables: dict
):
url = f"{API_BASE_URL}/api/mmp/service/version"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"service_id": service_id,
"service_name": service_name,
"source": 0,
"deploy_type": "web",
"version": version,
"description": description,
"replicas": replicas,
"computing_resource_id": computing_resource_id,
"model": model,
"mount_path": mount_path,
"image": image,
"env_variables": env_variables
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 创建模应用失败: {str(e)}"
@mcp.tool()
async def create_zs_service(
token: str,
service_name: str,
service_type: str,
description: str,
tag: str,
) -> str:
url = f"{API_BASE_URL}/api/mmp/service"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"service_name": service_name,
"service_type": service_type,
"description": description,
"tag": tag,
"source": 2,
"img_url": "https://www.minio.ai4mats.com/data/mini-model-platform-data/temp/fanshuai/1761528061144/app-1.png"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 创建智算应用失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,61 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,4 +0,0 @@
{
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}

View File

@ -1,25 +0,0 @@
import json
import os
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
except Exception as e:
print("读取配置文件失败: {}".format(e))
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")

View File

@ -1,58 +0,0 @@
import json
import os
import httpx
from mcp.server.fastmcp import FastMCP
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
except Exception as e:
print("读取配置文件失败: {}".format(e))
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
mcp = FastMCP("login mcp server")
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = "{}/api/auth/login".format(API_BASE_URL)
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return "登录失败: {}".format(str(e))
if __name__ == "__main__":
print("启动登录 MCP 服务,传输模式: {}".format(TRANSPORT_MODE))
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,115 +0,0 @@
---
name: create-dataset
description: 当用户需要新增数据集时,请使用此技能。
triggers:
- "新增数据集"
- "创建数据集"
metadata:
api-base: https://www.ai4mats.com
---
# 创建数据集(调用接口)
## 何时使用
- 用户需要创建一个新的数据集
- 用户提到“创建数据集”“新建数据集”“调用创建数据集 API”
## 执行流程Agent 必须遵守)
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 数据集名称 `name`
- 数据集标签 `data_tag`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`common/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **获取父级分类列表**
- 调用`scripts/dataset_mcp_server.get_parent_categories`方法
- 参数: `token`(来自步骤2)
- 返回父级分类列表,供用户选择需要展开的分类
4. **选择需要展开的父级分类**
- 展示父级分类列表给用户
- 询问用户需要展开哪个父级分类
- 获取用户选择的父级分类ID `parent_id`
5. **获取叶子节点列表**
- 调用`scripts/dataset_mcp_server.get_child_categories`方法
- 参数: `token`(来自步骤2), `parent_id`(来自步骤4)
- 返回该父级分类下的所有叶子节点列表
6. **选择数据类型**
- 展示叶子节点列表给用户
- 询问用户选择哪种数据类型 `data_type`
7. **创建数据集**
- 调用`scripts/dataset_mcp_server.create_dataset`方法
- 参数:`token`(来自步骤2), `name`, `data_tag`, `data_type`(来自步骤6)
8. **反馈结果**
- ✅ 成功:返回数据集名称和创建结果
- ❌ 失败:返回错误码和错误信息
9. **询问是否创建数据集版本**
- 如果创建数据集成功,则继续询问用户是否需要创建数据集版本
- 用户回答是则进行以下步骤,否则终止。
10. **输入版本描述**
- 输入版本描述version_desc
11. **上传文件**
- 调用`scripts/upload_file.upload_file`方法分片上传文件
12. **获取最新的版本号**
- 调用`scripts/dataset_mcp_server.query_next_version`方法获取最新的版本号
13. **创建数据集版本**
- 调用`scripts/dataset_mcp_server.create_dataset_version`方法
- 参数:`token`(来自步骤2), `git_id`(来自步骤7), `id`(来自步骤7), `identifier`(来自步骤7), `file_path`(来自步骤11的输入), `file_data`(来自步骤11的结果), `name`:name, `owner`:username, `version`(来自步骤12), `version_desc`(来自步骤10)
14. **反馈结果**
- 打印第13步的参数
- ✅ 成功:返回创建数据集版本结果
- ❌ 失败:返回错误码和错误信息
---
## 示例对话
**用户:**
> 帮我创建一个数据集,名字叫 test121标签是 test
**Agent 行为:**
1. 询问用户名和密码(如未知)
2. 调用登录接口获取token
3. 调用获取父级分类列表接口,返回:知识层级数据
4. 询问用户需要展开哪个父级分类
5. 用户选择"知识层级数据"
6. 调用获取叶子节点列表接口,返回:通用数据、领域基础数据、领域专业数据
7. 询问用户选择哪种数据类型
8. 用户选择"通用数据"
9. 调用创建数据集
10. 返回:
> ✅ 数据集 `test121` 创建成功
11. 询问是否创建数据集版本
12. 输入版本描述
13. 上传文件
14. 获取最新的版本号
15. 创建数据集版本
16. 反馈结果
---
## 注意事项
- Token 有效期由服务端控制,过期需重新登录
- 不建议将用户名、密码、Token 写入日志
- 创建失败时应明确提示是 **登录失败** 还是 **创建失败**
- 数据类型选择流程:先选择父级分类 → 展开叶子节点 → 选择叶子节点作为数据类型
- 如用户直接指定数据类型名称,可调用`get_data_types`获取所有叶子节点进行匹配验证

View File

@ -1,310 +0,0 @@
import httpx
import os
from mcp.server.fastmcp import FastMCP
from common.config import API_BASE_URL, TRANSPORT_MODE
mcp = FastMCP("数据集mcp server")
@mcp.tool()
async def create_dataset(
token: str,
name: str,
data_tag: str,
data_type: str = "通用数据"
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/addDataset"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"name": name,
"preview_pic": "https://www.ai4mats.com/minio/data/mini-model-platform-data/temp/fanshuai/1761528061144/dataset/电学材料.png",
"dataset_source": "add",
"data_type": data_type,
"data_tag": data_tag,
"is_public": False,
"is_hot_stone": False
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 创建数据集失败: {str(e)}"
@mcp.tool()
async def query_next_version(
token: str,
identifier: str,
owner: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/queryNextVersion"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"identifier": identifier,
"owner": owner
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 获取版本号失败: {str(e)}"
@mcp.tool()
async def create_dataset_version(
token: str,
git_id: int,
id: int,
identifier: str,
file_path: str,
file_data: dict,
name: str,
owner: str,
version: str,
version_desc: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/addVersion"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
dataset_version_vos = [{"file_name": os.path.basename(file_path), "file_size": os.path.getsize(file_path), "url": file_data.get("location")}]
payload = {
"git_id": git_id,
"id": id,
"identifier": identifier,
"is_public": False,
"owner": owner,
"dataset_version_vos": dataset_version_vos,
"name": name,
"version": version,
"version_desc": version_desc,
"dataset_source": "add"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 创建数据集版本失败: {str(e)}"
@mcp.tool()
async def query_asset_icon(
token: str,
category_id: int = 1
) -> str:
url = f"{API_BASE_URL}/api/mmp/assetIcon"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": 0,
"size": 10000,
"category_id": category_id
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询数据集分类失败: {str(e)}"
@mcp.tool()
async def get_parent_categories(token: str) -> str:
"""
获取父级分类列表用于用户选择需要展开的分类
参数:
- token: 访问令牌
返回: 父级分类列表格式为 {"code": 200, "msg": "操作成功", "data": [{"id": 137, "name": "知识层级数据"}, ...]}
"""
import json
try:
asset_icon_result = await query_asset_icon(token)
if isinstance(asset_icon_result, str):
try:
asset_icon_result = json.loads(asset_icon_result)
except:
return f"❌ 解析数据集分类失败"
if asset_icon_result.get("code") != 200:
return f"❌ 获取数据集分类失败: {asset_icon_result.get('msg', '未知错误')}"
data = asset_icon_result.get("data", [])
parent_categories = []
for category in data:
parent_categories.append({
"id": category.get("id"),
"name": category.get("name"),
"category_id": category.get("category_id"),
"parent_id": category.get("parent_id")
})
return {
"code": 200,
"msg": "操作成功",
"data": parent_categories
}
except Exception as e:
return f"❌ 获取父级分类列表失败: {str(e)}"
@mcp.tool()
async def get_child_categories(token: str, parent_id: int) -> str:
"""
根据父级分类ID获取其下的叶子节点列表
参数:
- token: 访问令牌
- parent_id: 父级分类ID
返回: 叶子节点列表格式为 {"code": 200, "msg": "操作成功", "data": [{"id": 138, "name": "通用数据", "parent_id": 137, "path": "icon-tongyongshuju"}, ...]}
"""
import json
try:
asset_icon_result = await query_asset_icon(token)
if isinstance(asset_icon_result, str):
try:
asset_icon_result = json.loads(asset_icon_result)
except:
return f"❌ 解析数据集分类失败"
if asset_icon_result.get("code") != 200:
return f"❌ 获取数据集分类失败: {asset_icon_result.get('msg', '未知错误')}"
data = asset_icon_result.get("data", [])
child_categories = []
for category in data:
if category.get("id") == parent_id:
second_list = category.get("second_asset_icon_list", [])
if second_list:
for item in second_list:
grandchild_list = item.get("second_asset_icon_list", [])
if grandchild_list:
for grandchild in grandchild_list:
child_categories.append({
"id": grandchild.get("id"),
"name": grandchild.get("name"),
"parent_id": grandchild.get("parent_id"),
"path": grandchild.get("path")
})
else:
child_categories.append({
"id": item.get("id"),
"name": item.get("name"),
"parent_id": item.get("parent_id"),
"path": item.get("path")
})
break
return {
"code": 200,
"msg": "操作成功",
"data": child_categories
}
except Exception as e:
return f"❌ 获取叶子节点列表失败: {str(e)}"
@mcp.tool()
async def get_data_types(token: str) -> str:
"""
获取所有可用的数据类型列表仅叶子节点用于直接选择
参数:
- token: 访问令牌
返回: 所有叶子节点列表格式为 {"code": 200, "msg": "操作成功", "data": [{"id": 138, "name": "通用数据", "parent_id": 137, "path": "icon-tongyongshuju"}, ...]}
"""
import json
try:
asset_icon_result = await query_asset_icon(token)
if isinstance(asset_icon_result, str):
try:
asset_icon_result = json.loads(asset_icon_result)
except:
return f"❌ 解析数据集分类失败"
if asset_icon_result.get("code") != 200:
return f"❌ 获取数据集分类失败: {asset_icon_result.get('msg', '未知错误')}"
data = asset_icon_result.get("data", [])
data_types = []
for category in data:
second_list = category.get("second_asset_icon_list", [])
if second_list:
for item in second_list:
grandchild_list = item.get("second_asset_icon_list", [])
if grandchild_list:
for grandchild in grandchild_list:
data_types.append({
"id": grandchild.get("id"),
"name": grandchild.get("name"),
"parent_id": grandchild.get("parent_id"),
"path": grandchild.get("path")
})
else:
data_types.append({
"id": item.get("id"),
"name": item.get("name"),
"parent_id": item.get("parent_id"),
"path": item.get("path")
})
else:
data_types.append({
"id": category.get("id"),
"name": category.get("name"),
"parent_id": category.get("parent_id"),
"path": category.get("path")
})
return {
"code": 200,
"msg": "操作成功",
"data": data_types
}
except Exception as e:
return f"❌ 获取数据类型列表失败: {str(e)}"
if __name__ == "__main__":
print(f"🚀 启动数据集 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,166 +0,0 @@
import asyncio
import hashlib
import json
import os
import sys
import time
import httpx
from common.config import API_BASE_URL
DEFAULT_SIZE = 10 * 1024 * 1024 # 10MB
def compute_md5(file_path: str) -> str:
file_size = os.path.getsize(file_path)
chunk_size = min(DEFAULT_SIZE, file_size)
with open(file_path, "rb") as f:
data = f.read(chunk_size)
md5 = hashlib.md5(data).hexdigest()
filename = os.path.basename(file_path)
name_bytes = filename.encode('utf-8')
combined = md5.encode('utf-8') + name_bytes
return hashlib.md5(combined).hexdigest()
async def get_upload_task(token: str, params: dict) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/chunk"
headers = {"Authorization": f"Bearer {token}"}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
return response.json()
async def upload_chunk(token: str, file_path: str, part_number: int, total_chunks: int, identifier: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/chunk"
file_size = os.path.getsize(file_path)
filename = os.path.basename(file_path)
start = DEFAULT_SIZE * (part_number - 1)
end = min(start + DEFAULT_SIZE, file_size)
current_chunk_size = end - start
with open(file_path, "rb") as f:
f.seek(start)
blob_data = f.read(current_chunk_size)
files = {
"chunkNumber": (None, str(part_number)),
"chunkSize": (None, str(DEFAULT_SIZE)),
"currentChunkSize": (None, str(current_chunk_size)),
"filename": (None, filename),
"relativePath": (None, filename),
"identifier": (None, identifier),
"totalChunks": (None, str(total_chunks)),
"totalSize": (None, str(file_size)),
"upfile": (filename, blob_data),
}
headers = {"Authorization": f"Bearer {token}"}
async with httpx.AsyncClient(timeout=600.0) as client:
response = await client.post(url, files=files, headers=headers)
response.raise_for_status()
return response.json()
async def merge_chunks(token: str, file_path: str, identifier: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/mergeFile"
file_size = os.path.getsize(file_path)
filename = os.path.basename(file_path)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json; charset=UTF-8",
}
payload = {
"fileType": "application/zip",
"name": filename,
"relativePath": filename,
"size": file_size,
"uniqueIdentifier": identifier,
"refProjectId": "123456789",
}
async with httpx.AsyncClient(timeout=600.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
async def get_merge_status(token: str, filename: str, identifier: str) -> dict:
url = f"{API_BASE_URL}/api/mmp/uploader/selectFile"
headers = {"Authorization": f"Bearer {token}"}
params = {"filename": filename, "identifier": identifier}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
return response.json()
async def upload_file(token: str, file_path: str) -> dict:
file_size = os.path.getsize(file_path)
filename = os.path.basename(file_path)
total_chunks = max(1, (file_size + DEFAULT_SIZE - 1) // DEFAULT_SIZE)
identifier = compute_md5(file_path)
print(f"File: {filename}, Size: {file_size}, Chunks: {total_chunks}, MD5: {identifier}")
task_params = {
"chunkNumber": 1,
"chunkSize": DEFAULT_SIZE,
"currentChunkSize": min(DEFAULT_SIZE, file_size),
"totalSize": file_size,
"identifier": identifier,
"filename": filename,
"relativePath": filename,
"totalChunks": total_chunks,
}
task_result = await get_upload_task(token, task_params)
print(f"Task result: {json.dumps(task_result, ensure_ascii=False)}")
if task_result.get("code") != 200:
raise Exception(f"Get upload task failed: {task_result}")
task = task_result.get("data", {})
if task.get("skip_upload"):
print("File already uploaded, skipping upload")
return task
for part in range(1, total_chunks + 1):
print(f"Uploading chunk {part}/{total_chunks}...")
result = await upload_chunk(token, file_path, part, total_chunks, identifier)
print(f" Chunk {part} result: {json.dumps(result, ensure_ascii=False)}")
print("Merging chunks...")
merge_result = await merge_chunks(token, file_path, identifier)
print(f"Merge result: {json.dumps(merge_result, ensure_ascii=False)}")
if merge_result.get("code") != 200:
raise Exception(f"Merge failed: {merge_result}")
merge_data = merge_result.get("data", {})
if merge_data.get("state") == "Succeeded":
print("Merge succeeded immediately!")
return merge_data
if merge_data.get("location"):
print("Merge has location, returning immediately despite state:", merge_data.get("state"))
return merge_data
for i in range(30):
await asyncio.sleep(3)
status_result = await get_merge_status(token, filename, identifier)
status_data = status_result.get("data", {})
state = status_data.get("state")
print(f" Merge status poll #{i+1}: {state}")
if state == "Succeeded":
print("Merge succeeded!")
return status_data
elif state == "Failed":
if status_data.get("location"):
print("Merge has location despite Failed state, using it")
return status_data
raise Exception(f"Merge failed: {status_result}")
raise Exception("Merge status polling timed out")
async def main():
token = sys.argv[1]
file_path = sys.argv[2]
result = await upload_file(token, file_path)
print(f"\nFinal result:\n{json.dumps(result, ensure_ascii=False, indent=2)}")
if __name__ == "__main__":
asyncio.run(main())

View File

@ -1,75 +0,0 @@
---
name: delete-dataset
description: 当用户需要删除数据集或版本时,请使用此技能。
triggers:
- "删除数据集"
- "删除数据集版本"
metadata:
api-base: http://172.20.32.121:31213
---
# 删除数据集(调用接口)
## 何时使用
- 用户需要删除数据集版本
- 用户需要删除整个数据集
## 执行流程Agent 必须遵守)
### 删除数据集版本
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- git_id `git_id`
- owner `owner`
- identifier `identifier`
- relative_paths `relative_paths`
- version `version`
- 若缺失用户名和密码,必须先向用户询问
2. **调用登录接口获取token**
- 调用`common/login_mcp_server.login`方法
- 获取 `access_token`
3. **删除版本**
- 调用`scripts/delete_mcp_server.delete_dataset_version`方法
4. **反馈结果**
- ✅ 成功:返回操作成功信息
- ❌ 失败:返回错误码和错误信息
### 删除数据集
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- id `id`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
3. **删除数据集**
- 调用`scripts/delete_mcp_server.delete_dataset`方法
4. **反馈结果**
---
## 示例对话
**用户:**
> 帮我删除数据集id是46
**Agent 行为:**
1. 询问用户名和密码
2. 调用登录接口获取token
3. 调用删除数据集接口
4. 返回删除结果
---
## 注意事项
- Token 有效期由服务端控制,过期需重新登录
- 不建议将用户名、密码、Token 写入日志
- 删除操作不可逆,请谨慎操作

View File

@ -1,63 +0,0 @@
import httpx
from mcp.server.fastmcp import FastMCP
from common.config import API_BASE_URL, TRANSPORT_MODE
mcp = FastMCP("删除数据集mcp server")
@mcp.tool()
async def delete_dataset_version(
token: str,
git_id: int,
owner: str,
identifier: str,
relative_paths: str,
version: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/deleteDatasetVersion"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"git_id": git_id,
"owner": owner,
"identifier": identifier,
"relative_paths": relative_paths,
"version": version
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.delete(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 删除数据集版本失败: {str(e)}"
@mcp.tool()
async def delete_dataset(
token: str,
id: int
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/deleteDataset/{id}"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.delete(url, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 删除数据集失败: {str(e)}"
if __name__ == "__main__":
print(f"🚀 启动删除数据集 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,77 +0,0 @@
---
name: download-dataset
description: 当用户需要下载数据集版本文件时,请使用此技能。
triggers:
- "下载数据集"
- "下载数据集版本"
- "下载数据集文件"
metadata:
api-base: http://172.20.32.121:31213
---
# 下载数据集版本文件(调用接口)
## 何时使用
- 用户需要下载数据集当前版本的所有文件
- 用户需要下载数据集当前版本的单个文件
## 执行流程Agent 必须遵守)
### 下载当前版本所有文件打包
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- name `name`
- git_id `git_id`
- version `version`
- identifier `identifier`
- owner `owner`
- is_public `is_public`
- 若缺失用户名和密码,必须先向用户询问
2. **调用登录接口获取token**
- 调用`common/login_mcp_server.login`方法
- 获取 `access_token`
3. **下载文件**
- 调用`scripts/download_mcp_server.download_all_files`方法
4. **反馈结果**
- ✅ 成功:返回文件内容
- ❌ 失败:返回错误码和错误信息
### 下载当前版本选中文件
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- url `url`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
3. **下载文件**
- 调用`scripts/download_mcp_server.download_single_file`方法
4. **反馈结果**
---
## 示例对话
**用户:**
> 帮我下载数据集的所有文件name是test121git_id是125version是v1identifier是fanshuai_dataset_20260519104635owner是fanshuaiis_public是false
**Agent 行为:**
1. 询问用户名和密码
2. 调用登录接口获取token
3. 调用下载所有文件接口
4. 返回文件内容
---
## 注意事项
- Token 有效期由服务端控制,过期需重新登录
- 不建议将用户名、密码、Token 写入日志
- 下载文件可能较大,请确保网络连接稳定

View File

@ -1,66 +0,0 @@
import httpx
from mcp.server.fastmcp import FastMCP
from common.config import API_BASE_URL, TRANSPORT_MODE
mcp = FastMCP("下载数据集mcp server")
@mcp.tool()
async def download_all_files(
token: str,
name: str,
git_id: int,
version: str,
identifier: str,
owner: str,
is_public: bool
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/downloadAllFiles"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"name": name,
"git_id": git_id,
"version": version,
"identifier": identifier,
"owner": owner,
"is_public": is_public
}
try:
async with httpx.AsyncClient(timeout=300.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
return f"✅ 下载成功,文件大小: {len(response.content)} 字节"
except Exception as e:
return f"❌ 下载所有文件失败: {str(e)}"
@mcp.tool()
async def download_single_file(
token: str,
url: str
) -> str:
api_url = f"{API_BASE_URL}/api/mmp/newdataset/downloadSingleFile"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"url": url
}
try:
async with httpx.AsyncClient(timeout=300.0) as client:
response = await client.get(api_url, params=params, headers=headers)
response.raise_for_status()
return f"✅ 下载成功,文件大小: {len(response.content)} 字节"
except Exception as e:
return f"❌ 下载单个文件失败: {str(e)}"
if __name__ == "__main__":
print(f"🚀 启动下载数据集 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,97 +0,0 @@
---
name: query-dataset
description: 当用户需要查询数据集信息时,请使用此技能。
triggers:
- "查询数据集"
- "查询数据集列表"
- "查询数据集详情"
- "发布数据集"
metadata:
api-base: http://172.20.32.121:31213
---
# 查询数据集(调用接口)
## 何时使用
- 用户需要查询数据集列表
- 用户需要查询数据集详情
- 用户需要发布数据集
## 执行流程Agent 必须遵守)
### 查询数据集列表
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 页码 `page`可选默认0
- 每页大小 `size`可选默认20
- 是否公开 `is_public`(可选)
- 数据类型 `data_type`(可选)
- 是否热门 `is_hot_stone`(可选)
- 若缺失用户名和密码,必须先向用户询问
2. **调用登录接口获取token**
- 调用`common/login_mcp_server.login`方法
- 获取 `access_token`
3. **查询数据集列表**
- 调用`scripts/query_mcp_server.query_datasets`方法
4. **反馈结果**
- ✅ 成功:返回数据集列表
- ❌ 失败:返回错误码和错误信息
### 查询数据集详情
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- git_id `git_id`
- owner `owner`
- name `name`
- identifier `identifier`
- is_public `is_public`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
3. **查询数据集详情**
- 调用`scripts/query_mcp_server.get_dataset_detail`方法
4. **反馈结果**
### 发布数据集
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- id `id`
- name `name`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
3. **发布数据集**
- 调用`scripts/query_mcp_server.publish_dataset`方法
4. **反馈结果**
---
## 示例对话
**用户:**
> 帮我查询数据集列表
**Agent 行为:**
1. 询问用户名和密码
2. 调用登录接口获取token
3. 调用查询数据集列表接口
4. 返回数据集列表
---
## 注意事项
- Token 有效期由服务端控制,过期需重新登录
- 不建议将用户名、密码、Token 写入日志

View File

@ -1,129 +0,0 @@
import httpx
from mcp.server.fastmcp import FastMCP
from common.config import API_BASE_URL, TRANSPORT_MODE
mcp = FastMCP("查询数据集mcp server")
@mcp.tool()
async def query_datasets(
token: str,
page: int = 0,
size: int = 20,
is_public: bool = None,
data_type: str = "",
is_hot_stone: bool = None
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/queryDatasets"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size
}
if is_public is not None:
params["is_public"] = is_public
if data_type:
params["data_type"] = data_type
if is_hot_stone is not None:
params["is_hot_stone"] = is_hot_stone
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询数据集列表失败: {str(e)}"
@mcp.tool()
async def get_dataset_detail(
token: str,
git_id: int,
owner: str,
name: str,
identifier: str,
is_public: bool
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/getDatasetDetail"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"git_id": git_id,
"owner": owner,
"name": name,
"identifier": identifier,
"is_public": is_public
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询数据集详情失败: {str(e)}"
@mcp.tool()
async def publish_dataset(
token: str,
id: int,
name: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/publish"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"id": id,
"name": name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 发布数据集失败: {str(e)}"
@mcp.tool()
async def get_version_list(
token: str,
owner: str,
identifier: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/getVersionList"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"owner": owner,
"identifier": identifier
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 获取版本列表失败: {str(e)}"
if __name__ == "__main__":
print(f"🚀 启动查询数据集 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,85 +0,0 @@
---
name: update-dataset
description: 当用户需要修改数据集信息时,请使用此技能。
triggers:
- "修改数据集"
- "编辑数据集"
- "修改数据集简介"
metadata:
api-base: http://172.20.32.121:31213
---
# 修改数据集(调用接口)
## 何时使用
- 用户需要修改数据集信息
- 用户需要修改数据集简介
## 执行流程Agent 必须遵守)
### 修改数据集
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- id `id`
- name `name`
- identifier `identifier`
- description `description`(可选)
- is_public `is_public`
- data_type `data_type`
- data_tag `data_tag`
- owner `owner`
- dataset_source `dataset_source`
- relative_paths `relative_paths`
- is_hot_stone `is_hot_stone`
- git_id `git_id`
- preview_pic `preview_pic`
- 若缺失用户名和密码,必须先向用户询问
2. **调用登录接口获取token**
- 调用`common/login_mcp_server.login`方法
- 获取 `access_token`
3. **修改数据集**
- 调用`scripts/update_mcp_server.update_dataset`方法
4. **反馈结果**
- ✅ 成功:返回修改后的数据集信息
- ❌ 失败:返回错误码和错误信息
### 修改数据集简介
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- git_id `git_id`
- identifier `identifier`
- description `description`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
3. **修改数据集简介**
- 调用`scripts/update_mcp_server.update_dataset_desc`方法
4. **反馈结果**
---
## 示例对话
**用户:**
> 帮我修改数据集简介git_id是125identifier是fanshuai_dataset_20260519104635简介是新的描述内容
**Agent 行为:**
1. 询问用户名和密码
2. 调用登录接口获取token
3. 调用修改数据集简介接口
4. 返回修改结果
---
## 注意事项
- Token 有效期由服务端控制,过期需重新登录
- 不建议将用户名、密码、Token 写入日志

View File

@ -1,91 +0,0 @@
import httpx
from mcp.server.fastmcp import FastMCP
from common.config import API_BASE_URL, TRANSPORT_MODE
mcp = FastMCP("修改数据集mcp server")
@mcp.tool()
async def update_dataset(
token: str,
id: int,
name: str,
identifier: str,
description: str = "",
is_public: bool = False,
data_type: str = "通用数据",
data_tag: str = "",
owner: str = "",
dataset_source: str = "add",
relative_paths: str = "",
is_hot_stone: bool = False,
git_id: int = 0,
preview_pic: str = ""
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/updateDataset"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"id": id,
"name": name,
"identifier": identifier,
"description": description,
"is_public": is_public,
"data_type": data_type,
"data_tag": data_tag,
"praises_count": 0,
"praised": False,
"create_by": owner,
"update_time": "",
"owner": owner,
"dataset_source": dataset_source,
"relative_paths": relative_paths,
"is_hot_stone": is_hot_stone,
"git_id": git_id,
"preview_pic": preview_pic,
"type": 0
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.put(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 修改数据集失败: {str(e)}"
@mcp.tool()
async def update_dataset_desc(
token: str,
git_id: int,
identifier: str,
description: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/newdataset/updateDesc"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"git_id": git_id,
"identifier": identifier,
"description": description
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.put(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 修改数据集简介失败: {str(e)}"
if __name__ == "__main__":
print(f"🚀 启动修改数据集 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,46 +0,0 @@
---
name: delete-code
description: 当用户需要删除代码配置时,请使用此技能。
triggers:
- "删除代码配置"
metadata:
api-base: https://www.ai4mats.com
---
# 删除代码配置(调用接口)
## 何时使用
- 用户需要删除代码配置时
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **输入参数**
- `page` (默认0)
- `size` (默认20)
- `code_repo_name`(镜像名称,非必填)
4. **查询代码配置**
- 调用`scripts/query_code_mcp_server.query_code`方法
- 参数:`token`(来自步骤2), `page`(来自步骤3), `size`(来自步骤3), `code_repo_name`(来自步骤3)
5. **展示结果**
- 将查询结果的总数展示出来,列表展示代码配置列表
6. **继续查询**
- 询问用户是否需要查询下一页的数据如果需要则page参数加1再次运行步骤4步骤5
- 否则结束查询
7. **删除代码配置**
- 用户从步骤4的结果中选择需要删除的代码配置
- 调用`scripts/delete_code_mcp_server.delete_code`方法
- 参数:`token`(来自步骤2), `id`(来自步骤4)

View File

@ -1,84 +0,0 @@
import json
import os
import httpx
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
@mcp.tool()
async def query_code(
token: str,
page: int,
size: int,
code_repo_name: str
):
url = f"{API_BASE_URL}/api/mmp/codeConfig"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": False,
"code_repo_name": code_repo_name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询代码配置列表失败: {str(e)}"
@mcp.tool()
async def delete_code(
token: str,
id: int
):
url = f"{API_BASE_URL}/api/mmp/codeConfig/" + str(id)
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.delete(url, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 删除代码配置失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,61 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,46 +0,0 @@
---
name: delete-image
description: 当用户需要删除镜像时,请使用此技能。
triggers:
- "删除镜像"
metadata:
api-base: https://www.ai4mats.com
---
# 删除镜像(调用接口)
## 何时使用
- 用户需要删除镜像时
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **输入参数**
- `page` (默认0)
- `size` (默认20)
- `name`(镜像名称,非必填)
4. **查询镜像**
- 调用`scripts/query_image_mcp_server.query_image`方法
- 参数:`token`(来自步骤2), `page`(来自步骤3), `size`(来自步骤3), `name`(来自步骤3)
5. **展示结果**
- 将查询结果的总数展示出来,列表展示镜像列表
6. **继续查询**
- 询问用户是否需要查询下一页的数据如果需要则page参数加1再次运行步骤4步骤5
- 否则结束查询
7. **删除镜像**
- 用户从步骤4的结果中选择需要删除的镜像
- 调用`scripts/delete_image_mcp_server.delete_image`方法
- 参数:`token`(来自步骤2), id(来自步骤4)

View File

@ -1,84 +0,0 @@
import json
import os
import httpx
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
@mcp.tool()
async def query_image(
token: str,
page: int,
size: int,
name: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/image"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": False,
"name": name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询镜像列表失败: {str(e)}"
@mcp.tool()
async def delete_image(
token: str,
id: int
) -> str:
url = f"{API_BASE_URL}/api/mmp/image/" + str(id)
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.delete(url, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 删除镜像失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,61 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,46 +0,0 @@
---
name: delete-model
description: 当用户需要删除模型时,请使用此技能。
triggers:
- "删除模型"
metadata:
api-base: https://www.ai4mats.com
---
# 删除模型(调用接口)
## 何时使用
- 用户需要删除模型时
## 执行流程Agent 必须遵守)
1. **用户登录**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
- 非必填参数:
- 模型类型 `model_type`
- 模型标签 `model_tag`
- 是否包含火石模型 `is_hot_stone`
- 模型名称 `name`
- 可以询问用户是否需要查询指定模型类型,模型标签,是否包含火石模型,模型名称的模型
- 默认参数:
- page = 0
- size = 20
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **查询模型**
- 调用`scripts/delete_model_mcp_server.query_model`方法
- 参数:`token`(来自步骤2), `model_type`, `model_tag`, `is_hot_stone`, `name`, `page`, `size`
- 如果用户说继续查询下一页则page加1后继续查询否则结束查询
4. **删除模型**
- 用户从步骤3的结果中选择需要删除的模型
- 调用`scripts/delete_model_mcp_server.delete_model`方法
- 参数:`token`(来自步骤2), id(来自步骤3)

View File

@ -1,92 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("模型mcp server")
@mcp.tool()
async def query_model(
token: str,
model_type: str,
model_tag: str,
is_hot_stone: bool,
name: str,
page: int,
size: int
) -> str:
url = f"{API_BASE_URL}/api/mmp/newmodel/queryModels"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"model_type": model_type,
"model_tag": model_tag,
"is_hot_stone": is_hot_stone,
"name": name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 查询模型失败: {str(e)}"
@mcp.tool()
async def delete_model(
token: str,
id: int
) -> str:
url = f"{API_BASE_URL}/api/mmp/newmodel/delete/" + str(id)
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.delete(url, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 删除模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,61 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,48 +0,0 @@
---
name: delete-serivce
description: 当用户需要删除应用时,请使用此技能。
triggers:
- "删除应用"
metadata:
api-base: https://www.ai4mats.com
---
# 删除应用
## 何时使用
- 用户需要删除应用时
## 执行流程Agent 必须遵守)
1. **确认参数**
- 如果有token则跳过步骤1步骤2token过期则再从这一步开始执行
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **输入参数**
- `page` (默认0)
- `size` (默认20)
- `service_name`(镜像名称,非必填)
4. **查询我的应用**
- 调用`scripts/delete_service_mcp_server.query_service`方法
- 参数:`token`(来自步骤2), `page`(来自步骤3), `size`(来自步骤3), `service_name`, `order_by` = "mine"
5. **展示结果**
- 将查询结果的总数展示出来,列表展示应用列表
6. **继续查询**
- 询问用户是否需要查询下一页的数据如果需要则page参数加1再次运行步骤4步骤5
- 否则结束查询
7. **删除应用**
- 用户从步骤4的结果中选择需要删除的应用
- 调用`scripts/delete_service_mcp_server.delete_service`方法
- 参数:`token`(来自步骤2), id(来自步骤4)

View File

@ -1,86 +0,0 @@
import json
import os
import httpx
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("service mcp server")
@mcp.tool()
async def query_service(
token: str,
page: int,
size: int,
service_name: str,
is_selected: bool,
is_public: bool,
order_by: str
):
url = f"{API_BASE_URL}/api/mmp/service"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"service_name": service_name,
"is_selected": is_selected,
"is_public": is_public,
"order_by": order_by,
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询应用列表失败: {str(e)}"
@mcp.tool()
async def delete_service(token: str,
id: int):
url = f"{API_BASE_URL}/api/mmp/service/" + str(id)
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.delete(url, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 删除应用失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,60 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,45 +0,0 @@
---
name: query-code
description: 当用户需要查询代码配置时,请使用此技能。
triggers:
- "查询代码配置"
metadata:
api-base: https://www.ai4mats.com
---
# 查询代码配置(调用接口)
## 何时使用
- 用户需要查询代码配置时
## 执行流程Agent 必须遵守)
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **输入参数**
- 查询公开代码配置还是个人代码配置 `is_public`(bool类型)
- `page` (默认0)
- `size` (默认20)
- `code_repo_name`(代码配置名称,非必填)
4. **查询代码配置**
- 调用`scripts/query_code_mcp_server.query_code`方法
- 参数:`token`(来自步骤2), `page`(来自步骤3), `size`(来自步骤3), `is_public`(来自步骤3), `code_repo_name`(来自步骤3)
5. **展示结果**
- 将查询结果的总数展示出来,列表展示代码配置列表
6. **继续查询**
- 询问用户是否需要查询下一页的数据如果需要则page参数加1再次运行步骤4步骤5
- 否则结束任务

View File

@ -1,61 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,66 +0,0 @@
import json
import os
import httpx
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
@mcp.tool()
async def query_code(
token: str,
page: int,
size: int,
is_public: bool,
code_repo_name: str
):
url = f"{API_BASE_URL}/api/mmp/codeConfig"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": is_public,
"code_repo_name": code_repo_name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询代码配置列表失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,43 +0,0 @@
---
name: query-image
description: 当用户需要查询镜像时,请使用此技能。
triggers:
- "查询镜像"
metadata:
api-base: https://www.ai4mats.com
---
# 查询镜像(调用接口)
## 何时使用
- 用户需要查询镜像时
## 执行流程Agent 必须遵守)
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **输入参数**
- 查询公开镜像还是个人镜像 `is_public`(bool类型)
- `page` (默认0)
- `size` (默认20)
- `name`(镜像名称,非必填)
4. **查询镜像**
- 调用`scripts/query_image_mcp_server.query_image`方法
- 参数:`token`(来自步骤2), `page`(来自步骤3), `size`(来自步骤3), `is_public`(来自步骤3), `name`(来自步骤3)
5. **展示结果**
- 将查询结果的总数展示出来,列表展示镜像列表
6. **继续查询**
- 询问用户是否需要查询下一页的数据如果需要则page参数加1再次运行步骤4步骤5
- 否则结束任务

View File

@ -1,61 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,66 +0,0 @@
import json
import os
import httpx
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
@mcp.tool()
async def query_image(
token: str,
page: int,
size: int,
is_public: bool,
name: str
) -> str:
url = f"{API_BASE_URL}/api/mmp/image"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": is_public,
"name": name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询镜像列表失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,50 +0,0 @@
---
name: query-model
description: 当用户需要查询模型时,请使用此技能。
triggers:
- "查询模型"
metadata:
api-base: https://www.ai4mats.com
---
# 查询模型(调用接口)
## 何时使用
- 用户需要查询模型时
## 执行流程Agent 必须遵守)
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 查询公开还是私有模型 `is_public`
- 若缺失,必须先向用户询问
- 非必填参数:
- 模型类型 `model_type`
- 模型标签 `model_tag`
- 是否包含火石模型 `is_hot_stone`
- 模型名称 `name`
- 可以询问用户是否需要查询指定模型类型,模型标签,是否包含火石模型,模型名称的模型
- 默认参数:
- page = 0
- size = 20
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **查询模型**
- 调用`scripts/query_model_mcp_server.query_model`方法
- 参数:`token`(来自步骤2), `is_public`, `model_type`, `model_tag`, `is_hot_stone`, `name`, `page`, `size`
4. **展示结果**
- 将查询结果的总数展示出来,列表展示模型列表
5. **继续查询**
- 询问用户是否需要查询下一页的数据如果需要则page参数加1再次运行步骤3步骤4
- 询问用户是否需要查询某一个模型的详细信息,如果需要则调用`scripts/query_model_mcp_server.get_model_detail`方法
- 参数: `token`(来自步骤2), `git_id`(来自步骤3), `identifier`(来自步骤3), `owner`(来自步骤3的结果中的create_by字段), `is_public`
- 否则结束任务

View File

@ -1,62 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,99 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("模型mcp server")
@mcp.tool()
async def query_model(
token: str,
is_public: bool,
model_type: str,
model_tag: str,
is_hot_stone: bool,
name: str,
page: int,
size: int
) -> str:
url = f"{API_BASE_URL}/api/mmp/newmodel/queryModels"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": is_public,
"model_type": model_type,
"model_tag": model_tag,
"is_hot_stone": is_hot_stone,
"name": name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询模型列表失败: {str(e)}"
@mcp.tool()
async def get_model_detail(
token: str,
git_id: int,
identifier: str,
owner: str,
is_public: bool
) -> str:
url = f"{API_BASE_URL}/api/mmp/newmodel/getModelDetail"
headers = {"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"}
params = {
"git_id": git_id,
"identifier": identifier,
"is_public": is_public,
"owner": owner
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 查询模型详情失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,57 +0,0 @@
import httpx
import json
import sys
API_BASE_URL = "https://www.ai4mats.com"
async def login(username, password):
url = f"{API_BASE_URL}/api/auth/login"
headers = {"Content-Type": "application/json; charset=UTF-8"}
payload = {"username": username, "password": password}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
async def query_model(token, is_public, model_type="", model_tag="", is_hot_stone=None, name="", page=0, size=20):
url = f"{API_BASE_URL}/api/mmp/newmodel/queryModels"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": is_public,
"model_type": model_type,
"model_tag": model_tag,
"name": name
}
if is_hot_stone is not None:
params["is_hot_stone"] = is_hot_stone
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
return response.json()
if __name__ == "__main__":
import asyncio
args = sys.argv[1:]
username = args[0]
password = args[1]
is_public = args[2] == "true"
model_type = args[3]
model_tag = args[4]
is_hot_stone = args[5] if args[5] != "None" else None
if is_hot_stone is not None:
is_hot_stone = is_hot_stone == "true"
name = args[6]
page = int(args[7])
size = int(args[8])
result = asyncio.run(login(username, password))
token = result.get("access_token") or result.get("token") or result.get("data", {}).get("access_token") or result.get("data", {}).get("token")
print(f"TOKEN:{token}")
result = asyncio.run(query_model(token, is_public, model_type, model_tag, is_hot_stone, name, page, size))
print(f"RESULT:{json.dumps(result, ensure_ascii=False)}")

View File

@ -1,47 +0,0 @@
---
name: query-service
description: 当用户需要查询应用时,请使用此技能。
triggers:
- "查询应用"
metadata:
api-base: https://www.ai4mats.com
---
# 查询应用
## 何时使用
- 用户需要查询应用时
## 执行流程Agent 必须遵守)
1. **确认参数**
- 如果有token则跳过步骤1步骤2token过期则再从这一步开始执行
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **输入参数**
- `page` (默认0)
- `size` (默认20)
- `service_name`(镜像名称,非必填)
4. **查询应用**
- 询问用户是需要查询精选应用,全部应用,我的应用,还是我的收藏;调用`scripts/query_service_mcp_server.query_service`方法
- 1. 如果是查询精选应用,则传入参数:`token`(来自步骤2), `page`(来自步骤3), `size`(来自步骤3), `service_name`, `is_selected` = True, `is_public` = True, `order_by` = "markCount"
- 2. 如果是查询全部应用,则传入参数:`token`(来自步骤2), `page`(来自步骤3), `size`(来自步骤3), `service_name`, `is_public` = True, `order_by` = "markCount"
- 3. 如果是查询我的应用,则传入参数:`token`(来自步骤2), `page`(来自步骤3), `size`(来自步骤3), `service_name`, `order_by` = "mine"
- 4. 如果是查询我的收藏,则调用`scripts/query_service_mcp_server.query_mark_service`方法,传入参数:`token`(来自步骤2), `page`(来自步骤3), `size`(来自步骤3), `service_name`
5. **展示结果**
- 将查询结果的总数展示出来,列表展示应用列表
6. **继续查询**
- 询问用户是否需要查询下一页的数据如果需要则page参数加1再次运行步骤4步骤5
- 询问用户是否需要查询某一个应用的详细信息,如果需要则调用`scripts/query_service_mcp_server.get_service_detail`方法,传入参数:`token`(来自步骤2), `id`(来自选择的应用)
- 否则结束任务

View File

@ -1,60 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,111 +0,0 @@
import json
import os
import httpx
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("service mcp server")
@mcp.tool()
async def query_service(
token: str,
page: int,
size: int,
service_name: str,
is_selected: bool,
is_public: bool,
order_by: str
):
url = f"{API_BASE_URL}/api/mmp/service"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"service_name": service_name,
"is_selected": is_selected,
"is_public": is_public,
"order_by": order_by,
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询应用列表失败: {str(e)}"
@mcp.tool()
async def query_mark_service(
token: str,
page: int,
size: int,
service_name: str):
url = f"{API_BASE_URL}/api/mmp/service"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"service_name": service_name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询我的收藏应用列表失败: {str(e)}"
@mcp.tool()
async def get_service_detail(token: str,
id: int):
url = f"{API_BASE_URL}/api/mmp/service/serviceDetail/" + str(id)
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询应用详情失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,140 +0,0 @@
---
name: smart-compute
description: 智算应用创建和部署,包括登录、镜像查询、模型查询、代码查询等功能
triggers:
- "创建智算应用"
- "智算应用部署"
- "部署智算应用"
metadata:
api-base: https://www.ai4mats.com
jsm-api-base: https://ai4m.jointcloud.net
---
# 智算应用创建与部署
## 何时使用
- 用户需要创建智算应用
- 用户需要查询镜像、模型、代码资源
- 用户提到"创建智算应用"、"智算应用部署"等
## 接口文档参考
执行过程中,请随时参考接口文档:`智算应用创建全流程接口文档.md`
## 执行流程Agent 必须遵守)
### 1. 登录平台获取 Token
- 确认是否已有 token如没有则询问用户名和密码
- 调用 `scripts/login_mcp_server.login_platform` 方法
- 参数:`username`, `password`
- 获取以下信息并保存:
- `platform_token``data.access_token`
### 2. 创建智算应用
- 询问用户:应用名称
- 调用 `scripts/deploy_mcp_server.create_service` 方法
- 参数:
- `token``platform_token`
- `service_name`:用户输入
- `service_type`"机器学习"(默认)
- `description`:同应用名称
- `tag`:同应用名称
- `img_url`:默认值
- 保存返回的应用ID
### 3. 登录外部系统获取 Token 和 UserID
- 调用 `scripts/login_mcp_server.login_jsm` 方法
- 获取以下信息并保存:
- `jsm_token``data.token`
- `user_id``data.jsmUserInfo.data.userID`
### 4. 查询资源类型列表
- 调用 `scripts/resource_mcp_server.get_resource_ranges` 方法
- 参数:
- `token``jsm_token`
- `user_id`:从登录结果获取
- `compute_type`"1"(默认)
- 获取可用的资源范围
### 5. 查询资源规格列表
- 调用 `scripts/resource_mcp_server.query_resource_specs` 方法
- 参数:
- `token``jsm_token`
- `query_resource`:从资源类型列表取第一个
- `resource_type`"Train"(默认)
- `cluster_ids`["1865927992266461184"](默认)
- 获取可用的资源规格,让用户选择一个
### 6. 查询镜像资源
- 调用 `scripts/image_mcp_server.query_images` 方法
- 参数:
- `token``jsm_token`
- `card_types`["GPU"](默认)
- 获取可用镜像列表,让用户选择一个
### 7. 查询代码资源
- 调用 `scripts/code_mcp_server.query_code` 方法
- 参数:
- `token``platform_token`
- `page`0
- `size`20
- `is_public`true
- 获取可用代码列表,让用户选择一个
### 8. 查询模型资源
- 调用 `scripts/model_mcp_server.query_model` 方法
- 参数:
- `token``platform_token`
- `is_public`false
- `page`0
- `size`2000
- 获取可用模型列表,让用户选择一个
### 9. 获取模型版本列表
- 调用 `scripts/model_mcp_server.get_version_list` 方法
- 参数:
- `token``platform_token`
- `owner`:从选中模型中获取
- `identifier`:从选中模型中获取
- 获取版本列表,让用户选择一个
### 10. 获取模型详情
- 调用 `scripts/model_mcp_server.get_model_detail` 方法
- 参数:
- `token``platform_token`
- `git_id`:从选中模型中获取
- `identifier`:从选中模型中获取
- `owner`:从选中模型中获取
- `is_public`false
- `id`:从选中模型中获取
- `name`:从选中模型中获取
- `version`:从选中版本中获取
- 获取模型详情,保存路径
### 11. 创建智算应用版本
- 询问用户:版本号
- 调用 `scripts/deploy_mcp_server.create_version` 方法
- 参数:
- `token``platform_token`
- `service_id`从步骤2获取
- `version`用户输入v1
- `description`:同版本号
- `resource_type`:从选中资源规格中获取
- `image_resource`:从选中资源规格中获取,添加 label/value 字段
- `image`:从选中镜像中获取,添加 label/value 字段
- `command`"test_pl_vor.py"(默认)
- `code_config`:从选中代码中获取,添加 label/value/showValue/fromSelect/activeTab 字段
- `model`:从模型详情中获取,添加 label/value/showValue/fromSelect/activeTab 字段
- `deploy_type`"web"(默认)
### 12. 反馈结果
- ✅ 成功:返回创建结果
- ❌ 失败:返回错误码和错误信息
## 注意事项
- 有两套系统:
- 平台系统www.ai4mats.com用于创建应用、查询模型和代码
- JSM 系统ai4m.jointcloud.net用于查询资源和镜像
- Token 有效期为 604800 秒7天
- UserID 来自 data.jsmUserInfo.data.userID
- 不建议将用户名、密码、Token 写入日志
- 参考接口文档构建完整的 payload特别是 image_resource/image/code_config/model 等对象需要添加额外的字段

View File

@ -1,70 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"PLATFORM_API_BASE": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
PLATFORM_API_BASE = config.get("PLATFORM_API_BASE")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("智算应用代码查询")
@mcp.tool()
async def query_code(
token: str,
page: int = 0,
size: int = 20,
is_public: bool = True,
code_repo_name: str = ""
) -> str:
"""查询代码配置列表"""
url = f"{PLATFORM_API_BASE}/api/mmp/codeConfig"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": is_public
}
if code_repo_name:
params["code_repo_name"] = code_repo_name
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询代码配置列表失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动智算应用代码查询 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,5 +0,0 @@
{
"PLATFORM_API_BASE": "https://www.ai4mats.com",
"JSM_API_BASE": "https://ai4m.jointcloud.net",
"MCP_TRANSPORT": "stdio"
}

View File

@ -1,114 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"PLATFORM_API_BASE": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
PLATFORM_API_BASE = config.get("PLATFORM_API_BASE")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("智算应用部署")
@mcp.tool()
async def create_service(
token: str,
service_name: str,
service_type: str = "机器学习",
description: str = "",
tag: str = "",
img_url: str = "https://www.minio.ai4mats.com/data/mini-model-platform-data/temp/fanshuai/1761528061144/app-1.png"
) -> str:
"""创建智算应用"""
url = f"{PLATFORM_API_BASE}/api/mmp/service"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"service_name": service_name,
"service_type": service_type,
"source": 2,
"description": description or service_name,
"img_url": img_url,
"tag": tag or service_name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 创建智算应用失败: {str(e)}"
@mcp.tool()
async def create_version(
token: str,
service_id: int,
version: str,
description: str,
resource_type: str,
image_resource: dict,
image: dict,
command: str,
code_config: dict,
model: dict,
deploy_type: str = "web"
) -> str:
"""创建智算应用版本"""
url = f"{PLATFORM_API_BASE}/api/mmp/service/version"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"service_id": service_id,
"version": version,
"description": description,
"resource_type": resource_type,
"image_resource": image_resource,
"image": image,
"command": command,
"code_config": code_config,
"model": model,
"source": 2,
"deploy_type": deploy_type
}
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 创建智算应用版本失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动智算应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,65 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://ai4m.jointcloud.net",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("智算应用镜像查询")
@mcp.tool()
async def query_images(
token: str,
card_types: list = None
) -> str:
url = f"{API_BASE_URL}/jsm/jobSet/queryImages"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
if card_types is None:
card_types = ["GPU"]
payload = {
"cardTypes": card_types
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询镜像列表失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动智算应用镜像查询 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,82 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"PLATFORM_API_BASE": "https://www.ai4mats.com",
"JSM_API_BASE": "https://ai4m.jointcloud.net",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
PLATFORM_API_BASE = config.get("PLATFORM_API_BASE")
JSM_API_BASE = config.get("JSM_API_BASE")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("智算应用登录")
@mcp.tool()
async def login_platform(username: str, password: str) -> str:
"""登录平台系统www.ai4mats.com"""
url = f"{PLATFORM_API_BASE}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 登录平台失败: {str(e)}"
@mcp.tool()
async def login_jsm() -> str:
"""登录 JSM 系统ai4m.jointcloud.net"""
url = f"{JSM_API_BASE}/jcc-admin/admin/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": "hnxjy-super1",
"password": "h1n2x3j4y5@"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 登录 JSM 失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动智算应用登录 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,143 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"PLATFORM_API_BASE": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
PLATFORM_API_BASE = config.get("PLATFORM_API_BASE")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("智算应用模型查询")
@mcp.tool()
async def query_model(
token: str,
is_public: bool = False,
model_type: str = "",
model_tag: str = "",
is_hot_stone: bool = False,
name: str = "",
page: int = 0,
size: int = 2000
) -> str:
"""查询模型列表"""
url = f"{PLATFORM_API_BASE}/api/mmp/newmodel/queryModels"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": is_public,
"is_hot_stone": is_hot_stone
}
if model_type:
params["model_type"] = model_type
if model_tag:
params["model_tag"] = model_tag
if name:
params["name"] = name
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询模型列表失败: {str(e)}"
@mcp.tool()
async def get_version_list(token: str, owner: str, identifier: str) -> str:
"""获取模型版本列表"""
url = f"{PLATFORM_API_BASE}/api/mmp/newmodel/getVersionList"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"owner": owner,
"identifier": identifier
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 获取模型版本列表失败: {str(e)}"
@mcp.tool()
async def get_model_detail(
token: str,
git_id: int = None,
identifier: str = None,
owner: str = None,
is_public: bool = False,
id: int = None,
name: str = None,
version: str = None
) -> str:
"""获取模型详情"""
url = f"{PLATFORM_API_BASE}/api/mmp/newmodel/getModelDetail"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"is_public": is_public
}
if git_id is not None:
params["git_id"] = git_id
if identifier is not None:
params["identifier"] = identifier
if owner is not None:
params["owner"] = owner
if id is not None:
params["id"] = id
if name is not None:
params["name"] = name
if version is not None:
params["version"] = version
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 获取模型详情失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动智算应用模型查询 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,103 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://ai4m.jointcloud.net",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("智算应用资源查询")
@mcp.tool()
async def get_resource_ranges(
token: str,
user_id: int,
compute_type: str = "1"
) -> str:
url = f"{API_BASE_URL}/jsm/v2/resource/range"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
payload = {
"userID": user_id,
"computeType": compute_type
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询资源类型列表失败: {str(e)}"
@mcp.tool()
async def query_resource_specs(
token: str,
query_resource: dict = None,
resource_type: str = "Train",
cluster_ids: list = None
) -> str:
url = f"{API_BASE_URL}/jsm/v2/resource/query"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
if query_resource is None:
query_resource = {
"cpu": {"min": 0, "max": 0},
"memory": {"min": 0, "max": 0},
"gpu": {"min": 0, "max": 0},
"storage": {"min": 0, "max": 0},
"type": "GPU"
}
if cluster_ids is None:
cluster_ids = ["1865927992266461184"]
payload = {
"queryResource": query_resource,
"resourceType": resource_type,
"clusterIDs": cluster_ids
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询资源规格列表失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动智算应用资源查询 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,5 +0,0 @@
import httpx, json, sys
r = httpx.post('https://www.ai4mats.com/api/auth/login', json={'username': 'chenzhihang11', 'password': 'H1n2x3j4y5@'}, timeout=30)
result = r.json()
print(json.dumps(result, ensure_ascii=False))
sys.stdout.flush()

View File

@ -1,770 +0,0 @@
# 智算应用
## 1. 登录系统页面
https://www.ai4mats.com/api/auth/login
POST
入参:
```json
{
"password": "H1n2x3j4y5@",
"username": "chenzhihang11"
}
```
响应:
```json
{
"code": 200,
"msg": null,
"data": {
"access_token": "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjo1OSwidXNlcl9rZXkiOiI2NWEyNjJiZi1lMzZiLTQ1ZDEtYjUwZi1kM2IyNDI2N2VlMGUiLCJ1c2VybmFtZSI6ImNoZW56aGloYW5nMTEifQ.67N9INM8UNTaO5buK4ClyZkBWttfaz6hl_A8iv9SpbC7eGb_kTy3R4rtrYJBhOWu3UHL9Tio93aG43qUnOh-aw",
"expires_in": 1780473393445
}
}
```
## 2. 创建智算应用
https://www.ai4mats.com/api/mmp/service
POST
入参:
```json
{
"service_name": "智算应用创建",
"service_type": "机器学习",
"source": 2,
"description": "测试",
"img_url": "https://www.minio.ai4mats.com/data/mini-model-platform-data/temp/fanshuai/1761528061144/app-1.png",
"tag": "智算"
}
```
响应:
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 51,
"service_name": "智算应用创建",
"service_type": "机器学习",
"source": 2,
"tag": "智算",
"service_type_name": null,
"img_url": "https://www.minio.ai4mats.com/data/mini-model-platform-data/temp/fanshuai/1761528061144/app-1.png",
"url": null,
"description": "测试",
"detail": null,
"manual": null,
"create_by": "chenzhihang11",
"update_by": "chenzhihang11",
"create_time": null,
"update_time": null,
"state": null,
"mark_count": null,
"is_public": null,
"public_version_id": null,
"is_selected": null,
"is_marked": null,
"version_count": null,
"comment_count": null,
"service_temp_id": null,
"service_temp_name": null
}
}
```
## 2. 智算应用详情
https://www.ai4mats.com/api/mmp/service/serviceDetail/51
GET
响应:
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 51,
"service_name": "智算应用创建",
"service_type": "机器学习",
"source": 2,
"tag": "智算",
"service_type_name": null,
"img_url": "https://www.minio.ai4mats.com/data/mini-model-platform-data/temp/fanshuai/1761528061144/app-1.png",
"url": null,
"description": "测试",
"detail": null,
"manual": null,
"create_by": "chenzhihang11",
"update_by": "chenzhihang11",
"create_time": "2026-06-05T09:07:17.000+08:00",
"update_time": "2026-06-05T09:07:17.000+08:00",
"state": 1,
"mark_count": 0,
"is_public": false,
"public_version_id": null,
"is_selected": false,
"is_marked": false,
"version_count": 0,
"comment_count": 0,
"service_temp_id": null,
"service_temp_name": null
}
}
```
## 3. 智算应用版本创建
## 4. 登录外部系统,获取资源类型,资源规格和运行镜像信息
https://ai4m.jointcloud.net/jcc-admin/admin/login
POST
入参:
```json
{
"username": "hnxjy-super1",
"password": "h1n2x3j4y5@"
}
```
响应:
```json
{
"code": 200,
"message": "OK",
"data": {
"tokenHead": "Bearer ",
"expiresIn": 604800,
"jsmUserInfo": {
"code": "OK",
"message": "",
"data": {
"userID": 137,
"buckets": {
"HPCSlurm": 787,
"code": 782,
"dataset": 783,
"image": 785,
"model": 784,
"result": 786
}
}
},
"tokenTimeout": 604800,
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjE5NTU1NDY1Njc5ODUyMjE2MzIsInJuU3RyIjoiYWpkTllzNUpwSUF5ZVMzck9HYlk1ekZqOUxjU0pxcEIiLCJ1c2VyX25hbWUiOiJobnhqeS1zdXBlcjEiLCJpZCI6MTk1NTU0NjU2Nzk4NTIyMTYzMn0.j6SxmuVhn3nvV_HXl0R0jIpTtM7dOC2waU68AOvKVFQ"
}
}
```
## 5. 获取远程资源类型列表
https://ai4m.jointcloud.net/jsm/v2/resource/range
POST
入参:
```json
{
"userID": 137,
"computeType": "1"
}
```
响应:
```json
{
"code": "OK",
"message": "",
"data": {
"resourceRanges": [
{
"userID": 0,
"type": "GPU",
"gpu": {
"min": 0,
"max": 0
},
"gpuNumber": 4,
"cpu": {
"min": 0,
"max": 64
},
"memory": {
"min": 0,
"max": 40
},
"storage": {
"min": 0,
"max": 1024
},
"ids": null
}
]
}
}
```
## 6. 获取远程资源规格列表
https://ai4m.jointcloud.net/jsm/v2/resource/query
POST
入参:
```json
{
"queryResource": {
"cpu": {
"min": 0,
"max": 0
},
"memory": {
"min": 0,
"max": 0
},
"gpu": {
"min": 0,
"max": 0
},
"storage": {
"min": 0,
"max": 0
},
"type": "GPU"
},
"resourceType": "Train",
"clusterIDs": [
"1865927992266461184"
]
}
```
响应:
```json
{
"code": "OK",
"message": "",
"data": {
"resource": [
{
"id": 362,
"sourceKey": "GPU::A100::Train",
"type": "GPU",
"name": "A100",
"totalCount": 1,
"availableCount": 1,
"changeType": 0,
"status": 1,
"region": "",
"clusterId": "1865927992266461184",
"costPerUnit": 2,
"costType": "hourly",
"tag": "Train",
"userId": "3",
"createTime": "2025-07-25T20:19:51+08:00",
"updateTime": "2026-03-25T11:15:08+08:00",
"baseResourceSpecs": [
{
"id": 2331,
"resourceSpecId": 362,
"type": "STORAGE",
"name": "disk",
"totalValue": 1024,
"totalUnit": "gb",
"availableValue": 1024,
"availableUnit": "gb",
"userId": "3",
"createTime": "2025-07-25T20:19:51+08:00",
"updateTime": "2025-07-25T20:19:51+08:00"
},
{
"id": 2332,
"resourceSpecId": 362,
"type": "CPU",
"name": "CPU",
"totalValue": 8,
"totalUnit": "core",
"availableValue": 8,
"availableUnit": "core",
"userId": "3",
"createTime": "2025-07-25T20:19:51+08:00",
"updateTime": "2025-07-25T20:19:51+08:00"
},
{
"id": 2333,
"resourceSpecId": 362,
"type": "MEMORY",
"name": "RAM",
"totalValue": 50,
"totalUnit": "gb",
"availableValue": 50,
"availableUnit": "gb",
"userId": "3",
"createTime": "2025-07-25T20:19:51+08:00",
"updateTime": "2025-07-25T20:19:51+08:00"
},
{
"id": 2334,
"resourceSpecId": 362,
"type": "MEMORY",
"name": "VRAM",
"totalValue": 40,
"totalUnit": "gb",
"availableValue": 40,
"availableUnit": "gb",
"userId": "3",
"createTime": "2025-07-25T20:19:51+08:00",
"updateTime": "2025-07-25T20:19:51+08:00"
}
],
"networkCost": 0
}
]
}
}
```
## 7. 获取远程镜像列表
https://ai4m.jointcloud.net/jsm/jobSet/queryImages
POST
入参:
```json
{
"cardTypes": [
"GPU"
]
}
```
响应:
```json
{
"code": "OK",
"message": "",
"data": {
"images": [
{
"imageID": 59,
"name": "原子掺杂推理服务镜像",
"createTime": "2025-12-24T17:04:55+08:00",
"clusterImages": [
{
"imageID": 59,
"clusterID": "1865927992266461184",
"originImageType": "id",
"originImageID": "6288897d8fe84a8d8c1f5c9debd1bf6e",
"originImageName": "6288897d8fe84a8d8c1f5c9debd1bf6e",
"cards": [
{
"originImageID": "6288897d8fe84a8d8c1f5c9debd1bf6e",
"card": "GPU"
}
]
}
]
}
]
}
}
```
## 8. 查询代码配置列表
https://www.ai4mats.com/api/mmp/codeConfig?page=0&size=9&is_public=true
GET
响应:
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"content": [
{
"id": 14,
"code_repo_name": "钙钛晶体特征提取1",
"code_repo_vis": 1,
"is_public": true,
"git_url": "http://192.168.20.156:30202/chenzhihang11/pipelingaitai.git",
"git_branch": "master",
"verify_mode": null,
"git_user_name": null,
"git_password": null,
"ssh_key": null,
"create_by": "chenzhihang11",
"create_time": "2026-03-16T15:28:25.000+08:00",
"update_by": "chenzhihang11",
"update_time": "2026-03-16T15:28:25.000+08:00",
"state": 1,
"is_visible": true
},
{
"id": 9,
"code_repo_name": "钙钛晶体特征提取",
"code_repo_vis": 1,
"is_public": true,
"git_url": "http://192.168.20.156:30202/chenzhihang11/perovskite_crystal_feature_extraction.git",
"git_branch": "master",
"verify_mode": null,
"git_user_name": null,
"git_password": null,
"ssh_key": null,
"create_by": "chenzhihang11",
"create_time": "2026-03-04T15:14:57.000+08:00",
"update_by": "chenzhihang11",
"update_time": "2026-03-04T15:14:57.000+08:00",
"state": 1,
"is_visible": true
}
],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"pageNumber": 1,
"pageSize": 9,
"offset": 9,
"unpaged": false,
"paged": true
},
"last": true,
"totalPages": 2,
"totalElements": 16,
"first": false,
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"number": 1,
"numberOfElements": 7,
"size": 9,
"empty": false
}
}
```
## 9. 查询模型列表
https://www.ai4mats.com/api/mmp/newmodel/queryModels?is_public=false&page=0&size=2000&is_hot_stone=false
GET
响应:
```json
{
"msg": "操作成功",
"code": 200,
"data": {
"content": [
{
"id": 2,
"name": "原子掺杂识别模型",
"create_by": "chenzhihang11",
"model_size": "0 B",
"model_tag": "原子掺杂识别",
"model_type": "分类",
"full_last_update_time": "2026-05-12T15:36:15.000+08:00",
"owner": "chenzhihang11",
"identifier": "chenzhihang11_model_20260126141937",
"is_public": true,
"relative_paths": "chenzhihang11/model/10/chenzhihang11_model_20260126141937/origin/model",
"preview_pic": "https://www.minio.ai4mats.com/data/mini-model-platform-data/temp/fanshuai/1761528061144/app-2.png",
"praises_count": 0,
"is_hot_stone": false,
"git_id": 10
}
],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"pageNumber": 0,
"pageSize": 2000,
"offset": 0,
"unpaged": false,
"paged": true
},
"last": true,
"totalPages": 1,
"totalElements": 31,
"first": true,
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"number": 0,
"numberOfElements": 31,
"size": 2000,
"empty": false
}
}
```
## 10. 获取指定模型的版本列表
https://www.ai4mats.com/api/mmp/newmodel/getVersionList?owner=chenzhihang11&identifier=chenzhihang11_model_20260126141937
GET
响应:
```json
{
"msg": "操作成功",
"code": 200,
"data": [
{
"name": "v45"
},
{
"name": "v44"
}
]
}
```
## 11. 根据模型版本查询模型详情
https://www.ai4mats.com/api/mmp/newmodel/getModelDetail?owner=chenzhihang11&identifier=chenzhihang11_model_20260126141937&id=2&name=%E5%8E%9F%E5%AD%90%E6%8E%BA%E6%9D%82%E8%AF%86%E5%88%AB%E6%A8%A1%E5%9E%8B&version=v45&is_public=true&git_id=10
GET
响应:
```json
{
"msg": "操作成功",
"code": 200,
"data": {
"id": 2,
"name": "原子掺杂识别模型",
"version": "v45",
"version_desc": "远程训练任务导出",
"create_by": "chenzhihang11",
"create_time": "2026-06-04 17:31:32",
"update_time": "2026-06-04 17:31:32",
"model_size": "114.52 KB",
"model_source": "auto_export",
"description": "",
"usage": "<pre><code># 克隆模型配置文件与存储参数到本地\ngit clone -b v45 https://www.gitlink2.ai4mats.com/chenzhihang11/chenzhihang11_model_20260126141937.git\n# 远程拉取配置文件\ndvc pull\n</code></pre>",
"owner": "chenzhihang11",
"identifier": "chenzhihang11_model_20260126141937",
"is_public": false,
"relative_paths": "chenzhihang11/model/10/chenzhihang11_model_20260126141937/v45/model",
"praises_count": 0,
"praised": false,
"model_version_vos": [
{
"url": "/home/resource/chenzhihang11/model/10/chenzhihang11_model_20260126141937/v45/model/final_model.ckpt",
"file_name": "final_model.ckpt",
"file_size": "87.00 KB"
},
{
"url": "/home/resource/chenzhihang11/model/10/chenzhihang11_model_20260126141937/v45/model/test.json",
"file_name": "test.json",
"file_size": "27.52 KB"
}
],
"git_id": 10
}
}
```
## 12. 创建智算应用版本接口
https://www.ai4mats.com/api/mmp/service/version
POST
入参:
```json
{
"service_name": "智算应用创建",
"version": "v1",
"description": "智算应用创建",
"resource_type": "GPU",
"image_resource": {
"id": 363,
"sourceKey": "GPU::V100::Train",
"type": "GPU",
"name": "V100",
"totalCount": 2,
"availableCount": 2,
"changeType": 0,
"status": 1,
"region": "",
"clusterId": "1865927992266461184",
"costPerUnit": 1,
"costType": "perUse",
"tag": "Train",
"userId": "3",
"createTime": "2025-07-25T20:19:51+08:00",
"updateTime": "2026-03-25T11:15:08+08:00",
"baseResourceSpecs": [
{
"id": 2335,
"resourceSpecId": 363,
"type": "STORAGE",
"name": "disk",
"totalValue": 1024,
"totalUnit": "gb",
"availableValue": 1024,
"availableUnit": "gb",
"userId": "3",
"createTime": "2025-07-25T20:19:51+08:00",
"updateTime": "2025-07-25T20:19:51+08:00"
},
{
"id": 2336,
"resourceSpecId": 363,
"type": "CPU",
"name": "CPU",
"totalValue": 16,
"totalUnit": "core",
"availableValue": 16,
"availableUnit": "core",
"userId": "3",
"createTime": "2025-07-25T20:19:51+08:00",
"updateTime": "2025-07-25T20:19:51+08:00"
},
{
"id": 2337,
"resourceSpecId": 363,
"type": "MEMORY",
"name": "RAM",
"totalValue": 100,
"totalUnit": "gb",
"availableValue": 100,
"availableUnit": "gb",
"userId": "3",
"createTime": "2025-07-25T20:19:51+08:00",
"updateTime": "2025-07-25T20:19:51+08:00"
},
{
"id": 2338,
"resourceSpecId": 363,
"type": "MEMORY",
"name": "VRAM",
"totalValue": 32,
"totalUnit": "gb",
"availableValue": 32,
"availableUnit": "gb",
"userId": "3",
"createTime": "2025-07-25T20:19:51+08:00",
"updateTime": "2025-07-25T20:19:51+08:00"
}
],
"networkCost": 0,
"label": "GPU: 2*V100(显存32GB), CPU:16, 内存: 100GB",
"value": 363
},
"image": {
"imageID": 59,
"name": "原子掺杂推理服务镜像",
"createTime": "2025-12-24T17:04:55+08:00",
"clusterImages": [
{
"imageID": 59,
"clusterID": "1865927992266461184",
"originImageType": "id",
"originImageID": "6288897d8fe84a8d8c1f5c9debd1bf6e",
"originImageName": "6288897d8fe84a8d8c1f5c9debd1bf6e",
"cards": [
{
"originImageID": "6288897d8fe84a8d8c1f5c9debd1bf6e",
"card": "GPU"
}
]
}
],
"label": "原子掺杂推理服务镜像",
"value": 59
},
"command": "test_pl_vor.py",
"code_config": {
"id": 9,
"code_repo_name": "钙钛晶体特征提取",
"code_repo_vis": 1,
"is_public": true,
"git_url": "http://192.168.20.156:30202/chenzhihang11/perovskite_crystal_feature_extraction.git",
"git_branch": "master",
"verify_mode": null,
"git_user_name": null,
"git_password": null,
"ssh_key": null,
"create_by": "chenzhihang11",
"create_time": "2026-03-04T15:14:57.000+08:00",
"update_by": "chenzhihang11",
"update_time": "2026-03-04T15:14:57.000+08:00",
"state": 1,
"is_visible": true,
"activeTab": "Public",
"value": "钙钛晶体特征提取",
"showValue": "钙钛晶体特征提取",
"fromSelect": true
},
"model": {
"id": 2,
"name": "原子掺杂识别模型",
"path": "chenzhihang11/model/10/chenzhihang11_model_20260126141937/v45/model",
"version": "v45",
"identifier": "chenzhihang11_model_20260126141937",
"owner": "chenzhihang11",
"git_id": 10,
"value": "原子掺杂识别模型:v45",
"showValue": "原子掺杂识别模型:v45",
"fromSelect": true,
"activeTab": "Private"
},
"service_id": 51,
"source": 2,
"deploy_type": "web"
}
```
响应:
```json
{
"code": 200,
"msg": "创建成功",
"data": null
}
```

View File

@ -1,50 +0,0 @@
---
name: update-model
description: 当用户需要更新代码配置时,请使用此技能。
triggers:
- "更新代码配置"
metadata:
api-base: https://www.ai4mats.com
---
# 更新代码配置(调用接口)
## 何时使用
- 用户需要更新代码配置时
## 执行流程Agent 必须遵守)
1. **确认参数**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **输入参数**
- `page` (默认0)
- `size` (默认20)
- `code_repo_name`(镜像名称,非必填)
4. **查询代码配置**
- 调用`scripts/query_code_mcp_server.query_code`方法
- 参数:`token`(来自步骤2), `page`(来自步骤3), `size`(来自步骤3), `code_repo_name`(来自步骤3)
5. **展示结果**
- 将查询结果的总数展示出来,列表展示代码配置列表
6. **继续查询**
- 询问用户是否需要查询下一页的数据如果需要则page参数加1再次运行步骤4步骤5
- 否则结束查询
7. **输入参数**
- 用户从步骤4的结果中选择需要修改的代码配置
- 输入修改后的`code_repo_name`,`git_branch`,`git_url`如果不输入则默认使用步骤3的结果即不修改。
8. **更新代码配置**
- 调用`scripts/update_code_mcp_server.update_code`方法
- 参数:`token`(来自步骤2), `id`(来自步骤4), `code_repo_name`(来自步骤7), `git_branch`(来自步骤7), `git_url`(来自步骤7), `is_public`(来自步骤4)

View File

@ -1,62 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,89 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("模型mcp server")
@mcp.tool()
async def query_code(
token: str,
page: int,
size: int,
code_repo_name: str
):
url = f"{API_BASE_URL}/api/mmp/codeConfig"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": False,
"code_repo_name": code_repo_name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 查询代码配置列表失败: {str(e)}"
@mcp.tool()
async def update_code(
token: str,
id: int,
code_repo_name: str,
git_branch: str,
git_url: str,
is_public:bool
):
url = f"{API_BASE_URL}/api/mmp/codeConfig"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"id": id,
"code_repo_name": code_repo_name,
"git_branch": git_branch,
"git_url": git_url,
"is_public": is_public
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.put(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return result
except Exception as e:
return f"❌ 更新代码配置失败: {str(e)}"

View File

@ -1,50 +0,0 @@
---
name: update-model
description: 当用户需要更新模型时,请使用此技能。
triggers:
- "更新模型"
metadata:
api-base: https://www.ai4mats.com
---
# 更新模型(调用接口)
## 何时使用
- 用户需要更新模型时
## 执行流程Agent 必须遵守)
1. **用户登录**
- 是否已提供:
- 用户名 `username`
- 密码 `password`
- 若缺失,必须先向用户询问
- 非必填参数:
- 模型类型 `model_type`
- 模型标签 `model_tag`
- 是否包含火石模型 `is_hot_stone`
- 模型名称 `name`
- 可以询问用户是否需要查询指定模型类型,模型标签,是否包含火石模型,模型名称的模型
- 默认参数:
- page = 0
- size = 20
2. **调用登录接口获取token**
- 调用`scripts/login_mcp_server.login`方法
- 参数: `username`, `password`
- 获取 `access_token`
- 保存为临时变量 `token`
3. **查询模型**
- 调用`scripts/update_model_mcp_server.query_model`方法
- 参数:`token`(来自步骤2), `model_type`, `model_tag`, `is_hot_stone`, `name`, `page`, `size`
- 如果用户说继续查询下一页则page加1后继续查询否则结束查询
4. **输入参数**
- 调用`scripts/update_model_mcp_server.query_model_type_list`方法,查询所有模型类型
- 输入修改后的`model_type`(范围在查询出的模型类型之内),`model_tag`,如果不输入则默认使用步骤3的结果即不修改。
5. **更新模型**
- 用户从步骤3的结果中选择需要更新的模型
- 调用`scripts/update_model_mcp_server.update_model`方法
- 参数:`token`(来自步骤2), `id`(来自步骤3), `git_id`(来自步骤3), `identifier`(来自步骤3), `owner`(来自步骤3的结果中的create_by字段), `model_type`(来自步骤3), `model_tag`(来自步骤3)

View File

@ -1,62 +0,0 @@
import json
import os
import httpx
from fastapi import UploadFile
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("login mcp server")
# 3. 定义工具
@mcp.tool()
async def login(
username: str,
password: str
) -> str:
url = f"{API_BASE_URL}/api/auth/login"
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
payload = {
"username": username,
"password": password
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 创建模型失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

View File

@ -1,125 +0,0 @@
import httpx
import json
import os
from mcp.server.fastmcp import FastMCP
# 1. 读取配置文件(不再包含 TOKEN
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return default_config
config = load_config()
API_BASE_URL = config.get("API_BASE_URL")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
# 2. 初始化 MCP Server
mcp = FastMCP("模型mcp server")
@mcp.tool()
async def query_model(
token: str,
model_type: str,
model_tag: str,
is_hot_stone: bool,
name: str,
page: int,
size: int
) -> str:
url = f"{API_BASE_URL}/api/mmp/newmodel/queryModels"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"page": page,
"size": size,
"is_public": False,
"model_type": model_type,
"model_tag": model_tag,
"is_hot_stone": is_hot_stone,
"name": name
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 查询模型失败: {str(e)}"
@mcp.tool()
async def update_model(token: str,
id: int,
git_id: int,
identifier: str,
owner: str,
model_type: str,
model_tag: str,
) -> str:
url = f"{API_BASE_URL}/api/mmp/newmodel/updateModel"
headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"
}
params = {
"id": id,
"git_id": git_id,
"identifier": identifier,
"owner": owner,
"model_type": model_type,
"model_tag": model_tag,
"preview_pic": "https://www.ai4mats.com/minio/data/mini-model-platform-data/temp/fanshuai/1761528061144/model/材料筛选.png"
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.put(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 更新模型失败: {str(e)}"
@mcp.tool()
async def query_model_type_list(
token: str
):
url = f"{API_BASE_URL}/api/mmp/assetIcon"
headers = { "Content-Type": "application/json; charset=UTF-8",
"Authorization": f"Bearer {token}"}
params = {
"category_id": 2,
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
# return f"✅ 应用模型成功!\n{json.dumps(result, indent=2, ensure_ascii=False)}"
return result
except Exception as e:
return f"❌ 查询模型类型列表失败: {str(e)}"
# 4. 运行服务
if __name__ == "__main__":
print(f"🚀 启动应用部署 MCP 服务,传输模式: {TRANSPORT_MODE}")
mcp.run(transport=TRANSPORT_MODE)

19
Dockerfile Normal file
View File

@ -0,0 +1,19 @@
FROM python:3.10-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制代码
COPY . .
# 暴露端口
EXPOSE 8000
# 启动命令
CMD ["python", "main.py"]

View File

@ -1,4 +1,5 @@
{
"BAYESIAN_API_BASE_URL": "http://218.77.58.19:22222",
"TIMEOUT": 120
"MCP_TRANSPORT": "http"
}

16
cvd_result.txt Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,108 +0,0 @@
{
"add_dataset": {
"name": "测试数据集",
"preview_pic": "http://172.20.32.121:31213/minio/data/mini-model-platform-data/temp/test/test.png",
"dataset_source": "add",
"data_type": "通用数据",
"data_tag": "test",
"is_public": false,
"is_hot_stone": false
},
"get_asset_icon": {
"page": 0,
"size": 100,
"category_id": 1
},
"upload_chunk": {
"chunkNumber": 1,
"chunkSize": 10485760,
"currentChunkSize": 9577,
"totalSize": 9577,
"identifier": "e174a5dd7c5357a2efc3416ee0465e3c",
"filename": "test.zip",
"relativePath": "test.zip",
"totalChunks": 1
},
"add_version": {
"git_id": 125,
"id": 47,
"identifier": "test_dataset_20260520100000",
"is_public": false,
"owner": "test_user",
"name": "测试数据集",
"version": "v1",
"version_desc": "初始版本",
"dataset_source": "add",
"dataset_version_vos": [
{
"file_name": "test.zip",
"file_size": 9577,
"url": "/home/resource/temp/test/e174a5dd7c5357a2efc3416ee0465e3c/test.zip"
}
]
},
"update_dataset": {
"id": 47,
"name": "测试数据集_修改",
"identifier": "test_dataset_20260520100000",
"description": "测试描述",
"is_public": false,
"data_type": "通用数据",
"data_tag": "test",
"praises_count": 0,
"praised": false,
"create_by": "test_user",
"update_time": "2026-05-20 10:00:00",
"owner": "test_user",
"dataset_source": "add",
"relative_paths": "test/datasets/125/test_dataset_20260520100000/origin/dataset",
"is_hot_stone": false,
"git_id": 125,
"preview_pic": "http://172.20.32.121:31213/minio/data/mini-model-platform-data/temp/test/test.png",
"type": 0
},
"update_desc": {
"git_id": 125,
"identifier": "test_dataset_20260520100000",
"description": "更新后的数据集简介"
},
"publish_dataset": {
"id": 47,
"name": "测试数据集"
},
"download_all_files": {
"name": "测试数据集",
"git_id": 125,
"version": "v1",
"identifier": "test_dataset_20260520100000",
"owner": "test_user",
"is_public": false
},
"download_single_file": {
"url": "/home/resource/test/datasets/125/test_dataset_20260520100000/v1/dataset/test.zip"
},
"delete_version": {
"git_id": 125,
"owner": "test_user",
"identifier": "test_dataset_20260520100000",
"relative_paths": "test/datasets/125/test_dataset_20260520100000/v1/dataset",
"version": "v1"
},
"delete_dataset": {
"id": 47
},
"query_datasets": {
"page": 0,
"size": 20,
"is_public": false,
"data_type": "",
"is_hot_stone": false
},
"get_dataset_detail": {
"git_id": 74,
"owner": "test_user",
"name": "测试数据集",
"identifier": "test_dataset_20260520100000",
"is_public": false
}
}

View File

@ -1,11 +1,14 @@
version: "3.9"
services:
mcp-service:
build: ./tools
container_name: cvd-app
environment:
- API_BASE_URL=http://218.77.58.19:22222
mcp-services:
build: .
container_name: ai4mats-mcp
ports:
- "18889:8000"
- "18425:8000"
volumes:
# 如需动态修改配置,可挂载
- ./config:/app/config
environment:
- TZ=Asia/Shanghai
restart: unless-stopped

31
main.py Normal file
View File

@ -0,0 +1,31 @@
import uvicorn
from starlette.applications import Starlette
from starlette.routing import Mount
from starlette.middleware.cors import CORSMiddleware
from tools.bayesian_mcp_server import mcp as bayesian_mcp
from tools.app_deploy_mcp_server import mcp as app_deploy_mcp
from tools.cvd_chat_recommender_mcp_server import mcp as cvd_chat_mcp
from tools.cvd_param_recommender_mcp_server import mcp as cvd_param_mcp
from tools.tem_analysis_mcp_server import mcp as tem_mcp
# FastMCP 内部就是 Starlette app
routes = [
Mount("/mcp/bayesian", bayesian_mcp.sse_app()),
Mount("/mcp/app-deploy", app_deploy_mcp.sse_app()),
Mount("/mcp/cvd-chat", cvd_chat_mcp.sse_app()),
Mount("/mcp/cvd-param", cvd_param_mcp.sse_app()),
Mount("/mcp/tem-analysis", tem_mcp.sse_app()),
]
app = Starlette(routes=routes)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)

44
test/test_bayesian.py Normal file
View File

@ -0,0 +1,44 @@
# test_bayesian.py
import asyncio
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tools.bayesian_mcp_server import predict_next_five_rounds
async def main():
print("🚀 开始测试 贝叶斯分析 MCP 服务...")
# 测试参数(使用您之前提供的示例数据)
try:
result = await predict_next_five_rounds(
Concentration=6,
T_S=210,
T_Mo=860,
growth_time=35,
Ar=520,
CO2=80,
H2=10,
Density=0.32,
Width=0.48,
R_stacking_ratio=0.77,
rounds=5,
suggestions_per_round=1
)
print("\n✅ 贝叶斯分析 MCP 服务调用成功!")
print("=" * 60)
print("返回结果:")
print(result)
print("=" * 60)
except Exception as e:
print(f"\n❌ 贝叶斯分析 MCP 服务调用失败: {e}")
if __name__ == "__main__":
asyncio.run(main())

31
test/test_cvd_chat.py Normal file
View File

@ -0,0 +1,31 @@
import asyncio
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tools.cvd_chat_recommender_mcp_server import recommend_cvd_params
async def main():
print("🚀 开始测试 CVD 聊天推荐 MCP 服务...")
# 测试参数
test_query = "我想制备单层MoS2用于制作化学传感器"
# 调用 MCP 工具函数
try:
result = await recommend_cvd_params(test_query)
print("\n✅ MCP 服务调用成功!")
print("=" * 50)
print("返回结果:")
print(result)
print("=" * 50)
except Exception as e:
print(f"\n❌ MCP 服务调用失败: {e}")
if __name__ == "__main__":
asyncio.run(main())

44
test/test_cvd_mcp.py Normal file
View File

@ -0,0 +1,44 @@
import asyncio
import json
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tools.cvd_param_recommender_mcp_server import convert_to_device_params
async def main():
print("🚀 开始测试 CVD 参数推荐 MCP 服务...")
# 读取测试参数文件
try:
with open("../dataset/test_cvd.json", "r", encoding="utf-8") as f:
params = json.load(f)
except FileNotFoundError:
print("❌ 错误:找不到 test_cvd.json 文件")
return
except json.JSONDecodeError as e:
print(f"❌ 错误test_cvd.json 格式不正确: {e}")
return
# 调用 MCP 工具函数
try:
# 注意convert_to_device_params 是 async 函数
result = await convert_to_device_params(
start_order=params["start_order"],
schemes_json_str=json.dumps(params["schemes"], ensure_ascii=False)
)
print("\n✅ MCP 服务调用成功!")
print("=" * 50)
print("返回结果:")
print(result)
print("=" * 50)
except Exception as e:
print(f"\n❌ MCP 服务调用失败: {e}")
if __name__ == "__main__":
asyncio.run(main())

View File

@ -1,148 +0,0 @@
import asyncio
import json
import sys
import os
import time
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from tools.dataset_mcp_server import (
login,
add_dataset,
get_asset_icon,
get_data_types,
upload_chunk,
add_version,
update_dataset,
update_desc,
publish_dataset,
download_all_files,
download_single_file,
delete_version,
delete_dataset,
query_datasets,
get_dataset_detail
)
async def run_test(test_name, func, params, retries=1):
"""运行单个测试用例"""
print(f"\n{'='*60}")
print(f"🔧 测试: {test_name}")
print(f"{'='*60}")
print(f"参数: {json.dumps(params, indent=2, ensure_ascii=False)}")
try:
result = await func(**params)
print(f"\n✅ 成功!")
print(f"返回结果: {result[:500]}{'...' if len(result) > 500 else ''}")
return result, True
except Exception as e:
if retries > 0:
print(f"\n⚠️ 失败,重试中 ({retries}次剩余): {e}")
return await run_test(test_name, func, params, retries - 1)
print(f"\n❌ 失败: {e}")
return None, False
async def main():
print("🚀 开始测试数据集 MCP 服务...")
try:
with open("../dataset/test_dataset.json", "r", encoding="utf-8") as f:
test_data = json.load(f)
except FileNotFoundError:
print("❌ 错误:找不到 test_dataset.json 文件")
return
except json.JSONDecodeError as e:
print(f"❌ 错误test_dataset.json 格式不正确: {e}")
return
token = None
login_result, success = await run_test("登录获取Token", login, {})
if success:
try:
login_data = json.loads(login_result)
token = login_data.get("data", {}).get("access_token")
print(f"\n📋 获取到Token: {token[:20]}...")
except:
print("❌ 解析Token失败")
return
else:
print("❌ 登录失败,无法继续测试")
return
test_cases = [
("查询数据集分类", get_asset_icon, {"token": token, **test_data["get_asset_icon"]}),
("获取可用数据类型", get_data_types, {"token": token}),
("查询数据集列表", query_datasets, {"token": token, **test_data["query_datasets"]}),
]
passed = 1
failed = 0
for test_name, func, params in test_cases:
_, success = await run_test(test_name, func, params)
if success:
passed += 1
else:
failed += 1
new_dataset_params = {"token": token, **test_data["add_dataset"]}
dataset_name = test_data["add_dataset"]["name"]
add_result, success = await run_test("新增数据集", add_dataset, new_dataset_params)
while not success or (add_result and "项目名称已被使用" in add_result):
if add_result and "项目名称已被使用" in add_result:
timestamp = int(time.time())
new_name = f"{dataset_name}_{timestamp}"
print(f"\n⚠️ 项目名称已被使用,尝试新名称: {new_name}")
new_dataset_params["name"] = new_name
add_result, success = await run_test("新增数据集", add_dataset, new_dataset_params)
else:
break
if success:
passed += 1
try:
add_result_data = json.loads(add_result)
dataset_id = add_result_data.get("data", {}).get("id", test_data["add_version"]["id"])
print(f"\n📋 创建的数据集ID: {dataset_id}")
except:
dataset_id = test_data["add_version"]["id"]
else:
failed += 1
dataset_id = test_data["add_version"]["id"]
remaining_tests = [
("上传文件分片", upload_chunk, {"token": token, **test_data["upload_chunk"]}),
("新增版本", add_version, {"token": token, **{"id": dataset_id, **test_data["add_version"]}}),
("修改数据集", update_dataset, {"token": token, **{"id": dataset_id, **test_data["update_dataset"]}}),
("编辑数据集简介", update_desc, {"token": token, **test_data["update_desc"]}),
("发布数据集", publish_dataset, {"token": token, **{"id": dataset_id, **test_data["publish_dataset"]}}),
("下载全部文件", download_all_files, {"token": token, **test_data["download_all_files"]}),
("下载单个文件", download_single_file, {"token": token, **test_data["download_single_file"]}),
("删除版本", delete_version, {"token": token, **test_data["delete_version"]}),
("删除数据集", delete_dataset, {"token": token, **{"id": dataset_id}}),
("查询数据集详情", get_dataset_detail, {"token": token, **test_data["get_dataset_detail"]})
]
for test_name, func, params in remaining_tests:
_, success = await run_test(test_name, func, params)
if success:
passed += 1
else:
failed += 1
print(f"\n{'='*60}")
print("📊 测试结果汇总")
print(f"{'='*60}")
print(f"通过: {passed}")
print(f"失败: {failed}")
print(f"成功率: {passed / (passed + failed) * 100:.1f}%")
if __name__ == "__main__":
asyncio.run(main())

36
test/test_tem.py Normal file
View File

@ -0,0 +1,36 @@
# test_tem.py
import asyncio
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tools.tem_analysis_mcp_server import analyze_tem_image
async def main():
print("🚀 开始测试 TEM 分析 MCP 服务...")
# 这是一个 1x1 像素的透明 PNG 图片的 Base64 编码(仅用于测试连通性)
dummy_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
# 测试参数
try:
result = await analyze_tem_image(
filename="test_sample.jpg",
content_base64=dummy_base64,
model="/detection/predict"
)
print("\n✅ TEM 分析 MCP 服务调用成功!")
print("=" * 60)
print("返回结果:")
print(result)
print("=" * 60)
except Exception as e:
print(f"\n❌ TEM 分析 MCP 服务调用失败: {e}")
if __name__ == "__main__":
asyncio.run(main())

View File

@ -1,14 +0,0 @@
FROM python:3.11-slim
WORKDIR /app
RUN pip install --no-cache-dir \
fastmcp==3.3.1 \
httpx[http2]>=0.24.0 \
uvicorn[standard]>=0.23.0
COPY cvd-app.py .
EXPOSE 8000
CMD ["python", "cvd-app.py"]

View File

@ -10,7 +10,7 @@ def load_config():
"""加载配置"""
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "https://www.ai4mats.com"
"API_BASE_URL": "http://172.20.32.121:31213"
}
try:

View File

@ -0,0 +1,117 @@
import os
import json
import httpx
from mcp.server.fastmcp import FastMCP
# ============================================
# 配置
# ============================================
def load_config():
"""加载配置"""
config_path = os.path.join(os.path.dirname(__file__), "config.json")
default_config = {
"API_BASE_URL": "http://218.77.58.19:22222"
}
try:
if os.path.exists(config_path):
with open(config_path, "r", encoding="utf-8") as f:
default_config.update(json.load(f))
except Exception:
pass
return default_config
config = load_config()
API_BASE_URL = config["API_BASE_URL"]
# ============================================
# MCP 服务定义
# ============================================
mcp = FastMCP("Bayesian-Analysis")
# ============================================
# 工具:贝叶斯预测
# ============================================
@mcp.tool()
async def predict_next_five_rounds(
Concentration: float,
T_S: int,
T_Mo: int,
growth_time: int,
Ar: int,
CO2: int,
H2: int,
Density: float,
Width: float,
R_stacking_ratio: float,
rounds: int = 5,
suggestions_per_round: int = 1,
) -> str:
"""
调用贝叶斯分析模型预测未来几轮的工艺参数建议
参数说明
- Concentration: 浓度
- T_S: 温度 S
- T_Mo: 温度 Mo
- growth_time: 生长时间
- Ar: 氩气流量
- CO2: 二氧化碳流量
- H2: 氢气流量
- Density: 密度
- Width: 宽度
- R_stacking_ratio: 堆叠比
- rounds: 预测轮数
- suggestions_per_round: 每轮建议数
"""
# ---------- 参数校验 ----------
if Concentration <= 0 or Density <= 0 or Width <= 0:
return "❌ 参数错误:浓度 / 密度 / 宽度必须大于 0"
if not (0 < R_stacking_ratio < 1):
return "❌ 参数错误:堆叠比应在 0~1 之间"
# ---------- 构造请求 ----------
url = f"{API_BASE_URL}/next-five-rounds"
payload = {
"Concentration": Concentration,
"T_S": T_S,
"T_Mo": T_Mo,
"growth_time": growth_time,
"Ar": Ar,
"CO2": CO2,
"H2": H2,
"Density": Density,
"Width": Width,
"R_stacking_ratio": R_stacking_ratio,
"rounds": rounds,
"suggestions_per_round": suggestions_per_round,
}
# ---------- 调用 API ----------
try:
async with httpx.AsyncClient(timeout=120.0) as client:
response = await client.post(url, json=payload)
response.raise_for_status()
return json.dumps(
response.json(),
indent=2,
ensure_ascii=False
)
except httpx.HTTPStatusError as e:
return f"❌ 贝叶斯接口错误 ({e.response.status_code})"
except httpx.TimeoutException:
return "❌ 贝叶斯接口超时"
except Exception as e:
return f"❌ 调用失败:{e}"
# ============================================
# ⚠️ 注意:这里不写 mcp.run()
# 由主网关统一启动
# ============================================

View File

@ -1,131 +0,0 @@
import os
import json
import uuid
import httpx
from fastmcp import FastMCP
# ============================================
# 配置
# ============================================
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "../config/config.json")
default_config = {
"API_BASE_URL": "http://218.77.58.19:22222"
}
try:
if os.path.exists(config_path):
with open(config_path, "r", encoding="utf-8") as f:
default_config.update(json.load(f))
except Exception:
pass
return default_config
config = load_config()
API_BASE_URL = config["API_BASE_URL"]
mcp = FastMCP("CVD-TEM-MCP-Service")
# ============================================
# Tool用户在 MCPHub 里只看到一个框「query」
# ============================================
@mcp.tool()
async def recommend_cvd_chat(query: str) -> dict:
"""
推荐CVD工艺方案
用户直接描述需求即可例如
"我想制备单层MoS₂用于制作化学传感器"
"""
# item_id 内部自动生成,不让用户操心
item_id = f"auto_{uuid.uuid4().hex[:8]}"
api_url = f"{API_BASE_URL}/svc/cvd/recommend_CVD_chat"
try:
async with httpx.AsyncClient(timeout=httpx.Timeout(120.0)) as client:
async with client.stream(
"POST",
api_url,
json={"item_id": item_id, "message": query}
) as resp:
resp.raise_for_status()
content = ""
async for chunk in resp.aiter_text():
if chunk:
content += chunk
return {
"content": [{"type": "text", "text": content.strip()}]
}
except httpx.ConnectTimeout:
return {
"content": [{"type": "text", "text": "❌ 连接后端服务超时,请检查网络"}],
"isError": True,
}
except Exception as e:
return {
"content": [{"type": "text", "text": f"❌ 调用失败: {str(e)}"}],
"isError": True,
}
@mcp.tool()
async def convert_to_device_params(config_json: str) -> dict:
"""
CVD配置转设备参数
直接粘贴JSON配置字符串即可例如
{"temperature": 700, "pressure": 5}
"""
import json as _json
try:
cfg = _json.loads(config_json)
except Exception:
return {
"content": [{"type": "text", "text": "❌ 请输入合法JSON字符串"}],
"isError": True,
}
item_id = f"auto_{uuid.uuid4().hex[:8]}"
api_url = f"{API_BASE_URL}/svc/cvd/convert_to_device_params"
async with httpx.AsyncClient(timeout=60.0) as client:
resp = await client.post(
api_url,
json={"item_id": item_id, "config": cfg}
)
return resp.json()
@mcp.tool()
async def bayesian(item_id: str = "") -> dict:
"""贝叶斯预测可不填item_id直接回车"""
if not item_id:
item_id = f"auto_{uuid.uuid4().hex[:8]}"
api_url = f"{API_BASE_URL}/next-five-rounds"
async with httpx.AsyncClient(timeout=60.0) as client:
resp = await client.get(api_url, params={"item_id": item_id})
return resp.json()
@mcp.tool()
async def tem_analysis(query: str) -> dict:
"""
TEM图像分析
描述你要做的分析即可例如
"对sample_001做原子位置识别"
"""
item_id = f"auto_{uuid.uuid4().hex[:8]}"
api_url = f"{API_BASE_URL}/svc/tem/analysis"
async with httpx.AsyncClient(timeout=60.0) as client:
resp = await client.post(
api_url,
json={"item_id": item_id, "query": query}
)
return resp.json()
# ============================================
if __name__ == "__main__":
mcp.run(
transport="streamable-http",
host="0.0.0.0",
port=8000
)

View File

@ -0,0 +1,78 @@
import os
import json
import httpx
from mcp.server.fastmcp import FastMCP
# ============================================
# 配置
# ============================================
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "../config/config.json")
default_config = {
"BAYESIAN_API_BASE_URL": "http://218.77.58.19:22222"
}
try:
if os.path.exists(config_path):
with open(config_path, "r", encoding="utf-8") as f:
default_config.update(json.load(f))
except Exception:
pass
return default_config
config = load_config()
API_BASE_URL = config["BAYESIAN_API_BASE_URL"]
# ============================================
# MCP 服务定义
# ============================================
mcp = FastMCP("CVD-Chat-Recommender")
# ============================================
# 工具CVD 参数推荐
# ============================================
@mcp.tool()
async def recommend_cvd_params(query: str) -> str:
"""
根据用户的自然语言需求推荐 CVD化学气相沉积工艺参数
参数说明
- query: 用户的工艺需求描述
示例"我想制备单层MoS2用于制作化学传感器"
返回
推荐的 CVD 工艺参数方案温度流量时间等
"""
api_url = f"{API_BASE_URL}/svc/cvd/recommend_CVD_chat"
payload = {"query": query}
try:
async with httpx.AsyncClient(timeout=120.0) as client:
response = await client.post(api_url, json=payload)
response.raise_for_status()
try:
return json.dumps(
response.json(),
indent=2,
ensure_ascii=False
)
except:
return response.text
except httpx.HTTPStatusError as e:
return f"❌ CVD 推荐接口错误 ({e.response.status_code})"
except httpx.RequestError:
return "❌ 无法连接 CVD 推荐服务"
except Exception as e:
return f"❌ 调用失败:{e}"
# ============================================
# ⚠️ 不写 mcp.run()
# 由主网关统一启动
# ============================================

View File

@ -0,0 +1,90 @@
import os
import json
import httpx
from mcp.server.fastmcp import FastMCP
# ============================================
# 配置
# ============================================
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "../config/config.json")
default_config = {
"BAYESIAN_API_BASE_URL": "http://218.77.58.19:22222"
}
try:
if os.path.exists(config_path):
with open(config_path, "r", encoding="utf-8") as f:
default_config.update(json.load(f))
except Exception:
pass
return default_config
config = load_config()
API_BASE_URL = config["BAYESIAN_API_BASE_URL"]
# ============================================
# MCP 服务定义
# ============================================
mcp = FastMCP("CVD-Param-Recommender")
# ============================================
# 工具:转换为设备参数
# ============================================
@mcp.tool()
async def convert_to_device_params(
start_order: int,
schemes_json_str: str
) -> str:
"""
CVD 工艺方案Schemes转换为设备可执行的具体参数
参数说明
- start_order: 起始指令序号例如1
- schemes_json_str: 工艺方案的 JSON 字符串数组
示例'[{"非金属前驱体A": "S", "金属前驱体B": "MoO3"}]'
"""
api_url = f"{API_BASE_URL}/svc/cvd/convert_to_device_params"
# ---------- 解析 JSON ----------
try:
schemes_data = json.loads(schemes_json_str)
except json.JSONDecodeError as e:
return f"❌ JSON 解析失败:{e}"
payload = {
"start_order": start_order,
"schemes": schemes_data
}
# ---------- 调用 API ----------
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(api_url, json=payload)
response.raise_for_status()
try:
return json.dumps(
response.json(),
indent=2,
ensure_ascii=False
)
except:
return response.text
except httpx.HTTPStatusError as e:
return f"❌ 设备参数转换接口错误 ({e.response.status_code})"
except httpx.RequestError:
return "❌ 无法连接设备参数转换服务"
except Exception as e:
return f"❌ 调用失败:{e}"
# ============================================
# ⚠️ 不写 mcp.run()
# 由主网关统一启动
# ============================================

View File

@ -1,779 +0,0 @@
import httpx
from mcp.server.fastmcp import FastMCP
import os
import json
def load_config():
config_path = os.path.join(os.path.dirname(__file__), "../config/config.json")
default_config = {
"DATASET_API_BASE_URL": "https://www.ai4mats.com",
"DATASET_DEFAULT_USERNAME": "fanshuai",
"DATASET_DEFAULT_PASSWORD": "h1n2x3j4y5@",
"MCP_TRANSPORT": "stdio"
}
try:
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
default_config.update(config)
print(f"✅ 已加载配置文件: {config_path}")
else:
print(f"⚠️ 配置文件不存在,使用默认配置: {config_path}")
except Exception as e:
print(f"❌ 读取配置文件失败: {e},使用默认配置")
return default_config
config = load_config()
API_BASE_URL = config.get("DATASET_API_BASE_URL")
DEFAULT_USERNAME = config.get("DATASET_DEFAULT_USERNAME")
DEFAULT_PASSWORD = config.get("DATASET_DEFAULT_PASSWORD")
TRANSPORT_MODE = config.get("MCP_TRANSPORT")
mcp = FastMCP("Dataset-Service")
@mcp.tool()
async def login(
username: str = "",
password: str = ""
) -> str:
"""
获取访问token
参数说明:
- username: 用户名 (可选默认使用配置文件中的用户名)
- password: 密码 (可选默认使用配置文件中的密码)
返回: 包含access_token和expires_in的JSON字符串
"""
api_url = f"{API_BASE_URL}/api/auth/login"
if not username:
username = DEFAULT_USERNAME
if not password:
password = DEFAULT_PASSWORD
payload = {
"username": username,
"password": password
}
headers = {"Content-Type": "application/json"}
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(api_url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"登录 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接认证服务: {str(e)}"
except Exception as e:
return f"登录时发生未知错误: {str(e)}"
def build_auth_headers(token: str) -> dict:
"""构建包含token的请求头"""
return {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
@mcp.tool()
async def add_dataset(
name: str,
token: str,
preview_pic: str = "",
dataset_source: str = "add",
data_type: str = "通用数据",
data_tag: str = "",
is_public: bool = False,
is_hot_stone: bool = False
) -> str:
"""
新增数据集
参数说明:
- name: 数据集名称
- token: 访问令牌
- preview_pic: 预览图片URL (可选)
- dataset_source: 数据集来源 (默认: add)
- data_type: 数据类型 (默认: 通用数据)
- data_tag: 数据标签 (可选)
- is_public: 是否公开 (默认: False)
- is_hot_stone: 是否热门 (默认: False)
返回: 新增数据集的详细信息
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/addDataset"
payload = {
"name": name,
"preview_pic": preview_pic,
"dataset_source": dataset_source,
"data_type": data_type,
"data_tag": data_tag,
"is_public": is_public,
"is_hot_stone": is_hot_stone
}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(api_url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"新增数据集 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"新增数据集时发生未知错误: {str(e)}"
@mcp.tool()
async def get_asset_icon(
token: str,
page: int = 0,
size: int = 10000,
category_id: int = 1
) -> str:
"""
查询数据集分类接口
参数说明:
- token: 访问令牌
- page: 页码 (默认: 0)
- size: 每页数量 (默认: 10000)
- category_id: 分类ID (默认: 1)
返回: 数据集分类列表包含一级分类和二级分类信息
"""
api_url = f"{API_BASE_URL}/api/mmp/assetIcon"
params = {
"page": page,
"size": size,
"category_id": category_id
}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.get(api_url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"查询数据集分类 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"查询数据集分类时发生未知错误: {str(e)}"
@mcp.tool()
async def get_data_types(token: str) -> str:
"""
获取可用的数据集类型列表
参数说明:
- token: 访问令牌
返回: 可用的数据类型列表格式为[{"id": 138, "name": "通用数据"}, ...]
"""
try:
asset_icon_result = await get_asset_icon(token)
asset_icon_data = json.loads(asset_icon_result)
if asset_icon_data.get("code") != 200:
return f"获取数据集分类失败: {asset_icon_data.get('msg', '未知错误')}"
data = asset_icon_data.get("data", [])
data_types = []
for category in data:
second_list = category.get("second_asset_icon_list", [])
if second_list:
for item in second_list:
data_types.append({
"id": item.get("id"),
"name": item.get("name"),
"parent_id": item.get("parent_id"),
"path": item.get("path")
})
else:
data_types.append({
"id": category.get("id"),
"name": category.get("name"),
"parent_id": category.get("parent_id"),
"path": category.get("path")
})
return json.dumps({
"code": 200,
"msg": "操作成功",
"data": data_types
}, indent=2, ensure_ascii=False)
except json.JSONDecodeError as e:
return f"解析数据集分类失败: {str(e)}"
except Exception as e:
return f"获取数据类型列表时发生未知错误: {str(e)}"
@mcp.tool()
async def upload_chunk(
token: str,
chunkNumber: int,
chunkSize: int,
currentChunkSize: int,
totalSize: int,
identifier: str,
filename: str,
relativePath: str,
totalChunks: int
) -> str:
"""
上传版本文件分片上传
参数说明:
- token: 访问令牌
- chunkNumber: 当前分片序号
- chunkSize: 分片大小
- currentChunkSize: 当前分片实际大小
- totalSize: 总文件大小
- identifier: 文件唯一标识
- filename: 文件名
- relativePath: 相对路径
- totalChunks: 总分片数
返回: 上传结果包含文件location用于新增版本
"""
api_url = f"{API_BASE_URL}/api/mmp/uploader/chunk"
params = {
"chunkNumber": chunkNumber,
"chunkSize": chunkSize,
"currentChunkSize": currentChunkSize,
"totalSize": totalSize,
"identifier": identifier,
"filename": filename,
"relativePath": relativePath,
"totalChunks": totalChunks
}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.get(api_url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"上传文件 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"上传文件时发生未知错误: {str(e)}"
@mcp.tool()
async def add_version(
token: str,
git_id: int,
id: int,
identifier: str,
is_public: bool,
owner: str,
name: str,
version: str,
version_desc: str,
dataset_source: str = "add",
dataset_version_vos: list = None
) -> str:
"""
新增数据集版本
参数说明:
- token: 访问令牌
- git_id: Git仓库ID
- id: 数据集ID
- identifier: 数据集标识
- is_public: 是否公开
- owner: 所有者
- name: 数据集名称
- version: 版本号 (例如: v1)
- version_desc: 版本描述
- dataset_source: 数据集来源 (默认: add)
- dataset_version_vos: 版本文件列表格式: [{"file_name":"xxx","file_size":xxx,"url":"xxx"}]
返回: 新增版本结果
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/addVersion"
payload = {
"git_id": git_id,
"id": id,
"identifier": identifier,
"is_public": is_public,
"owner": owner,
"name": name,
"version": version,
"version_desc": version_desc,
"dataset_source": dataset_source,
"dataset_version_vos": dataset_version_vos if dataset_version_vos else []
}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(api_url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"新增版本 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"新增版本时发生未知错误: {str(e)}"
@mcp.tool()
async def update_dataset(
token: str,
id: int,
name: str,
identifier: str,
description: str = "",
is_public: bool = False,
data_type: str = "通用数据",
data_tag: str = "",
praises_count: int = 0,
praised: bool = False,
create_by: str = "",
update_time: str = "",
owner: str = "",
dataset_source: str = "add",
relative_paths: str = "",
is_hot_stone: bool = False,
git_id: int = 0,
preview_pic: str = "",
type: int = 0
) -> str:
"""
修改数据集
参数说明:
- token: 访问令牌
- id: 数据集ID
- name: 数据集名称
- identifier: 数据集标识
- description: 描述 (可选)
- is_public: 是否公开 (默认: False)
- data_type: 数据类型 (默认: 通用数据)
- data_tag: 数据标签 (可选)
- praises_count: 点赞数 (默认: 0)
- praised: 是否已点赞 (默认: False)
- create_by: 创建者 (可选)
- update_time: 更新时间 (可选)
- owner: 所有者 (可选)
- dataset_source: 数据集来源 (默认: add)
- relative_paths: 相对路径 (可选)
- is_hot_stone: 是否热门 (默认: False)
- git_id: Git仓库ID (默认: 0)
- preview_pic: 预览图片URL (可选)
- type: 类型 (默认: 0)
返回: 修改后的数据集信息
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/updateDataset"
payload = {
"id": id,
"name": name,
"identifier": identifier,
"description": description,
"is_public": is_public,
"data_type": data_type,
"data_tag": data_tag,
"praises_count": praises_count,
"praised": praised,
"create_by": create_by,
"update_time": update_time,
"owner": owner,
"dataset_source": dataset_source,
"relative_paths": relative_paths,
"is_hot_stone": is_hot_stone,
"git_id": git_id,
"preview_pic": preview_pic,
"type": type
}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.put(api_url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"修改数据集 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"修改数据集时发生未知错误: {str(e)}"
@mcp.tool()
async def update_desc(
token: str,
git_id: int,
identifier: str,
description: str
) -> str:
"""
编辑数据集简介
参数说明:
- token: 访问令牌
- git_id: Git仓库ID
- identifier: 数据集标识
- description: 数据集简介
返回: 操作结果
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/updateDesc"
payload = {
"git_id": git_id,
"identifier": identifier,
"description": description
}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.put(api_url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"编辑简介 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"编辑简介时发生未知错误: {str(e)}"
@mcp.tool()
async def publish_dataset(
token: str,
id: int,
name: str
) -> str:
"""
发布数据集
参数说明:
- token: 访问令牌
- id: 数据集ID
- name: 数据集名称
返回: 发布后的数据集信息
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/publish"
payload = {
"id": id,
"name": name
}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(api_url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"发布数据集 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"发布数据集时发生未知错误: {str(e)}"
@mcp.tool()
async def download_all_files(
token: str,
name: str,
git_id: int,
version: str,
identifier: str,
owner: str,
is_public: bool
) -> str:
"""
当前版本所有文件打包下载
参数说明:
- token: 访问令牌
- name: 数据集名称
- git_id: Git仓库ID
- version: 版本号
- identifier: 数据集标识
- owner: 所有者
- is_public: 是否公开
返回: 文件下载链接或文件内容
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/downloadAllFiles"
params = {
"name": name,
"git_id": git_id,
"version": version,
"identifier": identifier,
"owner": owner,
"is_public": is_public
}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=120.0) as client:
response = await client.get(api_url, params=params, headers=headers)
response.raise_for_status()
content_type = response.headers.get("content-type", "")
if "application/json" in content_type:
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
else:
return f"文件下载成功,内容长度: {len(response.content)} bytes"
except httpx.HTTPStatusError as e:
return f"下载文件 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"下载文件时发生未知错误: {str(e)}"
@mcp.tool()
async def download_single_file(
token: str,
url: str
) -> str:
"""
当前版本选中文件下载
参数说明:
- token: 访问令牌
- url: 文件路径
返回: 文件下载链接或文件内容
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/downloadSingleFile"
params = {"url": url}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=120.0) as client:
response = await client.get(api_url, params=params, headers=headers)
response.raise_for_status()
content_type = response.headers.get("content-type", "")
if "application/json" in content_type:
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
else:
return f"文件下载成功,内容长度: {len(response.content)} bytes"
except httpx.HTTPStatusError as e:
return f"下载单个文件 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"下载单个文件时发生未知错误: {str(e)}"
@mcp.tool()
async def delete_version(
token: str,
git_id: int,
owner: str,
identifier: str,
relative_paths: str,
version: str
) -> str:
"""
删除当前版本
参数说明:
- token: 访问令牌
- git_id: Git仓库ID
- owner: 所有者
- identifier: 数据集标识
- relative_paths: 相对路径
- version: 版本号
返回: 操作结果
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/deleteDatasetVersion"
params = {
"git_id": git_id,
"owner": owner,
"identifier": identifier,
"relative_paths": relative_paths,
"version": version
}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.delete(api_url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"删除版本 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"删除版本时发生未知错误: {str(e)}"
@mcp.tool()
async def delete_dataset(
token: str,
id: int
) -> str:
"""
删除数据集
参数说明:
- token: 访问令牌
- id: 数据集ID
返回: 操作结果
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/deleteDataset/{id}"
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.delete(api_url, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"删除数据集 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"删除数据集时发生未知错误: {str(e)}"
@mcp.tool()
async def query_datasets(
token: str,
page: int = 0,
size: int = 20,
is_public: bool = None,
data_type: str = "",
is_hot_stone: bool = None
) -> str:
"""
查询数据集列表
参数说明:
- token: 访问令牌
- page: 页码 (默认: 0)
- size: 每页数量 (默认: 20)
- is_public: 是否公开 (可选)
- data_type: 数据类型 (可选)
- is_hot_stone: 是否热门 (可选)
返回: 数据集列表
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/queryDatasets"
params = {
"page": page,
"size": size
}
if is_public is not None:
params["is_public"] = is_public
if data_type:
params["data_type"] = data_type
if is_hot_stone is not None:
params["is_hot_stone"] = is_hot_stone
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.get(api_url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"查询数据集列表 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"查询数据集列表时发生未知错误: {str(e)}"
@mcp.tool()
async def get_dataset_detail(
token: str,
git_id: int,
owner: str,
name: str,
identifier: str,
is_public: bool
) -> str:
"""
查询数据集详情
参数说明:
- token: 访问令牌
- git_id: Git仓库ID
- owner: 所有者
- name: 数据集名称
- identifier: 数据集标识
- is_public: 是否公开
返回: 数据集详细信息
"""
api_url = f"{API_BASE_URL}/api/mmp/newdataset/getDatasetDetail"
params = {
"git_id": git_id,
"owner": owner,
"name": name,
"identifier": identifier,
"is_public": is_public
}
headers = build_auth_headers(token)
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.get(api_url, params=params, headers=headers)
response.raise_for_status()
result = response.json()
return json.dumps(result, indent=2, ensure_ascii=False)
except httpx.HTTPStatusError as e:
return f"查询数据集详情 API 返回错误 ({e.response.status_code}): {e.response.text}"
except httpx.RequestError as e:
return f"无法连接数据集服务: {str(e)}"
except Exception as e:
return f"查询数据集详情时发生未知错误: {str(e)}"
if __name__ == "__main__":
mcp.run(transport=TRANSPORT_MODE)

Some files were not shown because too many files have changed in this diff Show More