awslabs.postgres-mcp-server 1.0.2__tar.gz → 1.0.4__tar.gz

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.
Files changed (28) hide show
  1. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/Dockerfile +33 -23
  2. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/PKG-INFO +80 -5
  3. awslabs_postgres_mcp_server-1.0.4/README.md +171 -0
  4. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/awslabs/postgres_mcp_server/__init__.py +1 -1
  5. awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/__init__.py +18 -0
  6. awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/abstract_db_connection.py +68 -0
  7. awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/db_connection_singleton.py +117 -0
  8. awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/psycopg_pool_connection.py +287 -0
  9. awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/connection/rds_api_connection.py +157 -0
  10. awslabs_postgres_mcp_server-1.0.4/awslabs/postgres_mcp_server/server.py +323 -0
  11. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/docker-healthcheck.sh +7 -8
  12. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/pyproject.toml +3 -2
  13. awslabs_postgres_mcp_server-1.0.4/tests/conftest.py +597 -0
  14. awslabs_postgres_mcp_server-1.0.4/tests/test_psycopg_connector.py +402 -0
  15. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/tests/test_server.py +179 -4
  16. awslabs_postgres_mcp_server-1.0.4/tests/test_singleton.py +116 -0
  17. awslabs_postgres_mcp_server-1.0.4/uv-requirements.txt +26 -0
  18. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/uv.lock +707 -456
  19. awslabs_postgres_mcp_server-1.0.2/README.md +0 -97
  20. awslabs_postgres_mcp_server-1.0.2/awslabs/postgres_mcp_server/server.py +0 -429
  21. awslabs_postgres_mcp_server-1.0.2/tests/conftest.py +0 -217
  22. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/.gitignore +0 -0
  23. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/.python-version +0 -0
  24. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/CHANGELOG.md +0 -0
  25. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/LICENSE +0 -0
  26. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/NOTICE +0 -0
  27. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/awslabs/__init__.py +0 -0
  28. {awslabs_postgres_mcp_server-1.0.2 → awslabs_postgres_mcp_server-1.0.4}/awslabs/postgres_mcp_server/mutable_sql_detector.py +0 -0
@@ -12,8 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- #FROM public.ecr.aws/sam/build-python3.10:1.137.1-20250411084548
16
- FROM public.ecr.aws/sam/build-python3.10@sha256:d821662474d65f3cf2fc97dba2fa807a3adb580d02895fc4545527812550ea65 AS uv
15
+ # dependabot should continue to update this to the latest hash.
16
+ FROM public.ecr.aws/docker/library/python:3.13.5-alpine3.21@sha256:c9a09c45a4bcc618c7f7128585b8dd0d41d0c31a8a107db4c8255ffe0b69375d AS uv
17
17
 
18
18
  # Install the project into `/app`
19
19
  WORKDIR /app
@@ -31,40 +31,50 @@ ENV UV_PYTHON_PREFERENCE=only-system
31
31
  ENV UV_FROZEN=true
32
32
 
33
33
  # Copy the required files first
34
- COPY pyproject.toml uv.lock ./
34
+ COPY pyproject.toml uv.lock uv-requirements.txt ./
35
+
36
+ # Python optimization and uv configuration
37
+ ENV PIP_NO_CACHE_DIR=1 \
38
+ PIP_DISABLE_PIP_VERSION_CHECK=1
39
+
40
+ # Install system dependencies and Python package manager
41
+ RUN apk update && \
42
+ apk add --no-cache --virtual .build-deps \
43
+ build-base \
44
+ gcc \
45
+ musl-dev \
46
+ libffi-dev \
47
+ openssl-dev \
48
+ cargo
35
49
 
36
50
  # Install the project's dependencies using the lockfile and settings
37
51
  RUN --mount=type=cache,target=/root/.cache/uv \
38
- pip install uv==0.7.11 && \
39
- uv sync --frozen --no-install-project --no-dev --no-editable
52
+ pip install --require-hashes --requirement uv-requirements.txt --no-cache-dir && \
53
+ uv sync --python 3.13 --frozen --no-install-project --no-dev --no-editable
40
54
 
41
55
  # Then, add the rest of the project source code and install it
42
56
  # Installing separately from its dependencies allows optimal layer caching
43
57
  COPY . /app
