couchbase-mcp-server 0.5.0__tar.gz → 0.5.2__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.
- couchbase_mcp_server-0.5.2/.github/workflows/alert-on-pr.yml +74 -0
- couchbase_mcp_server-0.5.2/.github/workflows/docker.yml +94 -0
- couchbase_mcp_server-0.5.2/.github/workflows/release.yml +38 -0
- couchbase_mcp_server-0.5.2/.github/workflows/test_release.yml +32 -0
- couchbase_mcp_server-0.5.2/.github/workflows/update-mcp-registry.yml +149 -0
- couchbase_mcp_server-0.5.2/.gitignore +12 -0
- couchbase_mcp_server-0.5.2/.pre-commit-config.yaml +37 -0
- couchbase_mcp_server-0.5.2/CONTRIBUTING.md +234 -0
- couchbase_mcp_server-0.5.2/DOCKER.md +78 -0
- couchbase_mcp_server-0.5.2/Dockerfile +61 -0
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/PKG-INFO +19 -13
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/README.md +6 -0
- couchbase_mcp_server-0.5.2/RELEASE.md +264 -0
- couchbase_mcp_server-0.5.2/build.sh +24 -0
- couchbase_mcp_server-0.5.2/glama.json +6 -0
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/pyproject.toml +25 -6
- couchbase_mcp_server-0.5.2/scripts/lint.sh +28 -0
- couchbase_mcp_server-0.5.2/scripts/lint_fix.sh +26 -0
- couchbase_mcp_server-0.5.2/scripts/update_version.sh +79 -0
- couchbase_mcp_server-0.5.2/server.json +253 -0
- couchbase_mcp_server-0.5.2/smithery.yaml +40 -0
- couchbase_mcp_server-0.5.2/src/certs/__init__.py +0 -0
- couchbase_mcp_server-0.5.2/src/certs/capella_root_ca.pem +19 -0
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/src/mcp_server.py +0 -1
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/src/tools/__init__.py +10 -0
- couchbase_mcp_server-0.5.2/src/tools/index.py +172 -0
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/src/tools/query.py +9 -1
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/src/tools/server.py +41 -0
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/src/utils/__init__.py +7 -0
- couchbase_mcp_server-0.5.2/src/utils/index_utils.py +308 -0
- couchbase_mcp_server-0.5.2/uv.lock +974 -0
- couchbase_mcp_server-0.5.0/setup.cfg +0 -4
- couchbase_mcp_server-0.5.0/src/couchbase_mcp_server.egg-info/PKG-INFO +0 -477
- couchbase_mcp_server-0.5.0/src/couchbase_mcp_server.egg-info/SOURCES.txt +0 -19
- couchbase_mcp_server-0.5.0/src/couchbase_mcp_server.egg-info/dependency_links.txt +0 -1
- couchbase_mcp_server-0.5.0/src/couchbase_mcp_server.egg-info/entry_points.txt +0 -2
- couchbase_mcp_server-0.5.0/src/couchbase_mcp_server.egg-info/requires.txt +0 -8
- couchbase_mcp_server-0.5.0/src/couchbase_mcp_server.egg-info/top_level.txt +0 -3
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/LICENSE +0 -0
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/src/tools/kv.py +0 -0
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/src/utils/config.py +0 -0
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/src/utils/connection.py +0 -0
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/src/utils/constants.py +0 -0
- {couchbase_mcp_server-0.5.0 → couchbase_mcp_server-0.5.2}/src/utils/context.py +0 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: Alert on PR Changes
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize, reopened]
|
|
6
|
+
pull_request_target:
|
|
7
|
+
types: [opened, synchronize, reopened]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
alert:
|
|
14
|
+
# Only run this job if:
|
|
15
|
+
# - The event is 'pull_request' and the PR is from the same repository (not a fork), OR
|
|
16
|
+
# - The event is 'pull_request_target' and the PR is from a forked repository.
|
|
17
|
+
# This ensures that PRs from forks are handled with 'pull_request_target' (for security),
|
|
18
|
+
# while PRs from the same repo are handled with 'pull_request'.
|
|
19
|
+
if: >-
|
|
20
|
+
(
|
|
21
|
+
github.event_name == 'pull_request' &&
|
|
22
|
+
github.event.pull_request.head.repo.full_name == github.repository
|
|
23
|
+
) ||
|
|
24
|
+
(
|
|
25
|
+
github.event_name == 'pull_request_target' &&
|
|
26
|
+
github.event.pull_request.head.repo.full_name != github.repository
|
|
27
|
+
)
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- name: Set up Python
|
|
31
|
+
uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.11"
|
|
34
|
+
|
|
35
|
+
- name: Install requests
|
|
36
|
+
run: |
|
|
37
|
+
python -m pip install --upgrade pip
|
|
38
|
+
pip install requests
|
|
39
|
+
|
|
40
|
+
- name: Send Slack alert on PR changes
|
|
41
|
+
env:
|
|
42
|
+
SLACK_WEBHOOK: ${{ secrets.DEVEX_ALERTS_SECRET }}
|
|
43
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
44
|
+
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
45
|
+
REPO: ${{ github.repository }}
|
|
46
|
+
shell: python
|
|
47
|
+
run: |
|
|
48
|
+
import os, requests
|
|
49
|
+
repo = os.environ['REPO']
|
|
50
|
+
pr_number = os.environ['PR_NUMBER']
|
|
51
|
+
token = os.environ['GITHUB_TOKEN']
|
|
52
|
+
api_url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}"
|
|
53
|
+
headers = {'Authorization': f'token {token}', 'Accept': 'application/vnd.github.v3+json'}
|
|
54
|
+
pr_resp = requests.get(api_url, headers=headers, timeout=15)
|
|
55
|
+
if pr_resp.ok:
|
|
56
|
+
pr = pr_resp.json()
|
|
57
|
+
branch_name = pr.get('head', {}).get('ref') or os.environ.get('GITHUB_HEAD_REF', '')
|
|
58
|
+
pr_title = pr.get('title', '')
|
|
59
|
+
pr_body = pr.get('body', '')
|
|
60
|
+
pr_user = pr.get('user', {}).get('login', '')
|
|
61
|
+
pr_url = pr.get('html_url', '')
|
|
62
|
+
prefix = "PR Alert from Forked Repo!" if pr.get('head', {}).get('repo', {}).get('fork') else "PR Alert!"
|
|
63
|
+
message = f"{prefix}\nTitle: {pr_title}\nBranch: {branch_name}\nAuthor: {pr_user}\nURL: {pr_url}\nDescription: {pr_body}"
|
|
64
|
+
else:
|
|
65
|
+
message = f"PR Alert!\nUnable to fetch PR details.\nStatus Code: {pr_resp.status_code}\nResponse: {pr_resp.text}"
|
|
66
|
+
webhook = os.environ.get('SLACK_WEBHOOK', '').strip()
|
|
67
|
+
if webhook and webhook.startswith(("http://", "https://")):
|
|
68
|
+
try:
|
|
69
|
+
resp = requests.post(webhook, json={"text": message}, timeout=15)
|
|
70
|
+
resp.raise_for_status()
|
|
71
|
+
except Exception as e:
|
|
72
|
+
print(f"Slack notification failed: {e}")
|
|
73
|
+
else:
|
|
74
|
+
print("SLACK_WEBHOOK missing or invalid; skipping Slack notification.")
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
name: Build and Push Docker Image
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
REGISTRY: docker.io
|
|
11
|
+
IMAGE_NAME: couchbaseecosystem/mcp-server-couchbase
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
docker:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Set up QEMU
|
|
22
|
+
uses: docker/setup-qemu-action@v3
|
|
23
|
+
|
|
24
|
+
- name: Set up Docker Buildx
|
|
25
|
+
uses: docker/setup-buildx-action@v3
|
|
26
|
+
|
|
27
|
+
- name: Log in to Docker Hub
|
|
28
|
+
if: github.event_name != 'pull_request'
|
|
29
|
+
uses: docker/login-action@v3
|
|
30
|
+
with:
|
|
31
|
+
registry: ${{ env.REGISTRY }}
|
|
32
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
33
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
34
|
+
|
|
35
|
+
- name: Check if stable release
|
|
36
|
+
id: check-stable
|
|
37
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
38
|
+
run: |
|
|
39
|
+
TAG_NAME="${GITHUB_REF#refs/tags/}"
|
|
40
|
+
echo "Checking tag: $TAG_NAME"
|
|
41
|
+
|
|
42
|
+
# Only match vX.Y.Z format (no suffixes like rc, alpha, beta)
|
|
43
|
+
if [[ "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
44
|
+
echo "is_stable=true" >> $GITHUB_OUTPUT
|
|
45
|
+
echo "This is a STABLE release: $TAG_NAME"
|
|
46
|
+
else
|
|
47
|
+
echo "is_stable=false" >> $GITHUB_OUTPUT
|
|
48
|
+
echo "This is a PRE-RELEASE: $TAG_NAME (will not update 'latest' or major.minor tags)"
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
- name: Extract metadata
|
|
52
|
+
id: meta
|
|
53
|
+
uses: docker/metadata-action@v5
|
|
54
|
+
with:
|
|
55
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
56
|
+
flavor: |
|
|
57
|
+
# Disable automatic 'latest' tag to have explicit control
|
|
58
|
+
latest=false
|
|
59
|
+
tags: |
|
|
60
|
+
# For PRs: tag as pr-<number>
|
|
61
|
+
type=ref,event=pr
|
|
62
|
+
# For all tags: extract full version without 'v' prefix (e.g., 0.5.2 or 0.5.2rc3)
|
|
63
|
+
type=match,pattern=v(.*),group=1
|
|
64
|
+
# For stable releases only: extract major.minor (e.g., 0.5 from v0.5.2)
|
|
65
|
+
type=match,pattern=v(\d+\.\d+),group=1,enable=${{ steps.check-stable.outputs.is_stable == 'true' }}
|
|
66
|
+
# For stable releases only: tag as 'latest'
|
|
67
|
+
type=raw,value=latest,enable=${{ steps.check-stable.outputs.is_stable == 'true' }}
|
|
68
|
+
|
|
69
|
+
- name: Set build timestamp
|
|
70
|
+
id: timestamp
|
|
71
|
+
run: echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
|
|
72
|
+
|
|
73
|
+
- name: Build and push Docker image
|
|
74
|
+
uses: docker/build-push-action@v6
|
|
75
|
+
with:
|
|
76
|
+
context: .
|
|
77
|
+
platforms: linux/amd64,linux/arm64
|
|
78
|
+
push: ${{ github.event_name != 'pull_request' }}
|
|
79
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
80
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
81
|
+
build-args: |
|
|
82
|
+
GIT_COMMIT_HASH=${{ github.sha }}
|
|
83
|
+
BUILD_DATE=${{ steps.timestamp.outputs.BUILD_DATE }}
|
|
84
|
+
cache-from: type=gha
|
|
85
|
+
cache-to: type=gha,mode=max
|
|
86
|
+
|
|
87
|
+
- name: Update Docker Hub description
|
|
88
|
+
if: github.ref_type == 'tag'
|
|
89
|
+
uses: peter-evans/dockerhub-description@v3
|
|
90
|
+
with:
|
|
91
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
92
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
93
|
+
repository: ${{ env.IMAGE_NAME }}
|
|
94
|
+
readme-filepath: ./DOCKER.md
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: PyPI Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v[0-9]+.[0-9]+.[0-9]+*" # Match tags like v0.1.0, v1.2.3, v1.2.3-alpha.1
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
pypi-publish:
|
|
11
|
+
name: Build and publish Python distributions to PyPI
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write # Required for trusted publishing
|
|
15
|
+
contents: write # Required for creating releases
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout repository
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install uv with python 3.11
|
|
22
|
+
uses: astral-sh/setup-uv@v6
|
|
23
|
+
with:
|
|
24
|
+
version: latest
|
|
25
|
+
python-version: 3.11
|
|
26
|
+
|
|
27
|
+
- name: Build package
|
|
28
|
+
run: uv build
|
|
29
|
+
|
|
30
|
+
- name: Publish package to PyPI
|
|
31
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
32
|
+
|
|
33
|
+
- name: Generate changelog and create release
|
|
34
|
+
uses: softprops/action-gh-release@v2
|
|
35
|
+
with:
|
|
36
|
+
generate_release_notes: true
|
|
37
|
+
prerelease: false
|
|
38
|
+
files: dist/*
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Test PyPI Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v[0-9]+.[0-9]+.[0-9]+*" # Match tags like v0.1.0, v1.2.3, v1.2.3-alpha.1
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test-pypi-publish:
|
|
11
|
+
name: Build and publish Python distributions to Test PyPI
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write # Required for trusted publishing
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout repository
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Install uv with python 3.11
|
|
21
|
+
uses: astral-sh/setup-uv@v6
|
|
22
|
+
with:
|
|
23
|
+
version: latest
|
|
24
|
+
python-version: 3.11
|
|
25
|
+
|
|
26
|
+
- name: Build package
|
|
27
|
+
run: uv build
|
|
28
|
+
|
|
29
|
+
- name: Publish package to TestPyPI
|
|
30
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
31
|
+
with:
|
|
32
|
+
repository-url: https://test.pypi.org/legacy/
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
name: Update MCP Registry
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows: ["Build and Push Docker Image"]
|
|
6
|
+
types:
|
|
7
|
+
- completed
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
check-and-update-registry:
|
|
11
|
+
# Only run on tag pushes and if the docker workflow succeeded
|
|
12
|
+
if: |
|
|
13
|
+
github.event.workflow_run.conclusion == 'success' &&
|
|
14
|
+
github.event.workflow_run.event == 'push' &&
|
|
15
|
+
startsWith(github.event.workflow_run.head_branch, 'v')
|
|
16
|
+
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
permissions:
|
|
19
|
+
id-token: write # Required for GitHub OIDC authentication with MCP Registry
|
|
20
|
+
contents: read
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout repository
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
with:
|
|
26
|
+
ref: ${{ github.event.workflow_run.head_branch }}
|
|
27
|
+
|
|
28
|
+
- name: Wait for PyPI release to complete
|
|
29
|
+
uses: fountainhead/action-wait-for-check@v1.2.0
|
|
30
|
+
id: wait-for-pypi
|
|
31
|
+
with:
|
|
32
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
33
|
+
checkName: "Build and publish Python distributions to PyPI"
|
|
34
|
+
ref: ${{ github.event.workflow_run.head_sha }}
|
|
35
|
+
timeoutSeconds: 600
|
|
36
|
+
intervalSeconds: 10
|
|
37
|
+
|
|
38
|
+
- name: Check PyPI release status
|
|
39
|
+
if: steps.wait-for-pypi.outputs.conclusion != 'success'
|
|
40
|
+
run: |
|
|
41
|
+
echo "PyPI release did not succeed. Status: ${{ steps.wait-for-pypi.outputs.conclusion }}"
|
|
42
|
+
exit 1
|
|
43
|
+
|
|
44
|
+
- name: Validate version consistency
|
|
45
|
+
id: version
|
|
46
|
+
env:
|
|
47
|
+
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
|
|
48
|
+
run: |
|
|
49
|
+
# Read versions from files
|
|
50
|
+
ROOT_VERSION=$(jq -r '.version' server.json)
|
|
51
|
+
# Only get versions from packages that have a version field (exclude null/empty)
|
|
52
|
+
PACKAGE_VERSIONS=$(jq -r '.packages[] | select(.version != null) | .version' server.json | sort -u)
|
|
53
|
+
PYPROJECT_VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
|
|
54
|
+
# Get tag from the triggering workflow (Docker), not current workflow
|
|
55
|
+
# Use environment variable to prevent code injection
|
|
56
|
+
TAG_VERSION=${HEAD_BRANCH#v}
|
|
57
|
+
|
|
58
|
+
echo "Version Check:"
|
|
59
|
+
echo " server.json root: $ROOT_VERSION"
|
|
60
|
+
echo " server.json packages:"
|
|
61
|
+
jq -r '.packages[] |
|
|
62
|
+
if .version != null then
|
|
63
|
+
" - \(.registryType):\(.identifier) = \(.version)"
|
|
64
|
+
else
|
|
65
|
+
" - \(.registryType):\(.identifier) (no version field)"
|
|
66
|
+
end' server.json
|
|
67
|
+
echo " pyproject.toml: $PYPROJECT_VERSION"
|
|
68
|
+
echo " Git tag: $TAG_VERSION"
|
|
69
|
+
echo ""
|
|
70
|
+
|
|
71
|
+
# Check if all package versions match root version (only for packages with version field)
|
|
72
|
+
MISMATCH=false
|
|
73
|
+
if [ -n "$PACKAGE_VERSIONS" ]; then
|
|
74
|
+
while IFS= read -r pkg_ver; do
|
|
75
|
+
if [ "$pkg_ver" != "$ROOT_VERSION" ]; then
|
|
76
|
+
echo "ERROR: Package version ($pkg_ver) doesn't match root version ($ROOT_VERSION)"
|
|
77
|
+
MISMATCH=true
|
|
78
|
+
fi
|
|
79
|
+
done <<< "$PACKAGE_VERSIONS"
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
if [ "$MISMATCH" = true ]; then
|
|
83
|
+
echo ""
|
|
84
|
+
echo "Fix: Update server.json so all package versions match the root version"
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Check if root version matches tag
|
|
89
|
+
if [ "$ROOT_VERSION" != "$TAG_VERSION" ]; then
|
|
90
|
+
echo "ERROR: server.json version ($ROOT_VERSION) doesn't match tag ($TAG_VERSION)"
|
|
91
|
+
echo "Fix: Update server.json root version to match the tag"
|
|
92
|
+
exit 1
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Warn if pyproject.toml doesn't match
|
|
96
|
+
if [ "$PYPROJECT_VERSION" != "$TAG_VERSION" ]; then
|
|
97
|
+
echo "WARNING: pyproject.toml version ($PYPROJECT_VERSION) doesn't match tag ($TAG_VERSION)"
|
|
98
|
+
echo "This may cause PyPI issues"
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Check Docker image tags in OCI identifiers
|
|
102
|
+
echo ""
|
|
103
|
+
echo "Checking Docker image tags..."
|
|
104
|
+
OCI_PACKAGES=$(jq -r '.packages[] | select(.registryType == "oci") | .identifier' server.json)
|
|
105
|
+
if [ -n "$OCI_PACKAGES" ]; then
|
|
106
|
+
OCI_TAG_MISMATCH=false
|
|
107
|
+
while IFS= read -r oci_id; do
|
|
108
|
+
# Extract tag from identifier (everything after last :)
|
|
109
|
+
IMAGE_TAG="${oci_id##*:}"
|
|
110
|
+
echo " - Image: $oci_id"
|
|
111
|
+
echo " Tag: $IMAGE_TAG"
|
|
112
|
+
|
|
113
|
+
if [ "$IMAGE_TAG" != "$ROOT_VERSION" ]; then
|
|
114
|
+
echo " ERROR: Docker image tag ($IMAGE_TAG) doesn't match version ($ROOT_VERSION)"
|
|
115
|
+
OCI_TAG_MISMATCH=true
|
|
116
|
+
else
|
|
117
|
+
echo " Tag matches"
|
|
118
|
+
fi
|
|
119
|
+
done <<< "$OCI_PACKAGES"
|
|
120
|
+
|
|
121
|
+
if [ "$OCI_TAG_MISMATCH" = true ]; then
|
|
122
|
+
echo ""
|
|
123
|
+
echo "Fix: Update Docker image tags in server.json to match the version"
|
|
124
|
+
exit 1
|
|
125
|
+
fi
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
echo ""
|
|
129
|
+
echo "All version checks passed!"
|
|
130
|
+
echo "version=$ROOT_VERSION" >> $GITHUB_OUTPUT
|
|
131
|
+
|
|
132
|
+
- name: Install MCP Publisher
|
|
133
|
+
run: |
|
|
134
|
+
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
|
|
135
|
+
|
|
136
|
+
- name: Login to MCP Registry
|
|
137
|
+
run: ./mcp-publisher login github-oidc
|
|
138
|
+
|
|
139
|
+
- name: Publish to MCP Registry
|
|
140
|
+
run: ./mcp-publisher publish
|
|
141
|
+
|
|
142
|
+
- name: Notify completion
|
|
143
|
+
if: success()
|
|
144
|
+
env:
|
|
145
|
+
VERSION: ${{ steps.version.outputs.version }}
|
|
146
|
+
run: |
|
|
147
|
+
echo "MCP Registry updated successfully for version $VERSION"
|
|
148
|
+
echo "Docker image: docker.io/couchbaseecosystem/mcp-server-couchbase:$VERSION"
|
|
149
|
+
echo "PyPI package: couchbase-mcp-server==$VERSION"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Pre-commit hooks configuration
|
|
2
|
+
# See https://pre-commit.com for more information
|
|
3
|
+
|
|
4
|
+
repos:
|
|
5
|
+
# Ruff linter and formatter
|
|
6
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
7
|
+
rev: v0.12.0
|
|
8
|
+
hooks:
|
|
9
|
+
# Run the linter
|
|
10
|
+
- id: ruff
|
|
11
|
+
name: ruff-lint
|
|
12
|
+
args: [--fix]
|
|
13
|
+
types_or: [python, pyi, jupyter]
|
|
14
|
+
# Run the formatter
|
|
15
|
+
- id: ruff-format
|
|
16
|
+
name: ruff-format
|
|
17
|
+
types_or: [python, pyi, jupyter]
|
|
18
|
+
|
|
19
|
+
# Additional useful hooks
|
|
20
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
21
|
+
rev: v4.6.0
|
|
22
|
+
hooks:
|
|
23
|
+
- id: trailing-whitespace
|
|
24
|
+
- id: end-of-file-fixer
|
|
25
|
+
- id: check-yaml
|
|
26
|
+
- id: check-toml
|
|
27
|
+
- id: check-merge-conflict
|
|
28
|
+
- id: check-added-large-files
|
|
29
|
+
- id: check-case-conflict
|
|
30
|
+
- id: debug-statements
|
|
31
|
+
|
|
32
|
+
# Check for Python syntax errors
|
|
33
|
+
- repo: https://github.com/pre-commit/pygrep-hooks
|
|
34
|
+
rev: v1.10.0
|
|
35
|
+
hooks:
|
|
36
|
+
- id: python-check-blanket-noqa
|
|
37
|
+
- id: python-no-log-warn
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# Contributing to Couchbase MCP Server
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to the Couchbase MCP Server! This guide will help you set up your development environment and understand our development workflow.
|
|
4
|
+
|
|
5
|
+
## 🚀 Development Setup
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
- **Python 3.10+**: Required for the project
|
|
10
|
+
- **[uv](https://docs.astral.sh/uv/)**: Fast Python package installer and dependency manager
|
|
11
|
+
- **Git**: For version control
|
|
12
|
+
- **VS Code** (recommended): With Python extension for the best development experience
|
|
13
|
+
|
|
14
|
+
### Clone and Setup
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Clone the repository
|
|
18
|
+
git clone https://github.com/Couchbase-Ecosystem/mcp-server-couchbase.git
|
|
19
|
+
cd mcp-server-couchbase
|
|
20
|
+
|
|
21
|
+
# Install dependencies (including development tools)
|
|
22
|
+
uv sync --extra dev
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Install Development Tools
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Install pre-commit hooks (runs linting on every commit)
|
|
29
|
+
uv run pre-commit install
|
|
30
|
+
|
|
31
|
+
# Verify installation
|
|
32
|
+
uv run pre-commit run --all-files
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 🧹 Code Quality & Linting
|
|
36
|
+
|
|
37
|
+
We use **[Ruff](https://docs.astral.sh/ruff/)** for fast linting and code formatting to maintain consistent code quality.
|
|
38
|
+
|
|
39
|
+
### Manual Linting
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Check code quality (no changes made)
|
|
43
|
+
./scripts/lint.sh
|
|
44
|
+
# or: uv run ruff check src/
|
|
45
|
+
|
|
46
|
+
# Auto-fix issues
|
|
47
|
+
./scripts/fix_lint.sh
|
|
48
|
+
# or: uv run ruff check src/ --fix && uv run ruff format src/
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Automatic Linting
|
|
52
|
+
|
|
53
|
+
- **Pre-commit hooks**: Ruff runs automatically on every `git commit`
|
|
54
|
+
- **VS Code**: Auto-format on save using [Ruff extension](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff)
|
|
55
|
+
|
|
56
|
+
### Linting Rules
|
|
57
|
+
|
|
58
|
+
Our Ruff configuration includes:
|
|
59
|
+
|
|
60
|
+
- **Code style**: PEP 8 compliance with 88-character line limit
|
|
61
|
+
- **Import organization**: Automatic import sorting and cleanup
|
|
62
|
+
- **Code quality**: Detection of unused variables, simplification opportunities
|
|
63
|
+
- **Modern Python**: Encourages modern Python patterns with `pyupgrade`
|
|
64
|
+
|
|
65
|
+
## 🏗️ Project Structure
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
mcp-server-couchbase/
|
|
69
|
+
├── src/
|
|
70
|
+
│ ├── mcp_server.py # MCP server entry point
|
|
71
|
+
│ ├── certs/ # SSL/TLS certificates
|
|
72
|
+
│ │ ├── __init__.py # Package marker
|
|
73
|
+
│ │ └── capella_root_ca.pem # Capella root CA certificate (for Capella connections)
|
|
74
|
+
│ ├── tools/ # MCP tool implementations
|
|
75
|
+
│ │ ├── __init__.py # Tool exports and ALL_TOOLS list
|
|
76
|
+
│ │ ├── server.py # Server status and connection tools
|
|
77
|
+
│ │ ├── kv.py # Key-value operations (CRUD)
|
|
78
|
+
│ │ ├── query.py # SQL++ query operations
|
|
79
|
+
│ │ └── index.py # Index operations and recommendations
|
|
80
|
+
│ └── utils/ # Utility modules
|
|
81
|
+
│ ├── __init__.py # Utility exports
|
|
82
|
+
│ ├── constants.py # Project constants
|
|
83
|
+
│ ├── config.py # Configuration management
|
|
84
|
+
│ ├── connection.py # Couchbase connection handling
|
|
85
|
+
│ ├── context.py # Application context management
|
|
86
|
+
│ └── index_utils.py # Index-related helper functions
|
|
87
|
+
├── scripts/ # Development scripts
|
|
88
|
+
│ ├── lint.sh # Manual linting script
|
|
89
|
+
│ └── lint_fix.sh # Auto-fix linting issues
|
|
90
|
+
├── .pre-commit-config.yaml # Pre-commit hook configuration
|
|
91
|
+
├── pyproject.toml # Project dependencies and Ruff config
|
|
92
|
+
├── CONTRIBUTING.md # Contribution Guide
|
|
93
|
+
└── README.md # Usage
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 🛠️ Development Workflow
|
|
97
|
+
|
|
98
|
+
### Making Changes
|
|
99
|
+
|
|
100
|
+
1. **Create a branch** for your feature/fix:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
git checkout -b feature/your-feature-name
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
2. **Make your changes** following the existing patterns
|
|
107
|
+
|
|
108
|
+
3. **Test your changes**:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Run linting
|
|
112
|
+
./scripts/lint.sh
|
|
113
|
+
|
|
114
|
+
# Test the MCP server
|
|
115
|
+
uv run src/mcp_server.py --help
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
4. **Commit your changes**:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
git add .
|
|
122
|
+
git commit -m "feat: add your feature description"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The pre-commit hooks will automatically run and fix any formatting issues.
|
|
126
|
+
|
|
127
|
+
### Adding New Tools
|
|
128
|
+
|
|
129
|
+
When adding new MCP tools:
|
|
130
|
+
|
|
131
|
+
1. **Create the tool function** in the appropriate module (in `tools` directory)
|
|
132
|
+
2. **Export the tool** in `tools/__init__.py`
|
|
133
|
+
3. **Add to ALL_TOOLS** list in `tools/__init__.py`
|
|
134
|
+
4. **Test the tool** with an MCP client
|
|
135
|
+
|
|
136
|
+
### Code Style Guidelines
|
|
137
|
+
|
|
138
|
+
- **Line length**: 88 characters (enforced by Ruff)
|
|
139
|
+
- **Import organization**: Use isort-style grouping (standard library, third-party, local)
|
|
140
|
+
- **Type hints**: Use modern Python type hints where helpful
|
|
141
|
+
- **Docstrings**: Add docstrings for public functions and classes
|
|
142
|
+
- **Error handling**: Include appropriate exception handling with logging
|
|
143
|
+
|
|
144
|
+
## 🧪 Testing
|
|
145
|
+
|
|
146
|
+
### Manual Testing
|
|
147
|
+
|
|
148
|
+
Currently, testing is done manually with MCP clients:
|
|
149
|
+
|
|
150
|
+
1. **Set up environment variables** for your Couchbase cluster
|
|
151
|
+
2. **Run the server** with an MCP client like Claude Desktop
|
|
152
|
+
3. **Test tool functionality** through the client interface
|
|
153
|
+
|
|
154
|
+
### Future Testing Plans
|
|
155
|
+
|
|
156
|
+
We plan to add:
|
|
157
|
+
|
|
158
|
+
- Unit tests for utility functions
|
|
159
|
+
- Integration tests
|
|
160
|
+
- Automated testing in CI/CD
|
|
161
|
+
|
|
162
|
+
## 📋 Adding New Features
|
|
163
|
+
|
|
164
|
+
### Before You Start
|
|
165
|
+
|
|
166
|
+
1. **Check existing issues** to see if someone is already working on it
|
|
167
|
+
2. **Open an issue** to discuss larger changes
|
|
168
|
+
3. **Review the codebase** to understand existing patterns
|
|
169
|
+
|
|
170
|
+
### Implementation Guidelines
|
|
171
|
+
|
|
172
|
+
1. **Follow existing patterns**: Look at similar tools for guidance
|
|
173
|
+
2. **Use the utility modules**: Leverage existing connection and context management
|
|
174
|
+
3. **Add proper logging**: Use the hierarchical logging system
|
|
175
|
+
4. **Handle errors gracefully**: Provide helpful error messages
|
|
176
|
+
5. **Update documentation**: Update README.md if adding user-facing features
|
|
177
|
+
|
|
178
|
+
## 🤝 Submitting Changes
|
|
179
|
+
|
|
180
|
+
1. **Run final checks**:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Ensure all linting passes
|
|
184
|
+
./scripts/lint.sh
|
|
185
|
+
|
|
186
|
+
# Test with pre-commit
|
|
187
|
+
uv run pre-commit run --all-files
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
2. **Push your branch** and create a pull request
|
|
191
|
+
|
|
192
|
+
3. **Describe your changes** in the PR description:
|
|
193
|
+
- What does this change do?
|
|
194
|
+
- Why is this change needed?
|
|
195
|
+
- How have you tested it?
|
|
196
|
+
|
|
197
|
+
## 💡 Tips for Contributors
|
|
198
|
+
|
|
199
|
+
### Common Development Tasks
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Install new dependencies
|
|
203
|
+
uv add package-name
|
|
204
|
+
|
|
205
|
+
# Install new dev dependencies
|
|
206
|
+
uv add --dev package-name
|
|
207
|
+
|
|
208
|
+
# Update dependencies
|
|
209
|
+
uv sync
|
|
210
|
+
|
|
211
|
+
# Run the server for testing
|
|
212
|
+
uv run src/mcp_server.py --connection-string "..." --username "..." --password "..." --bucket-name "..."
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Debugging
|
|
216
|
+
|
|
217
|
+
- **Use logging**: The project uses hierarchical logging with the pattern `logger = logging.getLogger(f"{MCP_SERVER_NAME}.module.name")`
|
|
218
|
+
- **Check connection**: Ensure your Couchbase cluster is accessible
|
|
219
|
+
- **Validate configuration**: Make sure all required environment variables are set
|
|
220
|
+
|
|
221
|
+
## 📖 Additional Resources
|
|
222
|
+
|
|
223
|
+
- **[Model Context Protocol Documentation](https://modelcontextprotocol.io/)**
|
|
224
|
+
- **[Couchbase Python SDK Documentation](https://docs.couchbase.com/python-sdk/current/hello-world/start-using-sdk.html)**
|
|
225
|
+
- **[SQL++ Query Language](https://www.couchbase.com/sqlplusplus/)**
|
|
226
|
+
- **[Ruff Documentation](https://docs.astral.sh/ruff/)**
|
|
227
|
+
|
|
228
|
+
## 🆘 Getting Help
|
|
229
|
+
|
|
230
|
+
- **Open an issue** for bugs or feature requests
|
|
231
|
+
- **Check existing issues** for similar problems
|
|
232
|
+
- **Review the code** for examples and patterns
|
|
233
|
+
|
|
234
|
+
Thank you for contributing to the Couchbase MCP Server! 🚀
|