Skip to main content
Glama
aliyun

Alibaba Cloud DMS MCP Server

Official
by aliyun

executeScript

Destructive

Execute SQL scripts against Alibaba Cloud DMS databases and return structured results. Provide database ID and SQL script, with optional logical execution mode.

Instructions

Execute SQL script against a database in DMS and return structured results.If you don't know the databaseId, first use getDatabase or searchDatabase to retrieve it. (1) If you have the exact host, port, and database name, use getDatabase. (2) If you only know the database name, use searchDatabase. (3) If you don't know any information, ask the user to provide the necessary details. Note: searchDatabase may return multiple databases. In this case, let the user choose which one to use.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
database_idYesRequired DMS databaseId. Obtained via getDatabase tool
scriptYesSQL script to execute
logicNoWhether to use logical execution mode

Implementation Reference

  • Core handler function `execute_script` that executes SQL scripts via the DMS client. Takes database_id, script, and logic parameters, calls the Aliyun DMS API, processes results into ExecuteScriptResult with Markdown table formatting using the _format_as_markdown_table helper.
    async def execute_script(
            database_id: str = Field(description="DMS databaseId"),
            script: str = Field(description="SQL script to execute"),
            logic: bool = Field(default=False, description="Whether to use logical execution mode")
    ) -> ExecuteScriptResult:  # Return the object, __str__ will be used by wrapper if needed
        client = create_client()
        req = dms_enterprise_20181101_models.ExecuteScriptRequest(db_id=database_id, script=script, logic=logic)
        if mcp.state.real_login_uid:
            req.real_login_user_uid = mcp.state.real_login_uid
        try:
            resp = client.execute_script(req)
            if not resp or not resp.body:
                return ExecuteScriptResult(RequestId="", Results=[], Success=False)
            data = resp.body.to_map()
            processed_results = []
            if data.get('Success') and data.get('Results'):
                for res_item in data.get('Results', []):
                    if res_item.get('Success'):
                        column_names = res_item.get('ColumnNames', [])
                        rows_data = res_item.get('Rows', [])
                        markdown_table = _format_as_markdown_table(column_names, rows_data)
                        processed_results.append(
                            ResultSet(ColumnNames=column_names, RowCount=res_item.get('RowCount', 0), Rows=rows_data,
                                      MarkdownTable=markdown_table, Success=True, Message=''))
                    else:
                        processed_results.append(
                            ResultSet(ColumnNames=[], RowCount=0, Rows=[], MarkdownTable=None, Success=False,
                                      Message=res_item.get('Message')))
            return ExecuteScriptResult(RequestId=data.get('RequestId', ""), Results=processed_results,
                                       Success=data.get('Success', False))
        except Exception as e:
            logger.error(f"Error in execute_script: {e}")
            if "The instance is not in secure hosting mode" in str(e):
                return "当前实例尚未开启安全托管功能。您可以通过DMS控制台免费开启「安全托管模式」。请注意,该操作需要管理员或DBA身份权限。"
  • ExecuteScriptResult pydantic model - the return type schema for execute_script. Contains RequestId, Results (list of ResultSet), and Success fields, with a __str__ method for markdown rendering.
    class ExecuteScriptResult(MyBaseModel):
        RequestId: str = Field(description="Unique request identifier")
        Results: List[ResultSet] = Field(description="List of result sets from executed script")
        Success: bool = Field(description="Overall operation success status")
    
        def __str__(self) -> str:
            if self.Success and self.Results:
                first_result = self.Results[0]
                if first_result.Success and first_result.MarkdownTable:
                    return first_result.MarkdownTable
                elif not first_result.Success:
                    return first_result.Message
                else:
                    return "Result data is not available in Markdown format."
            elif not self.Success:
                return "Script execution failed."
            else:
                return "Script executed successfully, but no results were returned."
  • ResultSet pydantic model - schema for individual result sets within ExecuteScriptResult. Contains ColumnNames, RowCount, Rows, MarkdownTable, Success, and Message fields.
    class ResultSet(MyBaseModel):
        ColumnNames: List[str] = Field(description="Ordered list of column names")
        RowCount: int = Field(description="Number of rows returned")
        Rows: List[Dict[str, Any]] = Field(description="List of rows, where each row is a dictionary of column_name: value")
        MarkdownTable: Optional[str] = Field(default=None, description="Data formatted as a Markdown table string")
        Success: bool = Field(description="Whether this result set was successfully retrieved")
        Message: str = Field(description="Additional message returned")
  • Registration of the executeScript tool in the full toolset (via _register_full_toolset). Wraps the core execute_script with database_id, script, and logic parameters.
    @self.mcp.tool(name="executeScript",
                   description=f"Execute SQL script against a database in DMS and return structured results."
                               f"{DATABASE_ID_DESCRIPTION}",
                   annotations={"title": "在DMS中执行SQL脚本", "readOnlyHint": False, "destructiveHint": True})
    async def execute_script_full_wrapper(
            database_id: str = Field(description="Required DMS databaseId. Obtained via getDatabase tool"),
            script: str = Field(description="SQL script to execute"),
            logic: bool = Field(description="Whether to use logical execution mode", default=False)
    ) -> str:  # Return string representation
        result_obj = await execute_script(database_id=database_id, script=script, logic=logic)
        return str(result_obj)
  • Registration of the executeScript tool in the pre-configured DB toolset (via _register_configured_db_toolset). Wraps the core execute_script using the default_database_id, exposing only script parameter.
    @self.mcp.tool(name="executeScript",
                   description="Executes an SQL script against the pre-configured database.",
                   annotations={"title": "Execute SQL (Pre-configured DB)", "readOnlyHint": False,
                                "destructiveHint": True})
    async def execute_script_configured(
            script: str = Field(description="SQL script to execute")
    ) -> str:
        result_obj = await execute_script(database_id=self.default_database_id, script=script, logic=False)
        return str(result_obj)
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructiveHint=true, so the description's lack of additional safety warnings is acceptable. However, it does not mention potential long execution time or error behavior, relying on the structured results claim.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the purpose, followed by clear numbered steps. Minor redundancy but overall well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description's vague 'structured results' leaves some ambiguity. Also lacks details on error handling or performance implications, but the step-by-step ID retrieval helps compensate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage for all parameters. The description adds value by explaining how to obtain the database_id via other tools, supplementing the schema's description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool executes a SQL script against a database and returns structured results, distinguishing it from sibling tools like getDatabase and searchDatabase which retrieve database IDs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit step-by-step guidance on obtaining the databaseId using getDatabase or searchDatabase, including handling multiple search results and asking the user for missing info.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aliyun/alibabacloud-dms-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server