88 lines
3.5 KiB
Python
88 lines
3.5 KiB
Python
from mcp.server.fastmcp.server import FastMCP
|
||
from pydantic import BaseModel, ValidationError
|
||
import jsonschema
|
||
import uvicorn
|
||
import logging
|
||
from jsonschema import validate, ValidationError
|
||
from mcp.server.fastmcp.server import FastMCP
|
||
|
||
# 新增导入
|
||
from response_utils import extract_data_for_validation
|
||
|
||
mcp = FastMCP(
|
||
"SchemaValidatorServer",
|
||
title="JSON Schema Validator Server",
|
||
description="A server that provides a tool to validate data against a JSON Schema.",
|
||
version="0.1.0"
|
||
)
|
||
|
||
@mcp.tool()
|
||
def validate_schema(data_instance: dict, schema: dict) -> dict:
|
||
"""
|
||
Validates a data instance against a given JSON Schema.
|
||
|
||
Args:
|
||
data_instance: The data object to validate.
|
||
schema: The JSON Schema to validate against.
|
||
|
||
Returns:
|
||
A dictionary containing the validation result.
|
||
{"isValid": True} on success.
|
||
{"isValid": False, "error": "Validation error message"} on failure.
|
||
"""
|
||
try:
|
||
jsonschema.validate(instance=data_instance, schema=schema)
|
||
return {"isValid": True, "error": None}
|
||
except ValidationError as e:
|
||
logging.error(f"SchemaValidator: Validation failed. Error: {e.message}", exc_info=True)
|
||
return {"isValid": False, "error": e.message}
|
||
except Exception as e:
|
||
# Catch other potential errors from the jsonschema library
|
||
return {"isValid": False, "error": str(e)}
|
||
|
||
@mcp.tool()
|
||
def validate_flexible_schema(api_response: dict, item_schema: dict) -> dict:
|
||
"""
|
||
对一个可能带有标准包装(如 {code, message, data})的API响应进行灵活的schema验证。
|
||
它能自动提取核心业务数据(无论是单个对象还是列表)并逐项进行验证。
|
||
|
||
Args:
|
||
api_response (dict): 完整的API响应体。
|
||
item_schema (dict): 描述核心业务数据**单个元素**的JSON Schema。
|
||
|
||
Returns:
|
||
dict: 一个包含验证结果的字典, {"isValid": True} 或 {"isValid": False, "error": "..."}。
|
||
"""
|
||
logging.info("SchemaValidator: Running flexible validation...")
|
||
try:
|
||
# 使用工具函数提取需要验证的数据
|
||
items_to_validate = extract_data_for_validation(api_response)
|
||
|
||
if not items_to_validate:
|
||
error_message = "Flexible validation failed: Could not extract any items to validate from the response."
|
||
logging.warning(error_message)
|
||
return {"isValid": False, "error": error_message}
|
||
|
||
logging.info(f"Flexible validation: Extracted {len(items_to_validate)} item(s) to validate.")
|
||
|
||
# 逐个验证提取出的项
|
||
for i, item in enumerate(items_to_validate):
|
||
validate(instance=item, schema=item_schema)
|
||
logging.info(f" -> Item {i+1}/{len(items_to_validate)} passed validation.")
|
||
|
||
logging.info("SchemaValidator: Flexible validation successful. All items conform to the schema.")
|
||
return {"isValid": True}
|
||
|
||
except ValidationError as e:
|
||
error_message = f"Flexible validation failed on an item. Error: {e.message}"
|
||
logging.error(error_message, exc_info=True)
|
||
return {"isValid": False, "error": error_message}
|
||
except Exception as e:
|
||
error_message = f"An unexpected error occurred during flexible validation: {e}"
|
||
logging.error(error_message, exc_info=True)
|
||
return {"isValid": False, "error": error_message}
|
||
|
||
|
||
# --- 启动服务器 ---
|
||
if __name__ == "__main__":
|
||
uvicorn.run(mcp.streamable_http_app(), host="127.0.0.1", port=8002) |