Skip to content

Commit bef6349

Browse files
authored
Merge pull request #17 from yanbeipang/yinuo/mcp_server
Add Data Change Order Tools
2 parents 666a5e2 + 5de2499 commit bef6349

File tree

4 files changed

+108
-5
lines changed

4 files changed

+108
-5
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
## Core Features
1313
**Secure Access**
1414
- **Account and Password Security Management**:Safely manage database account passwords without manual maintenance, effectively preventing sensitive information leakage.
15+
- **Intranet Access Support**:Enables database access through an internal network, keeping data within the premises and significantly enhancing data security and privacy protection.
1516
- **Fine-grained Permission Control**:Supports instance, database, table, field, and row-level access control, precisely restricting caller permissions to prevent unauthorized operations and ensure data security.
1617
- **High-risk SQL Identification and Blocking**: Built-in rich rule engine that identifies and blocks potential high-risk SQL in real time to mitigate security risks.
1718
- **SQL Audit Trail**: Records all SQL operation logs, supporting full traceability and compliance audits to meet regulatory requirements.

doc/README-zh-cn.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
## 核心特性
1212
**安全访问**
1313
- **账号密码安全托管**:安全管理数据库账号密码,无需人工维护,有效防止敏感信息泄露。
14+
- **支持内网访问**:提供内网访问数据库能力,数据不出域,有效保障数据安全与隐私。
1415
- **细粒度权限管控**:支持实例、库、表、字段及行级别的精细化访问控制,精准限制调用方权限,杜绝越权操作,保障数据安全。
1516
- **高危SQL识别与拦截**:内置丰富的规则引擎,实时识别并拦截潜在高危SQL,防范安全风险。
1617
- **SQL审计追踪**:记录所有SQL操作日志,支持完整追溯与合规审计,满足监管要求。

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "alibabacloud-dms-mcp-server"
3-
version = "0.1.9"
3+
version = "0.1.10"
44
description = "MCP Server for AlibabaCloud DMS"
55
readme = "README.md"
66
authors = [

src/alibabacloud_dms_mcp_server/server.py

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ async def get_database(
287287
) -> DatabaseDetail:
288288
client = create_client()
289289
req = dms_enterprise_20181101_models.GetDatabaseRequest(host=host, port=port, schema_name=schema_name)
290-
if sid: req.sid = sid
290+
if sid:
291+
req.sid = sid
291292
try:
292293
resp = client.get_database(req)
293294
db_data = resp.body.to_map().get('Database', {}) if resp and resp.body else {}
@@ -377,6 +378,67 @@ async def execute_script(
377378
return "当前实例尚未开启安全托管功能。您可以通过DMS控制台免费开启「安全托管模式」。请注意,该操作需要管理员或DBA身份权限。"
378379

379380

381+
async def create_data_change_order(
382+
database_id: str = Field(description="DMS databaseId"),
383+
script: str = Field(description="SQL script to execute"),
384+
logic: bool = Field(default=False, description="Whether to use logical execution mode")
385+
) -> Dict[str, Any]:
386+
387+
client = create_client()
388+
req = dms_enterprise_20181101_models.CreateDataCorrectOrderRequest()
389+
req.comment = "Data correct order submitted by MCP"
390+
391+
param = dms_enterprise_20181101_models.CreateDataCorrectOrderRequestParam()
392+
param.estimate_affect_rows = 1
393+
param.sql_type = "TEXT"
394+
param.exec_sql = script
395+
param.classify = "MCP"
396+
397+
db_list = dms_enterprise_20181101_models.CreateDataCorrectOrderRequestParamDbItemList()
398+
db_list.db_id = database_id
399+
db_list.logic = logic
400+
401+
db_items = [db_list]
402+
param.db_item_list = db_items
403+
404+
req.param = param
405+
try:
406+
resp = client.create_data_correct_order(req)
407+
return resp.body
408+
except Exception as e:
409+
logger.error(f"Error in create_data_change_order: {e}")
410+
raise
411+
412+
413+
async def get_order_base_info(
414+
order_id: str = Field(description="DMS order ID")
415+
) -> Dict[str, Any]:
416+
417+
client = create_client()
418+
req = dms_enterprise_20181101_models.GetOrderBaseInfoRequest()
419+
req.order_id = order_id
420+
try:
421+
resp = client.get_order_base_info(req)
422+
return resp.body
423+
except Exception as e:
424+
logger.error(f"Error in get_order_base_info: {e}")
425+
raise
426+
427+
428+
async def submit_order_approval(
429+
order_id: str = Field(description="DMS order ID")
430+
) -> Dict[str, Any]:
431+
432+
client = create_client()
433+
req = dms_enterprise_20181101_models.SubmitOrderApprovalRequest()
434+
req.order_id = order_id
435+
try:
436+
resp = client.submit_order_approval(req)
437+
return resp.body
438+
except Exception as e:
439+
logger.error(f"Error in submit_order_approval: {e}")
440+
raise
441+
380442
async def nl2sql(
381443
database_id: str = Field(description="DMS databaseId"),
382444
question: str = Field(description="Natural language question"),
@@ -566,12 +628,28 @@ async def list_tables_configured(
566628
annotations={"title": "Execute SQL (Pre-configured DB)", "readOnlyHint": False,
567629
"destructiveHint": True})
568630
async def execute_script_configured(
569-
script: str = Field(description="SQL script to execute"),
570-
logic: bool = Field(description="Whether to use logical execution mode", default=False)
631+
script: str = Field(description="SQL script to execute")
571632
) -> str:
572-
result_obj = await execute_script(database_id=self.default_database_id, script=script, logic=logic)
633+
result_obj = await execute_script(database_id=self.default_database_id, script=script, logic=False)
573634
return str(result_obj)
574635

636+
@self.mcp.tool(name="createDataChangeOrder",
637+
description="Execute SQL changes through a data change order, and a corresponding order ID will be returned. "
638+
"Prefer using the executeScript tool for SQL execution; "
639+
"only use this tool when explicitly instructed to perform the operation via a order.",
640+
annotations={"title": "在DMS中创建数据变更工单", "readOnlyHint": False, "destructiveHint": True})
641+
async def create_data_change_order_configured(
642+
script: str = Field(description="SQL script to execute")
643+
) -> str:
644+
result_obj = await create_data_change_order(database_id=self.default_database_id, script=script, logic=False)
645+
return str(result_obj)
646+
647+
self.mcp.tool(name="getOrderInfo", description="Retrieve order information from DMS using the order ID.",
648+
annotations={"title": "获取DMS工单详情", "readOnlyHint": True})(get_order_base_info)
649+
650+
self.mcp.tool(name="submitOrderApproval", description="Submit the order for approval in DMS using the order ID.",
651+
annotations={"title": "提交工单审批", "readOnlyHint": False})(submit_order_approval)
652+
575653
@self.mcp.tool(name="askDatabase",
576654
description="Ask a question in natural language to the pre-configured database and get results directly.",
577655
annotations={"title": "Ask Pre-configured Database", "readOnlyHint": True})
@@ -655,6 +733,29 @@ async def execute_script_full_wrapper(
655733
result_obj = await execute_script(database_id=database_id, script=script, logic=logic)
656734
return str(result_obj)
657735

736+
@self.mcp.tool(name="createDataChangeOrder",
737+
description="Execute SQL changes through a data change order, and a corresponding order ID will be returned. "
738+
"Prefer using the executeScript tool for SQL execution; only use this tool when explicitly instructed to perform the operation via a order."
739+
"If you don't know the databaseId, first use getDatabase or searchDatabase to retrieve it."
740+
"(1)If you have the exact host, port, and database name, use getDatabase."
741+
"(2)If you only know the database name, use searchDatabase."
742+
"(3)If you don't know any information, ask the user to provide the necessary details."
743+
"Note: searchDatabase may return multiple databases. In this case, let the user choose which one to use.",
744+
annotations={"title": "在DMS中创建数据变更工单", "readOnlyHint": False, "destructiveHint": True})
745+
async def create_data_change_order_wrapper(
746+
database_id: str = Field(description="Required DMS databaseId. Obtained via getDatabase tool"),
747+
script: str = Field(description="SQL script to execute"),
748+
logic: bool = Field(description="Whether to use logical execution mode", default=False)
749+
) -> str: # Return string representation
750+
result_obj = await create_data_change_order(database_id=database_id, script=script, logic=logic)
751+
return str(result_obj)
752+
753+
self.mcp.tool(name="getOrderInfo", description="Retrieve order information from DMS using the order ID.",
754+
annotations={"title": "获取DMS工单详情", "readOnlyHint": True})(get_order_base_info)
755+
756+
self.mcp.tool(name="submitOrderApproval", description="Submit the order for approval in DMS using the order ID.",
757+
annotations={"title": "提交工单审批", "readOnlyHint": False})(submit_order_approval)
758+
658759
self.mcp.tool(name="generateSql", description="Generate SELECT-type SQL queries from natural language input.",
659760
annotations={"title": "自然语言转SQL (DMS)", "readOnlyHint": True})(nl2sql)
660761

0 commit comments

Comments
 (0)