Skip to main content
Glama
ClickHouse

mcp-clickhouse

Official
by ClickHouse

list_tables

List available ClickHouse database tables with schema details, row counts, and filtering options for efficient database exploration.

Instructions

List available ClickHouse tables in a database, including schema, comment, row count, and column count.

Args: database: The database to list tables from like: Optional LIKE pattern to filter table names not_like: Optional NOT LIKE pattern to exclude table names page_token: Token for pagination, obtained from a previous call page_size: Number of tables to return per page (default: 50) include_detailed_columns: Whether to include detailed column metadata (default: True). When False, the columns array will be empty but create_table_query still contains all column information. This reduces payload size for large schemas.

Returns: A dictionary containing: - tables: List of table information (as dictionaries) - next_page_token: Token for the next page, or None if no more pages - total_tables: Total number of tables matching the filters

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
databaseYes
likeNo
not_likeNo
page_tokenNo
page_sizeNo
include_detailed_columnsNo

Implementation Reference

  • Core handler function for the 'list_tables' tool. Implements table listing with support for LIKE/NOT LIKE filters, pagination (page_token, page_size), detailed column info, and caching for pagination state. Uses helper functions to query system.tables and system.columns.
    def list_tables( database: str, like: Optional[str] = None, not_like: Optional[str] = None, page_token: Optional[str] = None, page_size: int = 50, include_detailed_columns: bool = True, ) -> Dict[str, Any]: """List available ClickHouse tables in a database, including schema, comment, row count, and column count. Args: database: The database to list tables from like: Optional LIKE pattern to filter table names not_like: Optional NOT LIKE pattern to exclude table names page_token: Token for pagination, obtained from a previous call page_size: Number of tables to return per page (default: 50) include_detailed_columns: Whether to include detailed column metadata (default: True). When False, the columns array will be empty but create_table_query still contains all column information. This reduces payload size for large schemas. Returns: A dictionary containing: - tables: List of table information (as dictionaries) - next_page_token: Token for the next page, or None if no more pages - total_tables: Total number of tables matching the filters """ logger.info( "Listing tables in database '%s' with like=%s, not_like=%s, " "page_token=%s, page_size=%s, include_detailed_columns=%s", database, like, not_like, page_token, page_size, include_detailed_columns, ) client = create_clickhouse_client() if page_token and page_token in table_pagination_cache: cached_state = table_pagination_cache[page_token] cached_include_detailed = cached_state.get("include_detailed_columns", True) if ( cached_state["database"] != database or cached_state["like"] != like or cached_state["not_like"] != not_like or cached_include_detailed != include_detailed_columns ): logger.warning( "Page token %s is for a different database, filter, or metadata setting. " "Ignoring token and starting from beginning.", page_token, ) page_token = None else: table_names = cached_state["table_names"] start_idx = cached_state["start_idx"] tables, end_idx, has_more = get_paginated_table_data( client, database, table_names, start_idx, page_size, include_detailed_columns, ) next_page_token = None if has_more: next_page_token = create_page_token( database, like, not_like, table_names, end_idx, include_detailed_columns ) del table_pagination_cache[page_token] logger.info( "Returned page with %s tables (total: %s), next_page_token=%s", len(tables), len(table_names), next_page_token, ) return { "tables": [asdict(table) for table in tables], "next_page_token": next_page_token, "total_tables": len(table_names), } table_names = fetch_table_names_from_system(client, database, like, not_like) start_idx = 0 tables, end_idx, has_more = get_paginated_table_data( client, database, table_names, start_idx, page_size, include_detailed_columns, ) next_page_token = None if has_more: next_page_token = create_page_token( database, like, not_like, table_names, end_idx, include_detailed_columns ) logger.info( "Found %s tables, returning %s with next_page_token=%s", len(table_names), len(tables), next_page_token, ) return { "tables": [asdict(table) for table in tables], "next_page_token": next_page_token, "total_tables": len(table_names), }
  • Dataclass defining the output Table structure used by list_tables, including metadata like engine, row counts, and nested columns.
    @dataclass class Table: database: str name: str engine: str create_table_query: str dependencies_database: str dependencies_table: str engine_full: str sorting_key: str primary_key: str total_rows: int total_bytes: int total_bytes_uncompressed: int parts: int active_parts: int total_marks: int comment: Optional[str] = None columns: List[Column] = field(default_factory=list)
  • Registers the list_tables tool (along with others) to the FastMCP server instance when CLICKHOUSE_ENABLED is true.
    if os.getenv("CLICKHOUSE_ENABLED", "true").lower() == "true": mcp.add_tool(Tool.from_function(list_databases)) mcp.add_tool(Tool.from_function(list_tables)) mcp.add_tool(Tool.from_function(run_select_query)) logger.info("ClickHouse tools registered")
  • Helper function to fetch filtered table names from system.tables, used by list_tables.
    def fetch_table_names_from_system( client, database: str, like: Optional[str] = None, not_like: Optional[str] = None, ) -> List[str]: """Get list of table names from system.tables. Args: client: ClickHouse client database: Database name like: Optional pattern to filter table names (LIKE) not_like: Optional pattern to filter out table names (NOT LIKE) Returns: List of table names """ query = f"SELECT name FROM system.tables WHERE database = {format_query_value(database)}" if like: query += f" AND name LIKE {format_query_value(like)}" if not_like: query += f" AND name NOT LIKE {format_query_value(not_like)}" result = client.query(query) table_names = [row[0] for row in result.result_rows] return table_names
  • Helper function to retrieve detailed paginated table data including optional column details from system.tables and system.columns, used by list_tables.
    def get_paginated_table_data( client, database: str, table_names: List[str], start_idx: int, page_size: int, include_detailed_columns: bool = True, ) -> tuple[List[Table], int, bool]: """Get detailed information for a page of tables. Args: client: ClickHouse client database: Database name table_names: List of all table names to paginate start_idx: Starting index for pagination page_size: Number of tables per page include_detailed_columns: Whether to include detailed column metadata (default: True) Returns: Tuple of (list of Table objects, end index, has more pages) """ end_idx = min(start_idx + page_size, len(table_names)) current_page_table_names = table_names[start_idx:end_idx] if not current_page_table_names: return [], end_idx, False query = f""" SELECT database, name, engine, create_table_query, dependencies_database, dependencies_table, engine_full, sorting_key, primary_key, total_rows, total_bytes, total_bytes_uncompressed, parts, active_parts, total_marks, comment FROM system.tables WHERE database = {format_query_value(database)} AND name IN ({", ".join(format_query_value(name) for name in current_page_table_names)}) """ result = client.query(query) tables = result_to_table(result.column_names, result.result_rows) if include_detailed_columns: for table in tables: column_data_query = f""" SELECT database, table, name, type AS column_type, default_kind, default_expression, comment FROM system.columns WHERE database = {format_query_value(database)} AND table = {format_query_value(table.name)} """ column_data_query_result = client.query(column_data_query) table.columns = result_to_column( column_data_query_result.column_names, column_data_query_result.result_rows, ) else: for table in tables: table.columns = [] return tables, end_idx, end_idx < len(table_names)

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/ClickHouse/mcp-clickhouse'

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