Skip to content

Step 2 of publishing to PyPI #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*
!src
!uv.lock
!pyproject.toml
!pyproject.toml
!README.md
74 changes: 53 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,13 @@ jobs:
run: |
uv python install 3.12
uv sync --all-extras --dev
uv add --dev ruff isort mypy
uv add --dev ruff mypy

- name: ⚙️ Run linters and formatters
run: |
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
uv run isort --check-only src/ tests/
uv run mypy src/ --ignore-missing-imports
# uv run mypy src/ --ignore-missing-imports


security-scan:
Expand All @@ -66,14 +65,12 @@ jobs:
run: |
uv python install 3.12
uv sync --all-extras --dev
uv add --dev bandit safety
uv add --dev bandit

- name: ⚙️ Run security scan with bandit
run: |
uv run bandit -r src/ -f json -o bandit-report.json || true
uv run bandit -r src/
uv run safety check --output json > safety-report.json || true
uv run safety check

- name: ⚙️ Upload security reports
uses: actions/upload-artifact@v4
Expand All @@ -82,16 +79,14 @@ jobs:
name: security-reports
path: |
bandit-report.json
safety-report.json
retention-days: 30


test:
runs-on: ${{ matrix.os }}
test-ubuntu:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.10", "3.11", "3.12", "3.13"]

services:
Expand All @@ -110,7 +105,6 @@ jobs:
uses: step-security/harden-runner@v2
with:
egress-policy: audit
if: matrix.os == 'ubuntu-latest'

- name: ⚙️ Checkout the project
uses: actions/checkout@v4
Expand Down Expand Up @@ -139,7 +133,53 @@ jobs:
env:
REDIS_HOST: localhost
REDIS_PORT: 6379
if: matrix.os != 'windows-latest'

- name: ⚙️ Upload coverage reports
uses: codecov/codecov-action@v4
if: matrix.python-version == '3.12'
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella

test-other-os:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-latest]
python-version: ["3.10", "3.11", "3.12", "3.13"]

steps:
- name: ⚙️ Checkout the project
uses: actions/checkout@v4

- name: ⚙️ Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"

- name: ⚙️ Set Python ${{ matrix.python-version }} up and add dependencies
run: |
uv python install ${{ matrix.python-version }}
uv sync --all-extras --dev
uv add --dev pytest pytest-cov pytest-asyncio coverage

- name: ⚙️ Run tests (without Redis services)
run: |
uv run pytest tests/ -v
env:
REDIS_HOST: localhost
REDIS_PORT: 6379

- name: ⚙️ Test MCP server startup (macOS)
run: |
brew install coreutils
gtimeout 10s uv run python src/main.py || test $? = 124
env:
REDIS_HOST: localhost
REDIS_PORT: 6379
if: matrix.os == 'macos-latest'

- name: ⚙️ Test MCP server startup (Windows)
run: |
Expand All @@ -149,18 +189,10 @@ jobs:
REDIS_PORT: 6379
if: matrix.os == 'windows-latest'

- name: ⚙️ Upload coverage reports
uses: codecov/codecov-action@v4
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella


build-test:
runs-on: ubuntu-latest
needs: [lint-and-format, security-scan, test]
needs: [lint-and-format, security-scan, test-ubuntu, test-other-os]
steps:
- name: ⚙️ Harden Runner
uses: step-security/harden-runner@v2
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,11 @@ jobs:
run: |
uv python install 3.12
uv sync --all-extras --dev
uv add --dev bandit safety
uv add --dev bandit

- name: ⚙️ Run security scan with bandit
run: |
uv run bandit -r src/
uv run safety check