44
58
  RUN --mount=type=cache,target=/root/.cache/uv \
45
- uv sync --frozen --no-dev --no-editable
59
+ uv sync --python 3.13 --frozen --no-dev --no-editable
46
60
 
47
61
  # Make the directory just in case it doesn't exist
48
62
  RUN mkdir -p /root/.local
49
63
 
50
- FROM public.ecr.aws/sam/build-python3.10@sha256:d821662474d65f3cf2fc97dba2fa807a3adb580d02895fc4545527812550ea65
64
+ FROM public.ecr.aws/docker/library/python:3.13.5-alpine3.21@sha256:c9a09c45a4bcc618c7f7128585b8dd0d41d0c31a8a107db4c8255ffe0b69375d
51
65
 
52
66
  # Place executables in the environment at the front of the path and include other binaries
53
- ENV PATH="/app/.venv/bin:$PATH:/usr/sbin"
54
-
55
- # Install lsof for the healthcheck
56
- # Install other tools as needed for the MCP server
57
- # Add non-root user and ability to change directory into /root
58
- RUN yum update -y && \
59
- yum install -y lsof && \
60
- yum clean all -y && \
61
- rm -rf /var/cache/yum && \
62
- groupadd --force --system app && \
63
- useradd app -g app -d /app && \
64
- chmod o+x /root
65
-
66
- # Get the project from the uv layer
67
- COPY --from=uv --chown=app:app /root/.local /root/.local
67
+ ENV PATH="/app/.venv/bin:$PATH" \
68
+ PYTHONUNBUFFERED=1
69
+
70
+ # Install runtime dependencies and create application user
71
+ RUN apk update && \
72
+ apk add --no-cache ca-certificates && \
73
+ update-ca-certificates && \
74
+ addgroup -S app && \
75
+ adduser -S app -G app -h /app
76
+
77
+ # Copy application artifacts from build stage
68
78
  COPY --from=uv --chown=app:app /app/.venv /app/.venv
69
79
 
70
80
  # Get healthcheck script
@@ -74,5 +84,5 @@ COPY ./docker-healthcheck.sh /usr/local/bin/docker-healthcheck.sh
74
84
  USER app
75
85
 
76
86
  # When running the container, add --db-path and a bind mount to the host's db file
