awslabs.redshift-mcp-server 0.0.4__py3-none-any.whl → 0.0.7__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.
- awslabs/redshift_mcp_server/__init__.py +1 -1
- awslabs/redshift_mcp_server/consts.py +16 -8
- awslabs/redshift_mcp_server/redshift.py +42 -50
- awslabs/redshift_mcp_server/server.py +1 -1
- {awslabs_redshift_mcp_server-0.0.4.dist-info → awslabs_redshift_mcp_server-0.0.7.dist-info}/METADATA +39 -5
- awslabs_redshift_mcp_server-0.0.7.dist-info/RECORD +12 -0
- awslabs_redshift_mcp_server-0.0.4.dist-info/RECORD +0 -12
- {awslabs_redshift_mcp_server-0.0.4.dist-info → awslabs_redshift_mcp_server-0.0.7.dist-info}/WHEEL +0 -0
- {awslabs_redshift_mcp_server-0.0.4.dist-info → awslabs_redshift_mcp_server-0.0.7.dist-info}/entry_points.txt +0 -0
- {awslabs_redshift_mcp_server-0.0.4.dist-info → awslabs_redshift_mcp_server-0.0.7.dist-info}/licenses/LICENSE +0 -0
- {awslabs_redshift_mcp_server-0.0.4.dist-info → awslabs_redshift_mcp_server-0.0.7.dist-info}/licenses/NOTICE +0 -0
|
@@ -14,13 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
"""Redshift MCP Server constants."""
|
|
16
16
|
|
|
17
|
-
#
|
|
18
|
-
|
|
17
|
+
# System
|
|
18
|
+
CLIENT_CONNECT_TIMEOUT = 60
|
|
19
|
+
CLIENT_READ_TIMEOUT = 600
|
|
20
|
+
CLIENT_RETRIES = {'max_attempts': 5, 'mode': 'adaptive'}
|
|
21
|
+
CLIENT_USER_AGENT_NAME = 'awslabs/mcp/redshift-mcp-server'
|
|
19
22
|
DEFAULT_LOG_LEVEL = 'WARNING'
|
|
20
|
-
|
|
21
|
-
# Timeouts (seconds), etc
|
|
22
|
-
CLIENT_TIMEOUT = 60
|
|
23
|
-
DATA_CLIENT_TIMEOUT = 60
|
|
24
23
|
QUERY_TIMEOUT = 3600
|
|
25
24
|
QUERY_POLL_INTERVAL = 2
|
|
26
25
|
|
|
@@ -29,11 +28,20 @@ QUERY_POLL_INTERVAL = 2
|
|
|
29
28
|
CLIENT_BEST_PRACTICES = """
|
|
30
29
|
## AWS Client Best Practices
|
|
31
30
|
|
|
32
|
-
### Authentication
|
|
31
|
+
### Authentication and Configuration
|
|
33
32
|
|
|
34
33
|
- Default AWS credentials chain (IAM roles, ~/.aws/credentials, etc.).
|
|
35
34
|
- AWS_PROFILE environment variable (if set).
|
|
36
|
-
-
|
|
35
|
+
- Region configuration (in order of precedence):
|
|
36
|
+
- AWS_REGION environment variable (highest priority)
|
|
37
|
+
- AWS_DEFAULT_REGION environment variable
|
|
38
|
+
- Region specified in AWS profile configuration
|
|
39
|
+
|
|
40
|
+
### Error Handling
|
|
41
|
+
|
|
42
|
+
- Always print out AWS client errors in full to help diagnose configuration issues.
|
|
43
|
+
- For region-related errors, suggest checking AWS_REGION, AWS_DEFAULT_REGION, or AWS profile configuration.
|
|
44
|
+
- For credential errors, suggest verifying AWS credentials setup and permissions.
|
|
37
45
|
"""
|
|
38
46
|
|
|
39
47
|
REDSHIFT_BEST_PRACTICES = """
|
|
@@ -20,8 +20,10 @@ import os
|
|
|
20
20
|
import regex
|
|
21
21
|
from awslabs.redshift_mcp_server import __version__
|
|
22
22
|
from awslabs.redshift_mcp_server.consts import (
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
CLIENT_CONNECT_TIMEOUT,
|
|
24
|
+
CLIENT_READ_TIMEOUT,
|
|
25
|
+
CLIENT_RETRIES,
|
|
26
|
+
CLIENT_USER_AGENT_NAME,
|
|
25
27
|
QUERY_POLL_INTERVAL,
|
|
26
28
|
QUERY_TIMEOUT,
|
|
27
29
|
SUSPICIOUS_QUERY_REGEXP,
|
|
@@ -37,7 +39,9 @@ from loguru import logger
|
|
|
37
39
|
class RedshiftClientManager:
|
|
38
40
|
"""Manages AWS clients for Redshift operations."""
|
|
39
41
|
|
|
40
|
-
def __init__(
|
|
42
|
+
def __init__(
|
|
43
|
+
self, config: Config, aws_region: str | None = None, aws_profile: str | None = None
|
|
44
|
+
):
|
|
41
45
|
"""Initialize the client manager."""
|
|
42
46
|
self.aws_region = aws_region
|
|
43
47
|
self.aws_profile = aws_profile
|
|
@@ -50,15 +54,12 @@ class RedshiftClientManager:
|
|
|
50
54
|
"""Get or create the Redshift client for provisioned clusters."""
|
|
51
55
|
if self._redshift_client is None:
|
|
52
56
|
try:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
'redshift', config=self._config, region_name=self.aws_region
|
|
60
|
-
)
|
|
61
|
-
logger.info('Created Redshift client with default credentials')
|
|
57
|
+
# Session works with None values - uses default credentials/region chain
|
|
58
|
+
session = boto3.Session(profile_name=self.aws_profile, region_name=self.aws_region)
|
|
59
|
+
self._redshift_client = session.client('redshift', config=self._config)
|
|
60
|
+
logger.info(
|
|
61
|
+
f'Created Redshift client with profile: {self.aws_profile or "default"}, region: {self.aws_region or "default"}'
|
|
62
|
+
)
|
|
62
63
|
except Exception as e:
|
|
63
64
|
logger.error(f'Error creating Redshift client: {str(e)}')
|
|
64
65
|
raise
|
|
@@ -69,19 +70,14 @@ class RedshiftClientManager:
|
|
|
69
70
|
"""Get or create the Redshift Serverless client."""
|
|
70
71
|
if self._redshift_serverless_client is None:
|
|
71
72
|
try:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
else:
|
|
81
|
-
self._redshift_serverless_client = boto3.client(
|
|
82
|
-
'redshift-serverless', config=self._config, region_name=self.aws_region
|
|
83
|
-
)
|
|
84
|
-
logger.info('Created Redshift Serverless client with default credentials')
|
|
73
|
+
# Session works with None values - uses default credentials/region chain
|
|
74
|
+
session = boto3.Session(profile_name=self.aws_profile, region_name=self.aws_region)
|
|
75
|
+
self._redshift_serverless_client = session.client(
|
|
76
|
+
'redshift-serverless', config=self._config
|
|
77
|
+
)
|
|
78
|
+
logger.info(
|
|
79
|
+
f'Created Redshift Serverless client with profile: {self.aws_profile or "default"}, region: {self.aws_region or "default"}'
|
|
80
|
+
)
|
|
85
81
|
except Exception as e:
|
|
86
82
|
logger.error(f'Error creating Redshift Serverless client: {str(e)}')
|
|
87
83
|
raise
|
|
@@ -92,19 +88,12 @@ class RedshiftClientManager:
|
|
|
92
88
|
"""Get or create the Redshift Data API client."""
|
|
93
89
|
if self._redshift_data_client is None:
|
|
94
90
|
try:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
f'Created Redshift Data API client with profile: {self.aws_profile}'
|
|
102
|
-
)
|
|
103
|
-
else:
|
|
104
|
-
self._redshift_data_client = boto3.client(
|
|
105
|
-
'redshift-data', config=self._config, region_name=self.aws_region
|
|
106
|
-
)
|
|
107
|
-
logger.info('Created Redshift Data API client with default credentials')
|
|
91
|
+
# Session works with None values - uses default credentials/region chain
|
|
92
|
+
session = boto3.Session(profile_name=self.aws_profile, region_name=self.aws_region)
|
|
93
|
+
self._redshift_data_client = session.client('redshift-data', config=self._config)
|
|
94
|
+
logger.info(
|
|
95
|
+
f'Created Redshift Data API client with profile: {self.aws_profile or "default"}, region: {self.aws_region or "default"}'
|
|
96
|
+
)
|
|
108
97
|
except Exception as e:
|
|
109
98
|
logger.error(f'Error creating Redshift Data API client: {str(e)}')
|
|
110
99
|
raise
|
|
@@ -193,19 +182,22 @@ async def execute_statement(
|
|
|
193
182
|
)
|
|
194
183
|
|
|
195
184
|
# Guard from executing read-write statements if not allowed
|
|
196
|
-
|
|
197
|
-
|
|
185
|
+
sqls = protect_sql(sql, allow_read_write)
|
|
186
|
+
# Add application name and version
|
|
187
|
+
sqls = [f"SET application_name TO '{CLIENT_USER_AGENT_NAME}/{__version__}';"] + sqls
|
|
188
|
+
|
|
189
|
+
logger.debug(f'Protected and versioned SQL: {" ".join(sqls)}')
|
|
198
190
|
|
|
199
191
|
# Execute the query using Data API
|
|
200
192
|
if cluster_info['type'] == 'provisioned':
|
|
201
193
|
logger.debug(f'Using ClusterIdentifier for provisioned cluster: {cluster_identifier}')
|
|
202
194
|
response = data_client.batch_execute_statement(
|
|
203
|
-
ClusterIdentifier=cluster_identifier, Database=database_name, Sqls=
|
|
195
|
+
ClusterIdentifier=cluster_identifier, Database=database_name, Sqls=sqls
|
|
204
196
|
)
|
|
205
197
|
elif cluster_info['type'] == 'serverless':
|
|
206
198
|
logger.debug(f'Using WorkgroupName for serverless workgroup: {cluster_identifier}')
|
|
207
199
|
response = data_client.batch_execute_statement(
|
|
208
|
-
WorkgroupName=cluster_identifier, Database=database_name, Sqls=
|
|
200
|
+
WorkgroupName=cluster_identifier, Database=database_name, Sqls=sqls
|
|
209
201
|
)
|
|
210
202
|
else:
|
|
211
203
|
raise Exception(f'Unknown cluster type: {cluster_info["type"]}')
|
|
@@ -237,9 +229,9 @@ async def execute_statement(
|
|
|
237
229
|
raise Exception(f'Query timed out after {QUERY_TIMEOUT} seconds')
|
|
238
230
|
|
|
239
231
|
# Get user query results
|
|
240
|
-
|
|
241
|
-
results_response = data_client.get_statement_result(Id=
|
|
242
|
-
return results_response,
|
|
232
|
+
subquery2_id = status_response['SubStatements'][2]['Id']
|
|
233
|
+
results_response = data_client.get_statement_result(Id=subquery2_id)
|
|
234
|
+
return results_response, subquery2_id
|
|
243
235
|
|
|
244
236
|
|
|
245
237
|
async def discover_clusters() -> list[dict]:
|
|
@@ -620,11 +612,11 @@ async def execute_query(cluster_identifier: str, database_name: str, sql: str) -
|
|
|
620
612
|
# Global client manager instance
|
|
621
613
|
client_manager = RedshiftClientManager(
|
|
622
614
|
config=Config(
|
|
623
|
-
connect_timeout=
|
|
624
|
-
read_timeout=
|
|
625
|
-
retries=
|
|
626
|
-
user_agent_extra=f'
|
|
615
|
+
connect_timeout=CLIENT_CONNECT_TIMEOUT,
|
|
616
|
+
read_timeout=CLIENT_READ_TIMEOUT,
|
|
617
|
+
retries=CLIENT_RETRIES,
|
|
618
|
+
user_agent_extra=f'{CLIENT_USER_AGENT_NAME}/{__version__}',
|
|
627
619
|
),
|
|
628
|
-
aws_region=os.environ.get('AWS_REGION'
|
|
620
|
+
aws_region=os.environ.get('AWS_REGION'),
|
|
629
621
|
aws_profile=os.environ.get('AWS_PROFILE'),
|
|
630
622
|
)
|
|
@@ -85,7 +85,7 @@ This tool uses the Redshift Data API to run queries and return results.
|
|
|
85
85
|
|
|
86
86
|
## Getting Started
|
|
87
87
|
|
|
88
|
-
1. Ensure your AWS credentials are configured (
|
|
88
|
+
1. Ensure your AWS configuration and credentials are configured (environment variables or profile configuration file).
|
|
89
89
|
2. Use the list_clusters tool to discover available Redshift instances.
|
|
90
90
|
3. Note the cluster identifiers for use with other tools (coming in future milestones).
|
|
91
91
|
|
{awslabs_redshift_mcp_server-0.0.4.dist-info → awslabs_redshift_mcp_server-0.0.7.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: awslabs.redshift-mcp-server
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.7
|
|
4
4
|
Summary: An AWS Labs Model Context Protocol (MCP) server for Redshift
|
|
5
5
|
Project-URL: homepage, https://awslabs.github.io/mcp/
|
|
6
6
|
Project-URL: docs, https://awslabs.github.io/mcp/servers/redshift-mcp-server/
|
|
@@ -52,7 +52,11 @@ This MCP server provides tools to discover, explore, and query Amazon Redshift c
|
|
|
52
52
|
### AWS Client Requirements
|
|
53
53
|
|
|
54
54
|
1. **Credentials**: Configure AWS credentials via AWS CLI, or environment variables
|
|
55
|
-
2. **
|
|
55
|
+
2. **Region**: Configure AWS region using one of the following (in order of precedence):
|
|
56
|
+
- `AWS_REGION` environment variable (highest priority)
|
|
57
|
+
- `AWS_DEFAULT_REGION` environment variable
|
|
58
|
+
- Region specified in your AWS profile configuration
|
|
59
|
+
3. **Permissions**: Ensure your AWS credentials have the required permissions (see [Permissions](#permissions) section)
|
|
56
60
|
|
|
57
61
|
## Installation
|
|
58
62
|
|
|
@@ -70,7 +74,7 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
|
|
|
70
74
|
"args": ["awslabs.redshift-mcp-server@latest"],
|
|
71
75
|
"env": {
|
|
72
76
|
"AWS_PROFILE": "default",
|
|
73
|
-
"
|
|
77
|
+
"AWS_DEFAULT_REGION": "us-east-1",
|
|
74
78
|
"FASTMCP_LOG_LEVEL": "INFO"
|
|
75
79
|
},
|
|
76
80
|
"disabled": false,
|
|
@@ -80,6 +84,35 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
|
|
|
80
84
|
}
|
|
81
85
|
```
|
|
82
86
|
|
|
87
|
+
### Windows Installation
|
|
88
|
+
|
|
89
|
+
For Windows users, the MCP server configuration format is slightly different:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
"awslabs.redshift-mcp-server": {
|
|
95
|
+
"disabled": false,
|
|
96
|
+
"timeout": 60,
|
|
97
|
+
"type": "stdio",
|
|
98
|
+
"command": "uv",
|
|
99
|
+
"args": [
|
|
100
|
+
"tool",
|
|
101
|
+
"run",
|
|
102
|
+
"--from",
|
|
103
|
+
"awslabs.redshift-mcp-server@latest",
|
|
104
|
+
"awslabs.redshift-mcp-server.exe"
|
|
105
|
+
],
|
|
106
|
+
"env": {
|
|
107
|
+
"AWS_PROFILE": "your-aws-profile",
|
|
108
|
+
"AWS_DEFAULT_REGION": "us-east-1",
|
|
109
|
+
"FASTMCP_LOG_LEVEL": "ERROR"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
83
116
|
or docker after a successful `docker build -t awslabs/redshift-mcp-server:latest .`:
|
|
84
117
|
|
|
85
118
|
```json
|
|
@@ -93,7 +126,7 @@ or docker after a successful `docker build -t awslabs/redshift-mcp-server:latest
|
|
|
93
126
|
"--interactive",
|
|
94
127
|
"--env", "AWS_ACCESS_KEY_ID=[your data]",
|
|
95
128
|
"--env", "AWS_SECRET_ACCESS_KEY=[your data]",
|
|
96
|
-
"--env", "
|
|
129
|
+
"--env", "AWS_DEFAULT_REGION=[your data]",
|
|
97
130
|
"awslabs/redshift-mcp-server:latest"
|
|
98
131
|
]
|
|
99
132
|
}
|
|
@@ -103,7 +136,8 @@ or docker after a successful `docker build -t awslabs/redshift-mcp-server:latest
|
|
|
103
136
|
|
|
104
137
|
### Environment Variables
|
|
105
138
|
|
|
106
|
-
- `AWS_REGION`: AWS region to use (
|
|
139
|
+
- `AWS_REGION`: AWS region to use (overrides all other region settings)
|
|
140
|
+
- `AWS_DEFAULT_REGION`: Default AWS region (used if AWS_REGION not set and no region in profile)
|
|
107
141
|
- `AWS_PROFILE`: AWS profile to use (optional, uses default if not specified)
|
|
108
142
|
- `FASTMCP_LOG_LEVEL`: Logging level (`DEBUG`, `INFO`, `WARNING`, `ERROR`)
|
|
109
143
|
- `LOG_FILE`: Path to log file (optional, logs to stdout if not specified)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
awslabs/__init__.py,sha256=WuqxdDgUZylWNmVoPKiK7qGsTB_G4UmuXIrJ-VBwDew,731
|
|
2
|
+
awslabs/redshift_mcp_server/__init__.py,sha256=zubBv8l-CU0fO2qBX9BFtysTrX0q202KEIxSdlmACHk,673
|
|
3
|
+
awslabs/redshift_mcp_server/consts.py,sha256=0BElrreRZhjZ7sqbO7mtU5MkQP1NAupJp38MtKPfv64,4213
|
|
4
|
+
awslabs/redshift_mcp_server/models.py,sha256=p6oKcVz4xfaqQzXjJrZK9YlfuUnzMDCphXbTK1LT1k4,6437
|
|
5
|
+
awslabs/redshift_mcp_server/redshift.py,sha256=Hhb_t4ZJ61s42bIyHLXQviEuHu0Ngr8s8e8aXh5olCc,24314
|
|
6
|
+
awslabs/redshift_mcp_server/server.py,sha256=HL0stDv4BGWrqtKWvOfoONvZOxvl36TgwqU27g5Kdug,26131
|
|
7
|
+
awslabs_redshift_mcp_server-0.0.7.dist-info/METADATA,sha256=cegav5bZfvHNL_OoLI1QVYaRHvrCcrHIGIml7f846uY,16570
|
|
8
|
+
awslabs_redshift_mcp_server-0.0.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
9
|
+
awslabs_redshift_mcp_server-0.0.7.dist-info/entry_points.txt,sha256=o2G-onpmq80KMTQw2OrY1G07GmwPaurcJcIqfvMR9Sw,88
|
|
10
|
+
awslabs_redshift_mcp_server-0.0.7.dist-info/licenses/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
|
|
11
|
+
awslabs_redshift_mcp_server-0.0.7.dist-info/licenses/NOTICE,sha256=iIvfV8gFGERQ7xLtxV8bD_Lsrj9KOIPpvk49qp5-K0c,95
|
|
12
|
+
awslabs_redshift_mcp_server-0.0.7.dist-info/RECORD,,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
awslabs/__init__.py,sha256=WuqxdDgUZylWNmVoPKiK7qGsTB_G4UmuXIrJ-VBwDew,731
|
|
2
|
-
awslabs/redshift_mcp_server/__init__.py,sha256=Qco1mMifiQmcwValgxye-ykvoU_dTDfCZhoRuepHROk,673
|
|
3
|
-
awslabs/redshift_mcp_server/consts.py,sha256=_r7BEcNEjW8bEOxMwcb6ScCv3w9aXR0vRmd7HzAokyI,3683
|
|
4
|
-
awslabs/redshift_mcp_server/models.py,sha256=p6oKcVz4xfaqQzXjJrZK9YlfuUnzMDCphXbTK1LT1k4,6437
|
|
5
|
-
awslabs/redshift_mcp_server/redshift.py,sha256=FfzCPi5njzUvehNURHqAaHZr9Lz60Z9bAFXveGHLZR4,24696
|
|
6
|
-
awslabs/redshift_mcp_server/server.py,sha256=UNlBqgYS8KLhT9fFKKIPbszH1MtFTY5xCWbED_h-CJ8,26100
|
|
7
|
-
awslabs_redshift_mcp_server-0.0.4.dist-info/METADATA,sha256=wZnnDUdzkrvn6AMfJR_xdokKu25wX3xvzz_HA8MUHDI,15605
|
|
8
|
-
awslabs_redshift_mcp_server-0.0.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
9
|
-
awslabs_redshift_mcp_server-0.0.4.dist-info/entry_points.txt,sha256=o2G-onpmq80KMTQw2OrY1G07GmwPaurcJcIqfvMR9Sw,88
|
|
10
|
-
awslabs_redshift_mcp_server-0.0.4.dist-info/licenses/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
|
|
11
|
-
awslabs_redshift_mcp_server-0.0.4.dist-info/licenses/NOTICE,sha256=iIvfV8gFGERQ7xLtxV8bD_Lsrj9KOIPpvk49qp5-K0c,95
|
|
12
|
-
awslabs_redshift_mcp_server-0.0.4.dist-info/RECORD,,
|
{awslabs_redshift_mcp_server-0.0.4.dist-info → awslabs_redshift_mcp_server-0.0.7.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|