Skip to content

Commit 33faeb3

Browse files
Jove Zhongserprexiskakaushik
authored
Port/1.1.2: load comments (#4)
* 0.1.1 (#12) * Gather comments from CH tables as well (ClickHouse#13) * 1.1.2 * Update test_tool.py --------- Co-authored-by: Philip Dubé <serprex@users.noreply.github.com> Co-authored-by: Kaushik Iska <iska.kaushik@gmail.com> Co-authored-by: Philip Dubé <philip@peerdb.io>
1 parent 6cde490 commit 33faeb3

File tree

5 files changed

+57
-12
lines changed

5 files changed

+57
-12
lines changed

.editorconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[*]
2+
trim_trailing_whitespace = true
3+
end_of_line = lf

mcp_timeplus/mcp_server.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,21 @@ def list_tables(database: str, like: str = None):
4343
query += f" LIKE '{like}'"
4444
result = client.command(query)
4545

46+
# Get all table comments in one query
47+
table_comments_query = f"SELECT name, comment FROM system.tables WHERE database = '{database}'"
48+
table_comments_result = client.query(table_comments_query)
49+
table_comments = {row[0]: row[1] for row in table_comments_result.result_rows}
50+
51+
# Get all column comments in one query
52+
column_comments_query = f"SELECT table, name, comment FROM system.columns WHERE database = '{database}'"
53+
column_comments_result = client.query(column_comments_query)
54+
column_comments = {}
55+
for row in column_comments_result.result_rows:
56+
table, col_name, comment = row
57+
if table not in column_comments:
58+
column_comments[table] = {}
59+
column_comments[table][col_name] = comment
60+
4661
def get_table_info(table):
4762
logger.info(f"Getting schema info for table {database}.{table}")
4863
schema_query = f"DESCRIBE STREAM {database}.`{table}`"
@@ -54,6 +69,11 @@ def get_table_info(table):
5469
column_dict = {}
5570
for i, col_name in enumerate(column_names):
5671
column_dict[col_name] = row[i]
72+
# Add comment from our pre-fetched comments
73+
if table in column_comments and column_dict['name'] in column_comments[table]:
74+
column_dict['comment'] = column_comments[table][column_dict['name']]
75+
else:
76+
column_dict['comment'] = None
5777
columns.append(column_dict)
5878

5979
create_table_query = f"SHOW CREATE STREAM {database}.`{table}`"
@@ -62,6 +82,7 @@ def get_table_info(table):
6282
return {
6383
"database": database,
6484
"name": table,
85+
"comment": table_comments.get(table),
6586
"columns": columns,
6687
"create_table_query": create_table_result,
6788
}
@@ -108,7 +129,8 @@ def create_timeplus_client():
108129
f"as {client_config['username']} "
109130
f"(secure={client_config['secure']}, verify={client_config['verify']}, "
110131
f"connect_timeout={client_config['connect_timeout']}s, "
111-
f"send_receive_timeout={client_config['send_receive_timeout']}s)")
132+
f"send_receive_timeout={client_config['send_receive_timeout']}s)"
133+
)
112134

113135
try:
114136
client = timeplus_connect.get_client(**client_config)

pyproject.toml

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
[project]
22
name = "mcp-timeplus"
3-
version = "0.1.0"
3+
version = "0.1.2"
44
description = "An MCP server for Timeplus."
55
readme = "README.md"
66
license = "Apache-2.0"
77
license-files = ["LICENSE"]
88
requires-python = ">=3.13"
99
dependencies = [
10-
"mcp>=1.0.0",
11-
"python-dotenv>=1.0.1",
12-
"fastmcp>=0.4.0",
13-
"uvicorn>=0.34.0",
14-
"timeplus-connect>=0.8.14",
10+
"mcp>=1.0.0",
11+
"python-dotenv>=1.0.1",
12+
"fastmcp>=0.4.0",
13+
"uvicorn>=0.34.0",
14+
"timeplus-connect>=0.8.14",
1515
]
1616

1717
[project.scripts]
@@ -21,10 +21,7 @@ mcp-timeplus = "mcp_timeplus.main:main"
2121
Home = "https://github.com/jovezhong/mcp-timeplus"
2222

2323
[project.optional-dependencies]
24-
dev = [
25-
"ruff",
26-
"pytest"
27-
]
24+
dev = ["ruff", "pytest"]
2825

2926
[tool.hatch.build.targets.wheel]
3027
packages = ["mcp_timeplus"]

tests/test_tool.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@ def setUpClass(cls):
1717
cls.test_db = "default"
1818
cls.test_table = "test_table"
1919
cls.client.command(f"CREATE DATABASE IF NOT EXISTS {cls.test_db}")
20+
21+
# Drop table if exists to ensure clean state
22+
cls.client.command(f"DROP STREAM IF EXISTS {cls.test_db}.{cls.test_table}")
23+
24+
# Create table with comments
2025
cls.client.command(f"""
2126
CREATE STREAM IF NOT EXISTS {cls.test_db}.{cls.test_table} (
2227
id uint32,
2328
name string
2429
)
30+
COMMENT 'Test table for unit testing'
2531
""")
2632
cls.client.command(f"""
2733
INSERT INTO {cls.test_db}.{cls.test_table} (id, name) VALUES (1, 'Alice'), (2, 'Bob')
@@ -67,6 +73,23 @@ def test_run_select_query_failure(self):
6773
self.assertIsInstance(result, str)
6874
self.assertIn("error running query", result)
6975

76+
def test_table_and_column_comments(self):
77+
"""Test that table and column comments are correctly retrieved."""
78+
result = list_tables(self.test_db)
79+
self.assertIsInstance(result, list)
80+
self.assertEqual(len(result), 1)
81+
82+
table_info = result[0]
83+
# Verify table comment
84+
self.assertEqual(table_info["comment"], "Test table for unit testing")
85+
86+
# Get columns by name for easier testing
87+
columns = {col["name"]: col for col in table_info["columns"]}
88+
89+
# Verify column comments
90+
self.assertEqual(columns["id"]["comment"], "Primary identifier")
91+
self.assertEqual(columns["name"]["comment"], "User name field")
92+
7093

7194
if __name__ == "__main__":
7295
unittest.main()

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)