Skip to content

Commit 2696b9b

Browse files
author
Vinod Durairaj
committed
feat: add PyPI publishing automation
- Add GitHub Actions workflows for CI/CD - test.yml: Run tests on push/PR with Python 3.10-3.12 - publish.yml: Publish to PyPI on version tags - Configure Hatch version management in pyproject.toml - Add project URLs and keywords for PyPI listing - Create release automation script (scripts/release.sh) - Update README with PyPI installation instructions and badges - Add uv.lock for dependency management - Update version to 0.3.1 in __init__.py This enables automated releases to PyPI when pushing version tags, making the package installable via: pip install redshift-utils-mcp
1 parent 59d2420 commit 2696b9b

File tree

10 files changed

+1153
-27
lines changed

10 files changed

+1153
-27
lines changed

.github/workflows/publish.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
release:
8+
types: [published]
9+
10+
jobs:
11+
build-and-publish:
12+
runs-on: ubuntu-latest
13+
environment:
14+
name: pypi
15+
url: https://pypi.org/project/redshift-utils-mcp/
16+
permissions:
17+
id-token: write # For trusted publishing
18+
contents: write # For creating releases
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- name: Set up Python
24+
uses: actions/setup-python@v5
25+
with:
26+
python-version: '3.11'
27+
28+
- name: Install uv
29+
uses: astral-sh/setup-uv@v5
30+
with:
31+
enable-cache: true
32+
33+
- name: Install dependencies
34+
run: |
35+
uv pip install --system build twine
36+
37+
- name: Build package
38+
run: |
39+
python -m build
40+
ls -la dist/
41+
42+
- name: Check distribution
43+
run: |
44+
twine check dist/*
45+
46+
- name: Test package installation
47+
run: |
48+
python -m venv test_env
49+
source test_env/bin/activate
50+
pip install dist/*.whl
51+
redshift-utils-mcp --help
52+
deactivate
53+
rm -rf test_env
54+
55+
# Optional: Publish to Test PyPI first
56+
- name: Publish to Test PyPI
57+
if: github.event_name == 'push' && contains(github.ref, 'test')
58+
env:
59+
TWINE_USERNAME: __token__
60+
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
61+
run: |
62+
twine upload --repository testpypi dist/*
63+
64+
# Publish to production PyPI
65+
- name: Publish to PyPI
66+
if: github.event_name == 'release' || (github.event_name == 'push' && !contains(github.ref, 'test'))
67+
env:
68+
TWINE_USERNAME: __token__
69+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
70+
run: |
71+
twine upload dist/*
72+
73+
# Create GitHub Release with artifacts
74+
- name: Upload Release Assets
75+
if: github.event_name == 'push'
76+
uses: softprops/action-gh-release@v2
77+
with:
78+
files: |
79+
dist/*.whl
80+
dist/*.tar.gz
81+
fail_on_unmatched_files: true
82+
generate_release_notes: true

.github/workflows/test.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: CI Tests
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.10", "3.11", "3.12"]
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
24+
- name: Install uv
25+
uses: astral-sh/setup-uv@v5
26+
with:
27+
enable-cache: true
28+
29+
- name: Install dependencies
30+
run: |
31+
uv sync --dev
32+
33+
- name: Check code formatting with black
34+
run: |
35+
uv run black --check src/
36+
37+
- name: Lint with ruff
38+
run: |
39+
uv run ruff check src/
40+
41+
- name: Run tests
42+
run: |
43+
uv run pytest tests/ -v
44+
45+
- name: Check package build
46+
run: |
47+
uv build
48+
ls -la dist/

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,9 @@ dmypy.json
132132
cython_debug/
133133

134134
# VSCode settings
135-
.vscode/
135+
.vscode/
136+
.roo/
137+
.claude/
138+
.spec-workflow/
139+
.venv-test/
140+
CLAUDE.md

.mcp.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"mcpServers": {
3+
"Ref": {
4+
"type": "http",
5+
"url": "https://api.ref.tools/mcp?apiKey=ref-950cda57b035ec8e16a9"
6+
},
7+
"cookiecutter-pypackage-docs": {
8+
"type": "http",
9+
"url": "https://gitmcp.io/audreyfeldroy/cookiecutter-pypackage"
10+
},
11+
"spec-workflow": {
12+
"command": "npx",
13+
"args": ["-y", "@pimzino/spec-workflow-mcp@latest", "/Users/vinoddu/Documents/code/redshift-utils-mcp","--AutoStartDashboard"]
14+
}
15+
}
16+
}

README.md

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010

1111
<!-- Stats in a clean format -->
1212
<p>
13+
<a href="https://pypi.org/project/redshift-utils-mcp/"><img src="https://img.shields.io/pypi/v/redshift-utils-mcp.svg" alt="PyPI version"></a>
14+
<a href="https://pypi.org/project/redshift-utils-mcp/"><img src="https://img.shields.io/pypi/dm/redshift-utils-mcp.svg" alt="Downloads"></a>
15+
<a href="https://pypi.org/project/redshift-utils-mcp/"><img src="https://img.shields.io/pypi/pyversions/redshift-utils-mcp.svg" alt="Python versions"></a>
1316
<img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License">
1417
<img src="https://img.shields.io/badge/Language-Python-blue.svg" alt="Python">
1518
</p>
@@ -30,15 +33,17 @@ This server is for developers, data analysts, or teams looking to integrate LLM
3033
- [Table of Contents](#table-of-contents)
3134
- [Features](#features)
3235
- [Prerequisites](#prerequisites)
36+
- [Installation](#installation)
37+
- [Install from PyPI (Recommended)](#install-from-pypi-recommended)
38+
- [Install from Source](#install-from-source)
3339
- [Configuration](#configuration)
3440
- [Usage](#usage)
3541
- [Connecting with Claude Desktop / Anthropic Console:](#connecting-with-claude-desktop--anthropic-console)
42+
- [Connecting with Claude Code CLI:](#connecting-with-claude-code-cli)
3643
- [Connecting with Cursor IDE:](#connecting-with-cursor-ide)
3744
- [Available MCP Resources](#available-mcp-resources)
3845
- [Available MCP Tools](#available-mcp-tools)
3946
- [TO DO](#to-do)
40-
- [Contributing](#contributing)
41-
- [License](#license)
4247
- [References](#references)
4348

4449
## Features
@@ -59,9 +64,8 @@ This server is for developers, data analysts, or teams looking to integrate LLM
5964
## Prerequisites
6065

6166
Software:
62-
* Python 3.8+
63-
* `uv` (recommended package manager)
64-
* Git (for cloning the repository)
67+
* Python 3.10+
68+
* `uv` (recommended package manager) or `pip`
6569

6670
Infrastructure & Access:
6771

@@ -81,6 +85,36 @@ Your Redshift connection details are managed via AWS Secrets Manager, and the se
8185

8286
These details will be configured via environment variables as detailed in the [Configuration](#configuration) section.
8387

88+
## Installation
89+
90+
### Install from PyPI (Recommended)
91+
92+
The easiest way to install the Redshift Utils MCP Server is directly from PyPI:
93+
94+
```bash
95+
# Using pip
96+
pip install redshift-utils-mcp
97+
98+
# Using uv (recommended)
99+
uv pip install redshift-utils-mcp
100+
```
101+
102+
### Install from Source
103+
104+
Alternatively, you can install from the source repository:
105+
106+
```bash
107+
# Clone the repository
108+
git clone https://github.com/vinodismyname/redshift-utils-mcp.git
109+
cd redshift-utils-mcp
110+
111+
# Install using uv (recommended)
112+
uv sync
113+
114+
# Or install using pip
115+
pip install -e .
116+
```
117+
84118
## Configuration
85119

86120
Set Environment Variables:
@@ -122,8 +156,18 @@ Required Variables Table:
122156

123157
## Usage
124158

159+
After installation, you can run the server directly from the command line:
160+
161+
```bash
162+
# If installed from PyPI
163+
redshift-utils-mcp
164+
165+
# Or using uvx (no installation required)
166+
uvx redshift-utils-mcp
167+
```
168+
125169
### Connecting with Claude Desktop / Anthropic Console:
126-
Add the following configuration block to your `mcp.json` file. Adjust `command`, `args`, `env`, and `workingDirectory` based on your installation method and setup.
170+
Add the following configuration block to your `mcp.json` file:
127171

128172
```json
129173
{
@@ -191,24 +235,6 @@ Accessibility of schemas/tables depends on the permissions granted to the Redshi
191235
- [ ] Add support for more credential methods
192236
- [ ] Add Support for Redshift Serverless
193237

194-
## Contributing
195-
196-
Contributions are welcome! Please follow these guidelines.
197-
198-
Find/Report Issues: Check the GitHub Issues page for existing bugs or feature requests. Feel free to open a new issue if needed.
199-
200-
Security is critical when providing database access via an MCP server. Please consider the following:
201-
202-
🔒 **Credentials Management:** This server uses AWS Secrets Manager via the Redshift Data API, which is a more secure approach than storing credentials directly in environment variables or configuration files. Ensure your AWS credentials used by Boto3 (via environment, profile, or IAM role) are managed securely and have the minimum necessary permissions. Never commit your AWS credentials or `.env` files containing secrets to version control.
203-
204-
🛡️ **Principle of Least Privilege:** Configure the Redshift user whose credentials are in AWS Secrets Manager with the minimum permissions required for the server's intended functionality. For example, if only read access is needed, grant only `CONNECT` and `SELECT` privileges on the necessary schemas/tables and `SELECT` on the required system views. Avoid using highly privileged users like `admin` or the cluster superuser.
205-
206-
For guidance on creating restricted Redshift users and managing permissions, refer to the official (https://docs.aws.amazon.com/redshift/latest/mgmt/security.html).
207-
208-
## License
209-
210-
This project is licensed under the MIT License. See the (LICENSE) file for details.
211-
212238
## References
213239

214240
* This project relies heavily on the [Model Context Protocol specification](https://modelcontextprotocol.io/specification/).

pyproject.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ classifiers = [
1414
"License :: OSI Approved :: MIT License",
1515
"Operating System :: OS Independent",
1616
]
17+
keywords = ["mcp", "redshift", "aws", "database", "model-context-protocol"]
1718
# Dependencies updated based on Tech Plan Section 9
1819
dependencies = [
1920
"fastmcp>=2.2.5",
@@ -26,6 +27,12 @@ dependencies = [
2627
"pytest-asyncio>=0.26.0",
2728
]
2829

30+
[project.urls]
31+
Homepage = "https://github.com/vinodismyname/redshift-utils-mcp"
32+
Documentation = "https://github.com/vinodismyname/redshift-utils-mcp#readme"
33+
Repository = "https://github.com/vinodismyname/redshift-utils-mcp"
34+
Issues = "https://github.com/vinodismyname/redshift-utils-mcp/issues"
35+
2936
[project.scripts]
3037
redshift-utils-mcp = "redshift_utils_mcp.__main__:app"
3138

@@ -43,6 +50,9 @@ build-backend = "hatchling.build"
4350
[tool.hatch.build.targets.wheel]
4451
packages = ["src/redshift_utils_mcp"]
4552

53+
[tool.hatch.version]
54+
path = "src/redshift_utils_mcp/__init__.py"
55+
4656
[dependency-groups]
4757
dev = [
4858
"black>=25.1.0",

0 commit comments

Comments
 (0)