2025-05-06 12:56:55 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Tool Initialization Module
Centralized initialization of all tools , ensuring they are correctly registered with MCP
"""
import logging
import os
from typing import List , Dict , Any , Optional
import json
from datetime import datetime
import traceback
# Import Context
from mcp . server . fastmcp import Context
# Import doris mcp tools
from doris_mcp_server . tools . mcp_doris_tools import (
mcp_doris_exec_query ,
mcp_doris_get_table_schema ,
mcp_doris_get_db_table_list ,
mcp_doris_get_db_list ,
mcp_doris_get_table_comment ,
mcp_doris_get_table_column_comments ,
mcp_doris_get_table_indexes ,
2025-06-06 14:35:53 +08:00
mcp_doris_get_recent_audit_logs ,
mcp_doris_get_catalog_list
2025-05-06 12:56:55 +08:00
)
# Get logger
logger = logging . getLogger ( " doris-mcp-tools-initializer " )
async def register_mcp_tools ( mcp ) :
""" Register MCP tool functions
Args :
mcp : FastMCP instance
"""
logger . info ( " Starting to register MCP tools... " )
try :
# Register Tool: Execute SQL Query (Using long description string including parameters)
2025-06-06 14:35:53 +08:00
@mcp.tool ( " exec_query " , description = """ [Function Description]: Execute SQL query and return result command with catalog federation support. \n
2025-05-06 12:56:55 +08:00
[ Parameter Content ] : \n
- random_string ( string ) [ Required ] - Unique identifier for the tool call \n
2025-06-06 14:35:53 +08:00
- sql ( string ) [ Required ] - SQL statement to execute . MUST use three - part naming for all table references : ' catalog_name.db_name.table_name ' . For internal tables use ' internal.db_name.table_name ' , for external tables use ' catalog_name.db_name.table_name ' \n
2025-05-06 12:56:55 +08:00
- db_name ( string ) [ Optional ] - Target database name , defaults to the current database \n
2025-06-06 14:35:53 +08:00
- catalog_name ( string ) [ Optional ] - Reference catalog name for context , defaults to current catalog \n
2025-05-06 12:56:55 +08:00
- max_rows ( integer ) [ Optional ] - Maximum number of rows to return , default 100
- timeout ( integer ) [ Optional ] - Query timeout in seconds , default 30 """ )
2025-06-06 14:35:53 +08:00
async def exec_query_tool ( sql : str , db_name : str = None , catalog_name : str = None , max_rows : int = 100 , timeout : int = 30 ) - > Dict [ str , Any ] :
2025-05-06 12:56:55 +08:00
""" Wrapper: Execute SQL query and return result command """
# Note: ctx parameter is no longer needed here as we receive named parameters directly
2025-06-06 14:35:53 +08:00
return await mcp_doris_exec_query ( sql = sql , db_name = db_name , catalog_name = catalog_name , max_rows = max_rows , timeout = timeout )
2025-05-06 12:56:55 +08:00
# Register Tool: Get Table Schema (Keep long description string including parameters)
@mcp.tool ( " get_table_schema " , description = """ [Function Description]: Get detailed structure information of the specified table (columns, types, comments, etc.). \n
[ Parameter Content ] : \n
- random_string ( string ) [ Required ] - Unique identifier for the tool call \n
- table_name ( string ) [ Required ] - Name of the table to query \n
2025-06-06 14:35:53 +08:00
- db_name ( string ) [ Optional ] - Target database name , defaults to the current database \n
- catalog_name ( string ) [ Optional ] - Target catalog name for federation queries , defaults to current catalog \n """ )
async def get_table_schema_tool ( table_name : str , db_name : str = None , catalog_name : str = None ) - > Dict [ str , Any ] :
2025-05-06 12:56:55 +08:00
""" Wrapper: Get table schema """
if not table_name : return { " content " : [ { " type " : " text " , " text " : json . dumps ( { " success " : False , " error " : " Missing table_name parameter " } ) } ] }
2025-06-06 14:35:53 +08:00
return await mcp_doris_get_table_schema ( table_name = table_name , db_name = db_name , catalog_name = catalog_name )
2025-05-06 12:56:55 +08:00
# Register Tool: Get Database Table List (Keep long description string including parameters)
@mcp.tool ( " get_db_table_list " , description = """ [Function Description]: Get a list of all table names in the specified database. \n
[ Parameter Content ] : \n
- random_string ( string ) [ Required ] - Unique identifier for the tool call \n
2025-06-06 14:35:53 +08:00
- db_name ( string ) [ Optional ] - Target database name , defaults to the current database \n
- catalog_name ( string ) [ Optional ] - Target catalog name for federation queries , defaults to current catalog \n """ )
async def get_db_table_list_tool ( db_name : str = None , catalog_name : str = None ) - > Dict [ str , Any ] :
2025-05-06 12:56:55 +08:00
""" Wrapper: Get database table list """
2025-06-06 14:35:53 +08:00
return await mcp_doris_get_db_table_list ( db_name = db_name , catalog_name = catalog_name )
2025-05-06 12:56:55 +08:00
# Register Tool: Get Database List (Keep long description string including parameters)
# Note: Although the description mentions random_string, the wrapper function signature does not. See how mcp handles this.
@mcp.tool ( " get_db_list " , description = """ [Function Description]: Get a list of all database names on the server. \n
[ Parameter Content ] : \n
2025-06-06 14:35:53 +08:00
- random_string ( string ) [ Required ] - Unique identifier for the tool call \n
- catalog_name ( string ) [ Optional ] - Target catalog name for federation queries , defaults to current catalog \n """ )
async def get_db_list_tool ( catalog_name : str = None ) - > Dict [ str , Any ] : # Function signature has no parameters
2025-05-06 12:56:55 +08:00
""" Wrapper: Get database list """
2025-06-06 14:35:53 +08:00
return await mcp_doris_get_db_list ( catalog_name = catalog_name )
2025-05-06 12:56:55 +08:00
# Register Tool: Get Table Comment (Keep long description string including parameters)
@mcp.tool ( " get_table_comment " , description = """ [Function Description]: Get the comment information for the specified table. \n
[ Parameter Content ] : \n
- random_string ( string ) [ Required ] - Unique identifier for the tool call \n
- table_name ( string ) [ Required ] - Name of the table to query \n
2025-06-06 14:35:53 +08:00
- db_name ( string ) [ Optional ] - Target database name , defaults to the current database \n
- catalog_name ( string ) [ Optional ] - Target catalog name for federation queries , defaults to current catalog \n """ )
async def get_table_comment_tool ( table_name : str , db_name : str = None , catalog_name : str = None ) - > Dict [ str , Any ] :
2025-05-06 12:56:55 +08:00
""" Wrapper: Get table comment """
if not table_name : return { " content " : [ { " type " : " text " , " text " : json . dumps ( { " success " : False , " error " : " Missing table_name parameter " } ) } ] }
2025-06-06 14:35:53 +08:00
return await mcp_doris_get_table_comment ( table_name = table_name , db_name = db_name , catalog_name = catalog_name )
2025-05-06 12:56:55 +08:00
# Register Tool: Get Table Column Comments (Keep long description string including parameters)
@mcp.tool ( " get_table_column_comments " , description = """ [Function Description]: Get comment information for all columns in the specified table. \n
[ Parameter Content ] : \n
- random_string ( string ) [ Required ] - Unique identifier for the tool call \n
- table_name ( string ) [ Required ] - Name of the table to query \n
2025-06-06 14:35:53 +08:00
- db_name ( string ) [ Optional ] - Target database name , defaults to the current database \n
- catalog_name ( string ) [ Optional ] - Target catalog name for federation queries , defaults to current catalog \n """ )
async def get_table_column_comments_tool ( table_name : str , db_name : str = None , catalog_name : str = None ) - > Dict [ str , Any ] :
2025-05-06 12:56:55 +08:00
""" Wrapper: Get table column comments """
if not table_name : return { " content " : [ { " type " : " text " , " text " : json . dumps ( { " success " : False , " error " : " Missing table_name parameter " } ) } ] }
2025-06-06 14:35:53 +08:00
return await mcp_doris_get_table_column_comments ( table_name = table_name , db_name = db_name , catalog_name = catalog_name )
2025-05-06 12:56:55 +08:00
# Register Tool: Get Table Indexes (Keep long description string including parameters)
@mcp.tool ( " get_table_indexes " , description = """ [Function Description]: Get index information for the specified table. \n
[ Parameter Content ] : \n
- random_string ( string ) [ Required ] - Unique identifier for the tool call \n
- table_name ( string ) [ Required ] - Name of the table to query \n
2025-06-06 14:35:53 +08:00
- db_name ( string ) [ Optional ] - Target database name , defaults to the current database \n
- catalog_name ( string ) [ Optional ] - Target catalog name for federation queries , defaults to current catalog \n """ )
async def get_table_indexes_tool ( table_name : str , db_name : str = None , catalog_name : str = None ) - > Dict [ str , Any ] :
2025-05-06 12:56:55 +08:00
""" Wrapper: Get table indexes """
if not table_name : return { " content " : [ { " type " : " text " , " text " : json . dumps ( { " success " : False , " error " : " Missing table_name parameter " } ) } ] }
2025-06-06 14:35:53 +08:00
return await mcp_doris_get_table_indexes ( table_name = table_name , db_name = db_name , catalog_name = catalog_name )
2025-05-06 12:56:55 +08:00
# Register Tool: Get Recent Audit Logs (Keep long description string including parameters)
@mcp.tool ( " get_recent_audit_logs " , description = """ [Function Description]: Get audit log records for a recent period. \n
[ Parameter Content ] : \n
- random_string ( string ) [ Required ] - Unique identifier for the tool call \n
- days ( integer ) [ Optional ] - Number of recent days of logs to retrieve , default is 7 \n
- limit ( integer ) [ Optional ] - Maximum number of records to return , default is 100 \n """ )
async def get_recent_audit_logs_tool ( days : int = 7 , limit : int = 100 ) - > Dict [ str , Any ] :
""" Wrapper: Get recent audit logs """
try :
days = int ( days )
limit = int ( limit )
except ( ValueError , TypeError ) :
return { " content " : [ { " type " : " text " , " text " : json . dumps ( { " success " : False , " error " : " days and limit parameters must be integers " } ) } ] }
return await mcp_doris_get_recent_audit_logs ( days = days , limit = limit )
2025-06-06 14:35:53 +08:00
# Register Tool: Get Catalog List (Keep long description string including parameters)
@mcp.tool ( " get_catalog_list " , description = """ [Function Description]: Get a list of all catalog names on the server. \n
[ Parameter Content ] : \n
- random_string ( string ) [ Required ] - Unique identifier for the tool call \n """ )
async def get_catalog_list_tool ( ) - > Dict [ str , Any ] :
""" Wrapper: Get catalog list """
return await mcp_doris_get_catalog_list ( )
2025-05-06 12:56:55 +08:00
# Get tool count
tools_count = len ( await mcp . list_tools ( ) )
logger . info ( f " Registered all MCP tools, total { tools_count } tools " )
return True
except Exception as e :
logger . error ( f " Error registering MCP tools: { str ( e ) } " )
logger . error ( traceback . format_exc ( ) )
return False