From 9c597c9b0dd1176c83c66de1d7b8695a7eb72486 Mon Sep 17 00:00:00 2001 From: yuanzhipeng <2501363769@qq.com> Date: Thu, 11 Jun 2026 09:53:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E7=AE=A1=E7=90=86=E5=B9=B3=E5=8F=B0MCP=20Server?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增lzwcai-mcp-agile-db项目,提供数据库管理、表操作、数据CRUD、 API密钥管理、技能与工具管理等功能。 包含33个工具: - 数据源管理:创建、更新、删除数据源 - 数据库与表管理:表结构操作、数据查询等 - API密钥管理:密钥创建、权限管理等 - 技能与工具管理:SQL工具创建、配置更新等 - 数据导入和SQL执行功能 添加了完整的README文档说明安装使用方法, 以及Python 3.12版本支持和基本项目结构。 --- lzwcai_mcp_agile_db/README.md | 85 ++ .../lzwcai_mcp_agile_db/.python-version | 1 + .../lzwcai_mcp_agile_db/README.md | 0 .../lzwcai_mcp_agile_db/__init__.py | 5 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 323 bytes .../__pycache__/server.cpython-312.pyc | Bin 0 -> 5979 bytes .../logs/lzwcai_mcp_agile_db.log | 202 +++++ .../logs/lzwcai_mcp_agile_db_error.log | 15 + .../lzwcai_mcp_agile_db/main.py | 6 + .../lzwcai_mcp_agile_db/pyproject.toml | 7 + .../lzwcai_mcp_agile_db/server.py | 138 +++ .../lzwcai_mcp_agile_db/tools/__init__.py | 18 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 833 bytes .../tools/__pycache__/_base.cpython-312.pyc | Bin 0 -> 4053 bytes .../__pycache__/api_keys.cpython-312.pyc | Bin 0 -> 5420 bytes .../__pycache__/data_import.cpython-312.pyc | Bin 0 -> 3259 bytes .../database_tables.cpython-312.pyc | Bin 0 -> 6876 bytes .../__pycache__/datasources.cpython-312.pyc | Bin 0 -> 8404 bytes .../tools/__pycache__/skills.cpython-312.pyc | Bin 0 -> 6027 bytes .../__pycache__/sql_execution.cpython-312.pyc | Bin 0 -> 1386 bytes .../__pycache__/subscriptions.cpython-312.pyc | Bin 0 -> 1293 bytes .../__pycache__/table_data.cpython-312.pyc | Bin 0 -> 6518 bytes .../lzwcai_mcp_agile_db/tools/_base.py | 116 +++ .../lzwcai_mcp_agile_db/tools/api_keys.py | 121 +++ .../lzwcai_mcp_agile_db/tools/data_import.py | 72 ++ .../tools/database_tables.py | 151 ++++ .../lzwcai_mcp_agile_db/tools/datasources.py | 173 ++++ .../lzwcai_mcp_agile_db/tools/skills.py | 137 +++ .../tools/sql_execution.py | 25 + .../tools/subscriptions.py | 23 + .../lzwcai_mcp_agile_db/tools/table_data.py | 137 +++ .../lzwcai_mcp_agile_db/utils/__init__.py | 13 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 531 bytes .../__pycache__/api_client.cpython-312.pyc | Bin 0 -> 11555 bytes .../__pycache__/env_config.cpython-312.pyc | Bin 0 -> 2150 bytes .../__pycache__/logger_config.cpython-312.pyc | Bin 0 -> 5588 bytes .../lzwcai_mcp_agile_db/utils/api_client.py | 196 +++++ .../lzwcai_mcp_agile_db/utils/env_config.py | 60 ++ .../utils/logger_config.py | 121 +++ .../数据库管理平台-MCP工具设计方案.md | 621 +++++++++++++ .../数据库管理平台-功能总览.md | 303 +++++++ lzwcai_mcp_agile_db/main.py | 12 + lzwcai_mcp_agile_db/pyproject.toml | 34 + .../__pycache__/main.cpython-312.pyc | Bin 0 -> 820 bytes .../logs/lzwcai_mcp_sqlexecutor.log | 830 +++++------------- .../logs/lzwcai_mcp_sqlexecutor_daily.log | 314 ++++++- ...zwcai_mcp_sqlexecutor_daily.log.2026-01-26 | 223 ----- ...zwcai_mcp_sqlexecutor_daily.log.2026-02-07 | 358 -------- .../logs/lzwcai_mcp_sqlexecutor_error.log | 115 +-- .../logs/mcp_services.log | 353 ++------ .../lzwcai_mcp_sqlexecutor/main.py | 323 +++---- .../utils/api_client.py | 317 +++---- .../utils/schema_helper.py | 138 +-- lzwcai_mcp_sqlexecutor/main.py | 22 +- lzwcai_mcp_sqlexecutor/pyproject.toml | 2 +- .../utils/api_client.py | 2 +- lzwcai_workflow_to_mcp/pyproject.toml | 2 +- 57 files changed, 3688 insertions(+), 2103 deletions(-) create mode 100644 lzwcai_mcp_agile_db/README.md create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/.python-version create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/README.md create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/__init__.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/__pycache__/__init__.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/__pycache__/server.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/logs/lzwcai_mcp_agile_db.log create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/logs/lzwcai_mcp_agile_db_error.log create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/main.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/pyproject.toml create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/server.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__init__.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/__init__.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/_base.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/api_keys.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/data_import.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/database_tables.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/datasources.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/skills.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/sql_execution.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/subscriptions.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/table_data.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/_base.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/api_keys.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/data_import.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/database_tables.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/datasources.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/skills.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/sql_execution.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/subscriptions.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/table_data.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__init__.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__pycache__/__init__.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__pycache__/api_client.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__pycache__/env_config.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__pycache__/logger_config.cpython-312.pyc create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/api_client.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/env_config.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/logger_config.py create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/数据库管理平台-MCP工具设计方案.md create mode 100644 lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/数据库管理平台-功能总览.md create mode 100644 lzwcai_mcp_agile_db/main.py create mode 100644 lzwcai_mcp_agile_db/pyproject.toml create mode 100644 lzwcai_mcp_sqlexecutor/__pycache__/main.cpython-312.pyc delete mode 100644 lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log.2026-01-26 delete mode 100644 lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log.2026-02-07 diff --git a/lzwcai_mcp_agile_db/README.md b/lzwcai_mcp_agile_db/README.md new file mode 100644 index 0000000..383820b --- /dev/null +++ b/lzwcai_mcp_agile_db/README.md @@ -0,0 +1,85 @@ +# lzwcai-mcp-agile-db + +数据库管理平台 MCP Server,提供 33 个工具用于数据库管理、表操作、数据 CRUD、API 密钥管理、技能与工具管理等。 + +## 环境变量 + +| 变量名 | 必填 | 说明 | +|--------|------|------| +| `AGILE_DB_API_KEY` | 是 | 数据库管理平台的 API 密钥 | +| `AGILE_DB_BASE_URL` | 否 | 数据库管理平台后端地址(默认 `http://localhost:8080`) | + +## 安装 + +```bash +pip install -e . +``` + +## 运行 + +```bash +# 设置环境变量 +export AGILE_DB_API_KEY="your-api-key" +export AGILE_DB_BASE_URL="http://localhost:8080" # 可选 + +# 运行 MCP Server +lzwcai-mcp-agile-db +``` + +## 工具列表 + +### 数据源管理 +- `list_datasources` - 获取数据源列表 +- `get_datasource_detail` - 获取数据源详情 +- `create_datasource` - 创建数据源 +- `update_datasource` - 更新数据源 +- `toggle_datasource_status` - 启用/停用数据源 +- `delete_datasource` - 删除数据源 + +### 数据库与表管理 +- `list_databases` - 获取数据库列表 +- `list_tables` - 获取表列表 +- `get_table_detail` - 获取表详情 +- `create_table` - 创建表 +- `alter_table` - 修改表结构 +- `generate_table_by_description` - 通过自然语言生成表结构 + +### 表数据 CRUD +- `query_table_data` - 查询表数据 +- `insert_table_row` - 插入行数据 +- `update_table_row` - 更新行数据 +- `delete_table_rows` - 删除行数据 +- `export_table_excel` - 导出 Excel + +### API 密钥管理 +- `list_api_keys` - 获取密钥列表 +- `create_api_key` - 创建密钥 +- `toggle_api_key_status` - 启用/禁用密钥 +- `delete_api_key` - 删除密钥 +- `get_api_key_permissions` - 查看密钥权限 +- `grant_api_key_permissions` - 授予权限 + +### 技能与工具管理 +- `get_skill_by_datasource` - 获取技能信息 +- `get_skill_tools` - 获取技能工具列表 +- `create_skill` - 创建技能 +- `create_sql_tool` - 创建 SQL 工具 +- `delete_skill_tool` - 删除技能工具 +- `update_skill_config` - 更新技能配置 + +### 数据导入 +- `preview_import_data` - 预览导入数据 +- `confirm_import_data` - 确认导入数据 + +### 表订阅与 SQL 执行 +- `toggle_table_subscription` - 切换表订阅 +- `execute_sql` - 执行 SQL 查询 + +## 架构 + +- `tools/_base.py` - 工具注册装饰器和基类 +- `tools/*.py` - 工具实现文件 +- `utils/api_client.py` - 统一 HTTP 客户端 +- `utils/env_config.py` - 环境变量配置 +- `utils/logger_config.py` - 日志配置 +- `server.py` - MCP Server 注册和启动逻辑 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/.python-version b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/README.md b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/README.md new file mode 100644 index 0000000..e69de29 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/__init__.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/__init__.py new file mode 100644 index 0000000..72715c3 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/__init__.py @@ -0,0 +1,5 @@ +"""lzwcai-mcp-agile-db MCP Server 包""" + +from .server import main + +__all__ = ["main"] diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/__pycache__/__init__.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a0a9bb2e4250e40c02dcf9e60bea8a1a8fad546f GIT binary patch literal 323 zcmX@j%ge<81SOL-v%-P&V-N=hn4pZ$Qb5LZh7^V#wg}W z7ERVtC7^PO4oIC~QEEE*1h3AD9^#8E-OZJY|r0z%AIJ(a2uJ0Tc!R1ZZAS literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/__pycache__/server.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/__pycache__/server.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9caadc5e8ebea95e814769bc51fcd379e3010511 GIT binary patch literal 5979 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 +2026-06-11 09:30:50 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type ListToolsRequest +2026-06-11 09:30:50 - mcp.server.lowlevel.server - DEBUG - [server.py:723] - Dispatching request of type ListToolsRequest +2026-06-11 09:30:50 - lzwcai_mcp_agile_db.server - INFO - [server.py:42] - 收到 ListTools 请求 +2026-06-11 09:30:50 - mcp.server.lowlevel.server - DEBUG - [server.py:790] - Response sent +2026-06-11 09:33:24 - root - INFO - [logger_config.py:102] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\logs +2026-06-11 09:33:24 - mcp.server.lowlevel.server - DEBUG - [server.py:162] - Initializing server 'lzwcai_mcp_agile_db' +2026-06-11 09:33:24 - mcp.server.lowlevel.server - DEBUG - [server.py:439] - Registering handler for ListToolsRequest +2026-06-11 09:33:24 - mcp.server.lowlevel.server - DEBUG - [server.py:519] - Registering handler for CallToolRequest +2026-06-11 09:33:24 - lzwcai_mcp_agile_db.server - INFO - [server.py:124] - ================================================== +2026-06-11 09:33:24 - lzwcai_mcp_agile_db.server - INFO - [server.py:125] - lzwcai-mcp-agile-db MCP Server 启动 +2026-06-11 09:33:24 - lzwcai_mcp_agile_db.server - INFO - [server.py:130] - 已注册工具数量: 33 +2026-06-11 09:33:24 - lzwcai_mcp_agile_db.server - INFO - [server.py:131] - ================================================== +2026-06-11 09:33:24 - lzwcai_mcp_agile_db.server - INFO - [server.py:133] - 开始运行 MCP Server (stdio 模式) +2026-06-11 09:33:24 - asyncio - DEBUG - [proactor_events.py:634] - Using proactor: IocpProactor +2026-06-11 09:33:24 - mcp.server.lowlevel.server - DEBUG - [server.py:675] - Received message: root=InitializedNotification(method='notifications/initialized', params=None, jsonrpc='2.0') +2026-06-11 09:33:25 - mcp.server.lowlevel.server - DEBUG - [server.py:675] - Received message: +2026-06-11 09:33:25 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type ListToolsRequest +2026-06-11 09:33:25 - mcp.server.lowlevel.server - DEBUG - [server.py:723] - Dispatching request of type ListToolsRequest +2026-06-11 09:33:25 - lzwcai_mcp_agile_db.server - INFO - [server.py:42] - 收到 ListTools 请求 +2026-06-11 09:33:25 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:48] - [客户端初始化] base_url=https://dempdemo.lzwcai.com +2026-06-11 09:33:25 - lzwcai_mcp_agile_db.server - INFO - [server.py:56] - ListTools 响应: 返回 33 个工具 +2026-06-11 09:33:25 - mcp.server.lowlevel.server - DEBUG - [server.py:790] - Response sent +2026-06-11 09:33:45 - mcp.server.lowlevel.server - DEBUG - [server.py:675] - Received message: +2026-06-11 09:33:45 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type CallToolRequest +2026-06-11 09:33:45 - mcp.server.lowlevel.server - DEBUG - [server.py:723] - Dispatching request of type CallToolRequest +2026-06-11 09:33:45 - lzwcai_mcp_agile_db.server - INFO - [server.py:66] - 收到 CallTool 请求: name=list_datasources +2026-06-11 09:33:46 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:100] - [API请求] GET https://dempdemo.lzwcai.com/api/datasource/connection/list +2026-06-11 09:33:46 - httpx - DEBUG - [_config.py:82] - load_ssl_context verify=True cert=None trust_env=True http2=False +2026-06-11 09:33:46 - httpx - DEBUG - [_config.py:148] - load_verify_locations cafile='D:\\anaconda3\\Library\\ssl\\cacert.pem' +2026-06-11 09:33:46 - httpcore.connection - DEBUG - [_trace.py:47] - connect_tcp.started host='dempdemo.lzwcai.com' port=443 local_address=None timeout=30.0 socket_options=None +2026-06-11 09:33:46 - httpcore.connection - DEBUG - [_trace.py:47] - connect_tcp.complete return_value= +2026-06-11 09:33:46 - httpcore.connection - DEBUG - [_trace.py:47] - start_tls.started ssl_context= server_hostname='dempdemo.lzwcai.com' timeout=30.0 +2026-06-11 09:33:46 - httpcore.connection - DEBUG - [_trace.py:47] - start_tls.complete return_value= +2026-06-11 09:33:46 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_headers.started request= +2026-06-11 09:33:46 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_headers.complete +2026-06-11 09:33:46 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_body.started request= +2026-06-11 09:33:46 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_body.complete +2026-06-11 09:33:46 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_headers.started request= +2026-06-11 09:33:46 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'', [(b'Server', b'nginx/1.25.2'), (b'Date', b'Thu, 11 Jun 2026 01:33:40 GMT'), (b'Content-Type', b'application/json;charset=utf-8'), (b'Content-Length', b'51'), (b'Connection', b'keep-alive'), (b'Vary', b'Origin'), (b'Vary', b'Access-Control-Request-Method'), (b'Vary', b'Access-Control-Request-Headers'), (b'X-Content-Type-Options', b'nosniff'), (b'X-XSS-Protection', b'1; mode=block'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains'), (b'X-Frame-Options', b'DENY'), (b'X-Content-Type-Options', b'nosniff'), (b'X-XSS-Protection', b'1; mode=block')]) +2026-06-11 09:33:46 - httpx - INFO - [_client.py:1038] - HTTP Request: GET https://dempdemo.lzwcai.com/api/datasource/connection/list?pageNum=1&pageSize=20 "HTTP/1.1 200 " +2026-06-11 09:33:46 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_body.started request= +2026-06-11 09:33:46 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_body.complete +2026-06-11 09:33:46 - httpcore.http11 - DEBUG - [_trace.py:47] - response_closed.started +2026-06-11 09:33:46 - httpcore.http11 - DEBUG - [_trace.py:47] - response_closed.complete +2026-06-11 09:33:46 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:74] - [API响应] HTTP 200 +2026-06-11 09:33:46 - lzwcai_mcp_agile_db.utils.api_client - ERROR - [api_client.py:91] - [API错误] 登录过期,请重新登录 +2026-06-11 09:33:46 - lzwcai_mcp_agile_db.server - ERROR - [server.py:96] - 工具执行失败: list_datasources, 错误: 登录过期,请重新登录 +Traceback (most recent call last): + File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\server.py", line 84, in handle_call_tool + result = await tool_instance.execute(arguments or {}) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\tools\datasources.py", line 30, in execute + return self.client.get("/api/datasource/connection/list", params=params) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\utils\api_client.py", line 102, in get + return self._handle_response(response, url) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\utils\api_client.py", line 92, in _handle_response + raise Exception(error_msg) +Exception: 登录过期,请重新登录 +2026-06-11 09:33:46 - mcp.server.lowlevel.server - DEBUG - [server.py:790] - Response sent +2026-06-11 09:39:21 - root - INFO - [logger_config.py:102] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\logs +2026-06-11 09:39:21 - mcp.server.lowlevel.server - DEBUG - [server.py:162] - Initializing server 'lzwcai_mcp_agile_db' +2026-06-11 09:39:21 - mcp.server.lowlevel.server - DEBUG - [server.py:439] - Registering handler for ListToolsRequest +2026-06-11 09:39:21 - mcp.server.lowlevel.server - DEBUG - [server.py:519] - Registering handler for CallToolRequest +2026-06-11 09:39:21 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:48] - [客户端初始化] base_url=https://dempdemo.lzwcai.com +2026-06-11 09:39:21 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:100] - [API请求] GET https://dempdemo.lzwcai.com/api/datasource/connection/list +2026-06-11 09:39:21 - httpx - DEBUG - [_config.py:82] - load_ssl_context verify=True cert=None trust_env=True http2=False +2026-06-11 09:39:21 - httpx - DEBUG - [_config.py:148] - load_verify_locations cafile='C:\\Users\\HiWin10\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\certifi\\cacert.pem' +2026-06-11 09:39:21 - httpcore.connection - DEBUG - [_trace.py:47] - connect_tcp.started host='dempdemo.lzwcai.com' port=443 local_address=None timeout=30.0 socket_options=None +2026-06-11 09:39:21 - httpcore.connection - DEBUG - [_trace.py:47] - connect_tcp.complete return_value= +2026-06-11 09:39:21 - httpcore.connection - DEBUG - [_trace.py:47] - start_tls.started ssl_context= server_hostname='dempdemo.lzwcai.com' timeout=30.0 +2026-06-11 09:39:21 - httpcore.connection - DEBUG - [_trace.py:47] - start_tls.complete return_value= +2026-06-11 09:39:21 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_headers.started request= +2026-06-11 09:39:21 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_headers.complete +2026-06-11 09:39:21 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_body.started request= +2026-06-11 09:39:21 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_body.complete +2026-06-11 09:39:21 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_headers.started request= +2026-06-11 09:39:21 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'', [(b'Server', b'nginx/1.25.2'), (b'Date', b'Thu, 11 Jun 2026 01:39:15 GMT'), (b'Content-Type', b'application/json'), (b'Transfer-Encoding', b'chunked'), (b'Connection', b'keep-alive'), (b'Vary', b'Origin'), (b'Vary', b'Access-Control-Request-Method'), (b'Vary', b'Access-Control-Request-Headers'), (b'X-Content-Type-Options', b'nosniff'), (b'X-XSS-Protection', b'1; mode=block'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains'), (b'X-Frame-Options', b'DENY'), (b'X-Content-Type-Options', b'nosniff'), (b'X-XSS-Protection', b'1; mode=block')]) +2026-06-11 09:39:21 - httpx - INFO - [_client.py:1038] - HTTP Request: GET https://dempdemo.lzwcai.com/api/datasource/connection/list "HTTP/1.1 200 " +2026-06-11 09:39:21 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_body.started request= +2026-06-11 09:39:21 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_body.complete +2026-06-11 09:39:21 - httpcore.http11 - DEBUG - [_trace.py:47] - response_closed.started +2026-06-11 09:39:21 - httpcore.http11 - DEBUG - [_trace.py:47] - response_closed.complete +2026-06-11 09:39:21 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:74] - [API响应] HTTP 200 +2026-06-11 09:39:52 - root - INFO - [logger_config.py:102] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\logs +2026-06-11 09:39:52 - mcp.server.lowlevel.server - DEBUG - [server.py:162] - Initializing server 'lzwcai_mcp_agile_db' +2026-06-11 09:39:52 - mcp.server.lowlevel.server - DEBUG - [server.py:439] - Registering handler for ListToolsRequest +2026-06-11 09:39:52 - mcp.server.lowlevel.server - DEBUG - [server.py:519] - Registering handler for CallToolRequest +2026-06-11 09:39:52 - lzwcai_mcp_agile_db.server - INFO - [server.py:124] - ================================================== +2026-06-11 09:39:52 - lzwcai_mcp_agile_db.server - INFO - [server.py:125] - lzwcai-mcp-agile-db MCP Server 启动 +2026-06-11 09:39:52 - lzwcai_mcp_agile_db.server - INFO - [server.py:130] - 已注册工具数量: 33 +2026-06-11 09:39:52 - lzwcai_mcp_agile_db.server - INFO - [server.py:131] - ================================================== +2026-06-11 09:39:52 - lzwcai_mcp_agile_db.server - INFO - [server.py:133] - 开始运行 MCP Server (stdio 模式) +2026-06-11 09:39:52 - asyncio - DEBUG - [proactor_events.py:634] - Using proactor: IocpProactor +2026-06-11 09:39:52 - mcp.server.lowlevel.server - DEBUG - [server.py:675] - Received message: root=InitializedNotification(method='notifications/initialized', params=None, jsonrpc='2.0') +2026-06-11 09:39:53 - mcp.server.lowlevel.server - DEBUG - [server.py:675] - Received message: +2026-06-11 09:39:53 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type ListToolsRequest +2026-06-11 09:39:53 - mcp.server.lowlevel.server - DEBUG - [server.py:723] - Dispatching request of type ListToolsRequest +2026-06-11 09:39:53 - lzwcai_mcp_agile_db.server - INFO - [server.py:42] - 收到 ListTools 请求 +2026-06-11 09:39:53 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:48] - [客户端初始化] base_url=https://dempdemo.lzwcai.com +2026-06-11 09:39:53 - lzwcai_mcp_agile_db.server - INFO - [server.py:56] - ListTools 响应: 返回 33 个工具 +2026-06-11 09:39:53 - mcp.server.lowlevel.server - DEBUG - [server.py:790] - Response sent +2026-06-11 09:40:08 - mcp.server.lowlevel.server - DEBUG - [server.py:675] - Received message: +2026-06-11 09:40:08 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type CallToolRequest +2026-06-11 09:40:08 - mcp.server.lowlevel.server - DEBUG - [server.py:723] - Dispatching request of type CallToolRequest +2026-06-11 09:40:08 - lzwcai_mcp_agile_db.server - INFO - [server.py:66] - 收到 CallTool 请求: name=list_datasources +2026-06-11 09:40:08 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:100] - [API请求] GET https://dempdemo.lzwcai.com/api/datasource/connection/list +2026-06-11 09:40:08 - httpx - DEBUG - [_config.py:82] - load_ssl_context verify=True cert=None trust_env=True http2=False +2026-06-11 09:40:08 - httpx - DEBUG - [_config.py:148] - load_verify_locations cafile='D:\\anaconda3\\Library\\ssl\\cacert.pem' +2026-06-11 09:40:08 - httpcore.connection - DEBUG - [_trace.py:47] - connect_tcp.started host='dempdemo.lzwcai.com' port=443 local_address=None timeout=30.0 socket_options=None +2026-06-11 09:40:08 - httpcore.connection - DEBUG - [_trace.py:47] - connect_tcp.complete return_value= +2026-06-11 09:40:08 - httpcore.connection - DEBUG - [_trace.py:47] - start_tls.started ssl_context= server_hostname='dempdemo.lzwcai.com' timeout=30.0 +2026-06-11 09:40:08 - httpcore.connection - DEBUG - [_trace.py:47] - start_tls.complete return_value= +2026-06-11 09:40:08 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_headers.started request= +2026-06-11 09:40:08 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_headers.complete +2026-06-11 09:40:08 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_body.started request= +2026-06-11 09:40:08 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_body.complete +2026-06-11 09:40:08 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_headers.started request= +2026-06-11 09:40:08 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'', [(b'Server', b'nginx/1.25.2'), (b'Date', b'Thu, 11 Jun 2026 01:40:02 GMT'), (b'Content-Type', b'application/json'), (b'Transfer-Encoding', b'chunked'), (b'Connection', b'keep-alive'), (b'Vary', b'Origin'), (b'Vary', b'Access-Control-Request-Method'), (b'Vary', b'Access-Control-Request-Headers'), (b'X-Content-Type-Options', b'nosniff'), (b'X-XSS-Protection', b'1; mode=block'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains'), (b'X-Frame-Options', b'DENY'), (b'X-Content-Type-Options', b'nosniff'), (b'X-XSS-Protection', b'1; mode=block')]) +2026-06-11 09:40:08 - httpx - INFO - [_client.py:1038] - HTTP Request: GET https://dempdemo.lzwcai.com/api/datasource/connection/list?pageNum=1&pageSize=20 "HTTP/1.1 200 " +2026-06-11 09:40:08 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_body.started request= +2026-06-11 09:40:08 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_body.complete +2026-06-11 09:40:08 - httpcore.http11 - DEBUG - [_trace.py:47] - response_closed.started +2026-06-11 09:40:08 - httpcore.http11 - DEBUG - [_trace.py:47] - response_closed.complete +2026-06-11 09:40:08 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:74] - [API响应] HTTP 200 +2026-06-11 09:40:08 - lzwcai_mcp_agile_db.server - INFO - [server.py:86] - 工具执行成功: list_datasources +2026-06-11 09:40:08 - lzwcai_mcp_agile_db.server - DEBUG - [server.py:87] - 工具返回结果: { + "total": 14, + "rows": [ + { + "createBy": "", + "createTime": "2026-06-10 16:47:43", + "updateBy": "", + "updateTime": "2026-06-10 16:47:43", + "remark": "设备报价管理系统包含设备基础信息、预设方案模板、报价单主表和明细表四个核心数据对象,支持从设备参数管理到整套产线方案配置的完整报价流程,为销售部门提供标准化报价服务,实现快速方案生成和精准成本核算。", + "id": "58", + "enterpriseId": "1937166012193443842", + "deptId": "1171", + "userId": "292", + "host": "host.docker.internal", + "port": 5432, + "datasourceName": "HMD产品", + "database... +2026-06-11 09:40:08 - mcp.server.lowlevel.server - DEBUG - [server.py:790] - Response sent +2026-06-11 09:40:55 - mcp.server.lowlevel.server - DEBUG - [server.py:675] - Received message: +2026-06-11 09:40:55 - mcp.server.lowlevel.server - INFO - [server.py:720] - Processing request of type CallToolRequest +2026-06-11 09:40:55 - mcp.server.lowlevel.server - DEBUG - [server.py:723] - Dispatching request of type CallToolRequest +2026-06-11 09:40:55 - lzwcai_mcp_agile_db.server - INFO - [server.py:66] - 收到 CallTool 请求: name=list_api_keys +2026-06-11 09:40:55 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:100] - [API请求] GET https://dempdemo.lzwcai.com/api/datasource/api_key/list +2026-06-11 09:40:55 - httpcore.connection - DEBUG - [_trace.py:47] - close.started +2026-06-11 09:40:55 - httpcore.connection - DEBUG - [_trace.py:47] - close.complete +2026-06-11 09:40:55 - httpcore.connection - DEBUG - [_trace.py:47] - connect_tcp.started host='dempdemo.lzwcai.com' port=443 local_address=None timeout=30.0 socket_options=None +2026-06-11 09:40:55 - httpcore.connection - DEBUG - [_trace.py:47] - connect_tcp.complete return_value= +2026-06-11 09:40:55 - httpcore.connection - DEBUG - [_trace.py:47] - start_tls.started ssl_context= server_hostname='dempdemo.lzwcai.com' timeout=30.0 +2026-06-11 09:40:55 - httpcore.connection - DEBUG - [_trace.py:47] - start_tls.complete return_value= +2026-06-11 09:40:55 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_headers.started request= +2026-06-11 09:40:55 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_headers.complete +2026-06-11 09:40:55 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_body.started request= +2026-06-11 09:40:55 - httpcore.http11 - DEBUG - [_trace.py:47] - send_request_body.complete +2026-06-11 09:40:55 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_headers.started request= +2026-06-11 09:40:56 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'', [(b'Server', b'nginx/1.25.2'), (b'Date', b'Thu, 11 Jun 2026 01:40:49 GMT'), (b'Content-Type', b'application/json'), (b'Transfer-Encoding', b'chunked'), (b'Connection', b'keep-alive'), (b'Vary', b'Origin'), (b'Vary', b'Access-Control-Request-Method'), (b'Vary', b'Access-Control-Request-Headers'), (b'X-Content-Type-Options', b'nosniff'), (b'X-XSS-Protection', b'1; mode=block'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains'), (b'X-Frame-Options', b'DENY'), (b'X-Content-Type-Options', b'nosniff'), (b'X-XSS-Protection', b'1; mode=block')]) +2026-06-11 09:40:56 - httpx - INFO - [_client.py:1038] - HTTP Request: GET https://dempdemo.lzwcai.com/api/datasource/api_key/list?pageNum=1&pageSize=20 "HTTP/1.1 200 " +2026-06-11 09:40:56 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_body.started request= +2026-06-11 09:40:56 - httpcore.http11 - DEBUG - [_trace.py:47] - receive_response_body.complete +2026-06-11 09:40:56 - httpcore.http11 - DEBUG - [_trace.py:47] - response_closed.started +2026-06-11 09:40:56 - httpcore.http11 - DEBUG - [_trace.py:47] - response_closed.complete +2026-06-11 09:40:56 - lzwcai_mcp_agile_db.utils.api_client - INFO - [api_client.py:74] - [API响应] HTTP 200 +2026-06-11 09:40:56 - lzwcai_mcp_agile_db.server - INFO - [server.py:86] - 工具执行成功: list_api_keys +2026-06-11 09:40:56 - lzwcai_mcp_agile_db.server - DEBUG - [server.py:87] - 工具返回结果: { + "total": 6, + "rows": [ + { + "createBy": "", + "createTime": "2026-06-06 15:10:31", + "updateBy": "", + "updateTime": "2026-06-06 15:10:31", + "remark": null, + "id": "7", + "apiKey": "Lb8LgEJ7eBUU8QMifKUJvo9w6YLAotbKJ-w1DKU8ZrU", + "apiKeyName": "AWINBEXT", + "enterpriseId": "1937166012193443842", + "status": 0, + "expireTime": "2027-06-06T15:10:32.000+08:00" + }, + { + "createBy": "", + "createTime": "2026-05-25 14:47:11", + "u... +2026-06-11 09:40:56 - mcp.server.lowlevel.server - DEBUG - [server.py:790] - Response sent diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/logs/lzwcai_mcp_agile_db_error.log b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/logs/lzwcai_mcp_agile_db_error.log new file mode 100644 index 0000000..fa261fd --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/logs/lzwcai_mcp_agile_db_error.log @@ -0,0 +1,15 @@ +2026-06-11 09:33:46 - lzwcai_mcp_agile_db.utils.api_client - ERROR - [api_client.py:91] - [API错误] 登录过期,请重新登录 +2026-06-11 09:33:46 - lzwcai_mcp_agile_db.server - ERROR - [server.py:96] - 工具执行失败: list_datasources, 错误: 登录过期,请重新登录 +Traceback (most recent call last): + File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\server.py", line 84, in handle_call_tool + result = await tool_instance.execute(arguments or {}) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\tools\datasources.py", line 30, in execute + return self.client.get("/api/datasource/connection/list", params=params) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\utils\api_client.py", line 102, in get + return self._handle_response(response, url) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_agile_db\lzwcai_mcp_agile_db\utils\api_client.py", line 92, in _handle_response + raise Exception(error_msg) +Exception: 登录过期,请重新登录 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/main.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/main.py new file mode 100644 index 0000000..194ed3d --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from lzwcai-mcp-agile-db!") + + +if __name__ == "__main__": + main() diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/pyproject.toml b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/pyproject.toml new file mode 100644 index 0000000..5e91253 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/pyproject.toml @@ -0,0 +1,7 @@ +[project] +name = "lzwcai-mcp-agile-db" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [] diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/server.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/server.py new file mode 100644 index 0000000..035da04 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/server.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python3 +""" +lzwcai-mcp-agile-db MCP Server +数据库管理平台 MCP 工具服务,提供 33 个工具用于数据库管理、表操作、API 密钥管理等 +""" + +import json +import logging +import anyio + +import mcp.types as types +from mcp.server import NotificationOptions, Server +from mcp.server.models import InitializationOptions +from mcp.server.stdio import stdio_server + +from .utils.logger_config import setup_system_logging, get_logger +from .utils.api_client import AgileDBAPIClient +from .tools._base import get_registered_tools + +# 初始化日志系统 +setup_system_logging(app_name="lzwcai_mcp_agile_db", log_level=logging.DEBUG) +logger = get_logger(__name__) + +# 初始化 MCP Server +server = Server("lzwcai_mcp_agile_db") + +# 全局 API 客户端 +_api_client: AgileDBAPIClient = None + + +def get_api_client() -> AgileDBAPIClient: + """获取或创建 API 客户端""" + global _api_client + if _api_client is None: + _api_client = AgileDBAPIClient() + return _api_client + + +@server.list_tools() +async def handle_list_tools() -> list[types.Tool]: + """列出所有可用工具""" + logger.info("收到 ListTools 请求") + + tools = [] + for tool_cls in get_registered_tools(): + instance = tool_cls(get_api_client()) + tool_def = instance.to_tool_def() + tools.append( + types.Tool( + name=tool_def["name"], + description=tool_def["description"], + inputSchema=tool_def["inputSchema"], + ) + ) + + logger.info(f"ListTools 响应: 返回 {len(tools)} 个工具") + return tools + + +@server.call_tool() +async def handle_call_tool( + name: str, + arguments: dict | None, +) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: + """调用工具""" + logger.info(f"收到 CallTool 请求: name={name}") + + # 查找对应的工具类 + tool_cls = None + for cls in get_registered_tools(): + if cls.name == name: + tool_cls = cls + break + + if tool_cls is None: + logger.error(f"未找到工具: {name}") + raise ValueError(f"未知工具: {name}") + + # 创建工具实例并执行 + client = get_api_client() + tool_instance = tool_cls(client) + + try: + result = await tool_instance.execute(arguments or {}) + + logger.info(f"工具执行成功: {name}") + logger.debug(f"工具返回结果: {json.dumps(result, ensure_ascii=False, indent=2)[:500]}...") + + return [ + types.TextContent( + type="text", + text=json.dumps(result, ensure_ascii=False, indent=2), + ) + ] + except Exception as e: + logger.error(f"工具执行失败: {name}, 错误: {e}", exc_info=True) + return [ + types.TextContent( + type="text", + text=json.dumps({"error": str(e), "tool_name": name}, ensure_ascii=False, indent=2), + ) + ] + + +async def run_server(): + """运行 MCP Server (stdio 模式)""" + async with stdio_server() as streams: + await server.run( + streams[0], + streams[1], + InitializationOptions( + server_name="lzwcai_mcp_agile_db", + server_version="0.1.0", + capabilities=server.get_capabilities( + notification_options=NotificationOptions(), + experimental_capabilities={}, + ), + ), + ) + + +def main(): + """主入口""" + logger.info("=" * 50) + logger.info("lzwcai-mcp-agile-db MCP Server 启动") + + # 导入所有工具模块(触发装饰器注册) + from . import tools # noqa: F401 + + logger.info(f"已注册工具数量: {len(get_registered_tools())}") + logger.info("=" * 50) + + logger.info("开始运行 MCP Server (stdio 模式)") + anyio.run(run_server) + + +if __name__ == "__main__": + main() diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__init__.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__init__.py new file mode 100644 index 0000000..d47fce1 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__init__.py @@ -0,0 +1,18 @@ +""" +工具自动发现模块 +自动导入 tools/ 目录下所有工具模块,触发 @register_tool 装饰器注册 +""" + +import importlib +import pkgutil +from pathlib import Path + +# 获取当前包路径 +_package_path = Path(__file__).parent + +# 遍历所有 Python 文件(排除 __init__.py 和 _base.py) +for _, module_name, _ in pkgutil.iter_modules([str(_package_path)]): + if module_name.startswith("_"): + continue + # 动态导入模块,触发装饰器 + importlib.import_module(f".{module_name}", __package__) diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/__init__.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9dadb2cb065569b7706334a93489ba5e6621fd6 GIT binary patch literal 833 zcmZuv&rcIU6rR}*-F8c{7(ok?G$tH+*y35ySbrS67>{OCGg-Q0*|MdZ*{!4yl3uDo z8^sVq4U%XKS|m{t4|u@8zzYqUl0_2}-BM11+&DQ)yY}Kc%=_kh?|bvjWIhLj0$|~r zi>7-y0Dd|fH#%D2;2Q(;Kmig^pu%ZTf=8K?IF>z{Cxave0S5>o9V@V@N_VDO@KCI6a>d$AI+GhXn^-|-_Yc?TriIS9Rn1o_S6=}RG?k=s`&noo~ z75iRE*mYdoh(Zh9l+95KVhhHi$1EOWC7Z<9@~as=OHEB3v3Pwfl`~b10oKYG${qz+ zK8)|E8ezR&U8ZE*w1QZdlVfsFJ?@$WzPd4+~+(H9S8t+ zZ-cJy;MBesbob2On(L~C2CJdLLU7Lu`eNmiwXj$Xi_6C9h0US(M(pxt_{txE;BXc7 z6yk-c+4vTJyv7ey`GIos3x8(I7y5zv3)gF?zl!?H@{2%udgHWMnfi*(@B5jKo?s6C E0$J__od5s; literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/_base.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/_base.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..282110bf1de4e8c8ac4b47dd84620edfe8d0191b GIT binary patch literal 4053 zcmbVPZ)_CD6`#G^`{TRwAHaqpmvm!W#V5?6wp39qNCSo@4vC8bZQ3i%cG+E5f(tEZ)vBuMU7tU3)JSdfsqf9+t?$lA zl{(VR&dhr=^WK~He(&8M%FBHO+IP_d$naZXICPK`FGGyLAUNGSA)sU7G0%ZYtKl zu`UY6;3Yv5)I>@VWwkD7vx-qcRk>GyVaF03E!vnfYjEjUJQ{W3wsOmlv`<7XNmfNA zlGGxJI5KBWUN;8Mnr9}>6IaaXA){|NGj_SIXh$TTOliC-9*|=KZ25U86gphQP&5(L zuDA%dv~%(ySxjkiqbf(+n>az~P)h_xaTHlgDRE9XC`2?4IYT0Snox(VHP&qsl95et zUtJTI6ciz*Zl%Z23u(6vPF=DBTA(@iF2>M_`SHm|GkwPCt8-InbM(E;)nkul`suc! zCuiZMSK*T%gYFD7Of=gedLV)(&?TTLl|7_0H?~%+zMpyXIiPy_nI6Iy?9}jF+TLcA znx$E%C%?Y*?I9Dnoeb$A=w@vS27Zv$JqH9;&@_e4^%ZQs;s;%D;tx7_@>Yy z=O{c-cmYF(m-at(4MSMn$L|+ZIh5?u%OqJ$D1w$yy5U_5!aTGknh=Gk`h3Xdr~?Vr zt1%*Y7$6*K-g_yJB08~x(qDk7 zx;wESBMtMB)|HfXAB0{~RRv^DD-}^>Ne>iiBo?9yj_m|AOnMMiaxOqf7Xu0C zFidUB7=6Dq#*Z5VXD$6Lp>3)?D8@-Nsjc_!R#5e#*>`<@;_Cm_8Mn4UE_GY`0d-hJ zZG{7&EZE6~o|oq%@rcIr-Bmf~4CPn0BQI1lBu%mvWX-xh_Jp5CpUxt@>uxJ4EHldy z*s>UaZWm!79=n)Nod?k%e}*MnQ?q|OGd7TO?)1&f?Nc_%9xS&8-kbNmLLb8Xas4xM zbZp@_1Nmo16JWECdyVF>f;@y&EJl6;6-pBa1<6mFIZLkjo9~+!MxfX+CXdbC8kw7# zE+}v^cTO80UNF)#_Q`EZHRuNL_AGpqdgzL5?8&9r?#jH0a|^qW6D^!Un9HsvW##`- zF(19_V3}pfkGk8-Km~Uro$xJfPfvWXYNxoR9TGF*q;*n}n`UnP);w{sSY0bVtpK() zwg*o&ssu)DrWV84QbVXVST?;dl12!iVQ-%hbXr*fkyrQAfU`iOkf1yR)F49*tYQw% zxvyVK(EQ3nCDXksZ{C8%9|5nr9y+jZ6{%S}+Rh$YWRFP_;;GY7;jU8rK1s_QHI(9+q(3_|rG(9S7aEjd~_^Ize*GnEd z0xoa%t7OHh^p3vzBW(}YtWED4T6K?I`><*A7u)ad{o!o=>*-g98X#r23>`WZy2rl0 z$a-AsvMY(ZI_vPc%10YU)yplThsHu#0@KO8Q}t8oRO7Wb{)y8?XPz(n6~D`OZtp0h z{n5q`-grV_YDq^0YXEsf_}LBpl=>1L_UAA~%=zKC|+d zoii|f(XyBF(r%gaVVRCGjEOUIapLKz5l)1&=mCg}xJRh~8A{BqS3_;Ptd3K@37qZl zqs0l-CKV)5b-(J_d;Yq+Y#lXAkumH%(FA+I7|>g-6HQdo@DQ9)&>7wc{a`AEE@z{9aV)2mWiB&vqsj{BB{ggAk`-BZEmL#Oxk%viWXop8*C#$9@X5v*4^w|mS|spUtY(>KsDl3m DScuZl literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/api_keys.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/api_keys.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf3dd892d3f243771264f7326d0a27e87d242cbf GIT binary patch literal 5420 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 BcccIS literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/database_tables.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/database_tables.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f85dc86f6f2b5e0dafd4ee52e1cef21a760a4b8 GIT binary patch literal 6876 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 literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/datasources.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/datasources.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e71be68fcbed473f9782d7f0f8478122dcbcd30 GIT binary patch literal 8404 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 literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/skills.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/skills.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a0ffae0c0308abf3c22d6cf7a19186dafa0c51a GIT binary patch literal 6027 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 literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/sql_execution.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/sql_execution.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c327e76325e4275df3503a93da151ba736291b67 GIT binary patch literal 1386 zcmZux-ESL35a0Xo+4V;pnktR@kytdXFvW?W@PbO8QlY9L5=v>nia1?vH_nB#@3MPG zaT=tk1gSxk*mVVcfUQpce%c>{%Cgo@x6J! z3rr6-uGPO-sV`o6c;n80jP->}@Lv7)wFf_g!!yrpgeS4#8O-siNzP!N3My=j*#y|} z1QhxlDY~}d5uP0LnN=c;4H-qkRE*G7$sA_MG5Ar zK?{s)lz2WZnKE2#EfqGO!LK=PXORRwoI#T<>vK36j@ENWFqkvaPx4wAZy4QDE=XBr zX!_ND!?pUK(d!2?LFb^lgHEB}Bg_MqBbGNYY)+7(k(KzKN#>Mv;RH?5Oxq$QkE^c3 zJkcaZ>~Y!wk2CRFCiB!k{pM(SB4=2mz*zKn)SkXz8di=?mkX_Z(R6c+(2ohtxrX_X zQ6Qm32a9eLESuYJaIaBMoI^Jf`a_cWc zPwM)VZ`h$l6-X1{#gkUa^*x<6i^o-LnI1g|h9A)`NJI|^5p4(cDIfym!?<F^V| VT_V!r$SxANt01|%(L8F#{1@4Lv8w<8 literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/subscriptions.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/__pycache__/subscriptions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f88c8275884faaa8371d0ee83c532e9f140700e4 GIT binary patch literal 1293 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 literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/_base.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/_base.py new file mode 100644 index 0000000..52ccf5e --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/_base.py @@ -0,0 +1,116 @@ +""" +工具注册框架 +提供 ToolDef 基类和 @register_tool 装饰器,用于声明式定义 MCP 工具 +""" + +from abc import ABC, abstractmethod +from typing import Dict, Any, TYPE_CHECKING + +if TYPE_CHECKING: + from ..utils.api_client import AgileDBAPIClient + + +# 全局工具注册表 +_registered_tools = [] + + +def register_tool(name: str): + """ + 工具注册装饰器 + + 使用方式: + @register_tool("list_datasources") + class ListDatasourcesTool(ToolDef): + name = "list_datasources" + description = "获取数据源列表" + input_schema = {...} + + async def execute(self, args): + return await self.client.get("/api/...", params=args) + + Args: + name: 工具名称(唯一标识) + """ + def decorator(cls): + # 确保类有正确的 name 属性 + if not hasattr(cls, 'name') or cls.name != name: + cls.name = name + + # 注册到全局列表,避免重复注册 + if cls not in _registered_tools: + _registered_tools.append(cls) + return cls + + return decorator + + +class ToolDef(ABC): + """ + 工具定义基类 + + 所有工具都应继承此类并使用 @register_tool 装饰器注册 + + 类属性: + name: 工具名称(唯一标识) + description: 工具描述 + input_schema: JSON Schema 格式的工具输入参数定义 + + 实例属性: + client: AgileDBAPIClient 实例(由 server 注入) + """ + + name: str = "" + description: str = "" + input_schema: Dict[str, Any] = {"type": "object", "properties": {}, "required": []} + + def __init__(self, client: "AgileDBAPIClient"): + """ + 初始化工具实例 + + Args: + client: API 客户端实例(由 server 注入) + """ + self.client = client + + @abstractmethod + async def execute(self, args: Dict[str, Any]) -> Dict[str, Any]: + """ + 执行工具逻辑 + + Args: + args: 工具输入参数(已校验) + + Returns: + Dict[str, Any]: 执行结果,将作为 MCP 工具返回值 + """ + pass + + def to_tool_def(self) -> Dict[str, Any]: + """ + 转换为 MCP 工具定义格式 + + Returns: + dict: MCP types.Tool 所需的参数 + """ + return { + "name": self.name, + "description": self.description, + "inputSchema": self.input_schema, + } + + +def get_registered_tools() -> list: + """ + 获取所有已注册的工具类列表 + + Returns: + list: 所有被 @register_tool 装饰的类 + """ + return list(_registered_tools) + + +def clear_registered_tools(): + """ + 清空所有已注册的工具(主要用于测试) + """ + _registered_tools.clear() diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/api_keys.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/api_keys.py new file mode 100644 index 0000000..c309701 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/api_keys.py @@ -0,0 +1,121 @@ +""" +API 密钥管理工具 (工具 18-23) +""" + +from ._base import register_tool, ToolDef + + +@register_tool("list_api_keys") +class ListApiKeysTool(ToolDef): + name = "list_api_keys" + description = "获取 API 密钥列表" + input_schema = { + "type": "object", + "properties": { + "apiKeyName": {"type": "string", "description": "密钥名称模糊搜索"}, + "pageNum": {"type": "integer", "default": 1, "description": "页码"}, + "pageSize": {"type": "integer", "default": 20, "description": "每页数量"}, + }, + "required": [], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + params = {k: v for k, v in args.items() if v is not None} + return self.client.get("/api/datasource/api_key/list", params=params) + + +@register_tool("create_api_key") +class CreateApiKeyTool(ToolDef): + name = "create_api_key" + description = "创建新的 API 密钥" + input_schema = { + "type": "object", + "properties": { + "apiKeyName": {"type": "string", "description": "密钥名称(最多50字)"}, + }, + "required": ["apiKeyName"], + } + + async def execute(self, args: dict) -> dict: + return self.client.post("/api/datasource/api_key", json_data=args) + + +@register_tool("toggle_api_key_status") +class ToggleApiKeyStatusTool(ToolDef): + name = "toggle_api_key_status" + description = "启用/禁用 API 密钥" + input_schema = { + "type": "object", + "properties": { + "id": {"type": "string", "description": "密钥 ID"}, + "status": {"type": "integer", "enum": [0, 1], "description": "0=启用, 1=禁用"}, + }, + "required": ["id", "status"], + } + + async def execute(self, args: dict) -> dict: + return self.client.put("/api/datasource/api_key", json_data=args) + + +@register_tool("delete_api_key") +class DeleteApiKeyTool(ToolDef): + name = "delete_api_key" + description = "删除 API 密钥" + input_schema = { + "type": "object", + "properties": { + "id": {"type": "string", "description": "密钥 ID"}, + }, + "required": ["id"], + } + + async def execute(self, args: dict) -> dict: + return self.client.delete(f"/api/datasource/api_key/{args['id']}") + + +@register_tool("get_api_key_permissions") +class GetApiKeyPermissionsTool(ToolDef): + name = "get_api_key_permissions" + description = "查看指定密钥的权限配置" + input_schema = { + "type": "object", + "properties": { + "apiKeyId": {"type": "string", "description": "密钥 ID"}, + }, + "required": ["apiKeyId"], + } + + async def execute(self, args: dict) -> dict: + return self.client.get(f"/api/datasource/api_key/permission/{args['apiKeyId']}") + + +@register_tool("grant_api_key_permissions") +class GrantApiKeyPermissionsTool(ToolDef): + name = "grant_api_key_permissions" + description = "批量为 API 密钥授予权限" + input_schema = { + "type": "object", + "properties": { + "apiKeyId": {"type": "string", "description": "密钥 ID"}, + "batchDatas": { + "type": "array", + "description": "权限批量数据数组", + "items": { + "type": "object", + "properties": { + "connectionId": {"type": "string", "description": "数据源 ID"}, + "permissionLevel": {"type": "string", "enum": ["connection", "database", "table"], "description": "权限级别"}, + "permissionType": {"type": "string", "description": "权限类型(逗号分隔)"}, + "databaseName": {"type": "string", "description": "数据库名(level=database/table 时)"}, + "tableName": {"type": "string", "description": "表名(level=table 时)"}, + }, + "required": ["connectionId", "permissionLevel", "permissionType"], + }, + }, + }, + "required": ["apiKeyId", "batchDatas"], + } + + async def execute(self, args: dict) -> dict: + return self.client.post("/api/datasource/api_key/permission/grant_batch", json_data=args) diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/data_import.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/data_import.py new file mode 100644 index 0000000..9b4ef0d --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/data_import.py @@ -0,0 +1,72 @@ +""" +数据导入工具 (工具 30-31) +""" + +import base64 +import io + +from ._base import register_tool, ToolDef + + +@register_tool("preview_import_data") +class PreviewImportDataTool(ToolDef): + name = "preview_import_data" + description = "上传 Excel 文件,AI 智能识别并预览表结构/数据" + input_schema = { + "type": "object", + "properties": { + "connectionId": {"type": "string", "description": "数据源 ID"}, + "target": {"type": "string", "enum": ["prod", "test"], "default": "test", "description": "环境,默认 test"}, + "file_base64": {"type": "string", "description": "Excel 文件 base64 编码(.xlsx/.xls, <500KB)"}, + "file_name": {"type": "string", "description": "文件名(如 data.xlsx)"}, + }, + "required": ["connectionId", "file_base64"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + connection_id = args.pop("connectionId") + target = args.pop("target", "test") + file_base64 = args.pop("file_base64") + file_name = args.pop("file_name", "import.xlsx") + + # 解码 base64 文件 + file_content = base64.b64decode(file_base64) + + # 构建文件上传 + files = { + "file": (file_name, io.BytesIO(file_content), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"), + } + + return self.client.upload( + f"/api/datasource/connection/{connection_id}/import_document/preview", + files=files, + params={"target": target}, + ) + + +@register_tool("confirm_import_data") +class ConfirmImportDataTool(ToolDef): + name = "confirm_import_data" + description = "确认导入 AI 识别后的数据" + input_schema = { + "type": "object", + "properties": { + "connectionId": {"type": "string", "description": "数据源 ID"}, + "target": {"type": "string", "enum": ["prod", "test"], "description": "环境"}, + "data": {"type": "object", "description": "导入数据(含 tableStructure + allData)"}, + }, + "required": ["connectionId", "data"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + connection_id = args.pop("connectionId") + target = args.pop("target", "test") + data = args.pop("data") + + return self.client.post( + f"/api/datasource/connection/{connection_id}/import_document/confirm", + json_data=data, + params={"target": target}, + ) diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/database_tables.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/database_tables.py new file mode 100644 index 0000000..274838c --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/database_tables.py @@ -0,0 +1,151 @@ +""" +数据库与表管理工具 (工具 7-12) +""" + +from ._base import register_tool, ToolDef + + +@register_tool("list_databases") +class ListDatabasesTool(ToolDef): + name = "list_databases" + description = "获取指定数据源下的数据库列表" + input_schema = { + "type": "object", + "properties": { + "datasourceId": {"type": "string", "description": "数据源 ID"}, + "sourceType": {"type": "string", "enum": ["builtin", "external"], "description": "数据源类型"}, + "pageNum": {"type": "integer", "default": 1, "description": "页码"}, + "pageSize": {"type": "integer", "default": 20, "description": "每页数量"}, + }, + "required": ["datasourceId"], + } + + async def execute(self, args: dict) -> dict: + params = {k: v for k, v in args.items() if v is not None} + return self.client.get("/api/datasource/config/list", params=params) + + +@register_tool("list_tables") +class ListTablesTool(ToolDef): + name = "list_tables" + description = "获取指定数据源下的表列表" + input_schema = { + "type": "object", + "properties": { + "datasourceId": {"type": "string", "description": "数据源 ID"}, + "sourceType": {"type": "string", "enum": ["builtin", "external"], "description": "数据源类型"}, + "pageNum": {"type": "integer", "default": 1, "description": "页码"}, + "pageSize": {"type": "integer", "default": 20, "description": "每页数量"}, + }, + "required": ["datasourceId"], + } + + async def execute(self, args: dict) -> dict: + params = {k: v for k, v in args.items() if v is not None} + return self.client.get("/api/datasource/table/list", params=params) + + +@register_tool("get_table_detail") +class GetTableDetailTool(ToolDef): + name = "get_table_detail" + description = "获取表的完整结构信息(字段列表、主键、类型等)" + input_schema = { + "type": "object", + "properties": { + "tableId": {"type": "string", "description": "表 ID"}, + }, + "required": ["tableId"], + } + + async def execute(self, args: dict) -> dict: + table_id = args["tableId"] + return self.client.get(f"/api/datasource/table/{table_id}/detail") + + +@register_tool("create_table") +class CreateTableTool(ToolDef): + name = "create_table" + description = "在指定数据库创建新表" + input_schema = { + "type": "object", + "properties": { + "connectionId": {"type": "string", "description": "数据源连接 ID"}, + "databaseName": {"type": "string", "description": "目标数据库名"}, + "tableName": {"type": "string", "description": "表名(小写字母+数字+下划线)"}, + "tableComment": {"type": "string", "description": "表注释"}, + "columns": { + "type": "array", + "description": "字段定义数组", + "items": { + "type": "object", + "properties": { + "columnName": {"type": "string", "description": "字段名"}, + "columnType": {"type": "string", "description": "字段类型(VARCHAR/INTEGER/SERIAL等)"}, + "columnLength": {"type": "integer", "description": "字段长度"}, + "isPrimaryKey": {"type": "boolean", "description": "是否主键"}, + "isNullable": {"type": "boolean", "description": "是否可空"}, + "isAutoIncrement": {"type": "boolean", "description": "是否自增"}, + "columnComment": {"type": "string", "description": "字段注释"}, + "defaultValue": {"type": "string", "description": "默认值"}, + }, + "required": ["columnName", "columnType"], + }, + }, + }, + "required": ["connectionId", "databaseName", "tableName", "columns"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + connection_id = args.pop("connectionId") + return self.client.post(f"/api/datasource/connection/{connection_id}/create_table", json_data=args) + + +@register_tool("alter_table") +class AlterTableTool(ToolDef): + name = "alter_table" + description = "修改已有表结构(增/改/删字段)" + input_schema = { + "type": "object", + "properties": { + "connectionId": {"type": "string", "description": "数据源连接 ID"}, + "databaseName": {"type": "string", "description": "数据库名"}, + "tableName": {"type": "string", "description": "表名"}, + "operations": { + "type": "array", + "description": "表结构变更操作数组", + "items": { + "type": "object", + "properties": { + "operation": {"type": "string", "enum": ["ADD_COLUMN", "DROP_COLUMN", "RENAME_COLUMN", "ALTER_COLUMN_TYPE", "SET_NOT_NULL", "DROP_NOT_NULL", "SET_DEFAULT", "DROP_DEFAULT"], "description": "变更类型"}, + "column": {"type": "object", "description": "列定义(根据 operation 不同包含不同字段)"}, + }, + "required": ["operation", "column"], + }, + }, + "tableComment": {"type": "string", "description": "表注释"}, + }, + "required": ["connectionId", "databaseName", "tableName", "operations"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + connection_id = args.pop("connectionId") + return self.client.put(f"/api/datasource/connection/{connection_id}/alter_table", json_data=args) + + +@register_tool("generate_table_by_description") +class GenerateTableByDescriptionTool(ToolDef): + name = "generate_table_by_description" + description = "通过自然语言描述让 AI 生成表结构(异步任务)" + input_schema = { + "type": "object", + "properties": { + "requirement": {"type": "string", "description": "业务需求描述"}, + "databaseId": {"type": "integer", "description": "关联的数据库 ID(可选)"}, + }, + "required": ["requirement"], + } + + async def execute(self, args: dict) -> dict: + return self.client.post("/api/datasource/connection/generate_table", json_data=args) diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/datasources.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/datasources.py new file mode 100644 index 0000000..9cb5e66 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/datasources.py @@ -0,0 +1,173 @@ +""" +数据源管理工具 (工具 1-6) +""" + +import logging + +from ._base import register_tool, ToolDef + +logger = logging.getLogger(__name__) + + +@register_tool("list_datasources") +class ListDatasourcesTool(ToolDef): + name = "list_datasources" + description = "获取数据源列表,支持搜索和状态筛选" + input_schema = { + "type": "object", + "properties": { + "datasourceName": {"type": "string", "description": "数据源名称模糊搜索"}, + "status": {"type": "integer", "description": "0=运行中, 1=已停止, 不传=全部"}, + "sourceType": {"type": "string", "enum": ["builtin", "external"], "description": "数据源类型"}, + "pageNum": {"type": "integer", "default": 1, "description": "页码"}, + "pageSize": {"type": "integer", "default": 20, "description": "每页数量"}, + }, + "required": [], + } + + async def execute(self, args: dict) -> dict: + params = {k: v for k, v in args.items() if v is not None} + return self.client.get("/api/datasource/connection/list", params=params) + + +@register_tool("get_datasource_detail") +class GetDatasourceDetailTool(ToolDef): + name = "get_datasource_detail" + description = "获取单个数据源的完整详情(含配置和实时结构)" + input_schema = { + "type": "object", + "properties": { + "datasourceId": {"type": "string", "description": "数据源 ID"}, + }, + "required": ["datasourceId"], + } + + async def execute(self, args: dict) -> dict: + ds_id = args["datasourceId"] + result = {} + # 获取基本信息 + try: + result["detail"] = self.client.get(f"/api/datasource/connection/{ds_id}") + except Exception as e: + result["detail"] = {"error": str(e)} + # 获取配置 + try: + result["config"] = self.client.get(f"/api/datasource/config/{ds_id}") + except Exception as e: + result["config"] = {"error": str(e)} + # 获取实时结构 + try: + result["structure"] = self.client.get(f"/api/datasource/connection/realtime/structure/{ds_id}") + except Exception as e: + result["structure"] = {"error": str(e)} + return result + + +@register_tool("create_datasource") +class CreateDatasourceTool(ToolDef): + name = "create_datasource" + description = "创建外部数据源连接(可选先测试连接)" + input_schema = { + "type": "object", + "properties": { + "datasourceName": {"type": "string", "description": "数据源名称(3-20字)"}, + "datasourceType": {"type": "string", "enum": ["mysql", "postgresql", "oracle", "sqlserver", "dameng"], "description": "数据库类型"}, + "host": {"type": "string", "description": "数据库地址"}, + "port": {"type": "integer", "description": "端口号"}, + "databaseName": {"type": "string", "description": "要连接的数据库名"}, + "username": {"type": "string", "description": "数据库用户名"}, + "password": {"type": "string", "description": "密码"}, + "remark": {"type": "string", "description": "数据源描述"}, + "connectionType": {"type": "string", "enum": ["user_password", "ssl"], "description": "连接类型,默认 user_password"}, + "test_first": {"type": "boolean", "default": True, "description": "是否先测试连接,默认 true"}, + }, + "required": ["datasourceName", "datasourceType", "host", "port", "databaseName", "username"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + test_first = args.pop("test_first", True) + + # 如果需要先测试连接 + if test_first: + test_data = { + "datasourceName": args.get("datasourceName"), + "datasourceType": args.get("datasourceType"), + "host": args.get("host"), + "port": args.get("port"), + "databaseName": args.get("databaseName"), + "username": args.get("username"), + "password": args.get("password"), + "connectionType": args.get("connectionType", "user_password"), + } + test_result = self.client.post("/api/datasource/connection/test", json_data=test_data) + if test_result.get("code") != 200: + return {"success": False, "error": f"连接测试失败: {test_result.get('msg', '未知错误')}"} + + # 创建数据源 + return self.client.post("/api/datasource/connection", json_data=args) + + +@register_tool("update_datasource") +class UpdateDatasourceTool(ToolDef): + name = "update_datasource" + description = "更新数据源连接信息" + input_schema = { + "type": "object", + "properties": { + "id": {"type": "string", "description": "数据源 ID"}, + "datasourceName": {"type": "string", "description": "更新名称"}, + "host": {"type": "string", "description": "更新地址"}, + "port": {"type": "integer", "description": "更新端口"}, + "databaseName": {"type": "string", "description": "更新数据库名"}, + "username": {"type": "string", "description": "更新用户名"}, + "password": {"type": "string", "description": "新密码(不传则不变)"}, + "remark": {"type": "string", "description": "更新描述"}, + }, + "required": ["id"], + } + + async def execute(self, args: dict) -> dict: + return self.client.put("/api/datasource/connection", json_data=args) + + +@register_tool("toggle_datasource_status") +class ToggleDatasourceStatusTool(ToolDef): + name = "toggle_datasource_status" + description = "启用/停用数据源" + input_schema = { + "type": "object", + "properties": { + "id": {"type": "string", "description": "数据源 ID"}, + "status": {"type": "integer", "enum": [0, 1], "description": "0=启用, 1=停用"}, + }, + "required": ["id", "status"], + } + + async def execute(self, args: dict) -> dict: + return self.client.put("/api/datasource/connection/changeStatus", json_data=args) + + +@register_tool("delete_datasource") +class DeleteDatasourceTool(ToolDef): + name = "delete_datasource" + description = "删除数据源(运行中会自动先停用)" + input_schema = { + "type": "object", + "properties": { + "id": {"type": "string", "description": "数据源 ID"}, + }, + "required": ["id"], + } + + async def execute(self, args: dict) -> dict: + ds_id = args["id"] + # 先尝试停用(仅忽略已停用等预期错误) + try: + self.client.put("/api/datasource/connection/changeStatus", json_data={"id": ds_id, "status": 1}) + except Exception as e: + # 记录日志但继续删除 + logger.debug(f"停用数据源失败(可能已停用): {e}") + + # 删除数据源 + return self.client.delete(f"/api/datasource/connection/{ds_id}") diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/skills.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/skills.py new file mode 100644 index 0000000..50cbe5b --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/skills.py @@ -0,0 +1,137 @@ +""" +技能与工具管理工具 (工具 24-29) +""" + +import json + +from ._base import register_tool, ToolDef + + +@register_tool("get_skill_by_datasource") +class GetSkillByDatasourceTool(ToolDef): + name = "get_skill_by_datasource" + description = "根据数据源获取技能信息" + input_schema = { + "type": "object", + "properties": { + "datasourceId": {"type": "string", "description": "数据源 ID"}, + }, + "required": ["datasourceId"], + } + + async def execute(self, args: dict) -> dict: + return self.client.get(f"/api/datasource/skill/getByDatasource/{args['datasourceId']}") + + +@register_tool("get_skill_tools") +class GetSkillToolsTool(ToolDef): + name = "get_skill_tools" + description = "获取技能下的工具列表" + input_schema = { + "type": "object", + "properties": { + "skillId": {"type": "string", "description": "技能 ID"}, + }, + "required": ["skillId"], + } + + async def execute(self, args: dict) -> dict: + return self.client.get(f"/api/datasource/skill/getBySkillId/{args['skillId']}") + + +@register_tool("create_skill") +class CreateSkillTool(ToolDef): + name = "create_skill" + description = "为数据源创建技能" + input_schema = { + "type": "object", + "properties": { + "datasourceId": {"type": "string", "description": "数据源 ID"}, + "name": {"type": "string", "description": "技能名称(不传则自动生成)"}, + "description": {"type": "string", "description": "技能描述"}, + }, + "required": ["datasourceId"], + } + + async def execute(self, args: dict) -> dict: + return self.client.post("/api/datasource/skill/createOrGet", json_data=args) + + +@register_tool("create_sql_tool") +class CreateSqlToolTool(ToolDef): + name = "create_sql_tool" + description = "将 SQL 查询创建为可复用工具(支持批量)" + input_schema = { + "type": "object", + "properties": { + "skillId": {"type": "string", "description": "技能 ID"}, + "tableIds": { + "type": "array", + "description": "关联的表 ID 数组", + "items": {"type": "string"}, + }, + "suggestions": { + "type": "array", + "description": "SQL 工具建议数组", + "items": { + "type": "object", + "properties": { + "name": {"type": "string", "description": "工具名称"}, + "businessDescription": {"type": "string", "description": "业务描述"}, + "sqlTemplate": {"type": "string", "description": "SQL 模板(支持 #{param} 参数占位)"}, + "sqlParams": {"type": "string", "description": "参数 JSON Schema(JSON 字符串或对象)"}, + "resultType": {"type": "string", "enum": ["single", "list"], "default": "list", "description": "结果类型,默认 list"}, + "businessScenario": {"type": "string", "description": "业务场景描述"}, + }, + "required": ["name", "businessDescription", "sqlTemplate"], + }, + }, + }, + "required": ["skillId", "suggestions"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + # 处理 suggestions 中的 sqlParams + if "suggestions" in args and isinstance(args["suggestions"], list): + for suggestion in args["suggestions"]: + if "sqlParams" in suggestion and isinstance(suggestion["sqlParams"], dict): + suggestion["sqlParams"] = json.dumps(suggestion["sqlParams"]) + return self.client.post("/api/datasource/skill/confirmTools", json_data=args) + + +@register_tool("delete_skill_tool") +class DeleteSkillToolTool(ToolDef): + name = "delete_skill_tool" + description = "删除技能下的工具" + input_schema = { + "type": "object", + "properties": { + "skillToolId": {"type": "string", "description": "工具 ID"}, + }, + "required": ["skillToolId"], + } + + async def execute(self, args: dict) -> dict: + return self.client.delete(f"/api/datasource/skill/tskilltool/{args['skillToolId']}") + + +@register_tool("update_skill_config") +class UpdateSkillConfigTool(ToolDef): + name = "update_skill_config" + description = "更新技能配置(如 MCP Server 配置模板)" + input_schema = { + "type": "object", + "properties": { + "datasourceId": {"type": "string", "description": "数据源 ID"}, + "configTemplate": {"type": "string", "description": "配置模板 JSON 字符串"}, + }, + "required": ["datasourceId", "configTemplate"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + # 如果 configTemplate 是 dict,转为 JSON 字符串 + if "configTemplate" in args and isinstance(args["configTemplate"], dict): + args["configTemplate"] = json.dumps(args["configTemplate"]) + return self.client.post("/api/datasource/skill/updateOrGet", json_data=args) diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/sql_execution.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/sql_execution.py new file mode 100644 index 0000000..e041731 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/sql_execution.py @@ -0,0 +1,25 @@ +""" +SQL 执行工具 (工具 33) +""" + +from ._base import register_tool, ToolDef + + +@register_tool("execute_sql") +class ExecuteSqlTool(ToolDef): + name = "execute_sql" + description = "执行原生 SQL 查询" + input_schema = { + "type": "object", + "properties": { + "datasourceId": {"type": "string", "description": "数据源 ID"}, + "executableSql": {"type": "string", "description": "SQL 语句"}, + "sqlTemplate": {"type": "string", "description": "SQL 模板(可选)"}, + "businessName": {"type": "string", "description": "业务名称(可选)"}, + "parameters": {"type": "object", "description": "参数定义(可选)"}, + }, + "required": ["datasourceId", "executableSql"], + } + + async def execute(self, args: dict) -> dict: + return self.client.post("/api/datasource/sqlExecutionLog/testSqlWithSchema", json_data=args) diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/subscriptions.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/subscriptions.py new file mode 100644 index 0000000..33394ad --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/subscriptions.py @@ -0,0 +1,23 @@ +""" +表订阅工具 (工具 32) +""" + +from ._base import register_tool, ToolDef + + +@register_tool("toggle_table_subscription") +class ToggleTableSubscriptionTool(ToolDef): + name = "toggle_table_subscription" + description = "切换表的订阅状态" + input_schema = { + "type": "object", + "properties": { + "configId": {"type": "string", "description": "数据库配置 ID"}, + "tableName": {"type": "string", "description": "表名"}, + "isSubscribe": {"type": "boolean", "description": "true=订阅, false=取消订阅"}, + }, + "required": ["configId", "tableName", "isSubscribe"], + } + + async def execute(self, args: dict) -> dict: + return self.client.post("/api/datasource/subscription/toggle", json_data=args) diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/table_data.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/table_data.py new file mode 100644 index 0000000..55baed8 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/tools/table_data.py @@ -0,0 +1,137 @@ +""" +表数据 CRUD 工具 (工具 13-17) +""" + +import base64 + +from ._base import register_tool, ToolDef + + +@register_tool("query_table_data") +class QueryTableDataTool(ToolDef): + name = "query_table_data" + description = "查询内置表数据(分页)" + input_schema = { + "type": "object", + "properties": { + "tableId": {"type": "string", "description": "表 ID"}, + "target": {"type": "string", "enum": ["prod", "test"], "default": "prod", "description": "环境,默认 prod"}, + "pageNum": {"type": "integer", "default": 1, "description": "页码"}, + "pageSize": {"type": "integer", "default": 10, "description": "每页数量"}, + }, + "required": ["tableId"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + table_id = args.pop("tableId") + params = {k: v for k, v in args.items() if v is not None} + return self.client.get(f"/api/datasource/connection/builtin/table/{table_id}", params=params) + + +@register_tool("insert_table_row") +class InsertTableRowTool(ToolDef): + name = "insert_table_row" + description = "向内置表插入一行数据" + input_schema = { + "type": "object", + "properties": { + "tableId": {"type": "string", "description": "表 ID"}, + "target": {"type": "string", "enum": ["prod", "test"], "default": "prod", "description": "环境,默认 prod"}, + "data": {"type": "object", "description": "行数据(键值对,键为字段名)"}, + }, + "required": ["tableId", "data"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + table_id = args.pop("tableId") + target = args.pop("target", "prod") + data = args.pop("data", {}) + params = {"target": target} if target else {} + return self.client.post(f"/api/datasource/connection/builtin/table/{table_id}/rows", json_data=data, params=params) + + +@register_tool("update_table_row") +class UpdateTableRowTool(ToolDef): + name = "update_table_row" + description = "更新内置表的指定行" + input_schema = { + "type": "object", + "properties": { + "tableId": {"type": "string", "description": "表 ID"}, + "target": {"type": "string", "enum": ["prod", "test"], "default": "prod", "description": "环境,默认 prod"}, + "primaryKey": {"type": "object", "description": "主键值(如 {\"id\": 1})"}, + "data": {"type": "object", "description": "要更新的字段值"}, + }, + "required": ["tableId", "primaryKey", "data"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + table_id = args.pop("tableId") + target = args.pop("target", "prod") + primary_key = args.pop("primaryKey") + data = args.pop("data", {}) + params = {"target": target} if target else {} + body = {"primaryKey": primary_key, "data": data} + return self.client.put(f"/api/datasource/connection/builtin/table/{table_id}/rows", json_data=body, params=params) + + +@register_tool("delete_table_rows") +class DeleteTableRowsTool(ToolDef): + name = "delete_table_rows" + description = "删除内置表的指定行(根据主键批量删除)" + input_schema = { + "type": "object", + "properties": { + "tableId": {"type": "string", "description": "表 ID"}, + "target": {"type": "string", "enum": ["prod", "test"], "default": "prod", "description": "环境,默认 prod"}, + "primaryKeys": { + "type": "array", + "description": "主键数组(如 [{\"id\": 1}, {\"id\": 2}])", + "items": {"type": "object"}, + }, + }, + "required": ["tableId", "primaryKeys"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + table_id = args.pop("tableId") + target = args.pop("target", "prod") + primary_keys = args.pop("primaryKeys") + params = {"target": target} if target else {} + body = {"primaryKeys": primary_keys} + return self.client.delete(f"/api/datasource/connection/builtin/table/{table_id}/rows", json_data=body, params=params) + + +@register_tool("export_table_excel") +class ExportTableExcelTool(ToolDef): + name = "export_table_excel" + description = "导出表数据为 Excel 文件(返回 base64 编码)" + input_schema = { + "type": "object", + "properties": { + "tableId": {"type": "string", "description": "表 ID"}, + "target": {"type": "string", "enum": ["prod", "test"], "default": "prod", "description": "环境,默认 prod"}, + }, + "required": ["tableId"], + } + + async def execute(self, args: dict) -> dict: + args = dict(args) + table_id = args.pop("tableId") + target = args.pop("target", "prod") + params = {"target": target} if target else {} + result = self.client.get(f"/api/datasource/connection/builtin/table/{table_id}/export/excel", params=params) + + # 处理二进制响应 + if result.get("raw"): + content = result["data"] + return { + "success": True, + "file_base64": base64.b64encode(content).decode("utf-8"), + "message": "Excel 文件已导出,请解码 base64 内容获取文件", + } + return result diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__init__.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__init__.py new file mode 100644 index 0000000..1b6c953 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__init__.py @@ -0,0 +1,13 @@ +from .env_config import get_api_key, get_base_url, get_env_config +from .logger_config import setup_system_logging, get_logger +from .api_client import AgileDBAPIClient, get_default_client + +__all__ = [ + 'get_api_key', + 'get_base_url', + 'get_env_config', + 'setup_system_logging', + 'get_logger', + 'AgileDBAPIClient', + 'get_default_client', +] diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__pycache__/__init__.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af8ee54dda0ffe524fbbee1cdd6aa936b61daea0 GIT binary patch literal 531 zcmZutJx{|h5Ve!GNmI&~82Aer$`61FQ9cG1#2iIBxrs5Rb{aVeDBbu8EU>fjTbNkA zbYNmbbnAo-ttugIc)EA*{O-=L-EM$PJU)as3?uYz$ugWpGCMNK6G~Bv1(GJ$JYRXpB`r)qdq#yaR9knrHC~Z9BD5#rZ>%;h?(A6DAOCULi5v}!_B|}nB zsFcv_meK4Ml5uv$S?K7Uf|gYdMO~Csf*3Q#Go}OEX9-oNXLG=~pr^-!%kvY#X;$iO ztEcpeRHB6Brxtq3HS<-&LeoOaf@i_E&^B-pc66|s|L2A7{*GL1w=&RyJ?D4M%1nCz zLvT%I9KBvnv}7a+$Dtfib>6uxlHn2LDel)y__T?!stQ)qX4m& zLOT4nR+U^7F#yka39y&fbH6XgX(i~P+A<5+|1Wk8e7YFpDH^(()DSFHTER012RqHzY2`M@+NZfR?5~8Z52Gw4A;{$Lfx1>kXWd)pMri zj99ix93*BqN}r1q)LYmb)(9MuI31^J&>%;dt3EcTfo4s>H5nwX1HL*)qtvZz60~89 zu!;%TWSI_m&Qf?nzpPLr6Pvnsf zJZ49DBx*BJ-xTRZzs11L1|AuaZ_kh=8!5X7Nf_8nsGZ4X9VP0s*g4?OVY9){hB-f1 zN-1k}wQv>dV1k#oxHz}RTL1%*a5~GgSe^dWk|8=LC4F?NT3N2a;cf9S9#<>Z=JhzE z%8!GKaSHyE{{UVe;Ul|Do`~WSM07%Rl0FUOBc1Hje2tH6)<$!uLRJ%1ejmZ8wR{># zscrixNU3#M5>mP-2TyV|);ud3n+jQ|*{sq|<-bL|t+q=Nhe(gbXmaCC6zEN1Irm%KYs4JDKXFk30PM582Th&*ebx&OEzxlzt*DoHwar}Jf z*FOvO_D{UrYb)EZsj8BxSjVg@tEpsw(suLw#Zd3-Uwzgyjd5g*B7D#PV&c{JzMm&d z3ubfW&bzRT8|{@q_R08#mu`Oi^YOlq;WyFu5j1h*H?KlpzWVH#(tlg&5*uWxeXEwp z#a>u6h+XR3QpLAN6~}73kv9MluLn=k@q&kUweuFtNkR{YQPML`c@9fD1s)~Z^Lkt@!fuqm(!E9P0Qn5#a=SbX(=jJr0~bY$GNFUQ zF7UdDa4um<7tJ|WGYd`~>E3wFoZ7wSYR0@%t=${0W!cVH->~|r;jD$-^s%I|%sdDz zWBH4^=@CQj*y2)5UN27kz>S^eQ-M;_HhDblha{bXX!6`ROY*a!NWgY&Jg#e!P8p4k%oziq z6g-Udi@*c%>j+Cq@2Z|vqB;L+j_u5ZBoy}llwXvpEQ zvr-aw$iq9BCeFcfyx@!&B2W^8gQp?U2c}Ts4{uh{Os*w+Q)tIq64!Dkvw(exh6*vu zMRo#?^0R!JL|E!mhlM138W23?wL-HukADJiqNsN0-H)WCGOwqpjdyi8&}iw2W3>eG(6OrM zgjsi?P!|jyhM)%ZDRxpQY>2mjKMs^E{1nI>|I4GHi=T!*I5z&Pk8m02(Bs@*xp;Ah z0V4v$>>9oRC}ntqxGd=+$Pkc!RK6x=pV!sGq6yiNGgG>1;X16i6ud6tn%UaBre{t6 zVygFLh>gQC{SZ?BqoNg5wz1XSo z)4#oO=Dms6-ne=GyqtmjmE<0q-NK_d`E;ye2Bh(L1qPW&DZIl4Tcn0Io>8(Tx>;y* zOV%fAwp3SeNK?u4ZM>v+wz)lE=t?G+;Bo`4+sQ%y{>;q z7GT2X?r5ggebibI zv=-bZG|<{L=*o`KlGVYI)tA^{+U74Uo5NZxxFg_-eA$q)?jhpyhYHGPQ9~&t_>!*O z!8=-oX$XNDC?mve86f~76F}|MD%D9D36Bb*iB>dNTdC=~13VMh^NDmHcMZ*E=uw=D zVuDZezUEv6-#TfaMLRUk`Dh;%)pJ=pr*<1EhD=of?X;4FN5u=!(`mhbiHzB;pa#S_ zsK2078&jY5X%lVXo6$mvb8iu>R&Ff@QCMB4_K5aiY^&LE)gTG2=1*%CkPx^TJaeP8 zK5Z1GU@Q{wSFy$@<4LIZbQ!b&t3`*4njqQ&V@DwbXMBzR^AR7Q^>>T zWAbtI9z<^qdb!|9DYeSRR|OA#HD+6}%^Df4WDw$IELny{mTlZ~UQX~R;6%Z`#;%)M z!{yIYKnJTxBq!kXmBB`_oaAnFq|X2tfU>ICwV>CWV zUbUq5ZtmGEW-suU`U}OZB_o!lW0^U9&!2q0?}d{u36mv6$jIb{aJz1;j|T^WyQBwtpEmvL2Kb{f;2vQH8n@fTM|eMXvN&+!>LFi z6U+}<=Oe)mQl@w$;P|BZLi6bIs^Ib}@sX#l)QC^lid*Z%+-HVUw~LnTf0S#@3tH!4 zE$FYxH&Fk#)TOc^-QXcHcjIvCCegC#k6{XF?g;bYdry_kF0&Jt?WN_*sn2r@%Smd8 z%z*e%W_I~fYG|nz;*t@U2L{)rX{Qt_2L0E)VGw-}7!A+%$Am$IiBkgocM&!eqV(>_R7d(paSMkW~MPP~G(bg?BDj-G8o+u#6Wp^y)ie*t! zd$^sulj3M^Z*e*0P10hVYiB71v6cf*MX%A==F8Em0I!;_#OQkP&dxv_8D|i7B)Yu~ zKthEaegjrQl;P2am_inQ6DFSo@2nvPP^vI@EqbykBV(wHMw=l|z!|52OT?Jrw?R(F z>>2Qaop57~{{(L)zL;Y14@dwv5f4|jG|yhkv~s-Y_nKgHJtHO_l5}S zjAj-EGmHFGVEd)V#JXK#X3=ow?w>s3Oe%Iivg(AKhGWjj&ZAI^{5Hizf znSv0i-Ftrs!q-4s3BchQ$WCB;0Q*j?a0k5a!G>7d5^GhI_?`Yb zF{^aMvP`uqhBNG7O<1!;>-@0=t4`?qlY=Qms&!!xX4?G)frFP0h_!pfO#5)=vp;zd ziR@?c%SwsMrKJ@F_4$K^Y5Vd(op7{!>0-NopB5W>j2p=qZociY88_^SwG^x}EGf-vK+zkL1T$JYmc zdHu5iW%B|Tw5@Ps?}Fnv&tf<|Z7snqFKr>P-21L8y3+2zZqp=DZ#PrKL!+e0~J-3yVsUF^R2 z0N4gl9`6#})kL)&ZWi!ug<9n>2`?iwUcA!?{rtm;zTd^&+`5hyUTThwzcSu_d9t=F(Q^{Ae1!HhYTh&uFYRL;)@LQPmJd$(xk!ZP8$1q)a;%Dnu99I}$!n?E{iP>M!dgtg z)juQ)PRQ-(N)=3K!7{W2`{D3f69yoMiQP5tdWQyDB#a)cJ*C}#M;@+mwa^kaxLeJqAa}_1MH=asxDh^>00p9BBf>0gt~t zkmld`4tzAG2M=AL;jDUF-IX0*BnQ`QS8_#Xqu8`xY;6~t+JnyLCS}swHd<@DZ6USk zlRAxdwlWoQ0!mgU`gTfrYr^B5u@nBPQ^8^pWX0Z=Cwd*{h`CLNrvs!H5k`5pp**@$ zU(3L9uRf%KMII2i4M-K$*o!e$U8GcekrCI;=YZsI;4dIq7xA@@Fl37QysOy@hO-xT zTd$h4MLJvNVNd6A{ZO38L@_W&n`Xs|D1-+i&4?+Ph z0K&82!QBB#-quhgJ!vAyq(2bmKM=-$As!4858fb_{xebdug0_!8;6Z^yL12tX_;Nt t|Io1-a`r6({qR;TvADF$dLj$1Qi8J{8YUhN>$GH!n7i<60z$d{{|3otfjIyG literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__pycache__/env_config.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__pycache__/env_config.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a4b06100b7e0bc9203449ef637ed868db7e4b2f GIT binary patch literal 2150 zcmbVN|4&<06u<9Fzt93J5i=v`r2TU5ts2jeOK4I(L%;w^cW@7d6>bRL&+DarJuO>@ol(|5& zFLTy(>=X8!L4p>nrI4nS8Gk6LF~yH@1boc<(?aXJXU_V?ciKb-^M7eigSxgV9S`XYw3`D|xq2RG-+;GFqL@62)FDh|-2<}0EpuGVkfu7W( zsza%cWJjtq*}2xxv~cOx<&{^~E8kA|AGkdatLxT|w5?aSuQ}WQa(fbIcfbif16YzH z1#BBI{}-@DpaK-x*c}K&J9GdP&8f*;X33mgHg6=TEhW!^#R3e3eqE3HjvrSe0ZHwT zXu7ZYMDvN~L}=mc0#I+>&CMr-4=$W7K&qw$skYWGzX)&*Q9XPbA<&>&R9T(!C4H%uWXoDTG-%y@a*aQUJ)jQ2S6ZYC zv=hgGflidhip*pzUMG6GGS)7$vn*7di+v0NnuJyLWFkA8EIft6$fHV1{_}94&w#bmz8>tF-44XS34?21npt1=fM`(OIg}>!3-a5$50#JAzJu zU7P`2jssJu5FIP!V*-ZU#=S9fb^#`lnVi`CYS^}Wn3|coxyEl_ z$|GQx8+XXI{i=&;o@vY@*jCzi$d<2nG4>gr@b-MYlQ~M%u+0VNwje(tzv%h@0)k9{ AxBvhE literal 0 HcmV?d00001 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__pycache__/logger_config.cpython-312.pyc b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/__pycache__/logger_config.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6c581fde0576b17395c69d27397b969184836176 GIT binary patch literal 5588 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 httpx.Client: + """懒加载 HTTP 客户端""" + if self._client is None: + self._client = httpx.Client(timeout=self.default_timeout) + return self._client + + def _get_headers(self, extra_headers: Optional[Dict[str, str]] = None) -> Dict[str, str]: + """获取请求头""" + headers = { + 'Authorization': self.api_key if self.api_key.startswith('Bearer ') else f'Bearer {self.api_key}', + } + if extra_headers: + headers.update(extra_headers) + return headers + + def _build_url(self, path: str) -> str: + """构建完整 URL""" + if path.startswith('http://') or path.startswith('https://'): + return path + return f"{self.base_url}{path}" + + def _handle_response(self, response: httpx.Response, url: str) -> Dict[str, Any]: + """统一处理 API 响应""" + logger.info(f"[API响应] HTTP {response.status_code}") + + if response.status_code == 204: + return {"success": True, "data": None} + + response.raise_for_status() + + try: + data = response.json() + except json.JSONDecodeError: + # 非 JSON 响应(如文件下载) + return {"success": True, "data": response.content, "raw": True} + + # 检查平台 API 的 {code, msg} 格式 + if isinstance(data, dict) and 'code' in data: + if data['code'] != 200: + error_msg = data.get('msg', '未知错误') + logger.error(f"[API错误] {error_msg}") + raise Exception(error_msg) + + return data + + def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: + """发送 GET 请求""" + url = self._build_url(path) + try: + logger.info(f"[API请求] GET {url}") + response = self.client.get(url, headers=self._get_headers(), params=params) + return self._handle_response(response, url) + except httpx.TimeoutException: + raise Exception(f"API 请求超时: {url}") + except httpx.HTTPStatusError as e: + raise Exception(f"API 请求失败 (HTTP {e.response.status_code}): {url}") + except httpx.RequestError as e: + raise Exception(f"API 请求异常: {url}, 错误: {str(e)}") + + def post(self, path: str, json_data: Optional[Dict[str, Any]] = None, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: + """发送 POST 请求""" + url = self._build_url(path) + try: + logger.info(f"[API请求] POST {url}") + headers = self._get_headers({'Content-Type': 'application/json'}) + response = self.client.post(url, headers=headers, json=json_data, params=params) + return self._handle_response(response, url) + except httpx.TimeoutException: + raise Exception(f"API 请求超时: {url}") + except httpx.HTTPStatusError as e: + raise Exception(f"API 请求失败 (HTTP {e.response.status_code}): {url}") + except httpx.RequestError as e: + raise Exception(f"API 请求异常: {url}, 错误: {str(e)}") + + def put(self, path: str, json_data: Optional[Dict[str, Any]] = None, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: + """发送 PUT 请求""" + url = self._build_url(path) + try: + logger.info(f"[API请求] PUT {url}") + headers = self._get_headers({'Content-Type': 'application/json'}) + response = self.client.put(url, headers=headers, json=json_data, params=params) + return self._handle_response(response, url) + except httpx.TimeoutException: + raise Exception(f"API 请求超时: {url}") + except httpx.HTTPStatusError as e: + raise Exception(f"API 请求失败 (HTTP {e.response.status_code}): {url}") + except httpx.RequestError as e: + raise Exception(f"API 请求异常: {url}, 错误: {str(e)}") + + def delete(self, path: str, params: Optional[Dict[str, Any]] = None, json_data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: + """发送 DELETE 请求""" + url = self._build_url(path) + try: + logger.info(f"[API请求] DELETE {url}") + headers = self._get_headers() + if json_data is not None: + headers['Content-Type'] = 'application/json' + response = self.client.delete(url, headers=headers, params=params, json=json_data) + return self._handle_response(response, url) + except httpx.TimeoutException: + raise Exception(f"API 请求超时: {url}") + except httpx.HTTPStatusError as e: + raise Exception(f"API 请求失败 (HTTP {e.response.status_code}): {url}") + except httpx.RequestError as e: + raise Exception(f"API 请求异常: {url}, 错误: {str(e)}") + + def upload(self, path: str, files: Dict[str, Any], params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: + """发送文件上传请求(multipart/form-data)""" + url = self._build_url(path) + try: + logger.info(f"[API请求] UPLOAD {url}") + # 文件上传不需要 Content-Type,httpx 会自动设置 multipart/form-data + headers = self._get_headers() + response = self.client.post(url, headers=headers, files=files, params=params) + return self._handle_response(response, url) + except httpx.TimeoutException: + raise Exception(f"API 请求超时: {url}") + except httpx.HTTPStatusError as e: + raise Exception(f"API 请求失败 (HTTP {e.response.status_code}): {url}") + except httpx.RequestError as e: + raise Exception(f"API 请求异常: {url}, 错误: {str(e)}") + + def close(self): + """关闭 HTTP 客户端""" + if self._client is not None: + self._client.close() + self._client = None + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + return False + + +# 懒加载的默认客户端 +_default_client: Optional[AgileDBAPIClient] = None + + +def get_default_client() -> AgileDBAPIClient: + """获取默认客户端(懒加载)""" + global _default_client + if _default_client is None: + _default_client = AgileDBAPIClient() + return _default_client diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/env_config.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/env_config.py new file mode 100644 index 0000000..6de69e0 --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/env_config.py @@ -0,0 +1,60 @@ +"""环境变量配置模块 - 数据库管理平台 MCP Server""" + +import os +from typing import Optional + + +def get_api_key(default: Optional[str] = None) -> str: + """ + 获取数据库管理平台 API 密钥 + + Args: + default: 默认值(可选) + + Returns: + str: API 密钥 + + Raises: + ValueError: 当 AGILE_DB_API_KEY 未设置且无默认值时 + """ + value = os.environ.get("AGILE_DB_API_KEY", default or "") + if not value: + raise ValueError("环境变量 AGILE_DB_API_KEY 未设置") + return value + + +def get_base_url(default: str = "http://localhost:8080") -> str: + """ + 获取数据库管理平台后端地址 + + Args: + default: 默认值(默认 http://localhost:8080) + + Returns: + str: 后端 API 基础 URL + """ + return os.environ.get("AGILE_DB_BASE_URL", default) + + +def get_env_config() -> dict: + """ + 获取所有环境配置 + + Returns: + dict: 包含所有配置的字典 + """ + return { + "api_key": get_api_key(""), + "base_url": get_base_url(), + } + + +def set_env_variable(key: str, value: str) -> None: + """ + 设置环境变量(仅在当前进程中有效) + + Args: + key: 环境变量名 + value: 环境变量值 + """ + os.environ[key] = value diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/logger_config.py b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/logger_config.py new file mode 100644 index 0000000..4e17b5c --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/utils/logger_config.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +""" +统一日志配置模块 +提供系统级别的日志配置和管理 +""" + +import os +import sys +import logging +from logging.handlers import RotatingFileHandler +from pathlib import Path + + +class LoggerConfig: + """日志配置管理类""" + + def __init__(self, logs_dir: str = None): + """初始化日志配置 + + Args: + logs_dir: 日志目录路径,默认为项目根目录下的logs文件夹 + """ + if logs_dir: + self.logs_dir = Path(logs_dir) + else: + project_root = Path(__file__).parent.parent + self.logs_dir = project_root / "logs" + + self.logs_dir.mkdir(exist_ok=True) + + self.log_format = '%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s' + self.date_format = '%Y-%m-%d %H:%M:%S' + self.log_level = self._get_log_level_from_env() + self._initialized = False + + def _get_log_level_from_env(self) -> int: + log_level_str = os.getenv('LOG_LEVEL', 'INFO').upper() + level_mapping = { + 'DEBUG': logging.DEBUG, + 'INFO': logging.INFO, + 'WARNING': logging.WARNING, + 'WARN': logging.WARNING, + 'ERROR': logging.ERROR, + 'CRITICAL': logging.CRITICAL, + 'FATAL': logging.CRITICAL + } + return level_mapping.get(log_level_str, logging.INFO) + + def setup_logging(self, + app_name: str = "lzwcai_mcp_agile_db", + log_level: int = logging.INFO, + max_file_size: int = 10 * 1024 * 1024, + backup_count: int = 5, + console_output: bool = True) -> logging.Logger: + if self._initialized: + return logging.getLogger() + + root_logger = logging.getLogger() + root_logger.setLevel(log_level) + + for handler in root_logger.handlers[:]: + root_logger.removeHandler(handler) + + formatter = logging.Formatter(self.log_format, self.date_format) + + # 1. 主日志文件 - 按大小滚动 + main_log_file = self.logs_dir / f"{app_name}.log" + file_handler = RotatingFileHandler( + main_log_file, + maxBytes=max_file_size, + backupCount=backup_count, + encoding='utf-8' + ) + file_handler.setLevel(log_level) + file_handler.setFormatter(formatter) + root_logger.addHandler(file_handler) + + # 2. 错误日志文件 + error_log_file = self.logs_dir / f"{app_name}_error.log" + error_handler = RotatingFileHandler( + error_log_file, + maxBytes=max_file_size, + backupCount=backup_count, + encoding='utf-8' + ) + error_handler.setLevel(logging.ERROR) + error_handler.setFormatter(formatter) + root_logger.addHandler(error_handler) + + # 3. 控制台输出 (MCP协议使用stdio时,必须将日志输出到stderr) + if console_output: + console_handler = logging.StreamHandler(sys.stderr) + console_handler.setLevel(log_level) + console_formatter = logging.Formatter( + '%(asctime)s - %(name)s - %(levelname)s - %(message)s', + self.date_format + ) + console_handler.setFormatter(console_formatter) + root_logger.addHandler(console_handler) + + self._initialized = True + root_logger.info(f"日志系统初始化完成 - 日志目录: {self.logs_dir}") + + return root_logger + + def get_module_logger(self, name: str) -> logging.Logger: + """获取模块级别的 logger(继承根配置)""" + return logging.getLogger(name) + + +# 全局日志配置实例 +logger_config = LoggerConfig() + + +def setup_system_logging(app_name: str = "lzwcai_mcp_agile_db", + log_level: int = logging.INFO) -> logging.Logger: + return logger_config.setup_logging(app_name, log_level) + + +def get_logger(name: str) -> logging.Logger: + return logger_config.get_module_logger(name) diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/数据库管理平台-MCP工具设计方案.md b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/数据库管理平台-MCP工具设计方案.md new file mode 100644 index 0000000..33cec1a --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/数据库管理平台-MCP工具设计方案.md @@ -0,0 +1,621 @@ +# 数据库管理平台 - MCP 工具设计方案 + +> 基于平台现有功能,设计可供外部 AI Agent 通过 MCP 协议调用的工具集。 +> 目标:**用户脱离平台界面,通过 MCP 调用即可使用数据库管理平台的核心功能。** + +--- + +## 一、设计原则 + +1. **按用户场景分组**:不是简单映射 API,而是围绕用户真实工作流组织工具 +2. **最小化调用链**:复杂操作尽量合并为一个 tool,减少多轮调用 +3. **读写分离**:查询类工具可安全暴露,写操作需明确提示 +4. **环境感知**:所有操作默认携带环境参数(prod/test),内置数据源特有 +5. **权限前置**:调用方需提供 apiKeyId 或等效凭证,工具内部自动鉴权 + +--- + +## 二、工具清单 + +### 🗄️ 数据源管理 + +#### 1. `list_datasources` +- **用途**:获取数据源列表,支持搜索和状态筛选 +- **对应前端**:DataSourceList.vue +- **对应 API**:`getConnectionList` ✅ 已实现 + - **端点**:`GET /api/datasource/connection/list` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| datasourceName | string | 否 | 数据源名称模糊搜索 | +| status | int | 否 | 0=运行中, 1=已停止, 不传=全部 | +| sourceType | string | 否 | builtin/external | +| pageNum | int | 否 | 默认 1 | +| pageSize | int | 否 | 默认 20 | + +**返回**:数据源列表(含名称、类型、状态、库数、表数、创建时间等) + +--- + +#### 2. `get_datasource_detail` +- **用途**:获取单个数据源的完整详情 +- **对应前端**:DatabaseDetail.vue 头部 +- **对应 API**: + - `getConnectionDetail(id)` ✅ 已实现 — `GET /api/datasource/connection/{id}` + - `getConnectionConfig(id)` ✅ 已实现 — `GET /api/datasource/config/{id}` + - `getConnectionRealtimeStructure(id)` ✅ 已实现 — `GET /api/datasource/connection/realtime/structure/{id}` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| datasourceId | string | 是 | 数据源 ID | + +**返回**:数据源详情 + 数据库配置列表 + 实时结构(数据库列表、表列表、字段信息) + +--- + +#### 3. `create_datasource` +- **用途**:创建外部数据源连接 +- **对应前端**:CreateDataSource.vue +- **对应 API**: + - `testConnection(data)` ✅ 已实现 — `POST /api/datasource/connection/test` + - `postConnectionDetail(data)` ✅ 已实现 — `POST /api/datasource/connection` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| datasourceName | string | 是 | 数据源名称(3-20字) | +| datasourceType | string | 是 | mysql/postgresql/oracle/sqlserver/dameng | +| host | string | 是 | 数据库地址 | +| port | int | 是 | 端口号 | +| databaseName | string | 是 | 要连接的数据库名 | +| username | string | 是 | 数据库用户名 | +| password | string | 否 | 密码 | +| remark | string | 否 | 数据源描述 | +| connectionType | string | 否 | user_password/ssl,默认 user_password | +| test_first | bool | 否 | 是否先测试连接,默认 true | + +**返回**:创建结果,含数据源 ID + +--- + +#### 4. `update_datasource` +- **用途**:更新数据源连接信息 +- **对应 API**:`putConnectionDetail(data)` ✅ 已实现 — `PUT /api/datasource/connection` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | string | 是 | 数据源 ID | +| datasourceName | string | 否 | 更新名称 | +| host | string | 否 | 更新地址 | +| port | int | 否 | 更新端口 | +| databaseName | string | 否 | 更新数据库名 | +| username | string | 否 | 更新用户名 | +| password | string | 否 | 新密码(不传则不变) | +| remark | string | 否 | 更新描述 | + +**返回**:更新结果 + +--- + +#### 5. `toggle_datasource_status` +- **用途**:启用/停用数据源 +- **对应 API**:`putConnectionChangeStatus(data)` ✅ 已实现 — `PUT /api/datasource/connection/changeStatus` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | string | 是 | 数据源 ID | +| status | int | 是 | 0=启用, 1=停用 | + +**返回**:操作结果 + +--- + +#### 6. `delete_datasource` +- **用途**:删除数据源(运行中会自动先停用) +- **对应 API**: + - `putConnectionChangeStatus(data)` ✅ 已实现 — `PUT /api/datasource/connection/changeStatus` + - `deleteConnection(id)` ✅ 已实现 — `DELETE /api/datasource/connection/{id}` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | string | 是 | 数据源 ID | + +**返回**:删除结果 + +--- + +### 📊 数据库与表管理 + +#### 7. `list_databases` +- **用途**:获取指定数据源下的数据库列表 +- **对应 API**:`getConnectionConfigList(data)` ✅ 已实现 — `GET /api/datasource/config/list` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| datasourceId | string | 是 | 数据源 ID | + +**返回**:数据库列表(ID、名称、类型、状态、表数) + +--- + +#### 8. `list_tables` +- **用途**:获取指定数据库下的表列表 +- **对应前端**:DatabaseDetail.vue 左侧表列表 +- **对应 API**:`getTableList(data)` ✅ 已实现 — `GET /api/datasource/table/list` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| datasourceId | string | 是 | 数据源 ID | +| databaseName | string | 否 | 数据库名过滤 | +| keyword | string | 否 | 表名模糊搜索 | +| pageNum | int | 否 | 默认 1 | +| pageSize | int | 否 | 默认 20 | + +**返回**:表列表(表名、注释、字段数、创建时间等) + +--- + +#### 9. `get_table_detail` +- **用途**:获取表的完整结构信息 +- **对应前端**:DatabaseDetail.vue 右侧字段列表 +- **对应 API**:`getTableDetail(id)` ✅ 已实现 — `GET /api/datasource/table/{id}/detail` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| tableId | string | 是 | 表 ID | + +**返回**:表名、表注释、字段列表(字段名、类型、长度、主键、可空、默认值、注释、AI训练状态) + +--- + +#### 10. `create_table` +- **用途**:在指定数据库创建新表 +- **对应前端**:CreateBuiltinDataSource.vue 表结构编辑器 +- **对应 API**:`postCreateTable(connectionId, data)` ✅ 已实现 — `POST /api/datasource/connection/{connectionId}/create_table` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| datasourceId | string | 是 | 数据源 ID | +| databaseName | string | 是 | 目标数据库名 | +| tableName | string | 是 | 表名(小写字母+数字+下划线) | +| tableComment | string | 否 | 表注释 | +| columns | array | 是 | 字段定义数组 | +| columns[].columnName | string | 是 | 字段名 | +| columns[].columnType | string | 是 | 字段类型(VARCHAR/INTEGER/SERIAL等) | +| columns[].columnLength | int | 否 | 字段长度 | +| columns[].isPrimaryKey | bool | 否 | 是否主键 | +| columns[].isNullable | bool | 否 | 是否可空 | +| columns[].isAutoIncrement | bool | 否 | 是否自增 | +| columns[].columnComment | string | 否 | 字段注释 | +| columns[].defaultValue | string | 否 | 默认值 | + +**返回**:创建结果,含表 ID + +--- + +#### 11. `alter_table` +- **用途**:修改已有表结构(增/改/删字段) +- **对应 API**:`putAlterTable(connectionId, data)` ✅ 已实现 — `PUT /api/datasource/connection/{connectionId}/alter_table` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| tableId | string | 是 | 表 ID | +| columns | array | 是 | 字段变更数组 | +| columns[].operation | string | 是 | ADD_COLUMN / MODIFY_COLUMN / DROP_COLUMN | +| columns[].columnName | string | 是 | 字段名 | +| columns[].columnType | string | 否 | 字段类型(ADD/MODIFY) | +| columns[].columnLength | int | 否 | 字段长度 | +| columns[].isPrimaryKey | bool | 否 | 是否主键 | +| columns[].isNullable | bool | 否 | 是否可空 | +| columns[].columnComment | string | 否 | 字段注释 | +| columns[].defaultValue | string | 否 | 默认值 | +| newTableName | string | 否 | 新表名(重命名) | +| newTableComment | string | 否 | 新表注释 | + +**返回**:修改结果 + +--- + +#### 12. `generate_table_by_description` +- **用途**:通过自然语言描述让 AI 生成表结构 +- **对应前端**:CreateBuiltinDataSource.vue AI 生成表结构 +- **对应 API**:`postGenerateTable(data)` ✅ 已实现 — `POST /api/datasource/connection/generate_table` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| description | string | 是 | 业务场景描述(至少6个字符) | + +**返回**:AI 生成的表结构(表名、表注释、字段列表含类型/主键/注释等) + +> **场景示例**:用户说"我需要一个商城系统,管理商品、分类和用户评价",AI 返回完整的表结构设计。 + +--- + +### 📝 表数据操作 (内置数据源 CRUD) + +#### 13. `query_table_data` +- **用途**:查询内置表数据(分页) +- **对应前端**:CustomizeDbTable.vue 线上/调试数据视图 +- **对应 API**:`getBuiltinTableData(tableId, params)` ✅ 已实现 — `GET /api/datasource/connection/builtin/table/{tableId}` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| tableId | string | 是 | 表 ID | +| target | string | 否 | prod/test,默认 prod | +| pageNum | int | 否 | 默认 1 | +| pageSize | int | 否 | 默认 10 | + +**返回**:表结构信息 + 数据行(二维数组转换后的对象数组) + 总数 + +--- + +#### 14. `insert_table_row` +- **用途**:向内置表插入一行数据 +- **对应 API**:`postBuiltinTableRows(tableId, data, params)` ✅ 已实现 — `POST /api/datasource/connection/builtin/table/{tableId}/rows` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| tableId | string | 是 | 表 ID | +| target | string | 否 | prod/test,默认 prod | +| data | object | 是 | 行数据(键值对,键为字段名) | + +**返回**:插入结果 + +--- + +#### 15. `update_table_row` +- **用途**:更新内置表的指定行 +- **对应 API**:`putBuiltinTableRows(tableId, data, params)` ✅ 已实现 — `PUT /api/datasource/connection/builtin/table/{tableId}/rows` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| tableId | string | 是 | 表 ID | +| target | string | 否 | prod/test,默认 prod | +| primaryKey | object | 是 | 主键值(如 {"id": 1}) | +| data | object | 是 | 要更新的字段值 | + +**返回**:更新结果 + +--- + +#### 16. `delete_table_rows` +- **用途**:删除内置表的指定行 +- **对应 API**:`deleteBuiltinTableRows(tableId, data, params)` ✅ 已实现 — `DELETE /api/datasource/connection/builtin/table/{tableId}/rows` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| tableId | string | 是 | 表 ID | +| target | string | 否 | prod/test,默认 prod | +| primaryKeys | array | 是 | 主键数组(如 [{"id": 1}, {"id": 2}]) | + +**返回**:删除结果 + +--- + +#### 17. `export_table_excel` +- **用途**:导出表数据为 Excel 文件 +- **对应 API**:`getBuiltinTableExportExcel(tableId, params)` ✅ 已实现 — `GET /api/datasource/connection/builtin/table/{tableId}/export/excel` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| tableId | string | 是 | 表 ID | +| target | string | 否 | prod/test,默认 prod | + +**返回**:Excel 文件(二进制 blob)+ 文件名(从 Content-Disposition 解析) + +--- + +### 🔑 API 密钥与权限管理 + +#### 18. `list_api_keys` +- **用途**:获取 API 密钥列表 +- **对应前端**:DataSourceKeys.vue +- **对应 API**:`getApiKeyList(data)` ✅ 已实现 — `GET /api/datasource/api_key/list` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| apiKeyName | string | 否 | 密钥名称模糊搜索 | +| pageNum | int | 否 | 默认 1 | +| pageSize | int | 否 | 默认 20 | + +**返回**:密钥列表(名称、Key、状态、创建时间) + +--- + +#### 19. `create_api_key` +- **用途**:创建新的 API 密钥 +- **对应 API**:`postApiKey(data)` ✅ 已实现 — `POST /api/datasource/api_key` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| apiKeyName | string | 是 | 密钥名称(最多50字) | + +**返回**:密钥信息(含 API Key 明文、ID) + +--- + +#### 20. `toggle_api_key_status` +- **用途**:启用/禁用 API 密钥 +- **对应 API**:`putApiKey(data)` ✅ 已实现 — `PUT /api/datasource/api_key` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | string | 是 | 密钥 ID | +| status | int | 是 | 0=启用, 1=禁用 | + +**返回**:操作结果 + +--- + +#### 21. `delete_api_key` +- **用途**:删除 API 密钥 +- **对应 API**:`deleteApiKey(ids)` ✅ 已实现 — `DELETE /api/datasource/api_key/{ids}` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | string | 是 | 密钥 ID | + +**返回**:删除结果 + +--- + +#### 22. `get_api_key_permissions` +- **用途**:查看指定密钥的权限配置 +- **对应 API**:`getApiKeyPermission(apiKeyId)` ✅ 已实现 — `GET /api/datasource/api_key/permission/{apiKeyId}` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| apiKeyId | string | 是 | 密钥 ID | + +**返回**:三级权限(connectionPermissions / databasePermissions / tablePermissions) + +--- + +#### 23. `grant_api_key_permissions` +- **用途**:批量为 API 密钥授予权限 +- **对应前端**:DataSourceKeySetting.vue +- **对应 API**:`postApiKeyPermissionGrantBatch(data)` ✅ 已实现 — `POST /api/datasource/api_key/permission/grant_batch` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| apiKeyId | string | 是 | 密钥 ID | +| batchDatas | array | 是 | 权限批量数据数组 | +| batchDatas[].connectionId | string | 是 | 数据源 ID | +| batchDatas[].permissionLevel | string | 是 | connection/database/table | +| batchDatas[].permissionType | string | 是 | 权限类型(逗号分隔) | +| batchDatas[].databaseName | string | 否 | 数据库名(level=database/table 时) | +| batchDatas[].tableName | string | 否 | 表名(level=table 时) | + +**返回**:授权结果 + +--- + +### 🤖 技能与工具管理 (内置数据源 AI 能力) + +#### 24. `get_skill_by_datasource` +- **用途**:根据数据源获取技能信息 +- **对应 API**:`getSkillByDatasource(id)` ✅ 已实现 — `GET /api/datasource/skill/getByDatasource/{id}` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| datasourceId | string | 是 | 数据源 ID | + +**返回**:技能信息(含 skillBool 标识) + +--- + +#### 25. `get_skill_tools` +- **用途**:获取技能下的工具列表 +- **对应 API**:`getSkillBySkillId(id)` ✅ 已实现 — `GET /api/datasource/skill/getBySkillId/{id}` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| skillId | string | 是 | 技能 ID | + +**返回**:工具列表(名称、描述、SQL模板、参数定义、业务场景) + +--- + +#### 26. `create_skill` +- **用途**:为数据源创建技能 +- **对应 API**:`postSkillCreateOrGet(data)` ✅ 已实现 — `POST /api/datasource/skill/createOrGet` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| datasourceId | string | 是 | 数据源 ID | +| name | string | 否 | 技能名称(不传则自动生成) | +| description | string | 否 | 技能描述 | + +**返回**:技能 ID + +--- + +#### 27. `create_sql_tool` +- **用途**:将 SQL 查询创建为可复用工具 +- **对应前端**:SqlControllerMsg.vue 添加到工具功能 +- **对应 API**:`postSqlSkillConfirmTools(data)` ✅ 已实现 — `POST /api/datasource/skill/confirmTools` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| skillId | string | 是 | 技能 ID | +| name | string | 是 | 工具名称 | +| businessDescription | string | 是 | 业务描述 | +| sqlTemplate | string | 是 | SQL 模板(支持 #{param} 参数占位) | +| sqlParams | string | 否 | 参数 JSON Schema(默认空对象) | +| resultType | string | 否 | single/list,默认 list | +| businessScenario | string | 否 | 业务场景描述 | + +**返回**:工具创建结果 + +--- + +#### 28. `delete_skill_tool` +- **用途**:删除技能下的工具 +- **对应 API**:`postDeleteSkillTool(skillToolId)` ✅ 已实现 — `DELETE /api/datasource/skill/tskilltool/{skillToolId}` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| skillToolId | string | 是 | 工具 ID | + +**返回**:删除结果 + +--- + +#### 29. `update_skill_config` +- **用途**:更新技能配置(如 MCP Server 配置模板) +- **对应 API**:`putSkillUpdateOrGet(data)` ✅ 已实现 — `POST /api/datasource/skill/updateOrGet` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| datasourceId | string | 是 | 数据源 ID | +| configTemplate | string | 是 | 配置模板 JSON 字符串 | + +**返回**:更新结果 + +--- + +### 📥 数据导入 + +#### 30. `preview_import_data` +- **用途**:上传 Excel 文件,AI 智能识别并预览表结构/数据 +- **对应前端**:TableRecognition.vue +- **对应 API**:`postImportDocumentPreview(connectionId, file, target)` ✅ 已实现 — `POST /api/datasource/connection/{connectionId}/import_document/preview` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| connectionId | int | 是 | 数据源 ID | +| target | string | 否 | prod/test,默认 test | +| file | binary | 是 | Excel 文件 (.xlsx/.xls, <500KB) | + +**返回**:识别结果(表结构 + 数据预览) + +--- + +#### 31. `confirm_import_data` +- **用途**:确认导入 AI 识别后的数据 +- **对应 API**:`postImportDocumentConfirm(connectionId, data, params)` ✅ 已实现 — `POST /api/datasource/connection/{connectionId}/import_document/confirm` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| connectionId | int | 是 | 数据源 ID | +| target | string | 否 | prod/test | +| data | object | 是 | 导入数据(含 tableStructure + allData) | + +**返回**:导入结果 + +--- + +### 🏷️ 表订阅 + +#### 32. `toggle_table_subscription` +- **用途**:切换表的订阅状态 +- **对应前端**:DatabaseDetail.vue 订阅按钮 +- **对应 API**:`postDatasourceSubscriptionToggle(data)` ✅ 已实现 — `POST /api/datasource/subscription/toggle` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| tableId | string | 是 | 表 ID | +| datasourceId | string | 是 | 数据源 ID | +| subscribe | bool | 是 | true=订阅, false=取消订阅 | + +**返回**:操作结果 + +--- + +### 🔧 SQL 执行 + +#### 33. `execute_sql` +- **用途**:执行原生 SQL 查询 +- **对应 API**:`executeSql(data)` ✅ 已实现 — `POST /api/datasource/sqlExecutionLog/testSqlWithSchema` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| datasourceId | string | 是 | 数据源 ID | +| sql | string | 是 | SQL 语句 | +| target | string | 否 | prod/test,默认 prod | +| params | object | 否 | 参数对象 | + +**返回**:查询结果(表头、数据行、业务名称、描述等) + +--- + +## 三、推荐使用场景 + +### 场景 1:外部 AI Agent 管理数据库 + +``` +用户: "帮我查一下有哪些数据源" +Agent: 调用 list_datasources() + +用户: "看看 mall_db 有哪些表" +Agent: 调用 list_tables(datasourceId="xx", databaseName="mall_db") + +用户: "users 表结构给我看一下" +Agent: 调用 get_table_detail(tableId="xx") +``` + +### 场景 2:通过 AI 描述自动生成表结构 + +``` +用户: "我需要一个订单系统,包含订单、订单明细、支付方式" +Agent: 调用 generate_table_by_description(description="我需要一个订单系统...") +Agent: 返回 AI 生成的表结构,用户确认后调用 create_table() 批量创建 +``` + +### 场景 3:管理 API 密钥和权限 + +``` +用户: "帮我创建一个叫'第三方报表系统'的 API Key" +Agent: 调用 create_api_key(apiKeyName="第三方报表系统") + +用户: "给它开通 mall_db 数据库的读取权限" +Agent: 调用 grant_api_key_permissions(apiKeyId="xx", batchDatas=[{...}]) +``` + +### 场景 4:管理表数据 + +``` +用户: "查一下 users 表前 10 条数据" +Agent: 调用 query_table_data(tableId="xx", pageNum=1, pageSize=10) + +用户: "新增一个用户,用户名是 test_user" +Agent: 调用 insert_table_row(tableId="xx", data={"user_name": "test_user", ...}) +``` + +### 场景 5:创建 SQL 工具 + +``` +用户: "把这个查询保存为工具,叫'按地区统计订单'" +Agent: 调用 create_sql_tool(skillId="xx", name="按地区统计订单", + sqlTemplate="SELECT region, COUNT(*) FROM orders GROUP BY region", ...) +``` + +### 场景 6:导入 Excel 数据 + +``` +用户: "帮我导入这份 Excel 到测试环境" +Agent: 调用 preview_import_data(connectionId=xx, target="test", file=...) +Agent: 展示识别结果,用户确认后调用 confirm_import_data(...) +``` + +--- + +## 四、工具优先级建议 + +| 优先级 | 工具 | 理由 | +|--------|------|------| +| **P0 核心** | list_datasources, list_tables, get_table_detail, execute_sql, query_table_data | 覆盖 80% 查询场景 | +| **P1 常用** | create_datasource, create_table, generate_table_by_description, create_api_key, grant_api_key_permissions | 管理核心操作 | +| **P2 扩展** | insert/update/delete_table_row, export_table_excel, create_sql_tool, toggle_table_subscription | 数据操作与 AI 能力 | +| **P3 完整** | preview/confirm_import_data, update_skill_config, alter_table, delete_skill_tool | 高级功能 | + +--- + +## 五、实现建议 + +1. **MCP Server 实现**:建议用 Python + `mcp` 库或 Node.js + `@modelcontextprotocol/sdk` +2. **鉴权方式**:工具内部复用平台现有的 API Key 鉴权机制,调用方传入 apiKeyId +3. **错误处理**:统一错误格式 `{ success: false, error: "描述" }`,与平台 API 拦截器保持一致 +4. **环境默认值**:所有 target 参数默认 prod,调用方显式指定 test 才能操作测试数据 +5. **批量操作**:对于 create_table 等可能涉及多表的场景,支持批量参数或循环调用 +6. **AI 工具调用**:generate_table_by_description 等 AI 工具需要调用平台的 AI 服务接口(agent generic / aiTextGenerator) +7. **前端 API 映射**:所有 33 个 MCP 工具均已在前端 `src/server/database.ts` 中实现对应函数,可直接复用 diff --git a/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/数据库管理平台-功能总览.md b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/数据库管理平台-功能总览.md new file mode 100644 index 0000000..4ce2b3a --- /dev/null +++ b/lzwcai_mcp_agile_db/lzwcai_mcp_agile_db/数据库管理平台-功能总览.md @@ -0,0 +1,303 @@ +# 数据库管理平台 - 功能总览 + +> 本文档梳理 `databasePage` 组件集群与 `DatabaseDetailPage` 的整体功能架构。 + +--- + +## 一、系统定位 + +这是一个面向业务用户的**数据库管理与智能问数一体化平台**,支持两种数据源模式: + +| 模式 | 说明 | 核心差异 | +|------|------|----------| +| **外部数据源** | 远程 MySQL/PostgreSQL/Oracle/SQL Server/达梦 等 | 标准数据库连接,提供只读/CRUD 管理 | +| **内置数据源** | 平台内建 PostgreSQL 实例 | 支持 AI 技能、工具、环境切换(prod/test)、AI 训练 | + +--- + +## 二、功能模块全景 + +### 1. 数据源管理 + +#### 1.1 数据源列表 (`DataSourceList.vue`) +- **卡片式展示**:名称、ID、类型徽章(内置/外部)、数据库类型、运行状态、库数/表数统计 +- **无限滚动分页**:IntersectionObserver + useInfiniteScroll,每页 20 条 +- **搜索与筛选**:按名称模糊搜索、按状态筛选(运行中/已停止) +- **数据源操作**: + - 编辑(外部→CreateDataSource, 内置→CreateBuiltinDataSource) + - 启用/停用(切换 status 0/1) + - 删除(运行中自动先停用再删除) +- **业务执行入口**:点击打开智能问数聊天界面 (ChatDebugging) +- **查看详情入口**:右侧 Drawer 打开 DatabaseDetail (95% 宽度) + +#### 1.2 外部数据源创建/编辑 (`CreateDataSource.vue`) - 4步向导 +| 步骤 | 内容 | 核心功能 | +|------|------|----------| +| Step 1 | 选择数据库类型 | MySQL/PostgreSQL/Oracle/SQL Server/达梦,自动填充默认端口 | +| Step 2 | 配置连接信息 | 名称、描述(AI润色)、主机、端口、认证(基础认证/SSL)、用户名密码(AI生成名称)、测试连接 | +| Step 3 | 选择数据库和表 | 树形展开、多选、搜索过滤、分页加载表列表、全选/清空 | +| Step 4 | 确认信息 | 汇总展示已选数据库和表标签 | + +#### 1.3 内置数据源创建/编辑/添加表 (`CreateBuiltinDataSource.vue`) +| 模式 | 步骤 | 说明 | +|------|------|------| +| create | 名称描述→业务场景→表结构 | AI 生成表结构,批量创建数据库和表 | +| edit | 名称描述→表结构 | 更新已有内置数据源 | +| addTable | 业务场景→表结构 | 在已有内置数据源下新增表 | + +- **AI 能力**:AI 优化描述、AI 生成数据库名、AI 生成表名/表描述/字段描述 +- **表结构编辑器**:左右分栏(左侧表列表, 右侧 TableDetailEditor 预览/编辑) +- **提交流程**:创建数据源 → 创建 PostgreSQL 连接 → 创建数据库 → 批量建表 → 检查 AI 训练状态 + +### 2. 数据库详情 (`DatabaseDetail.vue`) + +左侧面板 + 右侧面板的经典布局: + +#### 2.1 左侧 - 数据库与表管理 +- **数据库选择器**:下拉切换当前数据库,悬浮显示数据库详情(ID/名称/数据源/类型) +- **数据表列表**: + - 搜索过滤 + - 多选/全选 (Checkbox) + - 无限滚动加载 + - AI 补全(选中多个表批量触发) + - 更多操作: AI智能建表、智能导入表、删除库 +- **底部功能按钮**:字段关联管理、AI补全管理 + +#### 2.2 右侧 - 详情视图(三种视图) + +**视图 A: 表详情 (`fieldViewMode = fields`)** +- 字段列表表格: 字段名、类型、长度、可空、主键、默认值、注释、描述 +- AI 训练状态徽章(已训练/未训练) +- 操作: 修改表、字段关联管理、表订阅(已订阅/未订阅)、刷新 +- 用户 ID 字段关联提示(user_id/createById 等自动关联系统用户) + +**视图 B: 线上数据 (`fieldViewMode = online`)** +- 通过 `CustomizeDbTable` 组件查看/编辑生产环境真实数据 +- 支持增删改查、导出 Excel、智能导入数据 + +**视图 C: 调试数据 (`fieldViewMode = debug`)** +- 同上,但操作测试环境数据 + +#### 2.3 右侧 - 字段关联管理视图 +- 为当前表的字段建立与目标表字段的映射关系 +- 目标表数据更新时自动同步到当前表 +- 支持保存配置、添加/删除关联 + +#### 2.4 右侧 - AI 补全管理视图 +- AI 补全任务列表: 任务名、类型、状态(待执行/运行中/成功/失败)、进度 +- 任务详情弹窗: 训练结果(格式化代码展示)、耗时、场景描述 +- 支持重新执行、删除任务 + +### 3. 内建表数据管理 (`CustomizeDbTable.vue`) +- 基于 `CommonDbTable` 的完整 CRUD 表格 +- 动态列配置: 根据表结构自动生成字段类型、宽度、可编辑性 +- **操作能力**: 新增行、编辑行、删除行、导出 Excel、导入数据、刷新 +- **导入流程**: 下载模板 → 上传 Excel → AI 识别预览 → 确认导入(调用 postImportDocumentConfirm) +- 环境切换: `target` prop 控制 prod/test + +### 4. 智能导入识别 (`TableRecognition.vue`) +- **Step 1: 上传文件**: 选择目标环境(prod/test),上传 Excel (.xlsx/.xls, <500KB) +- **Step 2: 智能识别**: AI 解析 Excel,预览表结构/数据,支持编辑 +- **两种模式**: + - `table` 模式: 根据 Excel 内容自动生成数据表结构 + - `data` 模式: 根据规范模板识别并导入数据 +- 空行过滤、字段标记、模板下载 + +### 5. 智能问数 / 业务执行 (`ChatDebugging.vue`) +- **三栏布局**: 左侧面板(可折叠) + 中间聊天区 + 右侧信息 +- **左侧面板**: + - 数字员工列表(可收起) + - 新建会话按钮 + - 会话列表(点击切换、删除) + - 技能列表(展开/折叠) + - 技能名称 + 编辑按钮 + - 工具列表(名称、别名、编辑、删除) + - 至少保留一个工具 +- **中间聊天区** (`ChatBusiness` 组件): + - 数据源插件嵌入输入区 (`DataSourcePlugIn`) + - 数据库下拉选择 + - 环境切换(生产/测试,仅内置数据源) + - SQL 消息控制器 (`SqlControllerMsg`) + - 默认数据库查询提示词(常用查询/数据统计/新手指引) + +#### 5.1 SQL 查询结果展示 (`SqlControllerMsg.vue`) +| 视图类型 | 说明 | +|----------|------| +| SQL 代码 | 展示可执行 SQL 语句,支持复制 | +| 图表可视化 | ChartGallery 组件渲染图表 | +| 查询数据 | JSON 格式原始数据,支持复制 | +| 文本说明 | 业务名称、描述、AI 解释 | +| 表格视图 | Ant Design Table 展示查询结果 | +| 添加到工具 | 将 SQL 查询保存为可复用工具 | + +- **添加工具功能**: + - 重复检测(按 sqlTemplate 归一化比对) + - 仅生产环境可用 + - 技能创建/更新流程(无技能时自动创建 skill + MCP 配置) + - 通过 EventBus 触发技能刷新 + +#### 5.2 数据源选择插件 (`DataSourcePlugIn.vue`) +- 紧凑的内联选择器: 数据源名称 → 数据库下拉 → 环境(prod/test) +- 监听 props 变化自动重置无效选择 +- 暴露 getSelection/clearSelection/setEnvironment 方法 + +### 6. API 密钥管理 (`DataSourceKeys.vue` + `DataSourceKeySetting.vue`) +- **密钥列表**: 名称、API Key(脱敏显示/可切换显示)、状态开关(启用/禁用)、创建时间、操作(详情/编辑/删除) +- **两步创建流程**: + 1. 输入密钥名称 → 调用 postApiKey 创建 + 2. 弹窗询问是否配置权限 → 打开权限配置 +- **权限配置** (`DataSourceKeySetting.vue`) - 3步向导: + - Step 1: 选择数据源(单选) + 配置数据源级权限 + - Step 2: 选择数据库(单选, 非必填) + 配置数据库级权限 + - Step 3: 选择数据表(多选, 非必填) + 行内配置表级权限 + - Step 4: 完成页(ApiKeyPermissionPreview 汇总) → 批量提交权限 +- **权限选项**: 按层级不同(connection/database/table),每种有对应的读/写/管理等权限 +- **API 调用文档**: 切换到文档视图查看调用说明 + +### 7. 表字段编辑器 (`TableDetailEditor.vue`) +- **表信息编辑**: 表名(AI生成)、表描述(AI优化) +- **字段列表表格**: + - 序号、字段名、字段类型(分组下拉)、长度、主键、自增、可空、默认值、注释 + - AI 生成字段描述(逐字段) + - 添加字段(首个字段自动设为主键+自增) + - 删除字段(有id的字段记录到 deletedColumns) + - 主键设置后不可取消(已有字段) + - 自增字段自动切换为整数类型 +- **两种模式**: `edit` (编辑) / `preview` (预览) +- **校验功能**: validateFields 供外部调用 +- **字段类型** (面向 PostgreSQL): VARCHAR/TEXT/SERIAL/INTEGER/BIGINT/NUMERIC/TIMESTAMP/BOOLEAN/JSONB/INT2/INT4/INT8/SMALLINT/SMALLSERIAL/BIGSERIAL/BOOL/BIGSERIAL + +### 8. 其他辅助组件 + +| 组件 | 功能 | +|------|------| +| `ChartGallery.vue` | 图表可视化渲染 | +| `AddToolModal.vue` | 添加工具弹窗(工具名、描述编辑+AI辅助) | +| `ApiKeyPermissionPreview.vue` | 权限汇总预览组件 | +| `ApiCallDocument.vue` | API 调用文档展示 | +| `DatabaseMessageList.vue` | 数据库消息列表 | +| `field-types-dictionary.json` | 字段类型字典 | + +--- + +## 三、API 接口层 (server/database.ts) + +### 数据源管理 +| 函数 | 方法 | 用途 | +|------|------|------| +| `getConnectionList` | GET | 数据源列表(分页+搜索+筛选) | +| `getConnectionDetail` | GET | 数据源详情 | +| `postConnectionDetail` | POST | 创建数据源 | +| `putConnectionDetail` | PUT | 更新数据源 | +| `deleteConnection` | DELETE | 删除数据源 | +| `putConnectionChangeStatus` | PUT | 切换数据源状态(启用/停用) | +| `testConnection` | POST | 测试连接 | + +### 内置数据库管理 +| 函数 | 方法 | 用途 | +|------|------|------| +| `postCreateBuiltinPostgreSQLConnection` | POST | 创建内置 PostgreSQL 连接 | +| `postCreateDatabase` | POST | 创建数据库 | +| `putAlterDatabase` | PUT | 修改数据库 | +| `postCreateTable` | POST | 创建表 | +| `putAlterTable` | PUT | 修改表 | +| `postGenerateTable` | POST | AI 生成表结构 | +| `putUpdateBuiltinDatabase` | PUT | 更新内置数据库 | + +### 数据库配置 +| 函数 | 方法 | 用途 | +|------|------|------| +| `getConnectionConfig` | GET | 获取数据库配置(含 skillBool) | +| `getConnectionConfigList` | GET | 数据库配置列表 | +| `postConnectionConfig` | POST | 创建数据库配置 | +| `putConnectionConfig` | PUT | 更新数据库配置 | +| `deleteConnectionConfig` | DELETE | 删除数据库配置 | +| `getConnectionRealtimeStructure` | GET | 获取实时数据库结构 | + +### 表数据管理 +| 函数 | 方法 | 用途 | +|------|------|------| +| `getTableList` | GET | 表列表 | +| `getTableDetail` | GET | 表详情 | +| `getBuiltinTableData` | GET | 获取内置表数据(分页) | +| `postBuiltinTableRows` | POST | 新增表数据行 | +| `putBuiltinTableRows` | PUT | 更新表数据行 | +| `deleteBuiltinTableRows` | DELETE | 删除表数据行 | +| `getBuiltinTableExportExcel` | GET | 导出表数据为 Excel | + +### 数据导入 +| 函数 | 方法 | 用途 | +|------|------|------| +| `postImportDocumentPreview` | POST | 上传 Excel 预览识别结果 | +| `postImportDocumentConfirm` | POST | 确认导入数据 | + +### 技能与工具 +| 函数 | 方法 | 用途 | +|------|------|------| +| `getSkillByDatasource` | GET | 根据数据源获取技能 | +| `getSkillBySkillId` | GET | 根据技能ID获取工具列表 | +| `postSkillCreateOrGet` | POST | 创建或获取技能 | +| `putSkillUpdateOrGet` | PUT | 更新技能配置 | +| `postSkillToolUpdateOrGet` | POST | 创建/更新技能工具 | +| `postDeleteSkillTool` | POST | 删除技能工具 | +| `postSqlSkillConfirmTools` | POST | 确认并创建 SQL 工具 | + +### AI 训练 +| 函数 | 方法 | 用途 | +|------|------|------| +| `getAiTrainingList` | GET | AI 训练任务列表 | +| `postAiTrainingCreateBySelected` | POST | 创建 AI 训练任务 | +| `getAiTrainingDetail` | GET | 训练任务详情 | + +### API 密钥 +| 函数 | 方法 | 用途 | +|------|------|------| +| `getApiKeyList` | GET | 密钥列表 | +| `postApiKey` | POST | 创建密钥 | +| `putApiKey` | PUT | 更新密钥 | +| `deleteApiKey` | DELETE | 删除密钥 | +| `getApiKeyPermission` | GET | 获取密钥权限 | +| `postApiKeyPermissionGrantBatch` | POST | 批量授予权限 | + +### 订阅 +| 函数 | 方法 | 用途 | +|------|------|------| +| `postDatasourceSubscriptionToggle` | POST | 切换表订阅状态 | + +### SQL 执行 +| 函数 | 方法 | 用途 | +|------|------|------| +| `executeSql` | POST | 执行 SQL 查询 | + +--- + +## 四、状态管理与通信 + +- **Pinia Store**: `useDatabaseChatStore` 管理选中数据库、环境、技能状态 +- **EventBus**: `EVENTS.RELOAD_SKILL_DATA` 用于工具添加后刷新技能数据 +- **权限控制**: `hasPermission()` 函数按权限标识控制按钮可见性 + +## 五、权限标识体系 + +| 权限标识 | 控制范围 | +|----------|----------| +| `database:create` | 创建数据源 | +| `database:edit` | 编辑数据源 | +| `database:delete` | 删除数据源 | +| `database:import` | 导入表/数据 | +| `database:export` | 导出表 | +| `database:table:create` | AI 智能建表 | +| `database:table:ai:complete` | AI 补全功能 | +| `database:apikey:view` | 查看密钥管理 | +| `database:apikey:create` | 创建密钥 | + +--- + +## 六、关键技术特点 + +1. **AI 深度集成**: 描述润色、名称生成、表结构自动生成、字段描述生成、AI 补全、AI 训练 +2. **双环境隔离**: 生产/测试环境切换,测试环境限制添加工具等敏感操作 +3. **无限滚动**: IntersectionObserver + 哨兵元素实现列表分页加载 +4. **三级权限体系**: 数据源 → 数据库 → 数据表,通过 API Key 控制访问粒度 +5. **MCP 工具集成**: 内置数据源自动配置 MCP Server (`lzwcai-mcp-sqlexecutor`),支持 AI 工具注册 +6. **Excel 智能导入**: AI 识别 Excel 内容,自动匹配表结构,支持表结构和数据两种导入模式 diff --git a/lzwcai_mcp_agile_db/main.py b/lzwcai_mcp_agile_db/main.py new file mode 100644 index 0000000..f53b660 --- /dev/null +++ b/lzwcai_mcp_agile_db/main.py @@ -0,0 +1,12 @@ +""" +Entry point for lzwcai-mcp-agile-db +Runs the MCP server for database management platform +""" + +from lzwcai_mcp_agile_db.server import main +import os + +if __name__ == "__main__": + os.environ["AGILE_DB_API_KEY"] = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiTE9HSU4iLCJsb2dpbl91c2VyX2tleSI6IjJiMDY0YzMzLTBiZWYtNDU0NC04NWY1LTRmNTFiOGMxMmI5NSJ9.Uv599TvlQvlTlwrnZGo3Tl2eLAvM0ldE9vpMI5jHxbTf4_tVSRA60rUNIV4LBiw6pt1r_xIi7aFcTRE2PeN5sg" + os.environ["AGILE_DB_BASE_URL"] = "https://dempdemo.lzwcai.com" + main() diff --git a/lzwcai_mcp_agile_db/pyproject.toml b/lzwcai_mcp_agile_db/pyproject.toml new file mode 100644 index 0000000..7262bad --- /dev/null +++ b/lzwcai_mcp_agile_db/pyproject.toml @@ -0,0 +1,34 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "lzwcai-mcp-agile-db" +version = "0.1.0" +description = "MCP server for database management platform with 33 tools for datasource, table, data, API key, and skill management" +readme = "README.md" +requires-python = ">=3.10" +license = {text = "MIT"} +authors = [ + {name = "lzwcai", email = "your-email@example.com"}, +] +keywords = ["mcp", "database", "agile", "server"] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] +dependencies = [ + "httpx>=0.28.1", + "mcp[cli]>=1.10.1", +] + +[project.scripts] +lzwcai-mcp-agile-db = "lzwcai_mcp_agile_db.server:main" + +[tool.hatch.build.targets.wheel] +packages = ["lzwcai_mcp_agile_db"] diff --git a/lzwcai_mcp_sqlexecutor/__pycache__/main.cpython-312.pyc b/lzwcai_mcp_sqlexecutor/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7730fb54bd94f9743b969e74f53fda8638537ffd GIT binary patch literal 820 zcmbtS!EVz)5S_I*v1_$ZseqJn$ps0c#&t}aH~}HV0ca07AaTiM<$AX?&BhM410(_o zBr5oW@(G}R3YUN)AuI$!z=2yJH%{!jDWq3e$>W*ld2hx$^Lk;y0CA{xYWEWY_#%U& zqfDKNEu4Lz&;*L8!ch}Z^(izJrc&HK4-n}JFy&yHj-apf6*D)e8n;+Cj9W<<^-DbT zJznHqFYtF*RNM}uA|KrMy;iB?cT4eI&K@woCsHlryA*2pQ@QMgg;m8f`6$djBpE2p z?opF}5P{`pf~hMTKbYpCf8mQ?{V#rw=Ku1kMs==s@FPH=z(bh1Ixy!NsX@KO+wx+z zK~vRPvr{c@w>THkl4GyCZn;*gtl8D-deyOOZhB(N^V=+-*97Bs#0Q0)BySIafW zDpy>~v7C#Qx@)^`B(K0kDeic!z|5se7^fNw?zN&YNR5~!lx=%Go}_0FheO10$n0<= zFPb|PneU3S-W^6H7>n(J;xA45R=1z!WJVWwydlhE_=@w-HlJ+1!-Y4v@M7gP;4!jN{ z +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] - 响应数据类型: +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] - 调用第三方 API,skill_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] - 调用第三方 API,skill_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 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 @@ -224,9 +212,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( ^^^^^^^^^^^^^ @@ -247,7 +235,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 @@ -257,401 +244,46 @@ 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 -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 工具 -2026-01-28 16:37:23 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs -2026-01-28 16:37:23 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:299] - ============================================================ -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:302] - ============================================================ -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 37 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID: 2016416951958351874 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:309] - ============================================================ -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接... -2026-01-28 16:37:24 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type ListToolsRequest -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:278] - 调用第三方API,skill_id: 2016416951958351874 -2026-01-28 16:37:24 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 16:37:24 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 "HTTP/1.1 200 " -2026-01-28 16:37:24 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:85] - API调用成功: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:283] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2016419268577308673', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:53:12', 'updateBy': None, 'updateTime': None, 'serviceId': '2016416951970934785', 'uniqueName': '按付款人账号和交易日期查询资金日报', 'name': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'description': '根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 7ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}, {'id': '2016419112255598594', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:52:34', 'updateBy': None, 'updateTime': None, 'serviceId': '2016416951970934785', 'uniqueName': '按收款人账号和交易日期查询资金日报', 'name': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'description': '根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 1 行数据,执行时间: 5ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}, {'id': '2016418808822870017', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:51:22', 'updateBy': None, 'updateTime': None, 'serviceId': '2016416951970934785', 'uniqueName': '按交易日期查询所有账号和账户名', 'name': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'description': '根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'visualizable': 1, 'toolPrompt': '查询成功,返回 5 行数据,执行时间: 6ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'sqlParams': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}]} -2026-01-28 16:37:24 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:322] - 成功处理 3 条技能数据 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:288] - 成功获取并处理 3 条数据 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:128] - API配置: 3 条 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2016419268577308673', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'businessDescription': '根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016419112255598594', 'businessName': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'businessDescription': '根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payeeAccountNo', 'transactionDate'], 'properties': {'payeeAccountNo': {'type': 'string', 'description': '收款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016418808822870017', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'businessDescription': '根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'parameters': {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}] -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:165] - 成功生成 3 个 MCP 工具 -2026-01-28 21:35:19 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs -2026-01-28 21:35:19 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:299] - ============================================================ -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:302] - ============================================================ -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 37 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID: 2016416951958351874 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:309] - ============================================================ -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接... -2026-01-28 21:35:20 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type ListToolsRequest -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:278] - 调用第三方API,skill_id: 2016416951958351874 -2026-01-28 21:35:20 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 21:35:20 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 "HTTP/1.1 200 " -2026-01-28 21:35:20 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:85] - API调用成功: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:283] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2016419268577308673', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:53:12', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按付款人账号和交易日期查询资金日报', 'name': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'description': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 7ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016419112255598594', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:52:34', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按收款人账号和交易日期查询资金日报', 'name': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'description': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 1 行数据,执行时间: 5ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016418808822870017', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:51:22', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按交易日期查询所有账号和账户名', 'name': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'description': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'visualizable': 1, 'toolPrompt': '查询成功,返回 5 行数据,执行时间: 6ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'sqlParams': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}]} -2026-01-28 21:35:20 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:322] - 成功处理 3 条技能数据 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:288] - 成功获取并处理 3 条数据 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:128] - API配置: 3 条 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2016419268577308673', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'businessDescription': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016419112255598594', 'businessName': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'businessDescription': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payeeAccountNo', 'transactionDate'], 'properties': {'payeeAccountNo': {'type': 'string', 'description': '收款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016418808822870017', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'businessDescription': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'parameters': {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}] -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:165] - 成功生成 3 个 MCP 工具 -2026-01-28 21:36:46 - mcp_services - INFO - [main.py:329] - MCP 服务器已关闭 -2026-01-28 21:44:42 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs -2026-01-28 21:44:42 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:299] - ============================================================ -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:302] - ============================================================ -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 37 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID: 2016416951958351874 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:309] - ============================================================ -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接... -2026-01-28 21:49:54 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type CallToolRequest -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:278] - 调用第三方API,skill_id: 2016416951958351874 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 21:49:54 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 "HTTP/1.1 200 " -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:85] - API调用成功: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:283] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2016419268577308673', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:53:12', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按付款人账号和交易日期查询资金日报', 'name': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'description': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 7ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016419112255598594', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:52:34', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按收款人账号和交易日期查询资金日报', 'name': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'description': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 1 行数据,执行时间: 5ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016418808822870017', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:51:22', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按交易日期查询所有账号和账户名', 'name': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'description': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'visualizable': 1, 'toolPrompt': '查询成功,返回 5 行数据,执行时间: 6ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'sqlParams': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}]} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:322] - 成功处理 3 条技能数据 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:288] - 成功获取并处理 3 条数据 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:128] - API配置: 3 条 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2016419268577308673', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'businessDescription': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016419112255598594', 'businessName': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'businessDescription': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payeeAccountNo', 'transactionDate'], 'properties': {'payeeAccountNo': {'type': 'string', 'description': '收款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016418808822870017', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'businessDescription': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'parameters': {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}] -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:165] - 成功生成 3 个 MCP 工具 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:190] - 收到工具调用请求: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:225] - 正在调用测试SQL API... -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:132] - ================================================================================ -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:133] - test_sql_with_schema 接口接收到的数据: -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:134] - 数据类型: -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:135] - 数据内容: { - "datasourceId": "37", - "businessName": "anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44", - "businessDescription": "anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细", - "sqlTemplate": "SELECT record_id AS \"记录标识号\", transaction_type AS \"交易类型\", business_type AS \"业务类型\", payer_account_no AS \"付款人账号\", payer_name AS \"付款人名称\", payee_account_no AS \"收款人账号\", payee_name AS \"收款人名称\", transaction_date AS \"交易日期\", transaction_time AS \"交易时间\", trade_currency AS \"交易货币\", trade_amount AS \"交易金额\", after_transaction_balance AS \"交易后余额\", value_date AS \"起息日期\", exchange_rate AS \"汇率\", transaction_ref_no AS \"交易流水号\", reference AS \"摘要\", purpose AS \"用途\" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date", - "parameters": { - "type": "object", - "required": [ - "payerAccountNo", - "transactionDate" - ], - "properties": { - "payerAccountNo": { - "type": "string", - "description": "付款人账号", - "examples": [ - "667866722135" - ] - }, - "transactionDate": { - "type": "string", - "description": "交易日期,格式为YYYY-MM-DD", - "examples": [ - "2026-01-26" - ] - }, - "targetDatabaseName": { - "type": "string", - "description": "目标数据库名称", - "default": "" - } - } - }, - "testParams": { - "payerAccountNo": "667866722135", - "transactionDate": "2026-01-26", - "targetDatabaseName": "" - } -} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:136] - 数据源ID: 37 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:137] - 业务名称: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:138] - 业务描述: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:139] - SQL模板: SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:140] - 参数定义: {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}, 'targetDatabaseName': {'type': 'string', 'description': '目标数据库名称', 'default': ''}}} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:141] - 测试参数: {'payerAccountNo': '667866722135', 'transactionDate': '2026-01-26', 'targetDatabaseName': ''} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:142] - ================================================================================ -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:151] - 正在调用测试SQL API: http://192.168.11.24:8088/datasource/sqlExecutionLog/testSqlWithSchema -2026-01-28 21:49:54 - httpx - INFO - [_client.py:1025] - HTTP Request: POST http://192.168.11.24:8088/datasource/sqlExecutionLog/testSqlWithSchema "HTTP/1.1 200 " -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:168] - ================================================================================ -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:169] - test_sql_with_schema 接口返回的数据: -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:170] - HTTP状态码: 200 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:171] - 响应数据类型: -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:172] - 响应数据内容: { - "msg": "操作成功", - "code": 200, - "data": { - "resultCount": 6, - "data": [ - { - "记录标识号": "2", - "交易类型": "往账", - "业务类型": "转账支出", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": "6217852000006363041", - "收款人名称": "范红霞", - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:25", - "交易货币": "CNY", - "交易金额": -787.5, - "交易后余额": 170220.05, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282055238690", - "摘要": "282055238999986690999986690", - "用途": "OBSS003756213754GIRO000000000000" - }, - { - "记录标识号": "3", - "交易类型": "往账", - "业务类型": "网上支付", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": "6212263602092911221", - "收款人名称": "吴小敏", - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:27", - "交易货币": "CNY", - "交易金额": -419.3, - "交易后余额": 169800.75, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282058995688", - "摘要": "282058995999986688999986688", - "用途": "OBSS003756219241GIRO000000000000" - }, - { - "记录标识号": "4", - "交易类型": "往账", - "业务类型": "收费", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": null, - "收款人名称": null, - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:27", - "交易货币": "CNY", - "交易金额": -4.5, - "交易后余额": 169796.25, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282058995686", - "摘要": "282058995999986686999986686", - "用途": "对公跨行转账汇款手续费" - }, - { - "记录标识号": "5", - "交易类型": "往账", - "业务类型": "网上支付", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": "7559016582106213872732048", - "收款人名称": "深圳市腾讯计算机系统有限公司", - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:27", - "交易货币": "CNY", - "交易金额": -0.14, - "交易后余额": 169796.11, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282056095685", - "摘要": "282056095999986685999986685", - "用途": "OBSS003756206850GIRO000000000000" - }, - { - "记录标识号": "6", - "交易类型": "往账", - "业务类型": "收费", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": null, - "收款人名称": null, - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:27", - "交易货币": "CNY", - "交易金额": -4.5, - "交易后余额": 169791.61, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282056095683", - "摘要": "282056095999986683999986683", - "用途": "对公跨行转账汇款手续费" - }, - { - "记录标识号": "7", - "交易类型": "往账", - "业务类型": "转账支出", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": "6217852000006363041", - "收款人名称": "范红霞", - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:36", - "交易货币": "CNY", - "交易金额": -67.97, - "交易后余额": 169723.64, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282098067682", - "摘要": "282098067999986682999986682", - "用途": "OBSS003756216834GIRO000000000000" - } - ], - "databaseName": "fund_daily_report_db_37", - "businessDescription": "anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细", - "originalTemplate": "SELECT record_id AS \"记录标识号\", transaction_type AS \"交易类型\", business_type AS \"业务类型\", payer_account_no AS \"付款人账号\", payer_name AS \"付款人名称\", payee_account_no AS \"收款人账号\", payee_name AS \"收款人名称\", transaction_date AS \"交易日期\", transaction_time AS \"交易时间\", trade_currency AS \"交易货币\", trade_amount AS \"交易金额\", after_transaction_balance AS \"交易后余额\", value_date AS \"起息日期\", exchange_rate AS \"汇率\", transaction_ref_no AS \"交易流水号\", reference AS \"摘要\", purpose AS \"用途\" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date", - "convertedTemplate": "SELECT record_id AS \"记录标识号\", transaction_type AS \"交易类型\", business_type AS \"业务类型\", payer_account_no AS \"付款人账号\", payer_name AS \"付款人名称\", payee_account_no AS \"收款人账号\", payee_name AS \"收款人名称\", transaction_date AS \"交易日期\", transaction_time AS \"交易时间\", trade_currency AS \"交易货币\", trade_amount AS \"交易金额\", after_transaction_balance AS \"交易后余额\", value_date AS \"起息日期\", exchange_rate AS \"汇率\", transaction_ref_no AS \"交易流水号\", reference AS \"摘要\", purpose AS \"用途\" FROM funds_daily_report WHERE payer_account_no = #{payerAccountNo} AND transaction_date::date = #{transactionDate}::date", - "executionStatus": "success", - "businessName": "anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44", - "testParams": { - "payerAccountNo": "667866722135", - "transactionDate": "2026-01-26", - "targetDatabaseName": "" - }, - "errorMessage": null, - "executionTime": 7, - "datasourceId": "37", - "logId": "1497", - "executableSql": "SELECT record_id AS \"记录标识号\", transaction_type AS \"交易类型\", business_type AS \"业务类型\", payer_account_no AS \"付款人账号\", payer_name AS \"付款人名称\", payee_account_no AS \"收款人账号\", payee_name AS \"收款人名称\", transaction_date AS \"交易日期\", transaction_time AS \"交易时间\", trade_currency AS \"交易货币\", trade_amount AS \"交易金额\", after_transaction_balance AS \"交易后余额\", value_date AS \"起息日期\", exchange_rate AS \"汇率\", transaction_ref_no AS \"交易流水号\", reference AS \"摘要\", purpose AS \"用途\" FROM funds_daily_report WHERE payer_account_no = '667866722135' AND transaction_date::date = '2026-01-26'::date", - "datasourceName": "fund_daily_report_db_37" - } -} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:174] - 响应code: 200 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:175] - 响应msg: 操作成功 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:176] - 响应data: {'resultCount': 6, 'data': [{'记录标识号': '2', '交易类型': '往账', '业务类型': '转账支出', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': '6217852000006363041', '收款人名称': '范红霞', '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:25', '交易货币': 'CNY', '交易金额': -787.5, '交易后余额': 170220.05, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282055238690', '摘要': '282055238999986690999986690', '用途': 'OBSS003756213754GIRO000000000000'}, {'记录标识号': '3', '交易类型': '往账', '业务类型': '网上支付', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': '6212263602092911221', '收款人名称': '吴小敏', '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:27', '交易货币': 'CNY', '交易金额': -419.3, '交易后余额': 169800.75, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282058995688', '摘要': '282058995999986688999986688', '用途': 'OBSS003756219241GIRO000000000000'}, {'记录标识号': '4', '交易类型': '往账', '业务类型': '收费', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': None, '收款人名称': None, '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:27', '交易货币': 'CNY', '交易金额': -4.5, '交易后余额': 169796.25, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282058995686', '摘要': '282058995999986686999986686', '用途': '对公跨行转账汇款手续费'}, {'记录标识号': '5', '交易类型': '往账', '业务类型': '网上支付', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': '7559016582106213872732048', '收款人名称': '深圳市腾讯计算机系统有限公司', '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:27', '交易货币': 'CNY', '交易金额': -0.14, '交易后余额': 169796.11, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282056095685', '摘要': '282056095999986685999986685', '用途': 'OBSS003756206850GIRO000000000000'}, {'记录标识号': '6', '交易类型': '往账', '业务类型': '收费', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': None, '收款人名称': None, '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:27', '交易货币': 'CNY', '交易金额': -4.5, '交易后余额': 169791.61, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282056095683', '摘要': '282056095999986683999986683', '用途': '对公跨行转账汇款手续费'}, {'记录标识号': '7', '交易类型': '往账', '业务类型': '转账支出', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': '6217852000006363041', '收款人名称': '范红霞', '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:36', '交易货币': 'CNY', '交易金额': -67.97, '交易后余额': 169723.64, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282098067682', '摘要': '282098067999986682999986682', '用途': 'OBSS003756216834GIRO000000000000'}], 'databaseName': 'fund_daily_report_db_37', 'businessDescription': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'originalTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'convertedTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = #{payerAccountNo} AND transaction_date::date = #{transactionDate}::date', 'executionStatus': 'success', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'testParams': {'payerAccountNo': '667866722135', 'transactionDate': '2026-01-26', 'targetDatabaseName': ''}, 'errorMessage': None, 'executionTime': 7, 'datasourceId': '37', 'logId': '1497', 'executableSql': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = \'667866722135\' AND transaction_date::date = \'2026-01-26\'::date', 'datasourceName': 'fund_daily_report_db_37'} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:177] - ================================================================================ -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:179] - 测试SQL API调用成功 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:227] - 测试SQL API调用成功 -2026-01-28 21:50:18 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type CallToolRequest -2026-01-28 21:50:18 - mcp_services - INFO - [main.py:190] - 收到工具调用请求: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98 -2026-01-28 21:50:18 - mcp_services - INFO - [main.py:225] - 正在调用测试SQL API... -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:132] - ================================================================================ -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:133] - test_sql_with_schema 接口接收到的数据: -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:134] - 数据类型: -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:135] - 数据内容: { - "datasourceId": "37", - "businessName": "anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98", - "businessDescription": "anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息", - "sqlTemplate": "SELECT DISTINCT payer_account_no AS \"账号\", payer_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS \"账号\", payee_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL", - "parameters": { - "type": "object", - "required": [ - "transactionDate" - ], - "properties": { - "transactionDate": { - "type": "string", - "description": "交易日期,格式为YYYY-MM-DD", - "examples": [ - "2026-01-26" - ] - }, - "targetDatabaseName": { - "type": "string", - "description": "目标数据库名称", - "default": "" - } - } - }, - "testParams": { - "transactionDate": "2026-01-02", - "targetDatabaseName": "" - } -} -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:136] - 数据源ID: 37 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:137] - 业务名称: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:138] - 业务描述: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:139] - SQL模板: SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:140] - 参数定义: {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}, 'targetDatabaseName': {'type': 'string', 'description': '目标数据库名称', 'default': ''}}} -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:141] - 测试参数: {'transactionDate': '2026-01-02', 'targetDatabaseName': ''} -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:142] - ================================================================================ -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:151] - 正在调用测试SQL API: http://192.168.11.24:8088/datasource/sqlExecutionLog/testSqlWithSchema -2026-01-28 21:50:18 - httpx - INFO - [_client.py:1025] - HTTP Request: POST http://192.168.11.24:8088/datasource/sqlExecutionLog/testSqlWithSchema "HTTP/1.1 200 " -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:168] - ================================================================================ -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:169] - test_sql_with_schema 接口返回的数据: -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:170] - HTTP状态码: 200 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:171] - 响应数据类型: -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:172] - 响应数据内容: { - "msg": "操作成功", - "code": 200, - "data": { - "resultCount": 0, - "data": [], - "databaseName": "fund_daily_report_db_37", - "businessDescription": "anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息", - "originalTemplate": "SELECT DISTINCT payer_account_no AS \"账号\", payer_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS \"账号\", payee_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL", - "convertedTemplate": "SELECT DISTINCT payer_account_no AS \"账号\", payer_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = #{transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS \"账号\", payee_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = #{transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL", - "executionStatus": "success", - "businessName": "anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98", - "testParams": { - "transactionDate": "2026-01-02", - "targetDatabaseName": "" - }, - "errorMessage": null, - "executionTime": 7, - "datasourceId": "37", - "logId": "1498", - "executableSql": "SELECT DISTINCT payer_account_no AS \"账号\", payer_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = '2026-01-02'::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS \"账号\", payee_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = '2026-01-02'::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL", - "datasourceName": "fund_daily_report_db_37" - } -} -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:174] - 响应code: 200 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:175] - 响应msg: 操作成功 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:176] - 响应data: {'resultCount': 0, 'data': [], 'databaseName': 'fund_daily_report_db_37', 'businessDescription': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'originalTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'convertedTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = #{transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = #{transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'executionStatus': 'success', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'testParams': {'transactionDate': '2026-01-02', 'targetDatabaseName': ''}, 'errorMessage': None, 'executionTime': 7, 'datasourceId': '37', 'logId': '1498', 'executableSql': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = \'2026-01-02\'::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = \'2026-01-02\'::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'datasourceName': 'fund_daily_report_db_37'} -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:177] - ================================================================================ -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:179] - 测试SQL API调用成功 -2026-01-28 21:50:18 - mcp_services - INFO - [main.py:227] - 测试SQL API调用成功 -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] - 调用第三方API,skill_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 工具 +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] - 调用第三方 API,skill_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 工具 diff --git a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log index 701e119..fd68929 100644 --- a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log +++ b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log @@ -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] - 调用第三方API,skill_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] - 调用第三方API,skill_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] - 数据类型: +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] - 响应数据类型: +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] - 调用第三方 API,skill_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] - 调用第三方 API,skill_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] - 调用第三方 API,skill_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 工具 diff --git a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log.2026-01-26 b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log.2026-01-26 deleted file mode 100644 index bb8c9e3..0000000 --- a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log.2026-01-26 +++ /dev/null @@ -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] - 调用第三方API,skill_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] - 调用第三方API,skill_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 工具 diff --git a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log.2026-02-07 b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log.2026-02-07 deleted file mode 100644 index fa790b0..0000000 --- a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_daily.log.2026-02-07 +++ /dev/null @@ -1,358 +0,0 @@ -2026-01-28 16:37:23 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs -2026-01-28 16:37:23 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:299] - ============================================================ -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:302] - ============================================================ -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 37 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID: 2016416951958351874 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:309] - ============================================================ -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接... -2026-01-28 16:37:24 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type ListToolsRequest -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:278] - 调用第三方API,skill_id: 2016416951958351874 -2026-01-28 16:37:24 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 16:37:24 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 "HTTP/1.1 200 " -2026-01-28 16:37:24 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:85] - API调用成功: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:283] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2016419268577308673', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:53:12', 'updateBy': None, 'updateTime': None, 'serviceId': '2016416951970934785', 'uniqueName': '按付款人账号和交易日期查询资金日报', 'name': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'description': '根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 7ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}, {'id': '2016419112255598594', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:52:34', 'updateBy': None, 'updateTime': None, 'serviceId': '2016416951970934785', 'uniqueName': '按收款人账号和交易日期查询资金日报', 'name': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'description': '根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 1 行数据,执行时间: 5ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}, {'id': '2016418808822870017', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:51:22', 'updateBy': None, 'updateTime': None, 'serviceId': '2016416951970934785', 'uniqueName': '按交易日期查询所有账号和账户名', 'name': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'description': '根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'visualizable': 1, 'toolPrompt': '查询成功,返回 5 行数据,执行时间: 6ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'sqlParams': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}]} -2026-01-28 16:37:24 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:322] - 成功处理 3 条技能数据 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:288] - 成功获取并处理 3 条数据 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:128] - API配置: 3 条 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2016419268577308673', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'businessDescription': '根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016419112255598594', 'businessName': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'businessDescription': '根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payeeAccountNo', 'transactionDate'], 'properties': {'payeeAccountNo': {'type': 'string', 'description': '收款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016418808822870017', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'businessDescription': '根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'parameters': {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}] -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:165] - 成功生成 3 个 MCP 工具 -2026-01-28 21:35:19 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs -2026-01-28 21:35:19 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:299] - ============================================================ -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:302] - ============================================================ -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 37 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID: 2016416951958351874 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:309] - ============================================================ -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接... -2026-01-28 21:35:20 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type ListToolsRequest -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:278] - 调用第三方API,skill_id: 2016416951958351874 -2026-01-28 21:35:20 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 21:35:20 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 "HTTP/1.1 200 " -2026-01-28 21:35:20 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:85] - API调用成功: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:283] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2016419268577308673', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:53:12', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按付款人账号和交易日期查询资金日报', 'name': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'description': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 7ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016419112255598594', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:52:34', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按收款人账号和交易日期查询资金日报', 'name': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'description': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 1 行数据,执行时间: 5ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016418808822870017', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:51:22', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按交易日期查询所有账号和账户名', 'name': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'description': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'visualizable': 1, 'toolPrompt': '查询成功,返回 5 行数据,执行时间: 6ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'sqlParams': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}]} -2026-01-28 21:35:20 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:322] - 成功处理 3 条技能数据 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:288] - 成功获取并处理 3 条数据 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:128] - API配置: 3 条 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2016419268577308673', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'businessDescription': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016419112255598594', 'businessName': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'businessDescription': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payeeAccountNo', 'transactionDate'], 'properties': {'payeeAccountNo': {'type': 'string', 'description': '收款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016418808822870017', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'businessDescription': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'parameters': {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}] -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:165] - 成功生成 3 个 MCP 工具 -2026-01-28 21:36:46 - mcp_services - INFO - [main.py:329] - MCP 服务器已关闭 -2026-01-28 21:44:42 - root - INFO - [logger_config.py:151] - 日志系统初始化完成 - 日志目录: E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_sqlexecutor\lzwcai_mcp_sqlexecutor\logs -2026-01-28 21:44:42 - root - INFO - [logger_config.py:152] - 日志配置 - 级别: INFO, 文件大小限制: 10MB, 备份数量: 5 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:299] - ============================================================ -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:302] - ============================================================ -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 37 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID: 2016416951958351874 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:309] - ============================================================ -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接... -2026-01-28 21:49:54 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type CallToolRequest -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:278] - 调用第三方API,skill_id: 2016416951958351874 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:71] - 正在调用API: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 21:49:54 - httpx - INFO - [_client.py:1025] - HTTP Request: GET http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 "HTTP/1.1 200 " -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:85] - API调用成功: http://192.168.11.24:8088/datasource/skill/getBySkillId/2016416951958351874 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:283] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2016419268577308673', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:53:12', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按付款人账号和交易日期查询资金日报', 'name': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'description': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 7ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016419112255598594', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:52:34', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按收款人账号和交易日期查询资金日报', 'name': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'description': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 1 行数据,执行时间: 5ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016418808822870017', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:51:22', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按交易日期查询所有账号和账户名', 'name': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'description': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'visualizable': 1, 'toolPrompt': '查询成功,返回 5 行数据,执行时间: 6ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'sqlParams': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}]} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:322] - 成功处理 3 条技能数据 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:288] - 成功获取并处理 3 条数据 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:128] - API配置: 3 条 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2016419268577308673', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'businessDescription': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016419112255598594', 'businessName': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'businessDescription': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payeeAccountNo', 'transactionDate'], 'properties': {'payeeAccountNo': {'type': 'string', 'description': '收款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016418808822870017', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'businessDescription': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'parameters': {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}] -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:165] - 成功生成 3 个 MCP 工具 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:190] - 收到工具调用请求: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:225] - 正在调用测试SQL API... -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:132] - ================================================================================ -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:133] - test_sql_with_schema 接口接收到的数据: -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:134] - 数据类型: -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:135] - 数据内容: { - "datasourceId": "37", - "businessName": "anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44", - "businessDescription": "anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细", - "sqlTemplate": "SELECT record_id AS \"记录标识号\", transaction_type AS \"交易类型\", business_type AS \"业务类型\", payer_account_no AS \"付款人账号\", payer_name AS \"付款人名称\", payee_account_no AS \"收款人账号\", payee_name AS \"收款人名称\", transaction_date AS \"交易日期\", transaction_time AS \"交易时间\", trade_currency AS \"交易货币\", trade_amount AS \"交易金额\", after_transaction_balance AS \"交易后余额\", value_date AS \"起息日期\", exchange_rate AS \"汇率\", transaction_ref_no AS \"交易流水号\", reference AS \"摘要\", purpose AS \"用途\" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date", - "parameters": { - "type": "object", - "required": [ - "payerAccountNo", - "transactionDate" - ], - "properties": { - "payerAccountNo": { - "type": "string", - "description": "付款人账号", - "examples": [ - "667866722135" - ] - }, - "transactionDate": { - "type": "string", - "description": "交易日期,格式为YYYY-MM-DD", - "examples": [ - "2026-01-26" - ] - }, - "targetDatabaseName": { - "type": "string", - "description": "目标数据库名称", - "default": "" - } - } - }, - "testParams": { - "payerAccountNo": "667866722135", - "transactionDate": "2026-01-26", - "targetDatabaseName": "" - } -} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:136] - 数据源ID: 37 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:137] - 业务名称: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:138] - 业务描述: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:139] - SQL模板: SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:140] - 参数定义: {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}, 'targetDatabaseName': {'type': 'string', 'description': '目标数据库名称', 'default': ''}}} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:141] - 测试参数: {'payerAccountNo': '667866722135', 'transactionDate': '2026-01-26', 'targetDatabaseName': ''} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:142] - ================================================================================ -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:151] - 正在调用测试SQL API: http://192.168.11.24:8088/datasource/sqlExecutionLog/testSqlWithSchema -2026-01-28 21:49:54 - httpx - INFO - [_client.py:1025] - HTTP Request: POST http://192.168.11.24:8088/datasource/sqlExecutionLog/testSqlWithSchema "HTTP/1.1 200 " -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:168] - ================================================================================ -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:169] - test_sql_with_schema 接口返回的数据: -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:170] - HTTP状态码: 200 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:171] - 响应数据类型: -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:172] - 响应数据内容: { - "msg": "操作成功", - "code": 200, - "data": { - "resultCount": 6, - "data": [ - { - "记录标识号": "2", - "交易类型": "往账", - "业务类型": "转账支出", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": "6217852000006363041", - "收款人名称": "范红霞", - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:25", - "交易货币": "CNY", - "交易金额": -787.5, - "交易后余额": 170220.05, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282055238690", - "摘要": "282055238999986690999986690", - "用途": "OBSS003756213754GIRO000000000000" - }, - { - "记录标识号": "3", - "交易类型": "往账", - "业务类型": "网上支付", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": "6212263602092911221", - "收款人名称": "吴小敏", - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:27", - "交易货币": "CNY", - "交易金额": -419.3, - "交易后余额": 169800.75, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282058995688", - "摘要": "282058995999986688999986688", - "用途": "OBSS003756219241GIRO000000000000" - }, - { - "记录标识号": "4", - "交易类型": "往账", - "业务类型": "收费", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": null, - "收款人名称": null, - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:27", - "交易货币": "CNY", - "交易金额": -4.5, - "交易后余额": 169796.25, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282058995686", - "摘要": "282058995999986686999986686", - "用途": "对公跨行转账汇款手续费" - }, - { - "记录标识号": "5", - "交易类型": "往账", - "业务类型": "网上支付", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": "7559016582106213872732048", - "收款人名称": "深圳市腾讯计算机系统有限公司", - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:27", - "交易货币": "CNY", - "交易金额": -0.14, - "交易后余额": 169796.11, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282056095685", - "摘要": "282056095999986685999986685", - "用途": "OBSS003756206850GIRO000000000000" - }, - { - "记录标识号": "6", - "交易类型": "往账", - "业务类型": "收费", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": null, - "收款人名称": null, - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:27", - "交易货币": "CNY", - "交易金额": -4.5, - "交易后余额": 169791.61, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282056095683", - "摘要": "282056095999986683999986683", - "用途": "对公跨行转账汇款手续费" - }, - { - "记录标识号": "7", - "交易类型": "往账", - "业务类型": "转账支出", - "付款人账号": "667866722135", - "付款人名称": "广东海圆圆农业科技有限公司", - "收款人账号": "6217852000006363041", - "收款人名称": "范红霞", - "交易日期": "2026-01-26T00:00:00.000+08:00", - "交易时间": "17:40:36", - "交易货币": "CNY", - "交易金额": -67.97, - "交易后余额": 169723.64, - "起息日期": "2026-01-26T00:00:00.000+08:00", - "汇率": 1, - "交易流水号": "282098067682", - "摘要": "282098067999986682999986682", - "用途": "OBSS003756216834GIRO000000000000" - } - ], - "databaseName": "fund_daily_report_db_37", - "businessDescription": "anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细", - "originalTemplate": "SELECT record_id AS \"记录标识号\", transaction_type AS \"交易类型\", business_type AS \"业务类型\", payer_account_no AS \"付款人账号\", payer_name AS \"付款人名称\", payee_account_no AS \"收款人账号\", payee_name AS \"收款人名称\", transaction_date AS \"交易日期\", transaction_time AS \"交易时间\", trade_currency AS \"交易货币\", trade_amount AS \"交易金额\", after_transaction_balance AS \"交易后余额\", value_date AS \"起息日期\", exchange_rate AS \"汇率\", transaction_ref_no AS \"交易流水号\", reference AS \"摘要\", purpose AS \"用途\" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date", - "convertedTemplate": "SELECT record_id AS \"记录标识号\", transaction_type AS \"交易类型\", business_type AS \"业务类型\", payer_account_no AS \"付款人账号\", payer_name AS \"付款人名称\", payee_account_no AS \"收款人账号\", payee_name AS \"收款人名称\", transaction_date AS \"交易日期\", transaction_time AS \"交易时间\", trade_currency AS \"交易货币\", trade_amount AS \"交易金额\", after_transaction_balance AS \"交易后余额\", value_date AS \"起息日期\", exchange_rate AS \"汇率\", transaction_ref_no AS \"交易流水号\", reference AS \"摘要\", purpose AS \"用途\" FROM funds_daily_report WHERE payer_account_no = #{payerAccountNo} AND transaction_date::date = #{transactionDate}::date", - "executionStatus": "success", - "businessName": "anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44", - "testParams": { - "payerAccountNo": "667866722135", - "transactionDate": "2026-01-26", - "targetDatabaseName": "" - }, - "errorMessage": null, - "executionTime": 7, - "datasourceId": "37", - "logId": "1497", - "executableSql": "SELECT record_id AS \"记录标识号\", transaction_type AS \"交易类型\", business_type AS \"业务类型\", payer_account_no AS \"付款人账号\", payer_name AS \"付款人名称\", payee_account_no AS \"收款人账号\", payee_name AS \"收款人名称\", transaction_date AS \"交易日期\", transaction_time AS \"交易时间\", trade_currency AS \"交易货币\", trade_amount AS \"交易金额\", after_transaction_balance AS \"交易后余额\", value_date AS \"起息日期\", exchange_rate AS \"汇率\", transaction_ref_no AS \"交易流水号\", reference AS \"摘要\", purpose AS \"用途\" FROM funds_daily_report WHERE payer_account_no = '667866722135' AND transaction_date::date = '2026-01-26'::date", - "datasourceName": "fund_daily_report_db_37" - } -} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:174] - 响应code: 200 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:175] - 响应msg: 操作成功 -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:176] - 响应data: {'resultCount': 6, 'data': [{'记录标识号': '2', '交易类型': '往账', '业务类型': '转账支出', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': '6217852000006363041', '收款人名称': '范红霞', '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:25', '交易货币': 'CNY', '交易金额': -787.5, '交易后余额': 170220.05, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282055238690', '摘要': '282055238999986690999986690', '用途': 'OBSS003756213754GIRO000000000000'}, {'记录标识号': '3', '交易类型': '往账', '业务类型': '网上支付', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': '6212263602092911221', '收款人名称': '吴小敏', '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:27', '交易货币': 'CNY', '交易金额': -419.3, '交易后余额': 169800.75, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282058995688', '摘要': '282058995999986688999986688', '用途': 'OBSS003756219241GIRO000000000000'}, {'记录标识号': '4', '交易类型': '往账', '业务类型': '收费', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': None, '收款人名称': None, '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:27', '交易货币': 'CNY', '交易金额': -4.5, '交易后余额': 169796.25, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282058995686', '摘要': '282058995999986686999986686', '用途': '对公跨行转账汇款手续费'}, {'记录标识号': '5', '交易类型': '往账', '业务类型': '网上支付', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': '7559016582106213872732048', '收款人名称': '深圳市腾讯计算机系统有限公司', '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:27', '交易货币': 'CNY', '交易金额': -0.14, '交易后余额': 169796.11, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282056095685', '摘要': '282056095999986685999986685', '用途': 'OBSS003756206850GIRO000000000000'}, {'记录标识号': '6', '交易类型': '往账', '业务类型': '收费', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': None, '收款人名称': None, '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:27', '交易货币': 'CNY', '交易金额': -4.5, '交易后余额': 169791.61, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282056095683', '摘要': '282056095999986683999986683', '用途': '对公跨行转账汇款手续费'}, {'记录标识号': '7', '交易类型': '往账', '业务类型': '转账支出', '付款人账号': '667866722135', '付款人名称': '广东海圆圆农业科技有限公司', '收款人账号': '6217852000006363041', '收款人名称': '范红霞', '交易日期': '2026-01-26T00:00:00.000+08:00', '交易时间': '17:40:36', '交易货币': 'CNY', '交易金额': -67.97, '交易后余额': 169723.64, '起息日期': '2026-01-26T00:00:00.000+08:00', '汇率': 1, '交易流水号': '282098067682', '摘要': '282098067999986682999986682', '用途': 'OBSS003756216834GIRO000000000000'}], 'databaseName': 'fund_daily_report_db_37', 'businessDescription': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'originalTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'convertedTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = #{payerAccountNo} AND transaction_date::date = #{transactionDate}::date', 'executionStatus': 'success', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'testParams': {'payerAccountNo': '667866722135', 'transactionDate': '2026-01-26', 'targetDatabaseName': ''}, 'errorMessage': None, 'executionTime': 7, 'datasourceId': '37', 'logId': '1497', 'executableSql': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = \'667866722135\' AND transaction_date::date = \'2026-01-26\'::date', 'datasourceName': 'fund_daily_report_db_37'} -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:177] - ================================================================================ -2026-01-28 21:49:54 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:179] - 测试SQL API调用成功 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:227] - 测试SQL API调用成功 -2026-01-28 21:50:18 - mcp.server.lowlevel.server - INFO - [server.py:619] - Processing request of type CallToolRequest -2026-01-28 21:50:18 - mcp_services - INFO - [main.py:190] - 收到工具调用请求: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98 -2026-01-28 21:50:18 - mcp_services - INFO - [main.py:225] - 正在调用测试SQL API... -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:132] - ================================================================================ -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:133] - test_sql_with_schema 接口接收到的数据: -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:134] - 数据类型: -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:135] - 数据内容: { - "datasourceId": "37", - "businessName": "anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98", - "businessDescription": "anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息", - "sqlTemplate": "SELECT DISTINCT payer_account_no AS \"账号\", payer_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS \"账号\", payee_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL", - "parameters": { - "type": "object", - "required": [ - "transactionDate" - ], - "properties": { - "transactionDate": { - "type": "string", - "description": "交易日期,格式为YYYY-MM-DD", - "examples": [ - "2026-01-26" - ] - }, - "targetDatabaseName": { - "type": "string", - "description": "目标数据库名称", - "default": "" - } - } - }, - "testParams": { - "transactionDate": "2026-01-02", - "targetDatabaseName": "" - } -} -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:136] - 数据源ID: 37 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:137] - 业务名称: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:138] - 业务描述: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:139] - SQL模板: SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:140] - 参数定义: {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}, 'targetDatabaseName': {'type': 'string', 'description': '目标数据库名称', 'default': ''}}} -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:141] - 测试参数: {'transactionDate': '2026-01-02', 'targetDatabaseName': ''} -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:142] - ================================================================================ -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:151] - 正在调用测试SQL API: http://192.168.11.24:8088/datasource/sqlExecutionLog/testSqlWithSchema -2026-01-28 21:50:18 - httpx - INFO - [_client.py:1025] - HTTP Request: POST http://192.168.11.24:8088/datasource/sqlExecutionLog/testSqlWithSchema "HTTP/1.1 200 " -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:168] - ================================================================================ -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:169] - test_sql_with_schema 接口返回的数据: -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:170] - HTTP状态码: 200 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:171] - 响应数据类型: -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:172] - 响应数据内容: { - "msg": "操作成功", - "code": 200, - "data": { - "resultCount": 0, - "data": [], - "databaseName": "fund_daily_report_db_37", - "businessDescription": "anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息", - "originalTemplate": "SELECT DISTINCT payer_account_no AS \"账号\", payer_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS \"账号\", payee_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL", - "convertedTemplate": "SELECT DISTINCT payer_account_no AS \"账号\", payer_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = #{transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS \"账号\", payee_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = #{transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL", - "executionStatus": "success", - "businessName": "anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98", - "testParams": { - "transactionDate": "2026-01-02", - "targetDatabaseName": "" - }, - "errorMessage": null, - "executionTime": 7, - "datasourceId": "37", - "logId": "1498", - "executableSql": "SELECT DISTINCT payer_account_no AS \"账号\", payer_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = '2026-01-02'::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS \"账号\", payee_name AS \"账户名\" FROM funds_daily_report WHERE transaction_date::date = '2026-01-02'::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL", - "datasourceName": "fund_daily_report_db_37" - } -} -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:174] - 响应code: 200 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:175] - 响应msg: 操作成功 -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:176] - 响应data: {'resultCount': 0, 'data': [], 'databaseName': 'fund_daily_report_db_37', 'businessDescription': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'originalTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'convertedTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = #{transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = #{transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'executionStatus': 'success', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'testParams': {'transactionDate': '2026-01-02', 'targetDatabaseName': ''}, 'errorMessage': None, 'executionTime': 7, 'datasourceId': '37', 'logId': '1498', 'executableSql': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = \'2026-01-02\'::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = \'2026-01-02\'::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'datasourceName': 'fund_daily_report_db_37'} -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:177] - ================================================================================ -2026-01-28 21:50:18 - lzwcai_mcp_sqlexecutor.utils.api_client - INFO - [api_client.py:179] - 测试SQL API调用成功 -2026-01-28 21:50:18 - mcp_services - INFO - [main.py:227] - 测试SQL API调用成功 diff --git a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_error.log b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_error.log index 7858e72..6e209b0 100644 --- a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_error.log +++ b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/lzwcai_mcp_sqlexecutor_error.log @@ -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 diff --git a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/mcp_services.log b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/mcp_services.log index f8d7923..29d95f7 100644 --- a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/mcp_services.log +++ b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/logs/mcp_services.log @@ -1,188 +1,77 @@ -2025-10-23 15:05:51 - mcp_services - INFO - [main.py:341] - 开始运行 MCP SQL Executor 服务器 -2025-10-23 15:05:51 - mcp_services - INFO - [main.py:293] - ============================================================ -2025-10-23 15:05:51 - mcp_services - INFO - [main.py:294] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2025-10-23 15:05:51 - mcp_services - INFO - [main.py:295] - 版本: 0.1.0 -2025-10-23 15:05:51 - mcp_services - INFO - [main.py:296] - ============================================================ -2025-10-23 15:05:51 - mcp_services - INFO - [main.py:300] - 环境配置 - Database ID: 29 -2025-10-23 15:05:51 - mcp_services - INFO - [main.py:301] - 环境配置 - Skill ID: 1981195682443014146 -2025-10-23 15:05:51 - mcp_services - INFO - [main.py:302] - 环境配置 - Backend Base URL: http://192.168.2.236:8088 -2025-10-23 15:05:51 - mcp_services - INFO - [main.py:303] - ============================================================ -2025-10-23 15:05:51 - mcp_services - INFO - [main.py:308] - MCP 服务器已启动,等待客户端连接... -2025-10-23 15:05:52 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2025-10-23 15:05:52 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2025-10-23 15:05:52 - mcp_services - INFO - [main.py:272] - 调用第三方API,skill_id: 1981195682443014146 -2025-10-23 15:05:52 - mcp_services - INFO - [main.py:277] - 成功{'msg': '查询失败: 技能不存在: 1981195682443014146', 'code': 500} -2025-10-23 15:05:52 - mcp_services - INFO - [main.py:282] - 成功获取并处理 0 条数据 -2025-10-23 15:05:52 - mcp_services - INFO - [main.py:128] - API配置: 0 条 -2025-10-23 15:05:52 - mcp_services - INFO - [main.py:129] - API配置数组: [] -2025-10-23 15:05:52 - mcp_services - INFO - [main.py:165] - 成功生成 0 个 MCP 工具 -2025-10-23 15:08:30 - mcp_services - INFO - [main.py:341] - 开始运行 MCP SQL Executor 服务器 -2025-10-23 15:08:30 - mcp_services - INFO - [main.py:293] - ============================================================ -2025-10-23 15:08:30 - mcp_services - INFO - [main.py:294] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2025-10-23 15:08:30 - mcp_services - INFO - [main.py:295] - 版本: 0.1.0 -2025-10-23 15:08:30 - mcp_services - INFO - [main.py:296] - ============================================================ -2025-10-23 15:08:30 - mcp_services - INFO - [main.py:300] - 环境配置 - Database ID: 29 -2025-10-23 15:08:30 - mcp_services - INFO - [main.py:301] - 环境配置 - Skill ID: 1981245768471322626 -2025-10-23 15:08:30 - mcp_services - INFO - [main.py:302] - 环境配置 - Backend Base URL: http://192.168.2.236:8088 -2025-10-23 15:08:30 - mcp_services - INFO - [main.py:303] - ============================================================ -2025-10-23 15:08:30 - mcp_services - INFO - [main.py:308] - MCP 服务器已启动,等待客户端连接... -2025-10-23 15:08:31 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2025-10-23 15:08:31 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2025-10-23 15:08:31 - mcp_services - INFO - [main.py:272] - 调用第三方API,skill_id: 1981245768471322626 -2025-10-23 15:08:31 - mcp_services - INFO - [main.py:277] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '1981245768769118209', 'createBy': 'yy8z6', 'createTime': '2025-10-23 14:26:16', 'updateBy': None, 'updateTime': None, 'serviceId': '1981245768475516930', 'uniqueName': '数字员工技能描述-SQL服务_数字员工列表查询', 'name': '数字员工列表查询', 'description': '查询系统中的所有数字员工信息,包括员工ID、名称、类型、状态等核心信息,用于展示数字员工管理列表', 'visualizable': 1, 'toolPrompt': '查询数字员工列表', 'toolType': 'sql', 'datasourceId': '32', 'sqlTemplate': 'SELECT id, employee_id, name, employee_type, status, created_at, updated_at, description FROM digital_employees WHERE is_deleted = 0 ORDER BY created_at DESC', 'sqlParams': '{"type":"object","required":[],"properties":{}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '889,890,891,892,893,894,895,896', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}]} -2025-10-23 15:08:31 - mcp_services - INFO - [main.py:282] - 成功获取并处理 1 条数据 -2025-10-23 15:08:31 - mcp_services - INFO - [main.py:128] - API配置: 1 条 -2025-10-23 15:08:31 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '1981245768769118209', 'businessName': '数字员工列表查询', 'businessDescription': '查询系统中的所有数字员工信息,包括员工ID、名称、类型、状态等核心信息,用于展示数字员工管理列表', 'sqlTemplate': 'SELECT id, employee_id, name, employee_type, status, created_at, updated_at, description FROM digital_employees WHERE is_deleted = 0 ORDER BY created_at DESC', 'parameters': {'type': 'object', 'required': ['employeeId'], 'properties': {'employeeId': {'type': 'number', 'description': '员工ID,用于标识员工的唯一数字标识符', 'examples': [1001, 2002]}}}, 'datasourceId': '32'}] -2025-10-23 15:08:31 - mcp_services - INFO - [main.py:165] - 成功生成 1 个 MCP 工具 -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_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] - 调用第三方API,skill_id: -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_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 - 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_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_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 - 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_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] - 调用第三方API,skill_id: -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: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_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] - 调用第三方API,skill_id: 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 - 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_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 - mcp_services - INFO - [main.py:232] - 测试SQL API调用成功 +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_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] - 调用第三方 API,skill_id: 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 - 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 - 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_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] - 调用第三方 API,skill_id: +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 @@ -192,9 +81,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( ^^^^^^^^^^^^^ @@ -215,7 +104,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 @@ -225,96 +113,37 @@ 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 -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_services - INFO - [main.py:156] - 收到列出工具请求 -2025-12-31 15:00:56 - mcp_services - INFO - [main.py:165] - 成功生成 0 个 MCP 工具 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:299] - ============================================================ -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:302] - ============================================================ -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 37 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID: 2016416951958351874 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088 -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:309] - ============================================================ -2026-01-28 16:37:23 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接... -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:278] - 调用第三方API,skill_id: 2016416951958351874 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:283] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2016419268577308673', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:53:12', 'updateBy': None, 'updateTime': None, 'serviceId': '2016416951970934785', 'uniqueName': '按付款人账号和交易日期查询资金日报', 'name': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'description': '根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 7ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}, {'id': '2016419112255598594', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:52:34', 'updateBy': None, 'updateTime': None, 'serviceId': '2016416951970934785', 'uniqueName': '按收款人账号和交易日期查询资金日报', 'name': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'description': '根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 1 行数据,执行时间: 5ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}, {'id': '2016418808822870017', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:51:22', 'updateBy': None, 'updateTime': None, 'serviceId': '2016416951970934785', 'uniqueName': '按交易日期查询所有账号和账户名', 'name': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'description': '根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'visualizable': 1, 'toolPrompt': '查询成功,返回 5 行数据,执行时间: 6ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'sqlParams': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{}', 'outputJsonSchema': '{"type":"object","properties":{"data":{"type":"array"}}}', 'lastExecutionTime': None}]} -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:288] - 成功获取并处理 3 条数据 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:128] - API配置: 3 条 -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2016419268577308673', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'businessDescription': '根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016419112255598594', 'businessName': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'businessDescription': '根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payeeAccountNo', 'transactionDate'], 'properties': {'payeeAccountNo': {'type': 'string', 'description': '收款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016418808822870017', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'businessDescription': '根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'parameters': {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}] -2026-01-28 16:37:24 - mcp_services - INFO - [main.py:165] - 成功生成 3 个 MCP 工具 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:299] - ============================================================ -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:302] - ============================================================ -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 37 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID: 2016416951958351874 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088 -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:309] - ============================================================ -2026-01-28 21:35:19 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接... -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:278] - 调用第三方API,skill_id: 2016416951958351874 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:283] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2016419268577308673', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:53:12', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按付款人账号和交易日期查询资金日报', 'name': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'description': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 7ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016419112255598594', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:52:34', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按收款人账号和交易日期查询资金日报', 'name': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'description': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 1 行数据,执行时间: 5ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016418808822870017', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:51:22', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按交易日期查询所有账号和账户名', 'name': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'description': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'visualizable': 1, 'toolPrompt': '查询成功,返回 5 行数据,执行时间: 6ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'sqlParams': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}]} -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:288] - 成功获取并处理 3 条数据 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:128] - API配置: 3 条 -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2016419268577308673', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'businessDescription': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016419112255598594', 'businessName': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'businessDescription': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payeeAccountNo', 'transactionDate'], 'properties': {'payeeAccountNo': {'type': 'string', 'description': '收款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016418808822870017', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'businessDescription': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'parameters': {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}] -2026-01-28 21:35:20 - mcp_services - INFO - [main.py:165] - 成功生成 3 个 MCP 工具 -2026-01-28 21:36:46 - mcp_services - INFO - [main.py:329] - MCP 服务器已关闭 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:347] - 开始运行 MCP SQL Executor 服务器 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:299] - ============================================================ -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:300] - 正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:301] - 版本: 0.1.0 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:302] - ============================================================ -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:306] - 环境配置 - Database ID: 37 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:307] - 环境配置 - Skill ID: 2016416951958351874 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:308] - 环境配置 - Backend Base URL: http://192.168.11.24:8088 -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:309] - ============================================================ -2026-01-28 21:44:42 - mcp_services - INFO - [main.py:314] - MCP 服务器已启动,等待客户端连接... -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:156] - 收到列出工具请求 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:119] - 初始化查询配置(数据源: api)... -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:278] - 调用第三方API,skill_id: 2016416951958351874 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:283] - 成功{'msg': '查询成功', 'code': 200, 'data': [{'id': '2016419268577308673', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:53:12', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按付款人账号和交易日期查询资金日报', 'name': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'description': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 6 行数据,执行时间: 7ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payerAccountNo","transactionDate"],"properties":{"payerAccountNo":{"type":"string","description":"付款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016419112255598594', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:52:34', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按收款人账号和交易日期查询资金日报', 'name': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'description': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'visualizable': 1, 'toolPrompt': '查询成功,返回 1 行数据,执行时间: 5ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'sqlParams': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["payeeAccountNo","transactionDate"],"properties":{"payeeAccountNo":{"type":"string","description":"收款人账号","examples":["667866722135"]},"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}, {'id': '2016418808822870017', 'createBy': 'heshuangfeng', 'createTime': '2026-01-28 15:51:22', 'updateBy': 'yy8z7', 'updateTime': '2026-01-28 20:53:14', 'serviceId': '2016416951970934785', 'uniqueName': '按交易日期查询所有账号和账户名', 'name': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'description': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'visualizable': 1, 'toolPrompt': '查询成功,返回 5 行数据,执行时间: 6ms', 'toolType': 'sql', 'datasourceId': '37', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'sqlParams': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]}}}', 'resultType': 'list', 'sourceType': 'ai', 'trainingTaskId': None, 'tableMetadataIds': '', 'executionCount': 0, 'visualizationConfigs': None, 'inputJsonSchema': '{"type":"object","required":["transactionDate"],"properties":{"transactionDate":{"type":"string","description":"交易日期,格式为YYYY-MM-DD","examples":["2026-01-26"]},"targetDatabaseName":{"type":"string","description":"目标数据库名称"}}}', 'outputJsonSchema': '{"type":"object","properties":{"text":{"type":"string"}},"additionalProperties":false}', 'lastExecutionTime': None}]} -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:288] - 成功获取并处理 3 条数据 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:128] - API配置: 3 条 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:129] - API配置数组: [{'id': '2016419268577308673', 'businessName': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44', 'businessDescription': 'anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44: 根据指定的付款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payer_account_no = {payerAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payerAccountNo', 'transactionDate'], 'properties': {'payerAccountNo': {'type': 'string', 'description': '付款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016419112255598594', 'businessName': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7', 'businessDescription': 'anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: anshoukuanrenzhanghaohejiaoyiriqichaxunzijinribao_1af995f7: 根据指定的收款人账号和交易日期查询资金日报表中的详细交易记录,包括交易类型、金额、双方信息等完整交易明细', 'sqlTemplate': 'SELECT record_id AS "记录标识号", transaction_type AS "交易类型", business_type AS "业务类型", payer_account_no AS "付款人账号", payer_name AS "付款人名称", payee_account_no AS "收款人账号", payee_name AS "收款人名称", transaction_date AS "交易日期", transaction_time AS "交易时间", trade_currency AS "交易货币", trade_amount AS "交易金额", after_transaction_balance AS "交易后余额", value_date AS "起息日期", exchange_rate AS "汇率", transaction_ref_no AS "交易流水号", reference AS "摘要", purpose AS "用途" FROM funds_daily_report WHERE payee_account_no = {payeeAccountNo} AND transaction_date::date = {transactionDate}::date', 'parameters': {'type': 'object', 'required': ['payeeAccountNo', 'transactionDate'], 'properties': {'payeeAccountNo': {'type': 'string', 'description': '收款人账号', 'examples': ['667866722135']}, 'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}, {'id': '2016418808822870017', 'businessName': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98', 'businessDescription': 'anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98: 根据指定的交易日期,从资金日报表中去重查询所有付款人和收款人的账号及对应的账户名,用于了解特定日期涉及的银行账户信息', 'sqlTemplate': 'SELECT DISTINCT payer_account_no AS "账号", payer_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payer_account_no IS NOT NULL AND payer_name IS NOT NULL UNION SELECT DISTINCT payee_account_no AS "账号", payee_name AS "账户名" FROM funds_daily_report WHERE transaction_date::date = {transactionDate}::date AND payee_account_no IS NOT NULL AND payee_name IS NOT NULL', 'parameters': {'type': 'object', 'required': ['transactionDate'], 'properties': {'transactionDate': {'type': 'string', 'description': '交易日期,格式为YYYY-MM-DD', 'examples': ['2026-01-26']}}}, 'datasourceId': '37'}] -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:165] - 成功生成 3 个 MCP 工具 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:190] - 收到工具调用请求: anfukuanrenzhanghaohejiaoyiriqichaxunzijinribao_b38c6d44 -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:225] - 正在调用测试SQL API... -2026-01-28 21:49:54 - mcp_services - INFO - [main.py:227] - 测试SQL API调用成功 -2026-01-28 21:50:18 - mcp_services - INFO - [main.py:190] - 收到工具调用请求: anjiaoyiriqichaxunsuoyouzhanghaohezhanghuming_0bf10c98 -2026-01-28 21:50:18 - mcp_services - INFO - [main.py:225] - 正在调用测试SQL API... -2026-01-28 21:50:18 - mcp_services - INFO - [main.py:227] - 测试SQL API调用成功 -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_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] - 调用第三方API,skill_id: 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 - 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 工具 +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_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_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 - 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_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] - 调用第三方 API,skill_id: 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 - 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 工具 diff --git a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/main.py b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/main.py index 32c4b7c..05e84e7 100644 --- a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/main.py +++ b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/main.py @@ -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"调用第三方API,skill_id: {skill_id}") - - # 获取原始数据 - raw_result = get_skill_by_id(skill_id) - mcp_logger.info(f"成功{raw_result}") - - # 处理并返回 + mcp_logger.info(f"调用第三方 API,skill_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 diff --git a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/utils/api_client.py b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/utils/api_client.py index 51a31df..fd0bc89 100644 --- a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/utils/api_client.py +++ b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/utils/api_client.py @@ -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 - diff --git a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/utils/schema_helper.py b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/utils/schema_helper.py index 25670ee..01f4bd4 100644 --- a/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/utils/schema_helper.py +++ b/lzwcai_mcp_sqlexecutor/lzwcai_mcp_sqlexecutor/utils/schema_helper.py @@ -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 验证通过" diff --git a/lzwcai_mcp_sqlexecutor/main.py b/lzwcai_mcp_sqlexecutor/main.py index 596993f..580155c 100644 --- a/lzwcai_mcp_sqlexecutor/main.py +++ b/lzwcai_mcp_sqlexecutor/main.py @@ -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() diff --git a/lzwcai_mcp_sqlexecutor/pyproject.toml b/lzwcai_mcp_sqlexecutor/pyproject.toml index ef0b905..d95f3ff 100644 --- a/lzwcai_mcp_sqlexecutor/pyproject.toml +++ b/lzwcai_mcp_sqlexecutor/pyproject.toml @@ -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" diff --git a/lzwcai_workflow_to_mcp/lzwcai_workflow_to_mcp/utils/api_client.py b/lzwcai_workflow_to_mcp/lzwcai_workflow_to_mcp/utils/api_client.py index cedb2a2..14e39d8 100644 --- a/lzwcai_workflow_to_mcp/lzwcai_workflow_to_mcp/utils/api_client.py +++ b/lzwcai_workflow_to_mcp/lzwcai_workflow_to_mcp/utils/api_client.py @@ -24,7 +24,7 @@ WORKFLOW_EXECUTE_TIMEOUT = 600.0 # 工作流执行超时(10分钟,参考 wo # 异步轮询默认配置(参考 workflow-execution-api.md) DEFAULT_POLLING_INTERVAL = 1.0 -DEFAULT_MAX_POLL_COUNT = 120 +DEFAULT_MAX_POLL_COUNT = 800 DEFAULT_MAX_ERROR_COUNT = 3 diff --git a/lzwcai_workflow_to_mcp/pyproject.toml b/lzwcai_workflow_to_mcp/pyproject.toml index c80313b..8389973 100644 --- a/lzwcai_workflow_to_mcp/pyproject.toml +++ b/lzwcai_workflow_to_mcp/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "lzwcai-workflow-to-mcp" -version = "0.1.8" +version = "0.1.9" description = "MCP server for executing business SQL queries with dynamic tool generation" readme = "README.md" requires-python = ">=3.10"