feat: 添加数据库管理平台MCP Server

新增lzwcai-mcp-agile-db项目,提供数据库管理、表操作、数据CRUD、
API密钥管理、技能与工具管理等功能。

包含33个工具:
- 数据源管理:创建、更新、删除数据源
- 数据库与表管理:表结构操作、数据查询等
- API密钥管理:密钥创建、权限管理等
- 技能与工具管理:SQL工具创建、配置更新等
- 数据导入和SQL执行功能

添加了完整的README文档说明安装使用方法,
以及Python 3.12版本支持和基本项目结构。
This commit is contained in:
2026-06-11 09:53:40 +08:00
parent a1012e61bf
commit 9c597c9b0d
57 changed files with 3688 additions and 2103 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,25 +1,289 @@
2026-05-25 14:32:22 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs
2026-05-25 14:32:22 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5
2026-05-25 14:32:22 - mcp_services - INFO - [main.py:352] - 开始运行 MCP SQL Executor 服务器
2026-05-25 14:32:22 - mcp_services - INFO - [main.py:304] - ============================================================
2026-05-25 14:32:22 - mcp_services - INFO - [main.py:305] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor
2026-05-25 14:32:22 - mcp_services - INFO - [main.py:306] - 版本: 0.1.0
2026-05-25 14:32:22 - mcp_services - INFO - [main.py:307] - ============================================================
2026-05-25 14:32:22 - mcp_services - INFO - [main.py:311] - 环境配置 - Database ID: 162
2026-05-25 14:32:22 - mcp_services - INFO - [main.py:312] - 环境配置 - Skill ID: 2008360664955854850
2026-05-25 14:32:22 - mcp_services - INFO - [main.py:313] - 环境配置 - Backend Base URL: http://192.168.2.236:8088
2026-05-25 14:32:22 - mcp_services - INFO - [main.py:314] - ============================================================
2026-05-25 14:32:22 - mcp_services - INFO - [main.py:319] - MCP 服务器已启动,等待客户端连接...
2026-05-25 14:32:35 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type ListToolsRequest
2026-05-25 14:32:35 - mcp_services - INFO - [main.py:156] - 收到列出工具请求
2026-05-25 14:32:35 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api...
2026-05-25 14:32:35 - mcp_services - INFO - [main.py:283] - 调用第三方APIskill_id: 2008360664955854850
2026-05-25 14:32:35 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://192.168.2.236:8088/datasource/skill/getBySkillId/2008360664955854850
2026-05-25 14:32:35 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.2.236:8088/datasource/skill/getBySkillId/2008360664955854850 "HTTP/1.1 200 "
2026-05-25 14:32:35 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:85] - API调用成功: http://192.168.2.236:8088/datasource/skill/getBySkillId/2008360664955854850
2026-05-25 14:32:35 - mcp_services - INFO - [main.py:288] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2008360824029028354', 'createBy': 'wxl06', 'createTime': '2026-01-06 10:11:49', 'updateBy': 'wxl06', 'updateTime': '2026-01-06 10:11:59', 'serviceId': '2008360664960049153', 'uniqueName': '查询订单信息', 'name': 'chaxundingdanxinxi_3acda9b4', 'description': 'chaxundingdanxinxi_3acda9b4: 查询订单表中的订单信息,包括订单号、产品名称、数量、购买客户、备注和状态等关键信息', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 4ms', 'toolType': 'sql', 'datasourceId': '162', 'sqlTemplate': 'SELECT order_id, product_name, quantity, customer, remarks, status FROM orders WHERE 1=1', 'sqlParams': '{"type":"object","required":[],"properties":{}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["employeeId"],"properties":{"employeeId":{"type":"number","description":"员工ID用于标识员工的唯一数字标识符","examples":[1001,2002]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}]}
2026-05-25 14:32:35 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:324] - 成功处理 1 条技能数据
2026-05-25 14:32:35 - mcp_services - INFO - [main.py:293] - 成功获取并处理 1 条数据
2026-05-25 14:32:35 - mcp_services - INFO - [main.py:128] - API配置: 1 条
2026-05-25 14:32:35 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2008360824029028354', 'businessName': 'chaxundingdanxinxi_3acda9b4', 'businessDescription': 'chaxundingdanxinxi_3acda9b4: 查询订单表中的订单信息,包括订单号、产品名称、数量、购买客户、备注和状态等关键信息', 'sqlTemplate': 'SELECT order_id, product_name, quantity, customer, remarks, status FROM orders WHERE 1=1', 'parameters': {'type': 'object', 'required': [], 'properties': {}}, 'datasourceId': '162'}]
2026-05-25 14:32:35 - mcp_services - INFO - [main.py:165] - 成功生成 1 个 MCP 工具
2026-05-25 16:05:46 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs
2026-05-25 16:05:46 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5
2026-05-25 16:05:46 - mcp_services - INFO - [main.py:352] - 开始运行 MCP SQL Executor 服务器
2026-05-25 16:05:46 - mcp_services - INFO - [main.py:304] - ============================================================
2026-05-25 16:05:46 - mcp_services - INFO - [main.py:305] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor
2026-05-25 16:05:46 - mcp_services - INFO - [main.py:306] - 版本: 0.1.0
2026-05-25 16:05:46 - mcp_services - INFO - [main.py:307] - ============================================================
2026-05-25 16:05:46 - mcp_services - INFO - [main.py:311] - 环境配置 - Database ID: 240
2026-05-25 16:05:46 - mcp_services - INFO - [main.py:312] - 环境配置 - Skill ID: 2058819964077572098
2026-05-25 16:05:46 - mcp_services - INFO - [main.py:313] - 环境配置 - Backend Base URL: http://192.168.2.236:8088
2026-05-25 16:05:46 - mcp_services - INFO - [main.py:314] - ============================================================
2026-05-25 16:05:46 - mcp_services - INFO - [main.py:319] - MCP 服务器已启动,等待客户端连接...
2026-05-25 16:05:49 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type ListToolsRequest
2026-05-25 16:05:49 - mcp_services - INFO - [main.py:156] - 收到列出工具请求
2026-05-25 16:05:49 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api...
2026-05-25 16:05:49 - mcp_services - INFO - [main.py:283] - 调用第三方APIskill_id: 2058819964077572098
2026-05-25 16:05:49 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://192.168.2.236:8088/datasource/skill/getBySkillId/2058819964077572098
2026-05-25 16:05:49 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.2.236:8088/datasource/skill/getBySkillId/2058819964077572098 "HTTP/1.1 200 "
2026-05-25 16:05:49 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:85] - API调用成功: http://192.168.2.236:8088/datasource/skill/getBySkillId/2058819964077572098
2026-05-25 16:05:49 - mcp_services - INFO - [main.py:288] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2058819964287287298', 'createBy': 'wxl06', 'createTime': '2026-05-25 15:58:25', 'updateBy': None, 'updateTime': None, 'serviceId': '2058819964085960705', 'uniqueName': '前50条导入数据明细查询', 'name': 'qian50tiaodaorushujumingxichaxun_32b1d628', 'description': 'qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: 查询数据导入明细表中的前50条记录包含原始数据、处理状态、错误原因等关键信息用于快速预览最近的导入情况。', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 1ms', 'toolType': 'sql', 'datasourceId': '240', 'sqlTemplate': 'SELECT record_id AS "记录ID", task_id AS "任务ID", original_data AS "原始数据", process_result AS "处理结果", error_reason AS "错误原因", process_status AS "处理状态", target_table AS "关联目标表", created_time AS "创建时间" FROM import_record_detail LIMIT 50;', 'sqlParams': '{}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","properties":{},"required":[]}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}]}
2026-05-25 16:05:49 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:324] - 成功处理 1 条技能数据
2026-05-25 16:05:49 - mcp_services - INFO - [main.py:293] - 成功获取并处理 1 条数据
2026-05-25 16:05:49 - mcp_services - INFO - [main.py:128] - API配置: 1 条
2026-05-25 16:05:49 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2058819964287287298', 'businessName': 'qian50tiaodaorushujumingxichaxun_32b1d628', 'businessDescription': 'qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: 查询数据导入明细表中的前50条记录包含原始数据、处理状态、错误原因等关键信息用于快速预览最近的导入情况。', 'sqlTemplate': 'SELECT record_id AS "记录ID", task_id AS "任务ID", original_data AS "原始数据", process_result AS "处理结果", error_reason AS "错误原因", process_status AS "处理状态", target_table AS "关联目标表", created_time AS "创建时间" FROM import_record_detail LIMIT 50;', 'parameters': {}, 'datasourceId': '240'}]
2026-05-25 16:05:49 - mcp_services - INFO - [main.py:165] - 成功生成 1 个 MCP 工具
2026-05-25 16:05:52 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type CallToolRequest
2026-05-25 16:05:52 - mcp_services - INFO - [main.py:190] - 收到工具调用请求: qian50tiaodaorushujumingxichaxun_32b1d628
2026-05-25 16:05:52 - mcp_services - INFO - [main.py:230] - 正在调用测试SQL API...
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:132] - ================================================================================
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:133] - test_sql_with_schema 接口接收到的数据:
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:134] - 数据类型: <class 'dict'>
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:135] - 数据内容: {
"datasourceId": "240",
"businessName": "qian50tiaodaorushujumingxichaxun_32b1d628",
"businessDescription": "qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: 查询数据导入明细表中的前50条记录包含原始数据、处理状态、错误原因等关键信息用于快速预览最近的导入情况。",
"sqlTemplate": "SELECT record_id AS \"记录ID\", task_id AS \"任务ID\", original_data AS \"原始数据\", process_result AS \"处理结果\", error_reason AS \"错误原因\", process_status AS \"处理状态\", target_table AS \"关联目标表\", created_time AS \"创建时间\" FROM import_record_detail LIMIT 50;",
"parameters": {},
"testParams": {}
}
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:136] - 数据源ID: 240
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:137] - 业务名称: qian50tiaodaorushujumingxichaxun_32b1d628
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:138] - 业务描述: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: 查询数据导入明细表中的前50条记录包含原始数据、处理状态、错误原因等关键信息用于快速预览最近的导入情况。
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:139] - SQL模板: SELECT record_id AS "记录ID", task_id AS "任务ID", original_data AS "原始数据", process_result AS "处理结果", error_reason AS "错误原因", process_status AS "处理状态", target_table AS "关联目标表", created_time AS "创建时间" FROM import_record_detail LIMIT 50;
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:140] - 参数定义: {}
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:141] - 测试参数: {}
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:144] - ================================================================================
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:153] - 正在调用测试SQL API: http://192.168.2.236:8088/datasource/sqlExecutionLog/testSqlWithSchema
2026-05-25 16:05:52 - httpx - INFO - [_client.py:1025] - HTTP Request: POST http://192.168.2.236:8088/datasource/sqlExecutionLog/testSqlWithSchema "HTTP/1.1 200 "
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:170] - ================================================================================
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:171] - test_sql_with_schema 接口返回的数据:
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:172] - HTTP状态码: 200
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:173] - 响应数据类型: <class 'dict'>
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:174] - 响应数据内容: {
"msg": "操作成功",
"code": 200,
"data": {
"resultCount": 6,
"data": [
{
"记录ID": 80001,
"任务ID": "3320260418001",
"原始数据": "{\"name\": \"张三\", \"mobile\": \"13800000101\", \"dept\": \"销售部\", \"amount\": 1200}",
"处理结果": "导入成功",
"错误原因": null,
"处理状态": "SUCCESS",
"关联目标表": "employee_import",
"创建时间": "2026-04-18T15:19:19.000+08:00"
},
{
"记录ID": 80002,
"任务ID": "3320260418002",
"原始数据": "{\"name\": \"李四\", \"mobile\": \"13800000102\", \"dept\": \"财务部\", \"amount\": 980}",
"处理结果": "导入成功",
"错误原因": null,
"处理状态": "SUCCESS",
"关联目标表": "employee_import",
"创建时间": "2026-04-18T15:19:34.000+08:00"
},
{
"记录ID": 80003,
"任务ID": "3320260418003",
"原始数据": "{\"name\": \"王五\", \"mobile\": \"13800000103\", \"dept\": \"技术部\", \"amount\": 1500}",
"处理结果": "导入失败",
"错误原因": "字段校验失败mobile格式不正确",
"处理状态": "FAILED",
"关联目标表": "employee_import",
"创建时间": "2026-04-18T15:19:49.000+08:00"
},
{
"记录ID": 80004,
"任务ID": "3320260418004",
"原始数据": "{\"name\": \"赵六\", \"mobile\": \"13800000104\", \"dept\": \"人事部\", \"amount\": 0}",
"处理结果": "导入成功",
"错误原因": null,
"处理状态": "SUCCESS",
"关联目标表": "employee_import",
"创建时间": "2026-04-18T15:20:04.000+08:00"
},
{
"记录ID": 80005,
"任务ID": "3320260418005",
"原始数据": "{\"name\": \"孙七\", \"mobile\": \"13800000105\", \"dept\": \"运营部\", \"amount\": 2000}",
"处理结果": "导入失败",
"错误原因": "目标表写入失败:唯一键冲突",
"处理状态": "FAILED",
"关联目标表": "employee_import",
"创建时间": "2026-04-18T15:20:19.000+08:00"
},
{
"记录ID": 80006,
"任务ID": "3320260418006",
"原始数据": "{\"name\": \"周八\", \"mobile\": \"13800000106\", \"dept\": \"法务部\", \"amount\": 300}",
"处理结果": "导入成功",
"错误原因": null,
"处理状态": "SUCCESS",
"关联目标表": "employee_import",
"创建时间": "2026-04-18T15:20:34.000+08:00"
}
],
"databaseName": "import_log_db_168",
"businessDescription": "qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: 查询数据导入明细表中的前50条记录包含原始数据、处理状态、错误原因等关键信息用于快速预览最近的导入情况。",
"originalTemplate": "SELECT record_id AS \"记录ID\", task_id AS \"任务ID\", original_data AS \"原始数据\", process_result AS \"处理结果\", error_reason AS \"错误原因\", process_status AS \"处理状态\", target_table AS \"关联目标表\", created_time AS \"创建时间\" FROM import_record_detail LIMIT 50;",
"convertedTemplate": "SELECT record_id AS \"记录ID\", task_id AS \"任务ID\", original_data AS \"原始数据\", process_result AS \"处理结果\", error_reason AS \"错误原因\", process_status AS \"处理状态\", target_table AS \"关联目标表\", created_time AS \"创建时间\" FROM import_record_detail LIMIT 50;",
"executionStatus": "success",
"businessName": "qian50tiaodaorushujumingxichaxun_32b1d628",
"testParams": {},
"errorMessage": null,
"executionTime": 8,
"datasourceId": "240",
"logId": "2058821884796174336",
"executableSql": "SELECT record_id AS \"记录ID\", task_id AS \"任务ID\", original_data AS \"原始数据\", process_result AS \"处理结果\", error_reason AS \"错误原因\", process_status AS \"处理状态\", target_table AS \"关联目标表\", created_time AS \"创建时间\" FROM import_record_detail LIMIT 50;",
"datasourceName": "import_log_db_168"
}
}
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:176] - 响应code: 200
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:177] - 响应msg: 操作成功
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:178] - 响应data: {'resultCount': 6, 'data': [{'记录ID': 80001, '任务ID': '3320260418001', '原始数据': '{"name": "张三", "mobile": "13800000101", "dept": "销售部", "amount": 1200}', '处理结果': '导入成功', '错误原因': None, '处理状态': 'SUCCESS', '关联目标表': 'employee_import', '创建时间': '2026-04-18T15:19:19.000+08:00'}, {'记录ID': 80002, '任务ID': '3320260418002', '原始数据': '{"name": "李四", "mobile": "13800000102", "dept": "财务部", "amount": 980}', '处理结果': '导入成功', '错误原因': None, '处理状态': 'SUCCESS', '关联目标表': 'employee_import', '创建时间': '2026-04-18T15:19:34.000+08:00'}, {'记录ID': 80003, '任务ID': '3320260418003', '原始数据': '{"name": "王五", "mobile": "13800000103", "dept": "技术部", "amount": 1500}', '处理结果': '导入失败', '错误原因': '字段校验失败mobile格式不正确', '处理状态': 'FAILED', '关联目标表': 'employee_import', '创建时间': '2026-04-18T15:19:49.000+08:00'}, {'记录ID': 80004, '任务ID': '3320260418004', '原始数据': '{"name": "赵六", "mobile": "13800000104", "dept": "人事部", "amount": 0}', '处理结果': '导入成功', '错误原因': None, '处理状态': 'SUCCESS', '关联目标表': 'employee_import', '创建时间': '2026-04-18T15:20:04.000+08:00'}, {'记录ID': 80005, '任务ID': '3320260418005', '原始数据': '{"name": "孙七", "mobile": "13800000105", "dept": "运营部", "amount": 2000}', '处理结果': '导入失败', '错误原因': '目标表写入失败:唯一键冲突', '处理状态': 'FAILED', '关联目标表': 'employee_import', '创建时间': '2026-04-18T15:20:19.000+08:00'}, {'记录ID': 80006, '任务ID': '3320260418006', '原始数据': '{"name": "周八", "mobile": "13800000106", "dept": "法务部", "amount": 300}', '处理结果': '导入成功', '错误原因': None, '处理状态': 'SUCCESS', '关联目标表': 'employee_import', '创建时间': '2026-04-18T15:20:34.000+08:00'}], 'databaseName': 'import_log_db_168', 'businessDescription': 'qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: 查询数据导入明细表中的前50条记录包含原始数据、处理状态、错误原因等关键信息用于快速预览最近的导入情况。', 'originalTemplate': 'SELECT record_id AS "记录ID", task_id AS "任务ID", original_data AS "原始数据", process_result AS "处理结果", error_reason AS "错误原因", process_status AS "处理状态", target_table AS "关联目标表", created_time AS "创建时间" FROM import_record_detail LIMIT 50;', 'convertedTemplate': 'SELECT record_id AS "记录ID", task_id AS "任务ID", original_data AS "原始数据", process_result AS "处理结果", error_reason AS "错误原因", process_status AS "处理状态", target_table AS "关联目标表", created_time AS "创建时间" FROM import_record_detail LIMIT 50;', 'executionStatus': 'success', 'businessName': 'qian50tiaodaorushujumingxichaxun_32b1d628', 'testParams': {}, 'errorMessage': None, 'executionTime': 8, 'datasourceId': '240', 'logId': '2058821884796174336', 'executableSql': 'SELECT record_id AS "记录ID", task_id AS "任务ID", original_data AS "原始数据", process_result AS "处理结果", error_reason AS "错误原因", process_status AS "处理状态", target_table AS "关联目标表", created_time AS "创建时间" FROM import_record_detail LIMIT 50;', 'datasourceName': 'import_log_db_168'}
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:179] - ================================================================================
2026-05-25 16:05:52 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:181] - 测试SQL API调用成功
2026-05-25 16:05:52 - mcp_services - INFO - [main.py:232] - 测试SQL API调用成功
2026-05-25 16:15:08 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs
2026-05-25 16:15:08 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5
2026-05-25 16:15:08 - mcp_services - INFO - [main.py:246] - 开始运行 MCP SQL Executor 服务
2026-05-25 16:15:08 - mcp_services - INFO - [main.py:204] - ============================================================
2026-05-25 16:15:08 - mcp_services - INFO - [main.py:205] - 正在启动 MCP 服务: lzwcai-mcp-sqlexecutor
2026-05-25 16:15:08 - mcp_services - INFO - [main.py:206] - 版本: 0.1.0
2026-05-25 16:15:08 - mcp_services - INFO - [main.py:207] - ============================================================
2026-05-25 16:15:08 - mcp_services - INFO - [main.py:210] - 环境配置 - Database ID: 240
2026-05-25 16:15:08 - mcp_services - INFO - [main.py:211] - 环境配置 - Skill ID: 2058819964077572098
2026-05-25 16:15:08 - mcp_services - INFO - [main.py:212] - 环境配置 - Backend Base URL: http://192.168.2.236:8088
2026-05-25 16:15:08 - mcp_services - INFO - [main.py:213] - ============================================================
2026-05-25 16:15:08 - mcp_services - INFO - [main.py:218] - MCP 服务已启动,等待客户端连接...
2026-05-25 16:15:09 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type ListToolsRequest
2026-05-25 16:15:09 - mcp_services - INFO - [main.py:107] - 收到列出工具请求
2026-05-25 16:15:09 - mcp_services - INFO - [main.py:77] - 初始化查询配置,数据源: api
2026-05-25 16:15:09 - mcp_services - INFO - [main.py:189] - 调用第三方 APIskill_id: 2058819964077572098
2026-05-25 16:15:09 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://192.168.2.236:8088/datasource/skill/getBySkillId/2058819964077572098
2026-05-25 16:15:09 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.2.236:8088/datasource/skill/getBySkillId/2058819964077572098 "HTTP/1.1 200 "
2026-05-25 16:15:09 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:85] - API调用成功: http://192.168.2.236:8088/datasource/skill/getBySkillId/2058819964077572098
2026-05-25 16:15:09 - mcp_services - INFO - [main.py:191] - 成功获取原始响应: {'msg': '查询成功', 'code': 200, 'data': [{'id': '2058819964287287298', 'createBy': 'wxl06', 'createTime': '2026-05-25 15:58:25', 'updateBy': None, 'updateTime': None, 'serviceId': '2058819964085960705', 'uniqueName': '前50条导入数据明细查询', 'name': 'qian50tiaodaorushujumingxichaxun_32b1d628', 'description': 'qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: 查询数据导入明细表中的前50条记录包含原始数据、处理状态、错误原因等关键信息用于快速预览最近的导入情况。', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 1ms', 'toolType': 'sql', 'datasourceId': '240', 'sqlTemplate': 'SELECT record_id AS "记录ID", task_id AS "任务ID", original_data AS "原始数据", process_result AS "处理结果", error_reason AS "错误原因", process_status AS "处理状态", target_table AS "关联目标表", created_time AS "创建时间" FROM import_record_detail LIMIT 50;', 'sqlParams': '{}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","properties":{},"required":[]}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}]}
2026-05-25 16:15:09 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:325] - 成功处理 1 条技能数据
2026-05-25 16:15:09 - mcp_services - INFO - [main.py:194] - 成功处理 1 条数据
2026-05-25 16:15:09 - mcp_services - INFO - [main.py:85] - API 配置: 1 条
2026-05-25 16:15:09 - mcp_services - INFO - [main.py:86] - API 配置数组: [{'id': '2058819964287287298', 'businessName': 'qian50tiaodaorushujumingxichaxun_32b1d628', 'businessDescription': 'qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: 查询数据导入明细表中的前50条记录包含原始数据、处理状态、错误原因等关键信息用于快速预览最近的导入情况。', 'sqlTemplate': 'SELECT record_id AS "记录ID", task_id AS "任务ID", original_data AS "原始数据", process_result AS "处理结果", error_reason AS "错误原因", process_status AS "处理状态", target_table AS "关联目标表", created_time AS "创建时间" FROM import_record_detail LIMIT 50;', 'parameters': {}, 'datasourceId': '240'}]
2026-05-25 16:15:09 - mcp_services - INFO - [main.py:110] - 成功生成 1 个 MCP 工具
2026-05-25 16:22:48 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs
2026-05-25 16:22:48 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5
2026-05-25 16:22:48 - mcp_services - INFO - [main.py:258] - 开始运行 MCP SQL Executor 服务
2026-05-25 16:22:48 - mcp_services - INFO - [main.py:216] - ============================================================
2026-05-25 16:22:48 - mcp_services - INFO - [main.py:217] - 正在启动 MCP 服务: lzwcai-mcp-sqlexecutor
2026-05-25 16:22:48 - mcp_services - INFO - [main.py:218] - 版本: 0.1.0
2026-05-25 16:22:48 - mcp_services - INFO - [main.py:219] - ============================================================
2026-05-25 16:22:48 - mcp_services - INFO - [main.py:222] - 环境配置 - Database ID: 29
2026-05-25 16:22:48 - mcp_services - INFO - [main.py:223] - 环境配置 - Skill ID:
2026-05-25 16:22:48 - mcp_services - INFO - [main.py:224] - 环境配置 - Backend Base URL: http://lzwcai-demp-corp-manager:8086
2026-05-25 16:22:48 - mcp_services - INFO - [main.py:225] - ============================================================
2026-05-25 16:22:48 - mcp_services - INFO - [main.py:230] - MCP 服务已启动,等待客户端连接...
2026-05-25 16:22:51 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type ListToolsRequest
2026-05-25 16:22:51 - mcp_services - INFO - [main.py:127] - 收到列出工具请求
2026-05-25 16:22:51 - mcp_services - INFO - [main.py:97] - 初始化查询配置,数据源: api
2026-05-25 16:22:51 - mcp_services - INFO - [main.py:201] - 调用第三方 APIskill_id:
2026-05-25 16:22:51 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:47] - 正在调用 API: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/
2026-05-25 16:22:53 - lzwcai_mcp_sqlexecutor.utils.api_client - ERROR - [api_client.py:69] - API 请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
2026-05-25 16:22:53 - mcp_services - ERROR - [main.py:209] - API 调用失败: API 请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
Traceback (most recent call last):
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 101, in map_httpcore_exceptions
yield
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 250, in handle_request
resp = self._pool.handle_request(req)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection_pool.py", line 256, in handle_request
raise exc from None
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection_pool.py", line 236, in handle_request
response = connection.handle_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 101, in handle_request
raise exc
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 78, in handle_request
stream = self._connect(request)
^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 124, in _connect
stream = self._network_backend.connect_tcp(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_backends\sync.py", line 207, in connect_tcp
with map_exceptions(exc_map):
File "D:\anaconda3\Lib\contextlib.py", line 158, in __exit__
self.gen.throw(value)
File "D:\anaconda3\Lib\site-packages\httpcore\_exceptions.py", line 14, in map_exceptions
raise to_exc(exc) from exc
httpcore.ConnectError: [Errno 11001] getaddrinfo failed
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 50, in get_skill_by_id
response = self.client.get(url, headers=self._get_headers())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 1053, in get
return self.request(
^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 825, in request
return self.send(request, auth=auth, follow_redirects=follow_redirects)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 914, in send
response = self._send_handling_auth(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 942, in _send_handling_auth
response = self._send_handling_redirects(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 979, in _send_handling_redirects
response = self._send_single_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 1014, in _send_single_request
response = transport.handle_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 249, in handle_request
with map_httpcore_exceptions():
File "D:\anaconda3\Lib\contextlib.py", line 158, in __exit__
self.gen.throw(value)
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 118, in map_httpcore_exceptions
raise mapped_exc(message) from exc
httpx.ConnectError: [Errno 11001] getaddrinfo failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 202, in call_third_party_api
raw_result = get_skill_by_id(skill_id)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 154, in get_skill_by_id
return default_client.get_skill_by_id(skill_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 70, in get_skill_by_id
raise Exception(error_msg)
Exception: API 请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
2026-05-25 16:22:53 - mcp_services - WARNING - [main.py:108] - API 获取失败,降级使用本地配置: API 请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
2026-05-25 16:22:53 - mcp_services - INFO - [main.py:58] - 成功加载 0 个业务查询配置
2026-05-25 16:22:53 - mcp_services - INFO - [main.py:130] - 成功生成 0 个 MCP 工具
2026-05-25 16:22:53 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type ListToolsRequest
2026-05-25 16:22:53 - mcp_services - INFO - [main.py:127] - 收到列出工具请求
2026-05-25 16:22:53 - mcp_services - INFO - [main.py:130] - 成功生成 0 个 MCP 工具
2026-05-25 16:23:09 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type ListToolsRequest
2026-05-25 16:23:09 - mcp_services - INFO - [main.py:127] - 收到列出工具请求
2026-05-25 16:23:09 - mcp_services - INFO - [main.py:130] - 成功生成 0 个 MCP 工具
2026-05-25 16:26:37 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs
2026-05-25 16:26:37 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5
2026-05-25 16:26:37 - mcp_services - INFO - [main.py:258] - 开始运行 MCP SQL Executor 服务
2026-05-25 16:26:37 - mcp_services - INFO - [main.py:216] - ============================================================
2026-05-25 16:26:37 - mcp_services - INFO - [main.py:217] - 正在启动 MCP 服务: lzwcai-mcp-sqlexecutor
2026-05-25 16:26:37 - mcp_services - INFO - [main.py:218] - 版本: 0.1.0
2026-05-25 16:26:37 - mcp_services - INFO - [main.py:219] - ============================================================
2026-05-25 16:26:37 - mcp_services - INFO - [main.py:222] - 环境配置 - Database ID: 240
2026-05-25 16:26:37 - mcp_services - INFO - [main.py:223] - 环境配置 - Skill ID: 2058819964077572098
2026-05-25 16:26:37 - mcp_services - INFO - [main.py:224] - 环境配置 - Backend Base URL: http://192.168.2.236:8088
2026-05-25 16:26:37 - mcp_services - INFO - [main.py:225] - ============================================================
2026-05-25 16:26:37 - mcp_services - INFO - [main.py:230] - MCP 服务已启动,等待客户端连接...
2026-05-25 16:26:38 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type ListToolsRequest
2026-05-25 16:26:38 - mcp_services - INFO - [main.py:127] - 收到列出工具请求
2026-05-25 16:26:38 - mcp_services - INFO - [main.py:97] - 初始化查询配置,数据源: api
2026-05-25 16:26:38 - mcp_services - INFO - [main.py:201] - 调用第三方 APIskill_id: 2058819964077572098
2026-05-25 16:26:38 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:47] - 正在调用 API: http://192.168.2.236:8088/datasource/skill/getBySkillId/2058819964077572098
2026-05-25 16:26:38 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.2.236:8088/datasource/skill/getBySkillId/2058819964077572098 "HTTP/1.1 200 "
2026-05-25 16:26:38 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:54] - API 调用成功: http://192.168.2.236:8088/datasource/skill/getBySkillId/2058819964077572098
2026-05-25 16:26:38 - mcp_services - INFO - [main.py:203] - 成功获取原始响应: {'msg': '查询成功', 'code': 200, 'data': [{'id': '2058819964287287298', 'createBy': 'wxl06', 'createTime': '2026-05-25 15:58:25', 'updateBy': None, 'updateTime': None, 'serviceId': '2058819964085960705', 'uniqueName': '前50条导入数据明细查询', 'name': 'qian50tiaodaorushujumingxichaxun_32b1d628', 'description': 'qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: 查询数据导入明细表中的前50条记录包含原始数据、处理状态、错误原因等关键信息用于快速预览最近的导入情况。', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 1ms', 'toolType': 'sql', 'datasourceId': '240', 'sqlTemplate': 'SELECT record_id AS "记录ID", task_id AS "任务ID", original_data AS "原始数据", process_result AS "处理结果", error_reason AS "错误原因", process_status AS "处理状态", target_table AS "关联目标表", created_time AS "创建时间" FROM import_record_detail LIMIT 50;', 'sqlParams': '{}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","properties":{},"required":[]}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}]}
2026-05-25 16:26:38 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:205] - 成功处理 1 条技能数据
2026-05-25 16:26:38 - mcp_services - INFO - [main.py:206] - 成功处理 1 条数据
2026-05-25 16:26:38 - mcp_services - INFO - [main.py:105] - API 配置: 1 条
2026-05-25 16:26:38 - mcp_services - INFO - [main.py:106] - API 配置数组: [{'id': '2058819964287287298', 'businessName': 'qian50tiaodaorushujumingxichaxun_32b1d628', 'businessDescription': 'qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: qian50tiaodaorushujumingxichaxun_32b1d628: 查询数据导入明细表中的前50条记录包含原始数据、处理状态、错误原因等关键信息用于快速预览最近的导入情况。', 'sqlTemplate': 'SELECT record_id AS "记录ID", task_id AS "任务ID", original_data AS "原始数据", process_result AS "处理结果", error_reason AS "错误原因", process_status AS "处理状态", target_table AS "关联目标表", created_time AS "创建时间" FROM import_record_detail LIMIT 50;', 'parameters': {}, 'datasourceId': '240'}]
2026-05-25 16:26:38 - mcp_services - INFO - [main.py:130] - 成功生成 1 个 MCP 工具

View File

@@ -1,223 +0,0 @@
2025-12-31 12:57:27 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs
2025-12-31 12:57:27 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5
2025-12-31 12:57:27 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器
2025-12-31 12:57:27 - mcp_services - INFO - [main.py:299] - ============================================================
2025-12-31 12:57:27 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor
2025-12-31 12:57:27 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0
2025-12-31 12:57:27 - mcp_services - INFO - [main.py:302] - ============================================================
2025-12-31 12:57:27 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 16
2025-12-31 12:57:27 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID:
2025-12-31 12:57:27 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088
2025-12-31 12:57:27 - mcp_services - INFO - [main.py:309] - ============================================================
2025-12-31 12:57:27 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接...
2025-12-31 12:57:28 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type ListToolsRequest
2025-12-31 12:57:28 - mcp_services - INFO - [main.py:156] - 收到列出工具请求
2025-12-31 12:57:28 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api...
2025-12-31 12:57:28 - mcp_services - INFO - [main.py:278] - 调用第三方APIskill_id:
2025-12-31 12:57:28 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://192.168.11.24:8088/datasource/skill/getBySkillId/
2025-12-31 12:57:29 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.11.24:8088/datasource/skill/getBySkillId/ "HTTP/1.1 404 "
2025-12-31 12:57:29 - lzwcai_mcp_sqlexecutor.utils.api_client - ERROR - [api_client.py:97] - API请求失败 (HTTP 404): http://192.168.11.24:8088/datasource/skill/getBySkillId/
2025-12-31 12:57:29 - lzwcai_mcp_sqlexecutor.utils.api_client - ERROR - [api_client.py:98] - 错误响应: {"timestamp":"2025-12-31T12:57:30.248+08:00","status":404,"error":"Not Found","path":"/datasource/skill/getBySkillId/"}
2025-12-31 12:57:29 - mcp_services - ERROR - [main.py:292] - API调用失败: API请求失败 (HTTP 404): http://192.168.11.24:8088/datasource/skill/getBySkillId/
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 80, in get_skill_by_id
response.raise_for_status()
File "D:\anaconda3\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status
raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '404 ' for url 'http://192.168.11.24:8088/datasource/skill/getBySkillId/'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 281, in call_third_party_api
raw_result = get_skill_by_id(skill_id)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 208, in get_skill_by_id
return default_client.get_skill_by_id(skill_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 99, in get_skill_by_id
raise Exception(error_msg)
Exception: API请求失败 (HTTP 404): http://192.168.11.24:8088/datasource/skill/getBySkillId/
2025-12-31 12:57:29 - mcp_services - WARNING - [main.py:131] - API获取失败降级使用本地配置: API请求失败 (HTTP 404): http://192.168.11.24:8088/datasource/skill/getBySkillId/
2025-12-31 12:57:29 - mcp_services - INFO - [main.py:55] - 成功加载 3 个业务查询配置
2025-12-31 12:57:29 - mcp_services - ERROR - [main.py:92] - 生成工具模式失败: 2006300000000000001, 错误: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 12:57:29 - mcp_services - ERROR - [main.py:170] - 列出工具失败: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 162, in handle_list_tools
tool = generate_tool_schema_from_query(query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 12:57:29 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type ListToolsRequest
2025-12-31 12:57:29 - mcp_services - INFO - [main.py:156] - 收到列出工具请求
2025-12-31 12:57:29 - mcp_services - ERROR - [main.py:92] - 生成工具模式失败: 2006300000000000001, 错误: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 12:57:29 - mcp_services - ERROR - [main.py:170] - 列出工具失败: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 162, in handle_list_tools
tool = generate_tool_schema_from_query(query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 12:57:54 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs
2025-12-31 12:57:54 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:299] - ============================================================
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:302] - ============================================================
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 16
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID:
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:309] - ============================================================
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接...
2025-12-31 12:57:54 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type ListToolsRequest
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:156] - 收到列出工具请求
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: local...
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:55] - 成功加载 3 个业务查询配置
2025-12-31 12:57:54 - mcp_services - INFO - [main.py:123] - 本地配置: 3 条
2025-12-31 12:57:54 - mcp_services - ERROR - [main.py:92] - 生成工具模式失败: 2006300000000000001, 错误: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 12:57:54 - mcp_services - ERROR - [main.py:170] - 列出工具失败: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 162, in handle_list_tools
tool = generate_tool_schema_from_query(query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 15:00:31 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type ListToolsRequest
2025-12-31 15:00:31 - mcp_services - INFO - [main.py:156] - 收到列出工具请求
2025-12-31 15:00:31 - mcp_services - ERROR - [main.py:92] - 生成工具模式失败: 2006300000000000001, 错误: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 15:00:31 - mcp_services - ERROR - [main.py:170] - 列出工具失败: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 162, in handle_list_tools
tool = generate_tool_schema_from_query(query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 15:00:34 - mcp_services - INFO - [main.py:329] - MCP 服务器已关闭
2025-12-31 15:00:53 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs
2025-12-31 15:00:53 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5
2025-12-31 15:00:53 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器
2025-12-31 15:00:53 - mcp_services - INFO - [main.py:299] - ============================================================
2025-12-31 15:00:53 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor
2025-12-31 15:00:53 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0
2025-12-31 15:00:53 - mcp_services - INFO - [main.py:302] - ============================================================
2025-12-31 15:00:53 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 29
2025-12-31 15:00:53 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID:
2025-12-31 15:00:53 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://lzwcai-demp-corp-manager:8086
2025-12-31 15:00:53 - mcp_services - INFO - [main.py:309] - ============================================================
2025-12-31 15:00:53 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接...
2025-12-31 15:00:54 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type ListToolsRequest
2025-12-31 15:00:54 - mcp_services - INFO - [main.py:156] - 收到列出工具请求
2025-12-31 15:00:54 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api...
2025-12-31 15:00:54 - mcp_services - INFO - [main.py:278] - 调用第三方APIskill_id:
2025-12-31 15:00:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/
2025-12-31 15:00:56 - lzwcai_mcp_sqlexecutor.utils.api_client - ERROR - [api_client.py:103] - API请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
2025-12-31 15:00:56 - mcp_services - ERROR - [main.py:292] - API调用失败: API请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
Traceback (most recent call last):
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 101, in map_httpcore_exceptions
yield
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 250, in handle_request
resp = self._pool.handle_request(req)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection_pool.py", line 216, in handle_request
raise exc from None
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection_pool.py", line 196, in handle_request
response = connection.handle_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 99, in handle_request
raise exc
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 76, in handle_request
stream = self._connect(request)
^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 122, in _connect
stream = self._network_backend.connect_tcp(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_backends\sync.py", line 205, in connect_tcp
with map_exceptions(exc_map):
^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\contextlib.py", line 158, in __exit__
self.gen.throw(value)
File "D:\anaconda3\Lib\site-packages\httpcore\_exceptions.py", line 14, in map_exceptions
raise to_exc(exc) from exc
httpcore.ConnectError: [Errno 11001] getaddrinfo failed
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 74, in get_skill_by_id
response = self.client.get(
^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 1053, in get
return self.request(
^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 825, in request
return self.send(request, auth=auth, follow_redirects=follow_redirects)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 914, in send
response = self._send_handling_auth(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 942, in _send_handling_auth
response = self._send_handling_redirects(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 979, in _send_handling_redirects
response = self._send_single_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 1014, in _send_single_request
response = transport.handle_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 249, in handle_request
with map_httpcore_exceptions():
^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\contextlib.py", line 158, in __exit__
self.gen.throw(value)
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 118, in map_httpcore_exceptions
raise mapped_exc(message) from exc
httpx.ConnectError: [Errno 11001] getaddrinfo failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 281, in call_third_party_api
raw_result = get_skill_by_id(skill_id)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 208, in get_skill_by_id
return default_client.get_skill_by_id(skill_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 104, in get_skill_by_id
raise Exception(error_msg)
Exception: API请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
2025-12-31 15:00:56 - mcp_services - WARNING - [main.py:131] - API获取失败降级使用本地配置: API请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
2025-12-31 15:00:56 - mcp_services - INFO - [main.py:55] - 成功加载 0 个业务查询配置
2025-12-31 15:00:56 - mcp_services - INFO - [main.py:165] - 成功生成 0 个 MCP 工具
2025-12-31 15:00:56 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type ListToolsRequest
2025-12-31 15:00:56 - mcp_services - INFO - [main.py:156] - 收到列出工具请求
2025-12-31 15:00:56 - mcp_services - INFO - [main.py:165] - 成功生成 0 个 MCP 工具

View File

@@ -1,110 +1,26 @@
2025-12-31 12:57:29 - lzwcai_mcp_sqlexecutor.utils.api_client - ERROR - [api_client.py:97] - API请求失败 (HTTP 404): http://192.168.11.24:8088/datasource/skill/getBySkillId/
2025-12-31 12:57:29 - lzwcai_mcp_sqlexecutor.utils.api_client - ERROR - [api_client.py:98] - 错误响应: {"timestamp":"2025-12-31T12:57:30.248+08:00","status":404,"error":"Not Found","path":"/datasource/skill/getBySkillId/"}
2025-12-31 12:57:29 - mcp_services - ERROR - [main.py:292] - API调用失败: API请求失败 (HTTP 404): http://192.168.11.24:8088/datasource/skill/getBySkillId/
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 80, in get_skill_by_id
response.raise_for_status()
File "D:\anaconda3\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status
raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '404 ' for url 'http://192.168.11.24:8088/datasource/skill/getBySkillId/'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 281, in call_third_party_api
raw_result = get_skill_by_id(skill_id)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 208, in get_skill_by_id
return default_client.get_skill_by_id(skill_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 99, in get_skill_by_id
raise Exception(error_msg)
Exception: API请求失败 (HTTP 404): http://192.168.11.24:8088/datasource/skill/getBySkillId/
2025-12-31 12:57:29 - mcp_services - ERROR - [main.py:92] - 生成工具模式失败: 2006300000000000001, 错误: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 12:57:29 - mcp_services - ERROR - [main.py:170] - 列出工具失败: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 162, in handle_list_tools
tool = generate_tool_schema_from_query(query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 12:57:29 - mcp_services - ERROR - [main.py:92] - 生成工具模式失败: 2006300000000000001, 错误: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 12:57:29 - mcp_services - ERROR - [main.py:170] - 列出工具失败: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 162, in handle_list_tools
tool = generate_tool_schema_from_query(query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 12:57:54 - mcp_services - ERROR - [main.py:92] - 生成工具模式失败: 2006300000000000001, 错误: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 12:57:54 - mcp_services - ERROR - [main.py:170] - 列出工具失败: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 162, in handle_list_tools
tool = generate_tool_schema_from_query(query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 15:00:31 - mcp_services - ERROR - [main.py:92] - 生成工具模式失败: 2006300000000000001, 错误: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 15:00:31 - mcp_services - ERROR - [main.py:170] - 列出工具失败: 'businessName'
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 162, in handle_list_tools
tool = generate_tool_schema_from_query(query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 80, in generate_tool_schema_from_query
tool_name = query['businessName']
~~~~~^^^^^^^^^^^^^^^^
KeyError: 'businessName'
2025-12-31 15:00:56 - lzwcai_mcp_sqlexecutor.utils.api_client - ERROR - [api_client.py:103] - API请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
2025-12-31 15:00:56 - mcp_services - ERROR - [main.py:292] - API调用失败: API请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
2026-05-25 16:22:53 - lzwcai_mcp_sqlexecutor.utils.api_client - ERROR - [api_client.py:69] - API 请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
2026-05-25 16:22:53 - mcp_services - ERROR - [main.py:209] - API 调用失败: API 请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
Traceback (most recent call last):
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 101, in map_httpcore_exceptions
yield
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 250, in handle_request
resp = self._pool.handle_request(req)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection_pool.py", line 216, in handle_request
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection_pool.py", line 256, in handle_request
raise exc from None
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection_pool.py", line 196, in handle_request
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection_pool.py", line 236, in handle_request
response = connection.handle_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 99, in handle_request
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 101, in handle_request
raise exc
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 76, in handle_request
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 78, in handle_request
stream = self._connect(request)
^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 122, in _connect
File "D:\anaconda3\Lib\site-packages\httpcore\_sync\connection.py", line 124, in _connect
stream = self._network_backend.connect_tcp(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpcore\_backends\sync.py", line 205, in connect_tcp
File "D:\anaconda3\Lib\site-packages\httpcore\_backends\sync.py", line 207, in connect_tcp
with map_exceptions(exc_map):
^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\contextlib.py", line 158, in __exit__
self.gen.throw(value)
File "D:\anaconda3\Lib\site-packages\httpcore\_exceptions.py", line 14, in map_exceptions
@@ -114,9 +30,9 @@ httpcore.ConnectError: [Errno 11001] getaddrinfo failed
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 74, in get_skill_by_id
response = self.client.get(
^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 50, in get_skill_by_id
response = self.client.get(url, headers=self._get_headers())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_client.py", line 1053, in get
return self.request(
^^^^^^^^^^^^^
@@ -137,7 +53,6 @@ Traceback (most recent call last):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 249, in handle_request
with map_httpcore_exceptions():
^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda3\Lib\contextlib.py", line 158, in __exit__
self.gen.throw(value)
File "D:\anaconda3\Lib\site-packages\httpx\_transports\default.py", line 118, in map_httpcore_exceptions
@@ -147,12 +62,12 @@ httpx.ConnectError: [Errno 11001] getaddrinfo failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 281, in call_third_party_api
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\main.py", line 202, in call_third_party_api
raw_result = get_skill_by_id(skill_id)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 208, in get_skill_by_id
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 154, in get_skill_by_id
return default_client.get_skill_by_id(skill_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 104, in get_skill_by_id
File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\utils\api_client.py", line 70, in get_skill_by_id
raise Exception(error_msg)
Exception: API请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed
Exception: API 请求异常: http://lzwcai-demp-corp-manager:8086/datasource/skill/getBySkillId/, 错误: [Errno 11001] getaddrinfo failed

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +1,13 @@
from pathlib import Path
from typing import Any
import asyncio
import json
import logging
# 支持直接运行和模块导入两种方式
try:
from .utils import load_json, generate_tool_name, generate_input_schema
from .utils import get_skill_by_id, DataSourceAPIClient, process_skill_response, test_sql_with_schema
from .utils import get_database_id, get_skill_id, get_env_config
from .utils import load_json, generate_input_schema
from .utils import get_skill_by_id, process_skill_response, test_sql_with_schema
from .utils import get_skill_id, get_env_config
from .utils.logger_config import logger_config
except ImportError:
from utils import load_json, generate_input_schema
@@ -19,41 +19,43 @@ from mcp.server.models import InitializationOptions
from mcp.server import NotificationOptions, Server
import mcp.types as types
# 初始化 MCP 专用日志器
mcp_logger = logger_config.setup_mcp_logging()
# ========== 数据源配置 ==========
# 数据源类型常量
DATA_SOURCE_API = "api" # 仅使用API数据
DATA_SOURCE_LOCAL = "local" # 仅使用本地JSON数据
DATA_SOURCE_BOTH = "both" # 合并本地和API数据
# 默认数据源(可修改)
DATA_SOURCE_API = "api"
DATA_SOURCE_LOCAL = "local"
DATA_SOURCE_BOTH = "both"
DEFAULT_DATA_SOURCE = DATA_SOURCE_API
# ================================
def _text_response(payload: dict[str, Any]) -> list[types.TextContent]:
"""Build a JSON text response."""
return [
types.TextContent(
type="text",
text=json.dumps(payload, ensure_ascii=False, indent=2)
)
]
def _extract_user_id(arguments: dict[str, Any]) -> Any:
"""Allow numeric 0, reject None and blank strings."""
user_id = arguments.get("userId")
if user_id is None:
return None
if isinstance(user_id, str) and not user_id.strip():
return None
return user_id
def get_queries():
"""
获取业务查询配置
Returns:
list: 包含所有业务查询配置的列表
"""
"""Read local business query config."""
try:
# 获取当前文件所在目录
current_dir = Path(__file__).parent
# 构建 businessQueries.json 的路径
json_path = current_dir / "businessQueries.json"
mcp_logger.debug(f"正在读取业务查询配置文件: {json_path}")
# 使用 load_json 方法读取 JSON 文件
queries = load_json(json_path)
mcp_logger.info(f"成功加载 {len(queries)} 个业务查询配置")
return queries
except Exception as e:
mcp_logger.error(f"加载业务查询配置失败: {e}", exc_info=True)
@@ -61,110 +63,72 @@ def get_queries():
def generate_tool_schema_from_query(query: dict) -> types.Tool:
"""
根据查询配置生成 MCP 工具模式
Args:
query: 单个查询配置字典
Returns:
types.Tool: MCP 工具对象
"""
"""Generate an MCP tool definition from one query config."""
try:
# 获取参数定义并生成 inputSchema
parameters = query.get('parameters', {})
parameters = query.get("parameters", {})
input_schema = generate_input_schema(parameters)
# 生成工具名称(格式: tool_拼音_id
# tool_name = generate_tool_name(query['businessName'], query['id'])
tool_name = query['businessName']
# 构建工具描述,包含业务名称和业务描述
tool_name = query["businessName"]
description = f"{query['businessName']}: {query['businessDescription']}"
mcp_logger.debug(f"生成工具模式: {tool_name} - {query['businessName']}")
return types.Tool(
name=tool_name,
description=description,
inputSchema=input_schema
)
except Exception as e:
mcp_logger.error(f"生成工具模式失败: {query.get('id', 'unknown')}, 错误: {e}", exc_info=True)
mcp_logger.error(
f"生成工具模式失败: {query.get('id', 'unknown')}, 错误: {e}",
exc_info=True
)
raise
# 创建 MCP 服务器实例
server = Server("lzwcai-mcp-sqlexecutor")
# 缓存查询配置,避免重复加载
_queries_cache = None
async def get_queries_cache(source: str = None):
"""
获取或初始化查询配置缓存
Args:
source: 数据源类型(默认使用 DEFAULT_DATA_SOURCE
- "api": 仅使用API数据
- "local": 仅使用本地JSON数据
- "both": 合并本地和API数据
Returns:
查询配置列表
"""
"""Get or initialize query config cache."""
global _queries_cache
if _queries_cache is None:
source = source or DEFAULT_DATA_SOURCE
mcp_logger.info(f"初始化查询配置数据源: {source}...")
mcp_logger.info(f"初始化查询配置数据源: {source}")
if source == DATA_SOURCE_LOCAL:
_queries_cache = get_queries()
mcp_logger.info(f"本地配置: {len(_queries_cache)}")
elif source == DATA_SOURCE_API:
try:
_queries_cache = await call_third_party_api()
mcp_logger.info(f"API配置: {len(_queries_cache)}")
mcp_logger.info(f"API配置数组: {_queries_cache}")
mcp_logger.info(f"API 配置: {len(_queries_cache)}")
mcp_logger.info(f"API 配置数组: {_queries_cache}")
except Exception as e:
mcp_logger.warning(f"API获取失败降级使用本地配置: {e}")
mcp_logger.warning(f"API 获取失败,降级使用本地配置: {e}")
_queries_cache = get_queries()
else: # DATA_SOURCE_BOTH
else:
local = get_queries()
try:
api = await call_third_party_api()
except Exception as e:
mcp_logger.warning(f"API获取失败: {e}")
mcp_logger.warning(f"API 获取失败: {e}")
api = []
_queries_cache = local + api
mcp_logger.info(f"配置总数: {len(_queries_cache)}本地{len(local)}+API{len(api)}")
mcp_logger.info(f"配置总数: {len(_queries_cache)}本地 {len(local)} + API {len(api)}")
return _queries_cache
@server.list_tools()
async def handle_list_tools() -> list[types.Tool]:
"""
列出所有动态生成的 MCP 工具
Returns:
list[types.Tool]: 所有可用的工具列表
"""
"""List all dynamically generated MCP tools."""
try:
mcp_logger.info("收到列出工具请求")
queries = await get_queries_cache()
tools = []
for query in queries:
tool = generate_tool_schema_from_query(query)
tools.append(tool)
tools = [generate_tool_schema_from_query(query) for query in queries]
mcp_logger.info(f"成功生成 {len(tools)} 个 MCP 工具")
mcp_logger.debug(f"工具列表: {[tool.name for tool in tools]}")
return tools
except Exception as e:
mcp_logger.error(f"列出工具失败: {e}", exc_info=True)
@@ -173,151 +137,97 @@ async def handle_list_tools() -> list[types.Tool]:
@server.call_tool()
async def handle_call_tool(
name: str,
name: str,
arguments: dict[str, Any] | None
) -> list[types.TextContent]:
"""
处理工具调用请求
Args:
name: 工具名称
arguments: 工具参数
Returns:
list[types.TextContent]: 工具执行结果(返回参数和对应的接口配置)
"""
"""Handle MCP tool invocation."""
try:
mcp_logger.info(f"收到工具调用请求: {name}")
mcp_logger.debug(f"工具参数: {arguments}")
# 获取查询配置缓存
queries = await get_queries_cache()
# 根据工具名称查找对应的 item接口配置
tool_item = None
for query in queries:
# tool_name = generate_tool_name(query['businessName'], query['id'])
tool_name = query['businessName']
if tool_name == name:
tool_item = query
break
# 构建返回结果
import json
if tool_item:
request_data = {
"datasourceId": tool_item.get("datasourceId"),
"businessName": tool_item.get("businessName"),
"businessDescription": tool_item.get("businessDescription"),
"sqlTemplate": tool_item.get("sqlTemplate"),
"parameters": tool_item.get("parameters"),
"testParams": arguments or {}
}
# 如果 arguments 中有 targetDatabaseName 且有值,添加到 request_data
if arguments and arguments.get("targetDatabaseName"):
request_data["targetDatabaseName"] = arguments["targetDatabaseName"]
mcp_logger.debug(f"添加目标数据库名称: {arguments['targetDatabaseName']}")
# 如果 arguments 中有 userId 且有值,添加到 request_data
if arguments and arguments.get("userId"):
request_data["userId"] = arguments["userId"]
mcp_logger.debug(f"添加用户ID: {arguments['userId']}")
# 调用测试SQL API
try:
mcp_logger.info("正在调用测试SQL API...")
api_response = test_sql_with_schema(request_data)
mcp_logger.info("测试SQL API调用成功")
# 只返回 API 响应结果
result_text = json.dumps(api_response, ensure_ascii=False, indent=2)
except Exception as e:
error_msg = f"调用测试SQL API失败: {str(e)}"
mcp_logger.error(error_msg, exc_info=True)
result_text = json.dumps({"error": error_msg}, ensure_ascii=False, indent=2)
else:
error_msg = f"未找到工具 {name} 对应的配置"
result_text = json.dumps({"error": error_msg}, ensure_ascii=False, indent=2)
mcp_logger.debug(f"工具调用结果: {result_text}")
return [
types.TextContent(
type="text",
text=result_text
)
]
tool_item = next((query for query in queries if query["businessName"] == name), None)
if not tool_item:
return _text_response({"error": f"未找到工具 {name} 对应的配置"})
normalized_parameters = generate_input_schema(tool_item.get("parameters"))
normalized_arguments = arguments or {}
user_id = _extract_user_id(normalized_arguments)
if user_id is None:
error_msg = f"工具 {name} 缺少必填参数 userId"
mcp_logger.warning(error_msg)
return _text_response({"error": error_msg, "required": ["userId"]})
request_data = {
"datasourceId": tool_item.get("datasourceId"),
"businessName": tool_item.get("businessName"),
"businessDescription": tool_item.get("businessDescription"),
"sqlTemplate": tool_item.get("sqlTemplate"),
"parameters": normalized_parameters,
"testParams": normalized_arguments,
"userId": user_id
}
target_database_name = normalized_arguments.get("targetDatabaseName")
if target_database_name:
request_data["targetDatabaseName"] = target_database_name
mcp_logger.debug(f"添加目标数据库名称: {target_database_name}")
try:
mcp_logger.info("正在调用测试 SQL API...")
result_payload = test_sql_with_schema(request_data)
mcp_logger.info("测试 SQL API 调用成功")
except Exception as e:
error_msg = f"调用测试 SQL API 失败: {str(e)}"
mcp_logger.error(error_msg, exc_info=True)
result_payload = {"error": error_msg}
mcp_logger.debug(f"工具调用结果: {result_payload}")
return _text_response(result_payload)
except Exception as e:
error_msg = f"工具调用失败: {name}, 错误: {e}"
mcp_logger.error(error_msg, exc_info=True)
return [
types.TextContent(
type="text",
text=f"错误: {error_msg}"
)
]
return [types.TextContent(type="text", text=f"错误: {error_msg}")]
async def call_third_party_api(skill_id: str = None) -> list:
"""
调用第三方API获取技能信息并返回处理后的数据
Args:
skill_id: 技能ID默认从环境变量 SKILL_ID 读取,如果未设置则使用 1981000305474482178
Returns:
处理后的查询配置列表businessQueries格式
Example:
queries = await call_third_party_api()
# 返回: [{"id": "...", "businessName": "...", ...}, ...]
"""
"""Call backend API and map the response into query configs."""
try:
# 如果没有传入 skill_id则从环境变量读取
if skill_id is None:
skill_id = get_skill_id()
mcp_logger.info(f"调用第三方APIskill_id: {skill_id}")
# 获取原始数据
raw_result = get_skill_by_id(skill_id)
mcp_logger.info(f"成功{raw_result}")
# 处理并返回
mcp_logger.info(f"调用第三方 APIskill_id: {skill_id}")
raw_result = get_skill_by_id(skill_id)
mcp_logger.info(f"成功获取原始响应: {raw_result}")
processed_queries = process_skill_response(raw_result)
mcp_logger.info(f"成功获取并处理 {len(processed_queries)} 条数据")
mcp_logger.info(f"成功处理 {len(processed_queries)} 条数据")
return processed_queries
except Exception as e:
mcp_logger.error(f"API调用失败: {e}", exc_info=True)
mcp_logger.error(f"API 调用失败: {e}", exc_info=True)
raise
async def async_main():
"""MCP 服务器异步主函数"""
"""Async entry for the MCP server."""
try:
mcp_logger.info("=" * 60)
mcp_logger.info("正在启动 MCP 服务: lzwcai-mcp-sqlexecutor")
mcp_logger.info("正在启动 MCP 服务: lzwcai-mcp-sqlexecutor")
mcp_logger.info("版本: 0.1.0")
mcp_logger.info("=" * 60)
# 输出环境配置信息
env_config = get_env_config()
mcp_logger.info(f"环境配置 - Database ID: {env_config['database_id']}")
mcp_logger.info(f"环境配置 - Skill ID: {env_config['skill_id']}")
mcp_logger.info(f"环境配置 - Backend Base URL: {env_config['backend_base_url']}")
mcp_logger.info("=" * 60)
from mcp.server.stdio import stdio_server
async with stdio_server() as (read_stream, write_stream):
mcp_logger.info("MCP 服务已启动,等待客户端连接...")
mcp_logger.info("MCP 服务已启动,等待客户端连接...")
await server.run(
read_stream,
write_stream,
@@ -330,30 +240,25 @@ async def async_main():
),
),
)
mcp_logger.info("MCP 服务已关闭")
mcp_logger.info("MCP 服务已关闭")
except Exception as e:
mcp_logger.error(f"MCP 服务运行失败: {e}", exc_info=True)
mcp_logger.error(f"MCP 服务运行失败: {e}", exc_info=True)
raise
def main():
"""入口点函数(用于 console_scripts"""
"""Console entrypoint."""
try:
# 初始化系统日志
# MCP协议使用stdio通信必须禁用控制台输出以避免干扰JSON-RPC通信
logger_config.setup_logging(
app_name="lzwcai_mcp_sqlexecutor",
log_level=logging.INFO,
console_output=False # 禁用控制台输出
console_output=False
)
mcp_logger.info("开始运行 MCP SQL Executor 服务器")
mcp_logger.info("开始运行 MCP SQL Executor 服务")
asyncio.run(async_main())
except KeyboardInterrupt:
mcp_logger.info("收到中断信号,正在关闭服务...")
mcp_logger.info("收到中断信号,正在关闭服务...")
except Exception as e:
mcp_logger.error(f"程序运行失败: {e}", exc_info=True)
raise

View File

@@ -1,330 +1,209 @@
"""
第三方API调用客户端
用于调用外部数据源接口
"""
"""Backend API client helpers."""
import json
import logging
from typing import Any, Dict, List, Optional
import httpx
import logging
import json
from typing import Dict, Any, Optional, List
# 支持直接运行和模块导入两种方式
try:
from .env_config import get_backend_base_url
except ImportError:
from env_config import get_backend_base_url
# 获取日志记录器
logger = logging.getLogger(__name__)
class DataSourceAPIClient:
"""数据源API客户端"""
"""HTTP client for backend datasource APIs."""
def __init__(
self,
self,
base_url: Optional[str] = None,
token: Optional[str] = None
):
"""
初始化API客户端
Args:
base_url: API基础URL默认从环境变量 BACKEND_BASE_URL 读取,如果未设置则使用 http://192.168.2.236:8088
token: 认证令牌Bearer Token
"""
# 如果没有传入 base_url则从环境变量读取
if base_url is None:
base_url = get_backend_base_url()
self.base_url = base_url.rstrip('/')
self.token = token or "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjJiYTk4ODllLWM2ZGItNDQ5YS1iZmFjLTQ2YzMxODFlODg5NCJ9.dvi8zm0LsWvJ_h9zD5blnHFRxa4z4_WBm1R487ekE7HlHzrN6dnvqhK8askqT5b1EcE8myHwRzLVMoI8UOjOrw"
self.base_url = base_url.rstrip("/")
self.token = token or (
"eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjJiYTk4ODllLWM2ZGItNDQ5YS1i"
"ZmFjLTQ2YzMxODFlODg5NCJ9.dvi8zm0LsWvJ_h9zD5blnHFRxa4z4_WBm1R487ekE7HlHzrN6dn"
"vqhK8askqT5b1EcE8myHwRzLVMoI8UOjOrw"
)
self.client = httpx.Client(timeout=30.0)
def _get_headers(self) -> Dict[str, str]:
"""
获取请求头
Returns:
请求头字典
"""
return {
'Authorization': f'Bearer {self.token}',
"Authorization": f"Bearer {self.token}",
}
def get_skill_by_id(self, skill_id: str) -> Dict[str, Any]:
"""
根据技能ID获取技能信息
Args:
skill_id: 技能ID
Returns:
API响应数据
Raises:
Exception: 请求失败时抛出
"""
"""Fetch skill details by skill id."""
try:
url = f"{self.base_url}/datasource/skill/getBySkillId/{skill_id}"
logger.info(f"正在调用API: {url}")
logger.info(f"正在调用 API: {url}")
logger.debug(f"请求参数 - skill_id: {skill_id}")
response = self.client.get(
url,
headers=self._get_headers()
)
# 检查HTTP状态码
response = self.client.get(url, headers=self._get_headers())
response.raise_for_status()
# 解析JSON响应
data = response.json()
logger.info(f"API调用成功: {url}")
logger.info(f"API 调用成功: {url}")
logger.debug(f"响应数据: {data}")
return data
except httpx.TimeoutException:
error_msg = f"API请求超时: {url}"
error_msg = f"API 请求超时: {url}"
logger.error(error_msg)
raise Exception(error_msg)
except httpx.HTTPStatusError as e:
error_msg = f"API请求失败 (HTTP {e.response.status_code}): {url}"
error_msg = f"API 请求失败 (HTTP {e.response.status_code}): {url}"
logger.error(error_msg)
logger.error(f"错误响应: {e.response.text}")
raise Exception(error_msg)
except httpx.RequestError as e:
error_msg = f"API请求异常: {url}, 错误: {str(e)}"
error_msg = f"API 请求异常: {url}, 错误: {str(e)}"
logger.error(error_msg)
raise Exception(error_msg)
except Exception as e:
error_msg = f"处理API响应时出错: {str(e)}"
error_msg = f"处理 API 响应时出错: {str(e)}"
logger.error(error_msg, exc_info=True)
raise Exception(error_msg)
def test_sql_with_schema(self, request_data: Dict[str, Any]) -> Dict[str, Any]:
"""
测试SQL语句并返回执行结果
Args:
request_data: 请求数据,包含以下字段:
- datasourceId: 数据源ID
- businessName: 业务名称
- businessDescription: 业务描述
- sqlTemplate: SQL模板
- parameters: 参数定义
- testParams: 测试参数
Returns:
API响应数据
Raises:
Exception: 请求失败时抛出
"""
"""Call backend SQL test endpoint."""
try:
# 详细记录传入的数据
logger.info("=" * 80)
logger.info("test_sql_with_schema 接口接收到的数据:")
logger.info(f"数据类型: {type(request_data)}")
logger.info(f"数据内容: {json.dumps(request_data, ensure_ascii=False, indent=2)}")
logger.info(f"数据源ID: {request_data.get('datasourceId')}")
logger.info(f"数据源 ID: {request_data.get('datasourceId')}")
logger.info(f"业务名称: {request_data.get('businessName')}")
logger.info(f"业务描述: {request_data.get('businessDescription')}")
logger.info(f"SQL模板: {request_data.get('sqlTemplate')}")
logger.info(f"SQL 模板: {request_data.get('sqlTemplate')}")
logger.info(f"参数定义: {request_data.get('parameters')}")
logger.info(f"测试参数: {request_data.get('testParams')}")
if 'userId' in request_data:
logger.info(f"用户ID: {request_data.get('userId')}")
if "userId" in request_data:
logger.info(f"用户 ID: {request_data.get('userId')}")
logger.info("=" * 80)
url = f"{self.base_url}/datasource/sqlExecutionLog/testSqlWithSchema"
# 构建请求头包含Content-Type
headers = self._get_headers()
headers['Content-Type'] = 'application/json'
headers['Accept'] = '*/*'
logger.info(f"正在调用测试SQL API: {url}")
headers["Content-Type"] = "application/json"
headers["Accept"] = "*/*"
logger.info(f"正在调用测试 SQL API: {url}")
logger.debug(f"请求数据: {json.dumps(request_data, ensure_ascii=False, indent=2)}")
# 发送POST请求
response = self.client.post(
url,
headers=headers,
json=request_data
)
# 检查HTTP状态码
response = self.client.post(url, headers=headers, json=request_data)
response.raise_for_status()
# 解析JSON响应
data = response.json()
# 详细记录返回的数据
logger.info("=" * 80)
logger.info("test_sql_with_schema 接口返回的数据:")
logger.info(f"HTTP状态码: {response.status_code}")
logger.info(f"HTTP 状态码: {response.status_code}")
logger.info(f"响应数据类型: {type(data)}")
logger.info(f"响应数据内容: {json.dumps(data, ensure_ascii=False, indent=2)}")
if isinstance(data, dict):
logger.info(f"响应code: {data.get('code')}")
logger.info(f"响应msg: {data.get('msg')}")
logger.info(f"响应data: {data.get('data')}")
logger.info(f"响应 code: {data.get('code')}")
logger.info(f"响应 msg: {data.get('msg')}")
logger.info(f"响应 data: {data.get('data')}")
logger.info("=" * 80)
logger.info("测试SQL API调用成功")
logger.info("测试 SQL API 调用成功")
return data
except httpx.TimeoutException:
error_msg = f"测试SQL API请求超时: {url}"
error_msg = f"测试 SQL API 请求超时: {url}"
logger.error(error_msg)
raise Exception(error_msg)
except httpx.HTTPStatusError as e:
error_msg = f"测试SQL API请求失败 (HTTP {e.response.status_code}): {url}"
error_msg = f"测试 SQL API 请求失败 (HTTP {e.response.status_code}): {url}"
logger.error(error_msg)
logger.error(f"错误响应: {e.response.text}")
raise Exception(error_msg)
except httpx.RequestError as e:
error_msg = f"测试SQL API请求异常: {url}, 错误: {str(e)}"
error_msg = f"测试 SQL API 请求异常: {url}, 错误: {str(e)}"
logger.error(error_msg)
raise Exception(error_msg)
except Exception as e:
error_msg = f"处理测试SQL API响应时出错: {str(e)}"
error_msg = f"处理测试 SQL API 响应时出错: {str(e)}"
logger.error(error_msg, exc_info=True)
raise Exception(error_msg)
def close(self):
"""关闭HTTP客户端"""
"""Close the underlying HTTP client."""
self.client.close()
# 创建默认客户端实例
default_client = DataSourceAPIClient()
def get_skill_by_id(skill_id: str, base_url: Optional[str] = None, token: Optional[str] = None) -> Dict[str, Any]:
"""
便捷函数根据技能ID获取技能信息
Args:
skill_id: 技能ID
base_url: API基础URL可选默认从环境变量 BACKEND_BASE_URL 读取)
token: 认证令牌(可选,使用默认值)
Returns:
API响应数据
"""
def get_skill_by_id(
skill_id: str,
base_url: Optional[str] = None,
token: Optional[str] = None
) -> Dict[str, Any]:
"""Convenience wrapper for skill lookup."""
if base_url or token:
client = DataSourceAPIClient(
base_url=base_url,
token=token
)
client = DataSourceAPIClient(base_url=base_url, token=token)
return client.get_skill_by_id(skill_id)
else:
return default_client.get_skill_by_id(skill_id)
return default_client.get_skill_by_id(skill_id)
def test_sql_with_schema(request_data: Dict[str, Any], base_url: Optional[str] = None, token: Optional[str] = None) -> Dict[str, Any]:
"""
便捷函数测试SQL语句并返回执行结果
Args:
request_data: 请求数据,包含以下字段:
- datasourceId: 数据源ID
- businessName: 业务名称
- businessDescription: 业务描述
- sqlTemplate: SQL模板
- parameters: 参数定义
- testParams: 测试参数
base_url: API基础URL可选默认从环境变量 BACKEND_BASE_URL 读取)
token: 认证令牌(可选,使用默认值)
Returns:
API响应数据
"""
def test_sql_with_schema(
request_data: Dict[str, Any],
base_url: Optional[str] = None,
token: Optional[str] = None
) -> Dict[str, Any]:
"""Convenience wrapper for SQL test endpoint."""
if base_url or token:
client = DataSourceAPIClient(
base_url=base_url,
token=token
)
client = DataSourceAPIClient(base_url=base_url, token=token)
return client.test_sql_with_schema(request_data)
else:
return default_client.test_sql_with_schema(request_data)
return default_client.test_sql_with_schema(request_data)
def process_skill_response(response: Dict[str, Any]) -> List[Dict[str, Any]]:
"""
处理API响应数据映射为businessQueries格式
Args:
response: API原始响应数据
Returns:
处理后的查询配置列表
"""
"""Map backend skill response into business query configs."""
try:
# 提取data数组
data_list = response.get("data", [])
# 默认的员工ID参数schema
default_employee_schema = {
"type": "object",
"required": ["employeeId"],
"properties": {
"employeeId": {
"type": "number",
"description": "员工ID用于标识员工的唯一数字标识符",
"examples": [1001, 2002]
}
}
}
# 映射每个skill为businessQuery格式
queries = []
for skill in data_list:
# 解析sqlParams字符串为JSON对象
sql_params_str = skill.get("sqlParams") or "{}"
sql_params = json.loads(sql_params_str)
# 判断sqlParams是否为空对象
is_empty_params = (
not sql_params.get("properties") or
len(sql_params.get("properties", {})) == 0
) and (
not sql_params.get("required") or
len(sql_params.get("required", [])) == 0
)
# # 如果是空对象使用默认的员工ID参数
# if is_empty_params:
# logger.info(f"技能 {skill.get('name')} (ID: {skill.get('id')}) 的sqlParams为空使用默认员工ID参数")
# sql_params = default_employee_schema
# 映射字段
sql_params_raw = skill.get("sqlParams")
sql_params: Dict[str, Any] = {}
if isinstance(sql_params_raw, dict):
sql_params = sql_params_raw
elif isinstance(sql_params_raw, str) and sql_params_raw.strip():
try:
parsed_sql_params = json.loads(sql_params_raw)
if isinstance(parsed_sql_params, dict):
sql_params = parsed_sql_params
else:
logger.warning(
f"技能 {skill.get('name')} (ID: {skill.get('id')}) 的 sqlParams 不是对象,已回退为空对象"
)
except json.JSONDecodeError:
logger.warning(
f"技能 {skill.get('name')} (ID: {skill.get('id')}) 的 sqlParams 不是合法 JSON已回退为空对象"
)
query = {
"id": skill.get("id"),
"businessName": skill.get("name"),
"businessDescription": skill.get("description"),
"sqlTemplate": skill.get("sqlTemplate"),
"parameters": sql_params,
"datasourceId": skill.get("datasourceId")
"datasourceId": skill.get("datasourceId"),
}
queries.append(query)
logger.info(f"成功处理 {len(queries)} 条技能数据")
return queries
except Exception as e:
logger.error(f"处理API响应数据失败: {e}", exc_info=True)
logger.error(f"处理 API 响应数据失败: {e}", exc_info=True)
raise

View File

@@ -1,149 +1,93 @@
# -*- coding: utf-8 -*-
"""
Schema 生成工具模块
Schema 生成工具模块
"""
from copy import deepcopy
from typing import Any, Dict
def generate_input_schema(parameters: Dict[str, Any]) -> Dict[str, Any]:
"""
从查询配置的参数定义生成 MCP 工具的 inputSchema
此函数会保留完整的 JSON Schema 信息,包括:
- type: Schema 类型(通常是 "object"
- required: 必填字段列表
- properties: 属性定义(包括每个属性的 type, description, format, examples 等)
- description: Schema 的整体描述(如果有)
- 以及其他任何 JSON Schema 标准字段
此函数还会自动添加以下字段(如果原始 parameters 中未定义):
- targetDatabaseName: 目标数据库名称(非必填,默认为空字符串)
Args:
parameters: 查询配置中的参数定义字典,应该是一个完整的 JSON Schema 对象
Returns:
Dict[str, Any]: 符合 JSON Schema 规范的 inputSchema 对象
Example:
>>> params = {
... "type": "object",
... "required": ["userId", "startTime"],
... "properties": {
... "userId": {
... "type": "integer",
... "description": "用户的唯一标识符",
... "examples": [10086]
... },
... "startTime": {
... "type": "string",
... "format": "date-time",
... "description": "查询的起始时间",
... "examples": ["2023-01-01 00:00:00"]
... }
... }
... }
>>> schema = generate_input_schema(params)
>>> # schema 将包含所有原始信息,包括 format 和 examples
>>> # 同时会自动添加 targetDatabaseName 字段
"""
# 如果 parameters 本身就是一个完整的 JSON Schema 对象,直接使用
# 但确保至少包含 type 和 properties
if not parameters:
# 如果 parameters 为空,返回一个空的 object schema
def _normalize_schema(parameters: Dict[str, Any] | None) -> Dict[str, Any]:
"""将任意参数定义归一化为 object schema。"""
if not isinstance(parameters, dict) or not parameters:
return {
"type": "object",
"properties": {},
"required": []
}
# 深拷贝 parameters 以避免修改原始数据
input_schema = dict(parameters)
# 确保必需的字段存在
if "type" not in input_schema:
input_schema["type"] = "object"
if "properties" not in input_schema:
input_schema = deepcopy(parameters)
input_schema["type"] = "object"
if not isinstance(input_schema.get("properties"), dict):
input_schema["properties"] = {}
if "required" not in input_schema:
if not isinstance(input_schema.get("required"), list):
input_schema["required"] = []
# 添加 targetDatabaseName 字段(如果不存在)
return input_schema
def generate_input_schema(parameters: Dict[str, Any] | None) -> Dict[str, Any]:
"""
从查询配置的参数定义生成 MCP 工具的 inputSchema。
会统一补齐:
- `targetDatabaseName`:可选
- `userId`:必填
"""
input_schema = _normalize_schema(parameters)
if "targetDatabaseName" not in input_schema["properties"]:
input_schema["properties"]["targetDatabaseName"] = {
"type": "string",
"description": "目标数据库名称",
"default": ""
}
# 添加 userId 字段(如果不存在)
if "userId" not in input_schema["properties"]:
input_schema["properties"]["userId"] = {
"type": "string",
"description": "当前ai平台用户id"
"description": "当前 AI 平台用户 ID"
}
# 保留所有其他字段,如 description, examples, format 等
# JSON Schema 标准支持的字段都会被保留:
# - additionalProperties
# - patternProperties
# - minProperties / maxProperties
# - dependencies
# - 等等
if "userId" not in input_schema["required"]:
input_schema["required"].append("userId")
return input_schema
def validate_input_schema(schema: Dict[str, Any]) -> tuple[bool, str]:
"""
验证 inputSchema 是否符合基本的 JSON Schema 规范
Args:
schema: 要验证的 schema 对象
Returns:
tuple[bool, str]: (是否有效, 错误消息或成功消息)
Example:
>>> schema = {"type": "object", "properties": {"id": {"type": "string"}}}
>>> is_valid, msg = validate_input_schema(schema)
>>> print(is_valid, msg)
True, "Schema 验证通过"
验证 inputSchema 是否符合基本的 JSON Schema 规范
"""
if not isinstance(schema, dict):
return False, "Schema 必须是一个字典对象"
if schema.get("type") != "object":
return False, "Schema 的 type 字段必须是 'object'"
if "properties" not in schema:
return False, "Schema 必须包含 properties 字段"
if not isinstance(schema.get("properties"), dict):
return False, "Schema 的 properties 字段必须是一个字典对象"
# 验证 required 字段(如果存在)
if "required" in schema:
required = schema["required"]
if not isinstance(required, list):
return False, "Schema 的 required 字段必须是一个列表"
# 验证所有 required 的字段都在 properties 中定义
properties = schema["properties"]
for field in required:
if field not in properties:
return False, f"必填字段 '{field}' 未在 properties 中定义"
# 验证 properties 中每个字段的定义
for prop_name, prop_def in schema["properties"].items():
if not isinstance(prop_def, dict):
return False, f"属性 '{prop_name}' 的定义必须是一个字典对象"
if "type" not in prop_def:
return False, f"属性 '{prop_name}' 必须包含 type 字段"
return True, "Schema 验证通过"
return True, "Schema 验证通过"

View File

@@ -1,14 +1,20 @@
"""
Entry point for lzwcai-mcp-sqlexecutor
Runs the MCP server for SQL query execution
Repository-local launcher for lzwcai-mcp-sqlexecutor.
"""
import os
os.environ["databaseId"] = "162"
os.environ["skillId"] = "2008360664955854850"
os.environ["backendBaseUrl"] = "http://192.168.2.236:8088"
if __name__ == "__main__":
# Import and run the actual MCP server
from lzwcai_mcp_sqlexecutor.main import main
def main():
# Keep local developer defaults without overriding explicit environment settings.
os.environ.setdefault("databaseId", "240")
os.environ.setdefault("skillId", "2058819964077572098")
os.environ.setdefault("backendBaseUrl", "http://192.168.2.236:8088")
from lzwcai_mcp_sqlexecutor.main import main as package_main
package_main()
if __name__ == "__main__":
main()

View File

@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "lzwcai-mcp-sqlexecutor"
version = "0.1.12"
version = "0.1.13"
description = "MCP server for executing business SQL queries with dynamic tool generation"
readme = "README.md"
requires-python = ">=3.10"