test:
runs-on: ubuntu-latest
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
# Redis MCP Server
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Integration](https://github.com/redis/mcp-redis/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/redis/lettuce/actions/workflows/integration.yml)
[![Python Version](https://img.shields.io/badge/python-3.13%2B-blue)](https://www.python.org/downloads/)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE.txt)
[![smithery badge](https://smithery.ai/badge/@redis/mcp-redis)](https://smithery.ai/server/@redis/mcp-redis)
[![Verified on MseeP](https://mseep.ai/badge.svg)](https://mseep.ai/app/70102150-efe0-4705-9f7d-87980109a279)
[![codecov](https://codecov.io/gh/redis/mcp-redis/branch/master/graph/badge.svg?token=yenl5fzxxr)](https://codecov.io/gh/redis/mcp-redis)


[![Discord](https://img.shields.io/discord/697882427875393627.svg?style=social&logo=discord)](https://discord.gg/redis)
[![Twitch](https://img.shields.io/twitch/status/redisinc?style=social)](https://www.twitch.tv/redisinc)
[![YouTube](https://img.shields.io/youtube/channel/views/UCD78lHSwYqMlyetR0_P4Vig?style=social)](https://www.youtube.com/redisinc)
[![Twitter](https://img.shields.io/twitter/follow/redisinc?style=social)](https://twitter.com/redisinc)
[![Stack Exchange questions](https://img.shields.io/stackexchange/stackoverflow/t/mcp-redis?style=social&logo=stackoverflow&label=Stackoverflow)](https://stackoverflow.com/questions/tagged/mcp-redis)

## Overview
The Redis MCP Server is a **natural language interface** designed for agentic applications to efficiently manage and search data in Redis. It integrates seamlessly with **MCP (Model Content Protocol) clients**, enabling AI-driven workflows to interact with structured and unstructured data in Redis. Using this MCP Server, you can ask questions like:
Expand Down
77 changes: 62 additions & 15 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,32 @@ skips = ["B101", "B601"] # Skip assert_used and shell_injection_process_args if
[tool.bandit.assert_used]
skips = ["*_test.py", "*/test_*.py"]

# Test configuration


[dependency-groups]
dev = [
"bandit[toml]>=1.8.6",
"black>=25.1.0",
"coverage>=7.10.1",
"mypy>=1.17.0",
"pytest>=8.4.1",
"pytest-asyncio>=1.1.0",
"pytest-cov>=6.2.1",
"pytest-mock>=3.12.0",
"ruff>=0.12.5",
"safety>=3.6.0",
"twine>=4.0",
]

test = [
"pytest>=8.4.1",
"pytest-asyncio>=1.1.0",
"pytest-cov>=6.2.1",
"pytest-mock>=3.12.0",
"coverage>=7.10.1",
]

# Testing configuration
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
Expand All @@ -62,23 +87,45 @@ addopts = [
"--strict-markers",
"--strict-config",
"--verbose",
"--cov=src",
"--cov-report=html",
"--cov-report=term",
"--cov-report=xml",
"--cov-fail-under=80",
]
markers = [
"slow: marks tests as slow",
"unit: marks tests as unit tests",
"integration: marks tests as integration tests",
"slow: marks tests as slow running",
]
asyncio_mode = "auto"
filterwarnings = [
"ignore::DeprecationWarning",
"ignore::PendingDeprecationWarning",
]

[dependency-groups]
dev = [
"bandit[toml]>=1.8.6",
"black>=25.1.0",
"coverage>=7.10.1",
"isort>=6.0.1",
"mypy>=1.17.0",
"pytest>=8.4.1",
"pytest-asyncio>=1.1.0",
"pytest-cov>=6.2.1",
"ruff>=0.12.5",
"safety>=3.6.0",
"twine>=4.0",
[tool.coverage.run]
source = ["src"]
omit = [
"*/tests/*",
"*/test_*.py",
"*/__pycache__/*",
"*/venv/*",
"*/.venv/*",
]

[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"if self.debug:",
"if settings.DEBUG",
"raise AssertionError",
"raise NotImplementedError",
"if 0:",
"if __name__ == .__main__.:",
"class .*\\bProtocol\\):",
"@(abc\\.)?abstractmethod",
]


2 changes: 1 addition & 1 deletion src/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.3.0"
__version__ = "0.3.0"
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Tests package for Redis MCP Server
Loading
Loading