nuuly-postgres-mcp-server 1.0.0__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.
@@ -0,0 +1,179 @@
1
+ Metadata-Version: 2.4
2
+ Name: nuuly-postgres-mcp-server
3
+ Version: 1.0.0
4
+ Summary: MCP server for accessing Nuuly PostgreSQL database resources
5
+ Author-email: Nuuly Engineering <engineering@nuuly.com>
6
+ License: Proprietary
7
+ Project-URL: Homepage, https://github.com/urbn/r15-mcp
8
+ Project-URL: Repository, https://github.com/urbn/r15-mcp
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: fastmcp>=2.2.1
12
+ Requires-Dist: httpx>=0.24.0
13
+ Requires-Dist: psycopg2-binary>=2.9.5
14
+
15
+ # Nuuly Postgres MCP Server
16
+
17
+ MCP server for accessing Nuuly PostgreSQL database resources through Claude Desktop and other AI assistants.
18
+
19
+ ## Contents
20
+ - `src/nuuly_postgres_mcp_server/`: Package source code
21
+ - `__init__.py`: Package initialization
22
+ - `__main__.py`: Entry point for running as a module
23
+ - `server.py`: Main server implementation
24
+ - `pyproject.toml`: Package configuration
25
+ - `.env.example`: Example environment variables
26
+
27
+ ## Purpose
28
+ This MCP server provides PostgreSQL database connectivity functionality for the broader MCP platform. It connects to CloudSQL Postgres non-prod databases and enables AI code editors to:
29
+
30
+ 1. Understand all tables and schemas
31
+ 2. Run queries against the non-prod database
32
+ 3. List available databases and their aliases
33
+
34
+ ---
35
+
36
+ ## Installation
37
+
38
+ ### Option 1: Install from PyPI
39
+
40
+ ```bash
41
+ pip install nuuly-postgres-mcp-server
42
+ ```
43
+
44
+ ### Option 2: Install from Source
45
+
46
+ 1. Clone the repository:
47
+ ```bash
48
+ git clone <REPO_URL>
49
+ cd r15-mcp/mcp_servers/postgres-mcp
50
+ ```
51
+
52
+ 2. Install the package in development mode:
53
+ ```bash
54
+ pip install -e .
55
+ ```
56
+
57
+ ## Local Development
58
+
59
+ ### Prerequisites
60
+ - Python 3.8 or higher
61
+ - pip package manager
62
+
63
+ ### Setup
64
+
65
+ 1. Clone the repository:
66
+ ```bash
67
+ git clone <REPO_URL>
68
+ cd r15-mcp/mcp_servers/postgres-mcp
69
+ ```
70
+
71
+ 2. Create and activate a virtual environment (optional but recommended):
72
+ ```bash
73
+ python -m venv venv
74
+ source venv/bin/activate # On Windows: venv\Scripts\activate
75
+ ```
76
+
77
+ 3. Install development dependencies:
78
+ ```bash
79
+ pip install -e .
80
+ ```
81
+
82
+ 4. Set up environment variables:
83
+ ```bash
84
+ cp .env.example .env
85
+ # Edit .env with your actual values
86
+ ```
87
+
88
+ ## Environment Variables
89
+
90
+ The following environment variables can be set to customize the behavior of the MCP server:
91
+
92
+ - `CLOUD_RUN_PROXY_URL`: URL of the Cloud Run DB Proxy (default: "https://postgres-mcp-toolbox-186512416539.us-east4.run.app")
93
+ - `DB_PROXY_API_KEY`: API key for authenticating with the Cloud Run DB Proxy (required)
94
+ - `LOG_LEVEL`: Logging level (default: INFO)
95
+
96
+ ## Usage
97
+
98
+ ### For Claude Desktop
99
+
100
+ Add this configuration to your Claude Desktop settings:
101
+
102
+ ```json
103
+ {
104
+ "Nuuly Postgres MCP": {
105
+ "command": "nuuly-postgres-mcp",
106
+ "env": {
107
+ "PYTHONUNBUFFERED": "1",
108
+ "CLOUD_RUN_PROXY_URL": "https://postgres-mcp-toolbox-186512416539.us-east4.run.app",
109
+ "DB_PROXY_API_KEY": "YOUR_API_KEY_HERE"
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ ### Command Line Usage
116
+
117
+ ```bash
118
+ nuuly-postgres-mcp
119
+ ```
120
+
121
+ ## Deployment
122
+
123
+ ### As a GCP Cloud Function
124
+
125
+ This MCP server is designed to be deployed as a GCP Cloud Function with the following parameters:
126
+
127
+ - Project: `rental-dev`
128
+ - Region: `us-east4`
129
+ - Serverless VPC Connector: `rental-vpc-connector`
130
+ - Entry point: `main.py`
131
+
132
+ The function connects to CloudSQL PostgreSQL using private IP (10.171.208.52) and uses environment variables for DB credentials.
133
+
134
+ ```yaml
135
+ environment_variables:
136
+ CLOUD_RUN_PROXY_URL: "https://postgres-mcp-toolbox-186512416539.us-east4.run.app"
137
+ DB_PROXY_API_KEY: "${DB_PROXY_API_KEY}"
138
+ LOG_LEVEL: "INFO"
139
+ ```
140
+
141
+ ### Building and Publishing the Package
142
+
143
+ To build and publish the package to PyPI:
144
+
145
+ ```bash
146
+ python -m build
147
+ python -m twine upload dist/*
148
+ ```
149
+
150
+ ## Available Tools
151
+
152
+ This MCP server provides the following tools to AI assistants:
153
+
154
+ - `run_query`: Execute SQL queries against the database
155
+ - `get_schema`: Get database schema information
156
+ - `list_databases`: List available databases
157
+
158
+ ## Troubleshooting
159
+
160
+ ### Connection Issues with Claude Desktop
161
+
162
+ If you experience connection issues with Claude Desktop (client transport closing), ensure that:
163
+
164
+ 1. The server is running with the correct URL for the Cloud Run DB Proxy
165
+ 2. The API key is correctly set and properly escaped in any curl commands (use single quotes)
166
+ 3. The server is properly handling heartbeat and shutdown messages
167
+ 4. The JSON-RPC initialization response includes `keepAlive: true` and `supportsHeartbeats: true`
168
+
169
+ Example curl command to test the API:
170
+ ```bash
171
+ curl -X GET "https://postgres-mcp-toolbox-186512416539.us-east4.run.app/databases" -H 'X-API-KEY: YOUR_API_KEY_HERE'
172
+ ```
173
+
174
+ ### Common Issues
175
+
176
+ - **Missing API Key**: Ensure the `DB_PROXY_API_KEY` environment variable is set
177
+ - **Permission Errors**: Verify that your API key has the necessary permissions
178
+ - **Timeout Errors**: Check network latency or increase the timeout settings in the code
179
+ - **Heartbeat Issues**: Ensure the MCP server properly implements heartbeat handlers
@@ -0,0 +1,165 @@
1
+ # Nuuly Postgres MCP Server
2
+
3
+ MCP server for accessing Nuuly PostgreSQL database resources through Claude Desktop and other AI assistants.
4
+
5
+ ## Contents
6
+ - `src/nuuly_postgres_mcp_server/`: Package source code
7
+ - `__init__.py`: Package initialization
8
+ - `__main__.py`: Entry point for running as a module
9
+ - `server.py`: Main server implementation
10
+ - `pyproject.toml`: Package configuration
11
+ - `.env.example`: Example environment variables
12
+
13
+ ## Purpose
14
+ This MCP server provides PostgreSQL database connectivity functionality for the broader MCP platform. It connects to CloudSQL Postgres non-prod databases and enables AI code editors to:
15
+
16
+ 1. Understand all tables and schemas
17
+ 2. Run queries against the non-prod database
18
+ 3. List available databases and their aliases
19
+
20
+ ---
21
+
22
+ ## Installation
23
+
24
+ ### Option 1: Install from PyPI
25
+
26
+ ```bash
27
+ pip install nuuly-postgres-mcp-server
28
+ ```
29
+
30
+ ### Option 2: Install from Source
31
+
32
+ 1. Clone the repository:
33
+ ```bash
34
+ git clone <REPO_URL>
35
+ cd r15-mcp/mcp_servers/postgres-mcp
36
+ ```
37
+
38
+ 2. Install the package in development mode:
39
+ ```bash
40
+ pip install -e .
41
+ ```
42
+
43
+ ## Local Development
44
+
45
+ ### Prerequisites
46
+ - Python 3.8 or higher
47
+ - pip package manager
48
+
49
+ ### Setup
50
+
51
+ 1. Clone the repository:
52
+ ```bash
53
+ git clone <REPO_URL>
54
+ cd r15-mcp/mcp_servers/postgres-mcp
55
+ ```
56
+
57
+ 2. Create and activate a virtual environment (optional but recommended):
58
+ ```bash
59
+ python -m venv venv
60
+ source venv/bin/activate # On Windows: venv\Scripts\activate
61
+ ```
62
+
63
+ 3. Install development dependencies:
64
+ ```bash
65
+ pip install -e .
66
+ ```
67
+
68
+ 4. Set up environment variables:
69
+ ```bash
70
+ cp .env.example .env
71
+ # Edit .env with your actual values
72
+ ```
73
+
74
+ ## Environment Variables
75
+
76
+ The following environment variables can be set to customize the behavior of the MCP server:
77
+
78
+ - `CLOUD_RUN_PROXY_URL`: URL of the Cloud Run DB Proxy (default: "https://postgres-mcp-toolbox-186512416539.us-east4.run.app")
79
+ - `DB_PROXY_API_KEY`: API key for authenticating with the Cloud Run DB Proxy (required)
80
+ - `LOG_LEVEL`: Logging level (default: INFO)
81
+
82
+ ## Usage
83
+
84
+ ### For Claude Desktop
85
+
86
+ Add this configuration to your Claude Desktop settings:
87
+
88
+ ```json
89
+ {
90
+ "Nuuly Postgres MCP": {
91
+ "command": "nuuly-postgres-mcp",
92
+ "env": {
93
+ "PYTHONUNBUFFERED": "1",
94
+ "CLOUD_RUN_PROXY_URL": "https://postgres-mcp-toolbox-186512416539.us-east4.run.app",
95
+ "DB_PROXY_API_KEY": "YOUR_API_KEY_HERE"
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ### Command Line Usage
102
+
103
+ ```bash
104
+ nuuly-postgres-mcp
105
+ ```
106
+
107
+ ## Deployment
108
+
109
+ ### As a GCP Cloud Function
110
+
111
+ This MCP server is designed to be deployed as a GCP Cloud Function with the following parameters:
112
+
113
+ - Project: `rental-dev`
114
+ - Region: `us-east4`
115
+ - Serverless VPC Connector: `rental-vpc-connector`
116
+ - Entry point: `main.py`
117
+
118
+ The function connects to CloudSQL PostgreSQL using private IP (10.171.208.52) and uses environment variables for DB credentials.
119
+
120
+ ```yaml
121
+ environment_variables:
122
+ CLOUD_RUN_PROXY_URL: "https://postgres-mcp-toolbox-186512416539.us-east4.run.app"
123
+ DB_PROXY_API_KEY: "${DB_PROXY_API_KEY}"
124
+ LOG_LEVEL: "INFO"
125
+ ```
126
+
127
+ ### Building and Publishing the Package
128
+
129
+ To build and publish the package to PyPI:
130
+
131
+ ```bash
132
+ python -m build
133
+ python -m twine upload dist/*
134
+ ```
135
+
136
+ ## Available Tools
137
+
138
+ This MCP server provides the following tools to AI assistants:
139
+
140
+ - `run_query`: Execute SQL queries against the database
141
+ - `get_schema`: Get database schema information
142
+ - `list_databases`: List available databases
143
+
144
+ ## Troubleshooting
145
+
146
+ ### Connection Issues with Claude Desktop
147
+
148
+ If you experience connection issues with Claude Desktop (client transport closing), ensure that:
149
+
150
+ 1. The server is running with the correct URL for the Cloud Run DB Proxy
151
+ 2. The API key is correctly set and properly escaped in any curl commands (use single quotes)
152
+ 3. The server is properly handling heartbeat and shutdown messages
153
+ 4. The JSON-RPC initialization response includes `keepAlive: true` and `supportsHeartbeats: true`
154
+
155
+ Example curl command to test the API:
156
+ ```bash
157
+ curl -X GET "https://postgres-mcp-toolbox-186512416539.us-east4.run.app/databases" -H 'X-API-KEY: YOUR_API_KEY_HERE'
158
+ ```
159
+
160
+ ### Common Issues
161
+
162
+ - **Missing API Key**: Ensure the `DB_PROXY_API_KEY` environment variable is set
163
+ - **Permission Errors**: Verify that your API key has the necessary permissions
164
+ - **Timeout Errors**: Check network latency or increase the timeout settings in the code
165
+ - **Heartbeat Issues**: Ensure the MCP server properly implements heartbeat handlers
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "nuuly-postgres-mcp-server"
7
+ version = "1.0.0"
8
+ description = "MCP server for accessing Nuuly PostgreSQL database resources"
9
+ readme = "README.md"
10
+ authors = [{name = "Nuuly Engineering", email = "engineering@nuuly.com"}]
11
+ license = {text = "Proprietary"}
12
+ requires-python = ">=3.8"
13
+ dependencies = [
14
+ "fastmcp>=2.2.1",
15
+ "httpx>=0.24.0",
16
+ "psycopg2-binary>=2.9.5",
17
+ ]
18
+
19
+ [project.urls]
20
+ Homepage = "https://github.com/urbn/r15-mcp"
21
+ Repository = "https://github.com/urbn/r15-mcp"
22
+
23
+ [project.scripts]
24
+ nuuly-postgres-mcp = "nuuly_postgres_mcp_server.__main__:main"
25
+
26
+ [tool.setuptools.packages.find]
27
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,8 @@
1
+ """
2
+ Nuuly Postgres MCP Server package.
3
+ """
4
+
5
+ from .server import run
6
+
7
+ __version__ = "1.0.0"
8
+ __all__ = ["run"]
@@ -0,0 +1,26 @@
1
+ """
2
+ Entry point for running the Nuuly Postgres MCP Server as a module.
3
+ """
4
+
5
+ import logging
6
+ import sys
7
+ from . import run
8
+
9
+ def main():
10
+ """Entry point for running the package as a module."""
11
+ # Setup logging configuration
12
+ logging.basicConfig(
13
+ level=logging.INFO,
14
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
15
+ stream=sys.stderr
16
+ )
17
+
18
+ # Run the MCP server
19
+ try:
20
+ run()
21
+ except Exception as e:
22
+ logging.error(f"Error running MCP server: {e}")
23
+ sys.exit(1)
24
+
25
+ if __name__ == "__main__":
26
+ main()
@@ -0,0 +1,146 @@
1
+ """
2
+ Nuuly Postgres MCP Server
3
+ """
4
+
5
+ import os
6
+ import httpx
7
+ import logging
8
+ import sys
9
+ import json
10
+ from typing import Any, Dict, Optional
11
+
12
+ # Configure logging
13
+ logger = logging.getLogger(__name__)
14
+
15
+ # Configuration for Cloud Run DB Proxy
16
+ CLOUD_RUN_PROXY_URL = os.getenv("CLOUD_RUN_PROXY_URL", "https://www.example.com")
17
+ db_proxy_api_key = os.getenv("DB_PROXY_API_KEY")
18
+
19
+ # Import FastMCP
20
+ from fastmcp import FastMCP, Context
21
+
22
+ # Create MCP server with proper initialization
23
+ mcp = FastMCP("Nuuly Postgres MCP")
24
+
25
+ @mcp.tool()
26
+ async def run_query(ctx: Context, database: str, sql: str) -> str:
27
+ """Run a SQL query against the database and return results.
28
+
29
+ Args:
30
+ ctx: The MCP server provided context.
31
+ database: The name of a database (like orders, waving, box, product, etc)
32
+ sql: The SQL query string to execute. Accepts SELECT, SHOW, EXPLAIN queries only
33
+ Returns:
34
+ A JSON string representing the query result (columns and rows).
35
+ """
36
+ try:
37
+ # Validate API key is available
38
+ if not db_proxy_api_key:
39
+ logger.error("DB_PROXY_API_KEY environment variable not set")
40
+ return json.dumps({"error": "DB_PROXY_API_KEY environment variable not set"})
41
+
42
+ # Prepare request payload
43
+ payload = {
44
+ "database": database,
45
+ "sql": sql
46
+ }
47
+ headers = {"X-API-KEY": db_proxy_api_key}
48
+ url = f"{CLOUD_RUN_PROXY_URL}/query"
49
+
50
+ logger.info(f"Executing query on database: {database}")
51
+ async with httpx.AsyncClient(timeout=15) as client:
52
+ response = await client.post(url, json=payload, headers=headers)
53
+ response.raise_for_status()
54
+ return response.json()
55
+ except httpx.HTTPStatusError as e:
56
+ logger.error(f"HTTPStatusError: status={e.response.status_code}, body={e.response.text}")
57
+ return json.dumps({"error": f"Cloud Run proxy error: {e.response.status_code}", "details": e.response.text})
58
+ except Exception as e:
59
+ logger.error(f"Exception reaching Cloud Run DB proxy: {e}")
60
+ return json.dumps({"error": "Failed to reach Cloud Run DB proxy", "details": str(e)})
61
+
62
+ @mcp.tool()
63
+ async def get_schema(ctx: Context, database: str) -> str:
64
+ """Get the schema of all tables in the database.
65
+
66
+ Args:
67
+ ctx: The MCP server provided context.
68
+ database: The name of a database (like orders, waving, box, product, etc) - this can
69
+ be an instance name or an alias. A full list of databases is available via the
70
+ `list_databases` tool.
71
+ Returns:
72
+ A JSON string describing the tables and their columns, foreign keys, primary keys,
73
+ and constraints.
74
+ """
75
+ try:
76
+ # Validate API key is available
77
+ if not db_proxy_api_key:
78
+ logger.error("DB_PROXY_API_KEY environment variable not set")
79
+ return json.dumps({"error": "DB_PROXY_API_KEY environment variable not set"})
80
+
81
+ payload = {"database": database}
82
+ headers = {"X-API-KEY": db_proxy_api_key}
83
+ url = f"{CLOUD_RUN_PROXY_URL}/schema"
84
+
85
+ logger.info(f"Fetching schema for database: {database}")
86
+ async with httpx.AsyncClient(timeout=15) as client:
87
+ response = await client.post(url, json=payload, headers=headers)
88
+ response.raise_for_status()
89
+ return response.json()
90
+ except httpx.HTTPStatusError as e:
91
+ logger.error(f"HTTPStatusError: status={e.response.status_code}, body={e.response.text}")
92
+ return json.dumps({"error": f"Cloud Run proxy error: {e.response.status_code}", "details": e.response.text})
93
+ except Exception as e:
94
+ logger.error(f"Exception reaching Cloud Run DB proxy: {e}")
95
+ return json.dumps({"error": "Failed to reach Cloud Run DB proxy", "details": str(e)})
96
+
97
+ @mcp.tool()
98
+ async def list_databases(ctx: Context) -> str:
99
+ """List all databases and their aliases accessible via the Cloud Run DB Proxy.
100
+
101
+ Args:
102
+ ctx: The MCP server provided context.
103
+ Returns:
104
+ A JSON string representing the list of databases, their aliases, and instance info.
105
+ """
106
+ try:
107
+ # Validate API key is available
108
+ if not db_proxy_api_key:
109
+ logger.error("DB_PROXY_API_KEY environment variable not set")
110
+ return json.dumps({"error": "DB_PROXY_API_KEY environment variable not set"})
111
+
112
+ headers = {"X-API-KEY": db_proxy_api_key}
113
+ url = f"{CLOUD_RUN_PROXY_URL}/databases"
114
+
115
+ logger.info("Listing available databases")
116
+ async with httpx.AsyncClient(timeout=15) as client:
117
+ response = await client.get(url, headers=headers)
118
+ response.raise_for_status()
119
+ return response.json()
120
+ except httpx.HTTPStatusError as e:
121
+ logger.error(f"HTTPStatusError: status={e.response.status_code}, body={e.response.text}")
122
+ return json.dumps({"error": f"Cloud Run proxy error: {e.response.status_code}", "details": e.response.text})
123
+ except Exception as e:
124
+ logger.error(f"Exception reaching Cloud Run DB proxy: {e}")
125
+ return json.dumps({"error": "Failed to reach Cloud Run DB proxy", "details": str(e)})
126
+
127
+ def run():
128
+ """Entry point for the MCP server."""
129
+ # Setup logging configuration if not already configured
130
+ if not logging.getLogger().handlers:
131
+ logging.basicConfig(
132
+ level=logging.INFO,
133
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
134
+ stream=sys.stderr
135
+ )
136
+
137
+ # Add global exception handler
138
+ try:
139
+ logger.info("Starting Nuuly Postgres MCP Server")
140
+ mcp.run()
141
+ except Exception as e:
142
+ logger.error(f"Unhandled exception in MCP server: {e}", exc_info=True)
143
+ sys.exit(1)
144
+
145
+ if __name__ == "__main__":
146
+ run()
@@ -0,0 +1,179 @@
1
+ Metadata-Version: 2.4
2
+ Name: nuuly-postgres-mcp-server
3
+ Version: 1.0.0
4
+ Summary: MCP server for accessing Nuuly PostgreSQL database resources
5
+ Author-email: Nuuly Engineering <engineering@nuuly.com>
6
+ License: Proprietary
7
+ Project-URL: Homepage, https://github.com/urbn/r15-mcp
8
+ Project-URL: Repository, https://github.com/urbn/r15-mcp
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: fastmcp>=2.2.1
12
+ Requires-Dist: httpx>=0.24.0
13
+ Requires-Dist: psycopg2-binary>=2.9.5
14
+
15
+ # Nuuly Postgres MCP Server
16
+
17
+ MCP server for accessing Nuuly PostgreSQL database resources through Claude Desktop and other AI assistants.
18
+
19
+ ## Contents
20
+ - `src/nuuly_postgres_mcp_server/`: Package source code
21
+ - `__init__.py`: Package initialization
22
+ - `__main__.py`: Entry point for running as a module
23
+ - `server.py`: Main server implementation
24
+ - `pyproject.toml`: Package configuration
25
+ - `.env.example`: Example environment variables
26
+
27
+ ## Purpose
28
+ This MCP server provides PostgreSQL database connectivity functionality for the broader MCP platform. It connects to CloudSQL Postgres non-prod databases and enables AI code editors to:
29
+
30
+ 1. Understand all tables and schemas
31
+ 2. Run queries against the non-prod database
32
+ 3. List available databases and their aliases
33
+
34
+ ---
35
+
36
+ ## Installation
37
+
38
+ ### Option 1: Install from PyPI
39
+
40
+ ```bash
41
+ pip install nuuly-postgres-mcp-server
42
+ ```
43
+
44
+ ### Option 2: Install from Source
45
+
46
+ 1. Clone the repository:
47
+ ```bash
48
+ git clone <REPO_URL>
49
+ cd r15-mcp/mcp_servers/postgres-mcp
50
+ ```
51
+
52
+ 2. Install the package in development mode:
53
+ ```bash
54
+ pip install -e .
55
+ ```
56
+
57
+ ## Local Development
58
+
59
+ ### Prerequisites
60
+ - Python 3.8 or higher
61
+ - pip package manager
62
+
63
+ ### Setup
64
+
65
+ 1. Clone the repository:
66
+ ```bash
67
+ git clone <REPO_URL>
68
+ cd r15-mcp/mcp_servers/postgres-mcp
69
+ ```
70
+
71
+ 2. Create and activate a virtual environment (optional but recommended):
72
+ ```bash
73
+ python -m venv venv
74
+ source venv/bin/activate # On Windows: venv\Scripts\activate
75
+ ```
76
+
77
+ 3. Install development dependencies:
78
+ ```bash
79
+ pip install -e .
80
+ ```
81
+
82
+ 4. Set up environment variables:
83
+ ```bash
84
+ cp .env.example .env
85
+ # Edit .env with your actual values
86
+ ```
87
+
88
+ ## Environment Variables
89
+
90
+ The following environment variables can be set to customize the behavior of the MCP server:
91
+
92
+ - `CLOUD_RUN_PROXY_URL`: URL of the Cloud Run DB Proxy (default: "https://postgres-mcp-toolbox-186512416539.us-east4.run.app")
93
+ - `DB_PROXY_API_KEY`: API key for authenticating with the Cloud Run DB Proxy (required)
94
+ - `LOG_LEVEL`: Logging level (default: INFO)
95
+
96
+ ## Usage
97
+
98
+ ### For Claude Desktop
99
+
100
+ Add this configuration to your Claude Desktop settings:
101
+
102
+ ```json
103
+ {
104
+ "Nuuly Postgres MCP": {
105
+ "command": "nuuly-postgres-mcp",
106
+ "env": {
107
+ "PYTHONUNBUFFERED": "1",
108
+ "CLOUD_RUN_PROXY_URL": "https://postgres-mcp-toolbox-186512416539.us-east4.run.app",
109
+ "DB_PROXY_API_KEY": "YOUR_API_KEY_HERE"
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ ### Command Line Usage
116
+
117
+ ```bash
118
+ nuuly-postgres-mcp
119
+ ```
120
+
121
+ ## Deployment
122
+
123
+ ### As a GCP Cloud Function
124
+
125
+ This MCP server is designed to be deployed as a GCP Cloud Function with the following parameters:
126
+
127
+ - Project: `rental-dev`
128
+ - Region: `us-east4`
129
+ - Serverless VPC Connector: `rental-vpc-connector`
130
+ - Entry point: `main.py`
131
+
132
+ The function connects to CloudSQL PostgreSQL using private IP (10.171.208.52) and uses environment variables for DB credentials.
133
+
134
+ ```yaml
135
+ environment_variables:
136
+ CLOUD_RUN_PROXY_URL: "https://postgres-mcp-toolbox-186512416539.us-east4.run.app"
137
+ DB_PROXY_API_KEY: "${DB_PROXY_API_KEY}"
138
+ LOG_LEVEL: "INFO"
139
+ ```
140
+
141
+ ### Building and Publishing the Package
142
+
143
+ To build and publish the package to PyPI:
144
+
145
+ ```bash
146
+ python -m build
147
+ python -m twine upload dist/*
148
+ ```
149
+
150
+ ## Available Tools
151
+
152
+ This MCP server provides the following tools to AI assistants:
153
+
154
+ - `run_query`: Execute SQL queries against the database
155
+ - `get_schema`: Get database schema information
156
+ - `list_databases`: List available databases
157
+
158
+ ## Troubleshooting
159
+
160
+ ### Connection Issues with Claude Desktop
161
+
162
+ If you experience connection issues with Claude Desktop (client transport closing), ensure that:
163
+
164
+ 1. The server is running with the correct URL for the Cloud Run DB Proxy
165
+ 2. The API key is correctly set and properly escaped in any curl commands (use single quotes)
166
+ 3. The server is properly handling heartbeat and shutdown messages
167
+ 4. The JSON-RPC initialization response includes `keepAlive: true` and `supportsHeartbeats: true`
168
+
169
+ Example curl command to test the API:
170
+ ```bash
171
+ curl -X GET "https://postgres-mcp-toolbox-186512416539.us-east4.run.app/databases" -H 'X-API-KEY: YOUR_API_KEY_HERE'
172
+ ```
173
+
174
+ ### Common Issues
175
+
176
+ - **Missing API Key**: Ensure the `DB_PROXY_API_KEY` environment variable is set
177
+ - **Permission Errors**: Verify that your API key has the necessary permissions
178
+ - **Timeout Errors**: Check network latency or increase the timeout settings in the code
179
+ - **Heartbeat Issues**: Ensure the MCP server properly implements heartbeat handlers
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/nuuly_postgres_mcp_server/__init__.py
4
+ src/nuuly_postgres_mcp_server/__main__.py
5
+ src/nuuly_postgres_mcp_server/server.py
6
+ src/nuuly_postgres_mcp_server.egg-info/PKG-INFO
7
+ src/nuuly_postgres_mcp_server.egg-info/SOURCES.txt
8
+ src/nuuly_postgres_mcp_server.egg-info/dependency_links.txt
9
+ src/nuuly_postgres_mcp_server.egg-info/entry_points.txt
10
+ src/nuuly_postgres_mcp_server.egg-info/requires.txt
11
+ src/nuuly_postgres_mcp_server.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ nuuly-postgres-mcp = nuuly_postgres_mcp_server.__main__:main
@@ -0,0 +1,3 @@
1
+ fastmcp>=2.2.1
2
+ httpx>=0.24.0
3
+ psycopg2-binary>=2.9.5