77
- HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 CMD [ "docker-healthcheck.sh" ]
87
+ HEALTHCHECK --interval=60s --timeout=10s --start-period=10s --retries=3 CMD ["docker-healthcheck.sh"]
78
88
  ENTRYPOINT ["awslabs.postgres-mcp-server"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: awslabs.postgres-mcp-server
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: An AWS Labs Model Context Protocol (MCP) server for postgres
5
5
  Project-URL: homepage, https://awslabs.github.io/mcp/
6
6
  Project-URL: docs, https://awslabs.github.io/mcp/servers/postgres-mcp-server/
@@ -24,7 +24,8 @@ Requires-Python: >=3.10
24
24
  Requires-Dist: boto3>=1.38.5
25
25
  Requires-Dist: botocore>=1.38.5
26
26
  Requires-Dist: loguru>=0.7.0
27
- Requires-Dist: mcp[cli]>=1.6.0
27
+ Requires-Dist: mcp[cli]>=1.11.0
28
+ Requires-Dist: psycopg[pool]>=3.1.12
28
29
  Requires-Dist: pydantic>=2.10.6
29
30
  Description-Content-Type: text/markdown
30
31
 
@@ -52,10 +53,14 @@ An AWS Labs Model Context Protocol (MCP) server for Aurora Postgres
52
53
 
53
54
  ## Installation
54
55
 
55
- [![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://cursor.com/install-mcp?name=awslabs.postgres-mcp-server&config=eyJjb21tYW5kIjoidXZ4IGF3c2xhYnMucG9zdGdyZXMtbWNwLXNlcnZlckBsYXRlc3QgLS1yZXNvdXJjZV9hcm4gW3lvdXIgZGF0YV0gLS1zZWNyZXRfYXJuIFt5b3VyIGRhdGFdIC0tZGF0YWJhc2UgW3lvdXIgZGF0YV0gLS1yZWdpb24gW3lvdXIgZGF0YV0gLS1yZWFkb25seSBUcnVlIiwiZW52Ijp7IkFXU19QUk9GSUxFIjoieW91ci1hd3MtcHJvZmlsZSIsIkFXU19SRUdJT04iOiJ1cy1lYXN0LTEiLCJGQVNUTUNQX0xPR19MRVZFTCI6IkVSUk9SIn0sImRpc2FibGVkIjpmYWxzZSwiYXV0b0FwcHJvdmUiOltdfQ%3D%3D)
56
+ | Cursor | VS Code |
57
+ |:------:|:-------:|
58
+ | [![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://cursor.com/install-mcp?name=awslabs.postgres-mcp-server&config=eyJjb21tYW5kIjoidXZ4IGF3c2xhYnMucG9zdGdyZXMtbWNwLXNlcnZlckBsYXRlc3QgLS1jb25uZWN0aW9uLXN0cmluZyBwb3N0Z3Jlc3FsOi8vW3VzZXJuYW1lXTpbcGFzc3dvcmRdQFtob3N0XTpbcG9ydF0vW2RhdGFiYXNlXSIsImVudiI6eyJGQVNUTUNQX0xPR19MRVZFTCI6IkVSUk9SIn0sImRpc2FibGVkIjpmYWxzZSwiYXV0b0FwcHJvdmUiOltdLCJ0cmFuc3BvcnRUeXBlIjoic3RkaW8iLCJhdXRvU3RhcnQiOnRydWV9) | [![Install on VS Code](https://img.shields.io/badge/Install_on-VS_Code-FF9900?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=PostgreSQL%20MCP%20Server&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.postgres-mcp-server%40latest%22%2C%22--connection-string%22%2C%22postgresql%3A%2F%2F%5Busername%5D%3A%5Bpassword%5D%40%5Bhost%5D%3A%5Bport%5D%2F%5Bdatabase%5D%22%5D%2C%22env%22%3A%7B%22FASTMCP_LOG_LEVEL%22%3A%22ERROR%22%7D%2C%22disabled%22%3Afalse%2C%22autoApprove%22%3A%5B%5D%2C%22transportType%22%3A%22stdio%22%2C%22autoStart%22%3Atrue%7D) |
56
59
 
57
60
  Configure the MCP server in your MCP client configuration (e.g., for Amazon Q Developer CLI, edit `~/.aws/amazonq/mcp.json`):
58
61
 
62
+ ### Option 1: Using RDS Data API Connection (for Aurora Postgres)
63
+
59
64
  ```json
60
65
  {
61
66
  "mcpServers": {
@@ -81,6 +86,35 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
81
86
  }
82
87
  ```
83
88
 
89
+ ### Option 2: Using Direct PostgreSQL(psycopg) Connection (for Aurora Postgres and RDS Postgres)
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "awslabs.postgres-mcp-server": {
95
+ "command": "uvx",
96
+ "args": [
97
+ "awslabs.postgres-mcp-server@latest",
98
+ "--hostname", "[your data]",
99
+ "--secret_arn", "[your data]",
100
+ "--database", "[your data]",
101
+ "--region", "[your data]",
102
+ "--readonly", "True"
103
+ ],
104
+ "env": {
105
+ "AWS_PROFILE": "your-aws-profile",
106
+ "AWS_REGION": "us-east-1",
107
+ "FASTMCP_LOG_LEVEL": "ERROR"
108
+ },
109
+ "disabled": false,
110
+ "autoApprove": []
111
+ }
112
+ }
113
+ }
114
+ ```
115
+
116
+ Note: The `--port` parameter is optional and defaults to 5432 (the standard PostgreSQL port). You only need to specify it if your PostgreSQL instance uses a non-standard port.
117
+
84
118
  ### Build and install docker image locally on the same host of your LLM client
85
119
 
86
120
  1. 'git clone https://github.com/awslabs/mcp.git'
@@ -88,7 +122,10 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
88
122
  3. Run 'docker build -t awslabs/postgres-mcp-server:latest .'
89
123
 
90
124
  ### Add or update your LLM client's config with following:
91
- <pre><code>
125
+
126
+ #### Option 1: Using RDS Data API Connection (for Aurora Postgres)
127
+
128
+ ```json
92
129
  {
93
130
  "mcpServers": {
94
131
  "awslabs.postgres-mcp-server": {
@@ -110,10 +147,48 @@ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q De
110
147
  }
111
148
  }
112
149
  }
113
- </code></pre>
150
+ ```
151
+
152
+ #### Option 2: Using Direct PostgreSQL (psycopg) Connection (for Aurora Postgres and RDS Postgres)
153
+
154
+ ```
155
+ {
156
+ "mcpServers": {
157
+ "awslabs.postgres-mcp-server": {
158
+ "command": "docker",
159
+ "args": [
160
+ "run",
161
+ "-i",
162
+ "--rm",
163
+ "-e", "AWS_ACCESS_KEY_ID=[your data]",
164
+ "-e", "AWS_SECRET_ACCESS_KEY=[your data]",
165
+ "-e", "AWS_REGION=[your data]",
166
+ "awslabs/postgres-mcp-server:latest",
167
+ "--hostname", "[your data]",
168
+ "--secret_arn", "[your data]",
169
+ "--database", "[your data]",
170
+ "--region", "[your data]",
171
+ "--readonly", "True"
172
+ ]
173
+ }
174
+ }
175
+ }
176
+ ```
177
+
178
+ Note: The `--port` parameter is optional and defaults to 5432 (the standard PostgreSQL port). You only need to specify it if your PostgreSQL instance uses a non-standard port.
114
179
 
115
180
  NOTE: By default, only read-only queries are allowed and it is controlled by --readonly parameter above. Set it to False if you also want to allow writable DML or DDL.
116
181
 
182
+ ## Connection Methods
183
+
184
+ This MCP server supports two connection methods:
185
+
186
+ 1. **RDS Data API Connection** (using `--resource_arn`): Uses the AWS RDS Data API to connect to Aurora PostgreSQL. This method requires that your Aurora cluster has the Data API enabled.
187
+
188
+ 2. **Direct PostgreSQL Connection** (using `--hostname`): Uses psycopg to connect directly to any PostgreSQL database, including Aurora PostgreSQL, RDS PostgreSQL, or self-hosted PostgreSQL instances. This method provides better performance for frequent queries but requires direct network access to the database.
189
+
190
+ Choose the connection method that best fits your environment and requirements.
191
+
117
192
  ### AWS Authentication
118
193
 
119
194
  The MCP server uses the AWS profile specified in the `AWS_PROFILE` environment variable. If not provided, it defaults to the "default" profile in your AWS configuration file.
@@ -0,0 +1,171 @@
1
+ # AWS Labs postgres MCP Server
2
+
3
+ An AWS Labs Model Context Protocol (MCP) server for Aurora Postgres
4
+
5
+ ## Features
6
+
7
+ ### Natural language to Postgres SQL query
8
+
9
+ - Converting human-readable questions and commands into structured Postgres-compatible SQL queries and executing them against the configured Aurora Postgres database.
10
+
11
+ ## Prerequisites
12
+
13
+ 1. Install `uv` from [Astral](https://docs.astral.sh/uv/getting-started/installation/) or the [GitHub README](https://github.com/astral-sh/uv#installation)
14
+ 2. Install Python using `uv python install 3.10`
15
+ 3. Aurora Postgres Cluster with Postgres username and password stored in AWS Secrets Manager
16
+ 4. Enable RDS Data API for your Aurora Postgres Cluster, see [instructions here](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html)
17
+ 5. This MCP server can only be run locally on the same host as your LLM client.
18
+ 6. Docker runtime
19
+ 7. Set up AWS credentials with access to AWS services
20
+ - You need an AWS account with appropriate permissions
21
+ - Configure AWS credentials with `aws configure` or environment variables
22
+
23
+ ## Installation
24
+
25
+ | Cursor | VS Code |
26
+ |:------:|:-------:|
27
+ | [![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://cursor.com/install-mcp?name=awslabs.postgres-mcp-server&config=eyJjb21tYW5kIjoidXZ4IGF3c2xhYnMucG9zdGdyZXMtbWNwLXNlcnZlckBsYXRlc3QgLS1jb25uZWN0aW9uLXN0cmluZyBwb3N0Z3Jlc3FsOi8vW3VzZXJuYW1lXTpbcGFzc3dvcmRdQFtob3N0XTpbcG9ydF0vW2RhdGFiYXNlXSIsImVudiI6eyJGQVNUTUNQX0xPR19MRVZFTCI6IkVSUk9SIn0sImRpc2FibGVkIjpmYWxzZSwiYXV0b0FwcHJvdmUiOltdLCJ0cmFuc3BvcnRUeXBlIjoic3RkaW8iLCJhdXRvU3RhcnQiOnRydWV9) | [![Install on VS Code](https://img.shields.io/badge/Install_on-VS_Code-FF9900?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=PostgreSQL%20MCP%20Server&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.postgres-mcp-server%40latest%22%2C%22--connection-string%22%2C%22postgresql%3A%2F%2F%5Busername%5D%3A%5Bpassword%5D%40%5Bhost%5D%3A%5Bport%5D%2F%5Bdatabase%5D%22%5D%2C%22env%22%3A%7B%22FASTMCP_LOG_LEVEL%22%3A%22ERROR%22%7D%2C%22disabled%22%3Afalse%2C%22autoApprove%22%3A%5B%5D%2C%22transportType%22%3A%22stdio%22%2C%22autoStart%22%3Atrue%7D) |
28
+
29
+ Configure the MCP server in your MCP client configuration (e.g., for Amazon Q Developer CLI, edit `~/.aws/amazonq/mcp.json`):
30
+
31
+ ### Option 1: Using RDS Data API Connection (for Aurora Postgres)
32
+
33
+ ```json
34
+ {
35
+ "mcpServers": {
36
+ "awslabs.postgres-mcp-server": {
37
+ "command": "uvx",
38
+ "args": [
39
+ "awslabs.postgres-mcp-server@latest",
40
+ "--resource_arn", "[your data]",
41
+ "--secret_arn", "[your data]",
42
+ "--database", "[your data]",
43
+ "--region", "[your data]",
44
+ "--readonly", "True"
45
+ ],
46
+ "env": {
47
+ "AWS_PROFILE": "your-aws-profile",
48
+ "AWS_REGION": "us-east-1",
49
+ "FASTMCP_LOG_LEVEL": "ERROR"
50
+ },
51
+ "disabled": false,
52
+ "autoApprove": []
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ ### Option 2: Using Direct PostgreSQL(psycopg) Connection (for Aurora Postgres and RDS Postgres)
59
+
60
+ ```json
61
+ {
62
+ "mcpServers": {
63
+ "awslabs.postgres-mcp-server": {
64
+ "command": "uvx",
65
+ "args": [
66
+ "awslabs.postgres-mcp-server@latest",
67
+ "--hostname", "[your data]",
68
+ "--secret_arn", "[your data]",
69
+ "--database", "[your data]",
70
+ "--region", "[your data]",
71
+ "--readonly", "True"
72
+ ],
73
+ "env": {
74
+ "AWS_PROFILE": "your-aws-profile",
75
+ "AWS_REGION": "us-east-1",
76
+ "FASTMCP_LOG_LEVEL": "ERROR"
77
+ },
78
+ "disabled": false,
79
+ "autoApprove": []
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ Note: The `--port` parameter is optional and defaults to 5432 (the standard PostgreSQL port). You only need to specify it if your PostgreSQL instance uses a non-standard port.
86
+
87
+ ### Build and install docker image locally on the same host of your LLM client
88
+
89
+ 1. 'git clone https://github.com/awslabs/mcp.git'
90
+ 2. Go to sub-directory 'src/postgres-mcp-server/'
91
+ 3. Run 'docker build -t awslabs/postgres-mcp-server:latest .'
92
+
93
+ ### Add or update your LLM client's config with following:
94
+
95
+ #### Option 1: Using RDS Data API Connection (for Aurora Postgres)
96
+
97
+ ```json
98
+ {
99
+ "mcpServers": {
100
+ "awslabs.postgres-mcp-server": {
101
+ "command": "docker",
102
+ "args": [
103
+ "run",
104
+ "-i",
105
+ "--rm",
106
+ "-e", "AWS_ACCESS_KEY_ID=[your data]",
107
+ "-e", "AWS_SECRET_ACCESS_KEY=[your data]",
108
+ "-e", "AWS_REGION=[your data]",
109
+ "awslabs/postgres-mcp-server:latest",
110
+ "--resource_arn", "[your data]",
111
+ "--secret_arn", "[your data]",
112
+ "--database", "[your data]",
113
+ "--region", "[your data]",
114
+ "--readonly", "True"
115
+ ]
116
+ }
117
+ }
118
+ }
119
+ ```
120
+
121
+ #### Option 2: Using Direct PostgreSQL (psycopg) Connection (for Aurora Postgres and RDS Postgres)
122
+
123
+ ```
124
+ {
125
+ "mcpServers": {
126
+ "awslabs.postgres-mcp-server": {
127
+ "command": "docker",
128
+ "args": [
129
+ "run",
130
+ "-i",
131
+ "--rm",
132
+ "-e", "AWS_ACCESS_KEY_ID=[your data]",
133
+ "-e", "AWS_SECRET_ACCESS_KEY=[your data]",
134
+ "-e", "AWS_REGION=[your data]",
135
+ "awslabs/postgres-mcp-server:latest",
136
+ "--hostname", "[your data]",
137
+ "--secret_arn", "[your data]",
138
+ "--database", "[your data]",
139
+ "--region", "[your data]",
140
+ "--readonly", "True"
141
+ ]
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ Note: The `--port` parameter is optional and defaults to 5432 (the standard PostgreSQL port). You only need to specify it if your PostgreSQL instance uses a non-standard port.
148
+
149
+ NOTE: By default, only read-only queries are allowed and it is controlled by --readonly parameter above. Set it to False if you also want to allow writable DML or DDL.
150
+
151
+ ## Connection Methods
152
+
153
+ This MCP server supports two connection methods:
154
+
155
+ 1. **RDS Data API Connection** (using `--resource_arn`): Uses the AWS RDS Data API to connect to Aurora PostgreSQL. This method requires that your Aurora cluster has the Data API enabled.
156
+
157
+ 2. **Direct PostgreSQL Connection** (using `--hostname`): Uses psycopg to connect directly to any PostgreSQL database, including Aurora PostgreSQL, RDS PostgreSQL, or self-hosted PostgreSQL instances. This method provides better performance for frequent queries but requires direct network access to the database.
158
+
159
+ Choose the connection method that best fits your environment and requirements.
160
+
161
+ ### AWS Authentication
162
+
163
+ The MCP server uses the AWS profile specified in the `AWS_PROFILE` environment variable. If not provided, it defaults to the "default" profile in your AWS configuration file.
164
+
165
+ ```json
166
+ "env": {
167
+ "AWS_PROFILE": "your-aws-profile"
168
+ }
169
+ ```
170
+
171
+ Make sure the AWS profile has permissions to access the [RDS data API](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html#data-api.access), and the secret from AWS Secrets Manager. The MCP server creates a boto3 session using the specified profile to authenticate with AWS services. Your AWS IAM credentials remain on your local machine and are strictly used for accessing AWS services.
@@ -14,4 +14,4 @@
14
14
 
15
15
  """awslabs.postgres-mcp-server"""
16
16
 
17
- __version__ = '0.0.4'
17
+ __version__ = '1.0.4'
@@ -0,0 +1,18 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """aws.postgres-mcp-server.connection"""
16
+
17
+ from awslabs.postgres_mcp_server.connection.db_connection_singleton import DBConnectionSingleton
18
+ from awslabs.postgres_mcp_server.connection.abstract_db_connection import AbstractDBConnection
@@ -0,0 +1,68 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Abstract database connection interface for postgres MCP Server."""
16
+
17
+ from abc import ABC, abstractmethod
18
+ from typing import Any, Dict, List, Optional
19
+
20
+
21
+ class AbstractDBConnection(ABC):
22
+ """Abstract base class for database connections."""
23
+
24
+ def __init__(self, readonly: bool):
25
+ """Initialize the database connection.
26
+
27
+ Args:
28
+ readonly: Whether the connection should be read-only
29
+ """
30
+ self._readonly = readonly
31
+
32
+ @property
33
+ def readonly_query(self) -> bool:
34
+ """Get whether this connection is read-only.
35
+
36
+ Returns:
37
+ bool: True if the connection is read-only, False otherwise
38
+ """
39
+ return self._readonly
40
+
41
+ @abstractmethod
42
+ async def execute_query(
43
+ self, sql: str, parameters: Optional[List[Dict[str, Any]]] = None
44
+ ) -> Dict[str, Any]:
45
+ """Execute a SQL query.
46
+
47
+ Args:
48
+ sql: The SQL query to execute
49
+ parameters: Optional parameters for the query
50
+
51
+ Returns:
52
+ Dict containing query results with column metadata and records
53
+ """
54
+ pass
55
+
56
+ @abstractmethod
57
+ async def close(self) -> None:
58
+ """Close the database connection."""
59
+ pass
60
+
61
+ @abstractmethod
62
+ async def check_connection_health(self) -> bool:
63
+ """Check if the database connection is healthy.
64
+
65
+ Returns:
66
+ bool: True if the connection is healthy, False otherwise
67
+ """
68
+ pass
@@ -0,0 +1,117 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Database connection singleton for postgres MCP Server."""
16
+
17
+ import asyncio
18
+ from awslabs.postgres_mcp_server.connection.rds_api_connection import RDSDataAPIConnection
19
+ from loguru import logger
20
+
21
+
22
+ class DBConnectionSingleton:
23
+ """Manages a single RDS Data API connection instance across the application."""
24
+
25
+ _instance = None
26
+
27
+ def __init__(
28
+ self,
29
+ resource_arn: str,
30
+ secret_arn: str,
31
+ database: str,
32
+ region: str,
33
+ readonly: bool = True,
34
+ is_test: bool = False,
35
+ ):
36
+ """Initialize a new DB connection singleton for RDS Data API.
37
+
38
+ Args:
39
+ resource_arn: The ARN of the RDS cluster
40
+ secret_arn: The ARN of the secret containing credentials
41
+ database: The name of the database to connect to
42
+ region: The AWS region where the RDS instance is located
43
+ readonly: Whether the connection should be read-only (default: True)
44
+ is_test: Whether this is a test connection (default: False)
45
+ """
46
+ if not all([resource_arn, secret_arn, database, region]):
47
+ raise ValueError(
48
+ 'Missing required connection parameters for RDS Data API. '
49
+ 'Please provide resource_arn, secret_arn, database, and region.'
50
+ )
51
+
52
+ self._db_connection = RDSDataAPIConnection(
53
+ cluster_arn=resource_arn,
54
+ secret_arn=secret_arn,
55
+ database=database,
56
+ region=region,
57
+ readonly=readonly,
58
+ is_test=is_test,
59
+ )
60
+
61
+ @classmethod
62
+ def initialize(
63
+ cls,
64
+ resource_arn: str,
65
+ secret_arn: str,
66
+ database: str,
67
+ region: str,
68
+ readonly: bool = True,
69
+ is_test: bool = False,
70
+ ):
71
+ """Initialize the singleton instance if it doesn't exist.
72
+
73
+ Args:
74
+ resource_arn: The ARN of the RDS cluster
75
+ secret_arn: The ARN of the secret containing credentials
76
+ database: The name of the database to connect to
77
+ region: The AWS region where the RDS instance is located
78
+ readonly: Whether the connection should be read-only (default: True)
79
+ is_test: Whether this is a test connection (default: False)
80
+ """
81
+ if cls._instance is None:
82
+ cls._instance = cls(
83
+ resource_arn=resource_arn,
84
+ secret_arn=secret_arn,
85
+ database=database,
86
+ region=region,
87
+ readonly=readonly,
88
+ is_test=is_test,
89
+ )
90
+
91
+ @classmethod
92
+ def get(cls):
93
+ """Get the singleton instance."""
94
+ if cls._instance is None:
95
+ raise RuntimeError('DBConnectionSingleton is not initialized.')
96
+ return cls._instance
97
+
98
+ @property
99
+ def db_connection(self):
100
+ """Get the database connection."""
101
+ return self._db_connection
102
+
103
+ @classmethod
104
+ def cleanup(cls):
105
+ """Clean up resources when shutting down."""
106
+ if cls._instance and cls._instance._db_connection:
107
+ # Handle calling async close method from sync context
108
+ try:
109
+ loop = asyncio.get_event_loop()
110
+ if loop.is_running():
111
+ # If we're in an async context, create a task
112
+ asyncio.create_task(cls._instance._db_connection.close())
113
+ else:
114
+ # If we're in a sync context, run the coroutine to completion
115
+ loop.run_until_complete(cls._instance._db_connection.close())
116
+ except Exception as e:
117
+ logger.error(f'Error during connection cleanup: {str(e)}')