feat(file_tools): 添加解析JSON或文本文件的新工具

新增 parse_json 工具,用于读取 txt 或 json 文件内容并智能解析。
工具优先尝试将内容解析为JSON,返回结构化数据;若解析失败则作为纯文本返回。
同时更新项目版本号至 0.1.3。
This commit is contained in:
2026-05-09 14:57:42 +08:00
parent 7e33e398ce
commit 4bce8dbad0
2 changed files with 64 additions and 1 deletions

View File

@@ -120,6 +120,24 @@ tools: List[Tool] = [
}, },
"required": ["file_path"] "required": ["file_path"]
} }
),
Tool(
name="parse_json",
description="读取txt或json文件内容优先按JSON解析并返回结构化数据",
inputSchema={
"type": "object",
"properties": {
"file": {
"type": "object",
"properties": {
"name": {"type": "string"},
"content_base64": {"type": "string"}
}
},
"file_path": {"type": "string"}
},
"required": []
}
) )
] ]
@@ -430,6 +448,49 @@ def _build_path_data_uri(arguments: Dict[str, Any]) -> str:
return _build_data_uri(data, mime_type) return _build_data_uri(data, mime_type)
def _build_txt_or_json_result(data: bytes, name: Optional[str]) -> str:
text = data.decode("utf-8-sig")
try:
parsed = json.loads(text)
return json.dumps(
{
"type": "json",
"name": name,
"data": parsed
},
ensure_ascii=False
)
except json.JSONDecodeError:
return json.dumps(
{
"type": "text",
"name": name,
"data": text
},
ensure_ascii=False
)
async def _parse_json(arguments: Dict[str, Any]) -> str:
raw_file_path = str(arguments.get("file_path", ""))
file_path = raw_file_path.strip().strip("`").strip()
if _is_url(file_path):
async with httpx.AsyncClient(follow_redirects=True, timeout=20) as client:
response = await client.get(file_path)
response.raise_for_status()
name = Path(urlparse(file_path).path).name or None
return _build_txt_or_json_result(response.content, name)
if file_path and file_path != arguments.get("file_path"):
arguments = dict(arguments)
arguments["file_path"] = file_path
file_info, data, _ = _extract_file_payload(arguments)
if data is None:
raise ValueError("missing file content")
return _build_txt_or_json_result(data, file_info.get("name"))
async def _build_url_data_uri(arguments: Dict[str, Any]) -> str: async def _build_url_data_uri(arguments: Dict[str, Any]) -> str:
url = arguments.get("url") url = arguments.get("url")
if not url: if not url:
@@ -519,6 +580,8 @@ async def handle_call_tool(name: str, arguments: Dict[str, Any]) -> List[TextCon
if not file_path: if not file_path:
raise ValueError("missing file_path") raise ValueError("missing file_path")
result = await asyncio.to_thread(_upload_file_to_minio_sync, file_path) result = await asyncio.to_thread(_upload_file_to_minio_sync, file_path)
elif name == "parse_json":
result = await _parse_json(arguments)
else: else:
raise ValueError(f"unknown tool name: {name}") raise ValueError(f"unknown tool name: {name}")
return [TextContent(type="text", text=result)] return [TextContent(type="text", text=result)]

View File

@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "lzwcai-file-tools-mcp" name = "lzwcai-file-tools-mcp"
version = "0.1.1" version = "0.1.3"
description = "File tools MCP server" description = "File tools MCP server"
requires-python = ">=3.10" requires-python = ">=3.10"
dependencies = [ dependencies = [