redshift-comment-mcp 0.1.0a0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- redshift_comment_mcp/__init__.py +0 -0
- redshift_comment_mcp/_version.py +34 -0
- redshift_comment_mcp/connection.py +81 -0
- redshift_comment_mcp/redshift_tools.py +135 -0
- redshift_comment_mcp/server.py +56 -0
- redshift_comment_mcp-0.1.0a0.dist-info/METADATA +211 -0
- redshift_comment_mcp-0.1.0a0.dist-info/RECORD +11 -0
- redshift_comment_mcp-0.1.0a0.dist-info/WHEEL +5 -0
- redshift_comment_mcp-0.1.0a0.dist-info/entry_points.txt +2 -0
- redshift_comment_mcp-0.1.0a0.dist-info/licenses/LICENSE +21 -0
- redshift_comment_mcp-0.1.0a0.dist-info/top_level.txt +1 -0
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '0.1.0a0'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 0, 'a0')
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import awswrangler as wr
|
|
3
|
+
import redshift_connector
|
|
4
|
+
from typing import Dict, Any
|
|
5
|
+
from contextlib import contextmanager
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
class RedshiftConnectionConfig:
|
|
10
|
+
"""
|
|
11
|
+
Redshift 連線配置類,儲存連線參數供每次使用時建立連線。
|
|
12
|
+
"""
|
|
13
|
+
def __init__(self, host: str, port: int, user: str, password: str, dbname: str):
|
|
14
|
+
self.host = host
|
|
15
|
+
self.port = port
|
|
16
|
+
self.user = user
|
|
17
|
+
self.password = password
|
|
18
|
+
self.dbname = dbname
|
|
19
|
+
|
|
20
|
+
def create_connection(self):
|
|
21
|
+
"""
|
|
22
|
+
使用 redshift-connector 建立新的 Redshift 連線。
|
|
23
|
+
"""
|
|
24
|
+
logger.debug(f"正在建立 Redshift 連線到 {self.host}:{self.port}/{self.dbname}")
|
|
25
|
+
try:
|
|
26
|
+
connection = redshift_connector.connect(
|
|
27
|
+
host=self.host,
|
|
28
|
+
port=self.port,
|
|
29
|
+
user=self.user,
|
|
30
|
+
password=self.password,
|
|
31
|
+
database=self.dbname
|
|
32
|
+
)
|
|
33
|
+
logger.debug("Redshift 連線建立成功")
|
|
34
|
+
return connection
|
|
35
|
+
except Exception as e:
|
|
36
|
+
logger.error(f"建立 Redshift 連線失敗: {e}", exc_info=True)
|
|
37
|
+
raise
|
|
38
|
+
|
|
39
|
+
@contextmanager
|
|
40
|
+
def get_connection(self):
|
|
41
|
+
"""
|
|
42
|
+
Context manager 用於自動管理連線的建立和清理。
|
|
43
|
+
|
|
44
|
+
使用方式:
|
|
45
|
+
with config.get_connection() as conn:
|
|
46
|
+
# 使用 conn 進行查詢
|
|
47
|
+
df = wr.redshift.read_sql_query(sql, con=conn)
|
|
48
|
+
"""
|
|
49
|
+
connection = None
|
|
50
|
+
try:
|
|
51
|
+
connection = self.create_connection()
|
|
52
|
+
yield connection
|
|
53
|
+
finally:
|
|
54
|
+
if connection:
|
|
55
|
+
try:
|
|
56
|
+
connection.close()
|
|
57
|
+
logger.debug("Redshift 連線已關閉")
|
|
58
|
+
except Exception as e:
|
|
59
|
+
logger.warning(f"關閉連線時發生警告: {e}")
|
|
60
|
+
|
|
61
|
+
def create_redshift_config(host: str, port: int, user: str, password: str, dbname: str) -> RedshiftConnectionConfig:
|
|
62
|
+
"""
|
|
63
|
+
建立 Redshift 連線配置。
|
|
64
|
+
"""
|
|
65
|
+
logger.info(f"建立 Redshift 連線配置: {host}:{port}/{dbname}")
|
|
66
|
+
|
|
67
|
+
# 驗證連線配置
|
|
68
|
+
config = RedshiftConnectionConfig(host, port, user, password, dbname)
|
|
69
|
+
|
|
70
|
+
# 測試連線以確保配置正確
|
|
71
|
+
try:
|
|
72
|
+
with config.get_connection() as conn:
|
|
73
|
+
# 簡單測試查詢
|
|
74
|
+
test_query = "SELECT 1 AS test"
|
|
75
|
+
wr.redshift.read_sql_query(test_query, con=conn)
|
|
76
|
+
logger.info("Redshift 連線配置驗證成功")
|
|
77
|
+
except Exception as e:
|
|
78
|
+
logger.error(f"Redshift 連線配置驗證失敗: {e}", exc_info=True)
|
|
79
|
+
raise ValueError(f"無法建立 Redshift 連線,請檢查連線參數。錯誤: {e}")
|
|
80
|
+
|
|
81
|
+
return config
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import awswrangler as wr
|
|
3
|
+
from fastmcp import FastMCP
|
|
4
|
+
from typing import List, Dict
|
|
5
|
+
from .connection import RedshiftConnectionConfig
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
# --- Redshift Tools Implementation ---
|
|
10
|
+
class RedshiftTools:
|
|
11
|
+
"""
|
|
12
|
+
Provides a set of tools for interacting with Redshift databases to support guided data exploration.
|
|
13
|
+
Uses a connect/disconnect pattern for each operation to ensure maximum robustness.
|
|
14
|
+
"""
|
|
15
|
+
def __init__(self, connection_config: RedshiftConnectionConfig):
|
|
16
|
+
self.config = connection_config
|
|
17
|
+
self.mcp = FastMCP("Redshift Tools")
|
|
18
|
+
self._setup_tools()
|
|
19
|
+
|
|
20
|
+
def _setup_tools(self):
|
|
21
|
+
"""設定所有 MCP 工具"""
|
|
22
|
+
|
|
23
|
+
@self.mcp.tool
|
|
24
|
+
def list_schemas() -> List[Dict[str, str]]:
|
|
25
|
+
"""
|
|
26
|
+
[功能] (探索流程第一步) 列出資料庫中所有可用的 schema 及其註解。
|
|
27
|
+
[用途] 用於理解資料庫的頂層結構和各個資料主題域的用途。
|
|
28
|
+
"""
|
|
29
|
+
sql = """
|
|
30
|
+
SELECT
|
|
31
|
+
n.nspname AS schema_name,
|
|
32
|
+
d.description AS schema_comment
|
|
33
|
+
FROM pg_namespace n
|
|
34
|
+
LEFT JOIN pg_description d ON n.oid = d.objoid
|
|
35
|
+
WHERE n.nspowner > 1 AND n.nspname NOT LIKE 'pg_%' AND n.nspname <> 'information_schema'
|
|
36
|
+
ORDER BY n.nspname;
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
# 每次使用時建立新連線
|
|
40
|
+
with self.config.get_connection() as conn:
|
|
41
|
+
df = wr.redshift.read_sql_query(sql, con=conn)
|
|
42
|
+
df['schema_comment'] = df['schema_comment'].fillna('')
|
|
43
|
+
return df.to_dict(orient='records')
|
|
44
|
+
|
|
45
|
+
@self.mcp.tool
|
|
46
|
+
def list_tables(schema_name: str) -> List[Dict[str, str]]:
|
|
47
|
+
"""
|
|
48
|
+
[功能] (探索流程第二步) 列出指定 schema 中的所有資料表、視圖及其註解。
|
|
49
|
+
[用途] 在選擇一個 schema 後,用此工具來了解該主題域下有哪些資料表以及它們的具體內容。
|
|
50
|
+
"""
|
|
51
|
+
# 輸入驗證
|
|
52
|
+
if not schema_name or not schema_name.isidentifier():
|
|
53
|
+
raise ValueError("無效的 schema 名稱。")
|
|
54
|
+
|
|
55
|
+
sql = """
|
|
56
|
+
SELECT
|
|
57
|
+
t.table_name,
|
|
58
|
+
t.table_type,
|
|
59
|
+
d.description AS table_comment
|
|
60
|
+
FROM information_schema.tables t
|
|
61
|
+
LEFT JOIN pg_class c ON c.relname = t.table_name AND c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = t.table_schema)
|
|
62
|
+
LEFT JOIN pg_description d ON d.objoid = c.oid AND d.objsubid = 0
|
|
63
|
+
WHERE t.table_schema = %s
|
|
64
|
+
ORDER BY t.table_name;
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
# 每次使用時建立新連線
|
|
68
|
+
with self.config.get_connection() as conn:
|
|
69
|
+
df = wr.redshift.read_sql_query(sql, con=conn, params=[schema_name])
|
|
70
|
+
df['table_comment'] = df['table_comment'].fillna('')
|
|
71
|
+
return df.to_dict(orient='records')
|
|
72
|
+
|
|
73
|
+
@self.mcp.tool
|
|
74
|
+
def list_columns(schema_name: str, table_name: str) -> List[Dict[str, str]]:
|
|
75
|
+
"""
|
|
76
|
+
[功能] (探索流程第三步) 列出指定資料表的所有欄位、資料型態及其註解。
|
|
77
|
+
[用途] 在鎖定目標資料表後,用此工具來精確理解每個欄位的商業意義、格式和用途。
|
|
78
|
+
"""
|
|
79
|
+
# 輸入驗證
|
|
80
|
+
if not schema_name.isidentifier() or not table_name.isidentifier():
|
|
81
|
+
raise ValueError("無效的 schema 或 table 名稱。")
|
|
82
|
+
|
|
83
|
+
sql = """
|
|
84
|
+
SELECT
|
|
85
|
+
c.column_name,
|
|
86
|
+
c.data_type,
|
|
87
|
+
c.is_nullable,
|
|
88
|
+
d.description AS column_comment
|
|
89
|
+
FROM information_schema.columns c
|
|
90
|
+
LEFT JOIN pg_description d ON d.objoid = (
|
|
91
|
+
SELECT oid FROM pg_class WHERE relname = c.table_name AND relnamespace = (
|
|
92
|
+
SELECT oid FROM pg_namespace WHERE nspname = c.table_schema
|
|
93
|
+
)
|
|
94
|
+
) AND d.objsubid = c.ordinal_position
|
|
95
|
+
WHERE c.table_schema = %s AND c.table_name = %s
|
|
96
|
+
ORDER BY c.ordinal_position;
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
# 每次使用時建立新連線
|
|
100
|
+
with self.config.get_connection() as conn:
|
|
101
|
+
df = wr.redshift.read_sql_query(sql, con=conn, params=[schema_name, table_name])
|
|
102
|
+
df['column_comment'] = df['column_comment'].fillna('')
|
|
103
|
+
return df.to_dict(orient='records')
|
|
104
|
+
|
|
105
|
+
@self.mcp.tool
|
|
106
|
+
def execute_sql(sql_statement: str) -> List[Dict]:
|
|
107
|
+
"""
|
|
108
|
+
[功能] (最終執行步驟) 在探索完資料結構後,執行一個 SQL 查詢以獲取資料。
|
|
109
|
+
[注意] 此工具僅能執行唯讀的 SELECT 查詢。任何 DML/DDL 操作都將失敗。
|
|
110
|
+
[範例] 若要查詢 public schema 中的 users 表,SQL 應為 "SELECT * FROM public.users LIMIT 10;"
|
|
111
|
+
"""
|
|
112
|
+
# 基本 SQL 安全檢查
|
|
113
|
+
sql_upper = sql_statement.strip().upper()
|
|
114
|
+
if not sql_upper.startswith('SELECT') and not sql_upper.startswith('WITH'):
|
|
115
|
+
raise ValueError("此工具僅支援 SELECT 和 WITH 查詢語句。")
|
|
116
|
+
|
|
117
|
+
# 檢查危險的 SQL 關鍵字
|
|
118
|
+
dangerous_keywords = ['DROP', 'DELETE', 'UPDATE', 'INSERT', 'ALTER', 'CREATE', 'TRUNCATE']
|
|
119
|
+
for keyword in dangerous_keywords:
|
|
120
|
+
if keyword in sql_upper:
|
|
121
|
+
raise ValueError(f"不允許使用 {keyword} 語句。")
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
# 每次使用時建立新連線
|
|
125
|
+
with self.config.get_connection() as conn:
|
|
126
|
+
df = wr.redshift.read_sql_query(sql_statement, con=conn)
|
|
127
|
+
return df.to_dict(orient='records')
|
|
128
|
+
except Exception as e:
|
|
129
|
+
logger.error(f"執行 SQL 失敗: {sql_statement}", exc_info=True)
|
|
130
|
+
error_message = f"執行 SQL 時發生錯誤,請檢查您的語法。原始錯誤訊息: {e}"
|
|
131
|
+
raise ValueError(error_message)
|
|
132
|
+
|
|
133
|
+
def get_server(self):
|
|
134
|
+
"""取得配置好的 MCP 伺服器"""
|
|
135
|
+
return self.mcp
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import argparse
|
|
3
|
+
import logging
|
|
4
|
+
from .connection import create_redshift_config
|
|
5
|
+
from .redshift_tools import RedshiftTools
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
"""主程式進入點,負責解析命令列參數並啟動伺服器。"""
|
|
11
|
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(name)s - %(message)s')
|
|
12
|
+
parser = argparse.ArgumentParser(description="Redshift MCP Server")
|
|
13
|
+
parser.add_argument("--host", required=True, help="Redshift 主機位址")
|
|
14
|
+
parser.add_argument("--port", type=int, default=5439, help="Redshift 連接埠")
|
|
15
|
+
parser.add_argument("--user", required=True, help="Redshift 使用者名稱")
|
|
16
|
+
parser.add_argument("--password", required=False, help="Redshift 密碼 (若未提供,則嘗試從 REDSHIFT_PASSWORD 環境變數讀取)")
|
|
17
|
+
parser.add_argument("--dbname", required=True, help="Redshift 資料庫名稱")
|
|
18
|
+
args = parser.parse_args()
|
|
19
|
+
|
|
20
|
+
password = args.password or os.getenv('REDSHIFT_PASSWORD')
|
|
21
|
+
if not password:
|
|
22
|
+
raise ValueError("必須透過 --password 參數或 REDSHIFT_PASSWORD 環境變數提供密碼。")
|
|
23
|
+
|
|
24
|
+
logger.info("正在啟動 Redshift MCP 伺服器...")
|
|
25
|
+
|
|
26
|
+
# 1. 建立 Redshift 連線配置(會進行連線測試)
|
|
27
|
+
try:
|
|
28
|
+
connection_config = create_redshift_config(
|
|
29
|
+
host=args.host,
|
|
30
|
+
port=args.port,
|
|
31
|
+
user=args.user,
|
|
32
|
+
password=password,
|
|
33
|
+
dbname=args.dbname
|
|
34
|
+
)
|
|
35
|
+
logger.info("Redshift 連線配置建立成功")
|
|
36
|
+
except Exception as e:
|
|
37
|
+
logger.critical(f"無法建立 Redshift 連線配置:{e}")
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
# 2. 實例化工具提供者,傳入連線配置
|
|
41
|
+
redshift_tools = RedshiftTools(connection_config)
|
|
42
|
+
mcp_server = redshift_tools.get_server()
|
|
43
|
+
|
|
44
|
+
# 3. 啟動 MCP 伺服器
|
|
45
|
+
try:
|
|
46
|
+
logger.info("MCP 伺服器啟動中...")
|
|
47
|
+
mcp_server.run() # FastMCP defaults to STDIO transport
|
|
48
|
+
except KeyboardInterrupt:
|
|
49
|
+
logger.info("收到中止信號,正在關閉伺服器...")
|
|
50
|
+
except Exception as e:
|
|
51
|
+
logger.error(f"伺服器運行時發生錯誤: {e}", exc_info=True)
|
|
52
|
+
finally:
|
|
53
|
+
logger.info("MCP 伺服器已關閉。")
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
main()
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: redshift-comment-mcp
|
|
3
|
+
Version: 0.1.0a0
|
|
4
|
+
Summary: A Model-Context Protocol server for Amazon Redshift.
|
|
5
|
+
Author-email: kouko <kouko@users.noreply.github.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 Redshift Comment MCP Contributors
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
Project-URL: Homepage, https://github.com/kouko/redshift-comment-mcp
|
|
28
|
+
Project-URL: Bug Tracker, https://github.com/kouko/redshift-comment-mcp/issues
|
|
29
|
+
Classifier: Programming Language :: Python :: 3
|
|
30
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
31
|
+
Classifier: Operating System :: OS Independent
|
|
32
|
+
Requires-Python: >=3.10
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
License-File: LICENSE
|
|
35
|
+
Requires-Dist: awswrangler[redshift]
|
|
36
|
+
Requires-Dist: redshift-connector
|
|
37
|
+
Requires-Dist: pandas
|
|
38
|
+
Requires-Dist: fastmcp
|
|
39
|
+
Provides-Extra: dev
|
|
40
|
+
Requires-Dist: pytest; extra == "dev"
|
|
41
|
+
Requires-Dist: pytest-mock; extra == "dev"
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
# Redshift MCP 伺服器
|
|
45
|
+
|
|
46
|
+
這是一個基於 Model Context Protocol (MCP) 的 Amazon Redshift 資料庫探索工具,專為 AI 語言模型設計,提供結構化的資料庫探索功能。
|
|
47
|
+
|
|
48
|
+
## 功能特色
|
|
49
|
+
|
|
50
|
+
- **引導式資料探索**:遵循 Schema → Table → Column 的探索流程
|
|
51
|
+
- **穩健連線管理**:採用每次使用時建立/切斷連線的模式確保最高穩定性
|
|
52
|
+
- **MCP 標準協定**:使用 FastMCP 框架實作,符合 MCP 協定標準
|
|
53
|
+
- **多種工具**:提供 schema、table、column 列表查詢及 SQL 執行功能
|
|
54
|
+
|
|
55
|
+
## 安裝
|
|
56
|
+
|
|
57
|
+
### 從 PyPI 安裝 (推薦)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install redshift-comment-mcp
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 本地開發安裝
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
git clone https://github.com/kouko/redshift-comment-mcp.git
|
|
67
|
+
cd redshift-comment-mcp
|
|
68
|
+
pip install -e ".[dev]"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**系統需求**:本專案需要 Python 3.10 或更高版本。
|
|
72
|
+
|
|
73
|
+
## 使用方式
|
|
74
|
+
|
|
75
|
+
### 命令列執行
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
redshift-comment-mcp --host your-cluster.region.redshift.amazonaws.com \
|
|
79
|
+
--port 5439 \
|
|
80
|
+
--user your_username \
|
|
81
|
+
--password your_password \
|
|
82
|
+
--dbname your_database
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 使用環境變數
|
|
86
|
+
|
|
87
|
+
您可以將密碼存放在環境變數中:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
export REDSHIFT_PASSWORD=your_password
|
|
91
|
+
redshift-comment-mcp --host your-cluster.region.redshift.amazonaws.com \
|
|
92
|
+
--port 5439 \
|
|
93
|
+
--user your_username \
|
|
94
|
+
--dbname your_database
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### MCP Client 設定
|
|
98
|
+
|
|
99
|
+
在 MCP Client 的設定檔中加入以下設定:
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"mcpServers": {
|
|
104
|
+
"redshift-comment-mcp": {
|
|
105
|
+
"command": "uvx",
|
|
106
|
+
"args": [
|
|
107
|
+
"redshift-comment-mcp@latest",
|
|
108
|
+
"--host", "your-cluster.region.redshift.amazonaws.com",
|
|
109
|
+
"--port", "5439",
|
|
110
|
+
"--user", "your_username",
|
|
111
|
+
"--password", "your_password",
|
|
112
|
+
"--dbname", "your_database"
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 本地開發設定
|
|
120
|
+
|
|
121
|
+
對於本地開發,可以使用以下設定:
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"redshift-comment-mcp-local": {
|
|
127
|
+
"command": "python",
|
|
128
|
+
"args": [
|
|
129
|
+
"-m", "redshift_comment_mcp.server",
|
|
130
|
+
"--host", "your-local-db-host",
|
|
131
|
+
"--port", "5439",
|
|
132
|
+
"--user", "your_username",
|
|
133
|
+
"--password", "your_password",
|
|
134
|
+
"--dbname", "dev"
|
|
135
|
+
],
|
|
136
|
+
"cwd": "/path/to/your/project"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## 可用工具
|
|
143
|
+
|
|
144
|
+
### 1. List Schemas
|
|
145
|
+
列出資料庫中所有可用的 schema 及其註解。這是探索流程的第一步。
|
|
146
|
+
|
|
147
|
+
### 2. List Tables
|
|
148
|
+
列出指定 schema 中的所有資料表、視圖及其註解。
|
|
149
|
+
|
|
150
|
+
### 3. List Columns
|
|
151
|
+
列出指定資料表的所有欄位、資料型態及其註解。
|
|
152
|
+
|
|
153
|
+
### 4. Execute SQL
|
|
154
|
+
執行 SQL 查詢以獲取資料。僅支援 SELECT 查詢。
|
|
155
|
+
|
|
156
|
+
## 開發
|
|
157
|
+
|
|
158
|
+
### 執行測試
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
pytest tests/
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 建置套件
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
python -m build
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### 發佈到 PyPI
|
|
171
|
+
|
|
172
|
+
#### 自動化發佈(推薦)
|
|
173
|
+
本專案使用 GitHub Actions 自動化發佈流程:
|
|
174
|
+
|
|
175
|
+
1. 更新 `pyproject.toml` 中的版本號
|
|
176
|
+
2. 建立 GitHub Release
|
|
177
|
+
3. GitHub Actions 自動執行測試、建置並發佈到 PyPI
|
|
178
|
+
|
|
179
|
+
詳細設定請參考 [.github/DEPLOYMENT.md](.github/DEPLOYMENT.md)
|
|
180
|
+
|
|
181
|
+
#### 手動發佈
|
|
182
|
+
```bash
|
|
183
|
+
python -m twine upload dist/*
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 資料庫註解最佳實踐
|
|
187
|
+
|
|
188
|
+
為了讓 AI 更好地理解您的資料庫結構,建議在資料庫中新增結構化的註解:
|
|
189
|
+
|
|
190
|
+
### Schema 註解範例
|
|
191
|
+
```sql
|
|
192
|
+
COMMENT ON SCHEMA sales IS '[用途] 儲存所有與線上零售相關的銷售數據。 [主要實體] 訂單, 客戶, 產品';
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Table 註解範例
|
|
196
|
+
```sql
|
|
197
|
+
COMMENT ON TABLE sales.orders IS '[實體] 訂單 [內容] 包含每一筆客戶訂單的詳細記錄。 [PK] order_id [FK] customer_id -> customers.customer_id';
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Column 註解範例
|
|
201
|
+
```sql
|
|
202
|
+
COMMENT ON COLUMN sales.orders.revenue IS '[定義] 該筆訂單的總銷售金額。 [語意類型] Metric [單位] 新台幣 [計算方式] 未稅商品總價 + 稅金 - 折扣。';
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## 授權
|
|
206
|
+
|
|
207
|
+
MIT License
|
|
208
|
+
|
|
209
|
+
## 貢獻
|
|
210
|
+
|
|
211
|
+
歡迎提交 Issue 和 Pull Request。
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
redshift_comment_mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
redshift_comment_mcp/_version.py,sha256=BwAbItUzx8GHBL4bMhoyf_-80mXHGCMRjXF_rX0pWbM,712
|
|
3
|
+
redshift_comment_mcp/connection.py,sha256=N2AnBP2zxorhCjgDOFJOEhl3HmuRotA7y4rFvbowAhY,2802
|
|
4
|
+
redshift_comment_mcp/redshift_tools.py,sha256=zoA2IDi5wDuWjHEZ5XJ4Hfx0egRi2mTBAnvMpmJRxi0,6286
|
|
5
|
+
redshift_comment_mcp/server.py,sha256=l2GUt0zFEekHchBe8qFX06pA_HNym6WY964e3ApPNHo,2267
|
|
6
|
+
redshift_comment_mcp-0.1.0a0.dist-info/licenses/LICENSE,sha256=XzRdj7ZLKC7b5gI7Q5et406Gt6OltI0lgBdbAHu5muk,1089
|
|
7
|
+
redshift_comment_mcp-0.1.0a0.dist-info/METADATA,sha256=fwpo-CFO_TkEnSHrD5HTK8gtcIcTwszI05oQiPNQDMk,6036
|
|
8
|
+
redshift_comment_mcp-0.1.0a0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
+
redshift_comment_mcp-0.1.0a0.dist-info/entry_points.txt,sha256=xJNvUHN7qO54_K1lVLtBClwosE-Aheh-JUX6Jx7Qyhs,74
|
|
10
|
+
redshift_comment_mcp-0.1.0a0.dist-info/top_level.txt,sha256=SZLawNXj6WzG1McXwau3YDqHhLYakjPj_imvdRjLS6A,21
|
|
11
|
+
redshift_comment_mcp-0.1.0a0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Redshift Comment MCP Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
redshift_comment_mcp
|