couchbase-mcp-server 0.5.2rc5__tar.gz → 0.5.3__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.2rc5 → couchbase_mcp_server-0.5.3}/.github/workflows/docker.yml +12 -5
- couchbase_mcp_server-0.5.3/.github/workflows/test.yml +285 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/.github/workflows/update-mcp-registry.yml +5 -3
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/DOCKER.md +9 -0
- couchbase_mcp_server-0.5.2rc5/README.md → couchbase_mcp_server-0.5.3/PKG-INFO +50 -0
- couchbase_mcp_server-0.5.2rc5/PKG-INFO → couchbase_mcp_server-0.5.3/README.md +24 -24
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/pyproject.toml +8 -1
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/server.json +3 -3
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/tools/__init__.py +21 -0
- couchbase_mcp_server-0.5.3/src/tools/query.py +360 -0
- couchbase_mcp_server-0.5.3/tests/conftest.py +234 -0
- couchbase_mcp_server-0.5.3/tests/test_index_tools.py +209 -0
- couchbase_mcp_server-0.5.3/tests/test_kv_tools.py +217 -0
- couchbase_mcp_server-0.5.3/tests/test_mcp_integration.py +262 -0
- couchbase_mcp_server-0.5.3/tests/test_performance_tools.py +291 -0
- couchbase_mcp_server-0.5.3/tests/test_query_tools.py +156 -0
- couchbase_mcp_server-0.5.3/tests/test_server_tools.py +137 -0
- couchbase_mcp_server-0.5.3/tests/test_utils.py +556 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/uv.lock +94 -1
- couchbase_mcp_server-0.5.2rc5/src/tools/query.py +0 -98
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/.github/workflows/alert-on-pr.yml +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/.github/workflows/release.yml +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/.github/workflows/test_release.yml +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/.gitignore +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/.pre-commit-config.yaml +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/CONTRIBUTING.md +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/Dockerfile +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/LICENSE +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/RELEASE.md +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/build.sh +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/glama.json +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/scripts/lint.sh +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/scripts/lint_fix.sh +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/scripts/update_version.sh +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/smithery.yaml +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/certs/__init__.py +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/certs/capella_root_ca.pem +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/mcp_server.py +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/tools/index.py +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/tools/kv.py +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/tools/server.py +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/utils/__init__.py +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/utils/config.py +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/utils/connection.py +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/utils/constants.py +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/utils/context.py +0 -0
- {couchbase_mcp_server-0.5.2rc5 → couchbase_mcp_server-0.5.3}/src/utils/index_utils.py +0 -0
|
@@ -34,14 +34,18 @@ jobs:
|
|
|
34
34
|
|
|
35
35
|
- name: Check if stable release
|
|
36
36
|
id: check-stable
|
|
37
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
37
38
|
run: |
|
|
38
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)
|
|
39
43
|
if [[ "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
40
44
|
echo "is_stable=true" >> $GITHUB_OUTPUT
|
|
41
|
-
echo "This is a
|
|
45
|
+
echo "This is a STABLE release: $TAG_NAME"
|
|
42
46
|
else
|
|
43
47
|
echo "is_stable=false" >> $GITHUB_OUTPUT
|
|
44
|
-
echo "This is a
|
|
48
|
+
echo "This is a PRE-RELEASE: $TAG_NAME (will not update 'latest' or major.minor tags)"
|
|
45
49
|
fi
|
|
46
50
|
|
|
47
51
|
- name: Extract metadata
|
|
@@ -49,14 +53,17 @@ jobs:
|
|
|
49
53
|
uses: docker/metadata-action@v5
|
|
50
54
|
with:
|
|
51
55
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
56
|
+
flavor: |
|
|
57
|
+
# Disable automatic 'latest' tag to have explicit control
|
|
58
|
+
latest=false
|
|
52
59
|
tags: |
|
|
53
60
|
# For PRs: tag as pr-<number>
|
|
54
61
|
type=ref,event=pr
|
|
55
|
-
# For tags: extract full version without 'v' prefix (e.g., 0.5.2 or 0.5.2rc3)
|
|
56
|
-
type=match,pattern=v(.*),group=1
|
|
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
|
|
57
64
|
# For stable releases only: extract major.minor (e.g., 0.5 from v0.5.2)
|
|
58
65
|
type=match,pattern=v(\d+\.\d+),group=1,enable=${{ steps.check-stable.outputs.is_stable == 'true' }}
|
|
59
|
-
#
|
|
66
|
+
# For stable releases only: tag as 'latest'
|
|
60
67
|
type=raw,value=latest,enable=${{ steps.check-stable.outputs.is_stable == 'true' }}
|
|
61
68
|
|
|
62
69
|
- name: Set build timestamp
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
permissions:
|
|
4
|
+
contents: read
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [main]
|
|
11
|
+
|
|
12
|
+
env:
|
|
13
|
+
# Default test credentials for Couchbase
|
|
14
|
+
CB_USERNAME: Administrator
|
|
15
|
+
CB_PASSWORD: password
|
|
16
|
+
CB_MCP_TEST_BUCKET: travel-sample
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
# ============================================
|
|
20
|
+
# Integration Tests - All Transport Modes
|
|
21
|
+
# ============================================
|
|
22
|
+
integration-tests:
|
|
23
|
+
name: Integration (${{ matrix.transport }} transport)
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
strategy:
|
|
26
|
+
fail-fast: false
|
|
27
|
+
matrix:
|
|
28
|
+
transport: ["stdio", "http", "sse"]
|
|
29
|
+
|
|
30
|
+
services:
|
|
31
|
+
couchbase:
|
|
32
|
+
image: couchbase:enterprise-8.0.0
|
|
33
|
+
ports:
|
|
34
|
+
- 8091:8091
|
|
35
|
+
- 8092:8092
|
|
36
|
+
- 8093:8093
|
|
37
|
+
- 8094:8094
|
|
38
|
+
- 8095:8095
|
|
39
|
+
- 8096:8096
|
|
40
|
+
- 9102:9102
|
|
41
|
+
- 11210:11210
|
|
42
|
+
- 11207:11207
|
|
43
|
+
options: >-
|
|
44
|
+
--health-cmd "curl -s http://localhost:8091/pools || exit 1"
|
|
45
|
+
--health-interval 10s
|
|
46
|
+
--health-timeout 5s
|
|
47
|
+
--health-retries 30
|
|
48
|
+
|
|
49
|
+
steps:
|
|
50
|
+
- name: Checkout code
|
|
51
|
+
uses: actions/checkout@v4
|
|
52
|
+
|
|
53
|
+
- name: Install uv
|
|
54
|
+
uses: astral-sh/setup-uv@v4
|
|
55
|
+
with:
|
|
56
|
+
version: "latest"
|
|
57
|
+
|
|
58
|
+
- name: Set up Python (latest)
|
|
59
|
+
run: uv python install 3.13
|
|
60
|
+
|
|
61
|
+
- name: Install dependencies
|
|
62
|
+
run: uv sync --extra dev
|
|
63
|
+
|
|
64
|
+
- name: Wait for Couchbase to be ready
|
|
65
|
+
run: |
|
|
66
|
+
echo "Waiting for Couchbase to be fully ready..."
|
|
67
|
+
for i in {1..60}; do
|
|
68
|
+
if curl -s http://localhost:8091/pools > /dev/null 2>&1; then
|
|
69
|
+
echo "Couchbase REST API is responding"
|
|
70
|
+
break
|
|
71
|
+
fi
|
|
72
|
+
echo "Waiting for Couchbase... ($i/60)"
|
|
73
|
+
sleep 2
|
|
74
|
+
done
|
|
75
|
+
|
|
76
|
+
- name: Initialize Couchbase cluster
|
|
77
|
+
run: |
|
|
78
|
+
echo "Initializing Couchbase cluster..."
|
|
79
|
+
|
|
80
|
+
# Initialize node
|
|
81
|
+
curl -s -X POST http://localhost:8091/nodes/self/controller/settings \
|
|
82
|
+
-d 'path=/opt/couchbase/var/lib/couchbase/data' \
|
|
83
|
+
-d 'index_path=/opt/couchbase/var/lib/couchbase/data'
|
|
84
|
+
|
|
85
|
+
# Set up services
|
|
86
|
+
curl -s -X POST http://localhost:8091/node/controller/setupServices \
|
|
87
|
+
-d 'services=kv,n1ql,index,fts'
|
|
88
|
+
|
|
89
|
+
# Set memory quotas
|
|
90
|
+
curl -s -X POST http://localhost:8091/pools/default \
|
|
91
|
+
-d 'memoryQuota=512' \
|
|
92
|
+
-d 'indexMemoryQuota=256' \
|
|
93
|
+
-d 'ftsMemoryQuota=256'
|
|
94
|
+
|
|
95
|
+
# Set credentials
|
|
96
|
+
curl -s -X POST http://localhost:8091/settings/web \
|
|
97
|
+
-d "password=${{ env.CB_PASSWORD }}" \
|
|
98
|
+
-d "username=${{ env.CB_USERNAME }}" \
|
|
99
|
+
-d 'port=SAME'
|
|
100
|
+
|
|
101
|
+
echo "Cluster initialization complete"
|
|
102
|
+
|
|
103
|
+
- name: Create test bucket
|
|
104
|
+
run: |
|
|
105
|
+
echo "Creating test bucket..."
|
|
106
|
+
|
|
107
|
+
# Wait for cluster to be fully initialized
|
|
108
|
+
sleep 5
|
|
109
|
+
|
|
110
|
+
# Create travel-sample bucket (or a test bucket)
|
|
111
|
+
curl -s -X POST http://localhost:8091/pools/default/buckets \
|
|
112
|
+
-u "${{ env.CB_USERNAME }}:${{ env.CB_PASSWORD }}" \
|
|
113
|
+
-d 'name=${{ env.CB_MCP_TEST_BUCKET }}' \
|
|
114
|
+
-d 'bucketType=couchbase' \
|
|
115
|
+
-d 'ramQuota=256' \
|
|
116
|
+
-d 'flushEnabled=1'
|
|
117
|
+
|
|
118
|
+
# Wait for bucket to be ready
|
|
119
|
+
echo "Waiting for bucket to be ready..."
|
|
120
|
+
for i in {1..30}; do
|
|
121
|
+
if curl -s -u "${{ env.CB_USERNAME }}:${{ env.CB_PASSWORD }}" \
|
|
122
|
+
http://localhost:8091/pools/default/buckets/${{ env.CB_MCP_TEST_BUCKET }} | grep -q '"status":"healthy"'; then
|
|
123
|
+
echo "Bucket is healthy"
|
|
124
|
+
break
|
|
125
|
+
fi
|
|
126
|
+
echo "Waiting for bucket... ($i/30)"
|
|
127
|
+
sleep 2
|
|
128
|
+
done
|
|
129
|
+
|
|
130
|
+
- name: Create primary index
|
|
131
|
+
run: |
|
|
132
|
+
echo "Creating primary index..."
|
|
133
|
+
sleep 5
|
|
134
|
+
curl -s -X POST http://localhost:8093/query/service \
|
|
135
|
+
-u "${{ env.CB_USERNAME }}:${{ env.CB_PASSWORD }}" \
|
|
136
|
+
-d "statement=CREATE PRIMARY INDEX ON \`${{ env.CB_MCP_TEST_BUCKET }}\`._default._default" \
|
|
137
|
+
|| echo "Primary index may already exist or query service not ready"
|
|
138
|
+
|
|
139
|
+
- name: Insert test documents
|
|
140
|
+
run: |
|
|
141
|
+
echo "Inserting test documents..."
|
|
142
|
+
curl -s -X POST http://localhost:8093/query/service \
|
|
143
|
+
-u "${{ env.CB_USERNAME }}:${{ env.CB_PASSWORD }}" \
|
|
144
|
+
-d "statement=INSERT INTO \`${{ env.CB_MCP_TEST_BUCKET }}\`._default._default (KEY, VALUE) VALUES {\"type\": \"test\", \"name\": \"Test Document 1\", \"id\": 1})" \
|
|
145
|
+
|| echo "Insert may have failed"
|
|
146
|
+
|
|
147
|
+
curl -s -X POST http://localhost:8093/query/service \
|
|
148
|
+
-u "${{ env.CB_USERNAME }}:${{ env.CB_PASSWORD }}" \
|
|
149
|
+
-d "statement=INSERT INTO \`${{ env.CB_MCP_TEST_BUCKET }}\`._default._default (KEY, VALUE) VALUES ('test-doc-2', {\"type\": \"test\", \"name\": \"Test Document 2\", \"id\": 2})" \
|
|
150
|
+
|| echo "Insert may have failed"
|
|
151
|
+
|
|
152
|
+
# ============================================
|
|
153
|
+
# STDIO Transport Tests
|
|
154
|
+
# ============================================
|
|
155
|
+
- name: Run STDIO integration tests
|
|
156
|
+
if: matrix.transport == 'stdio'
|
|
157
|
+
env:
|
|
158
|
+
CB_CONNECTION_STRING: couchbase://localhost
|
|
159
|
+
CB_MCP_TRANSPORT: stdio
|
|
160
|
+
PYTHONPATH: src
|
|
161
|
+
run: |
|
|
162
|
+
echo "Running tests with STDIO transport..."
|
|
163
|
+
uv run pytest tests/ -v --tb=short
|
|
164
|
+
|
|
165
|
+
# ============================================
|
|
166
|
+
# HTTP Transport Tests
|
|
167
|
+
# ============================================
|
|
168
|
+
- name: Start MCP server (HTTP)
|
|
169
|
+
if: matrix.transport == 'http'
|
|
170
|
+
env:
|
|
171
|
+
CB_CONNECTION_STRING: couchbase://localhost
|
|
172
|
+
CB_MCP_TRANSPORT: http
|
|
173
|
+
CB_MCP_HOST: 127.0.0.1
|
|
174
|
+
CB_MCP_PORT: 8000
|
|
175
|
+
PYTHONPATH: src
|
|
176
|
+
run: |
|
|
177
|
+
echo "Starting MCP server with HTTP transport..."
|
|
178
|
+
uv run python -m mcp_server &
|
|
179
|
+
SERVER_PID=$!
|
|
180
|
+
echo "SERVER_PID=$SERVER_PID" >> $GITHUB_ENV
|
|
181
|
+
|
|
182
|
+
# Wait for server to be ready (check if port is listening)
|
|
183
|
+
echo "Waiting for HTTP server to be ready..."
|
|
184
|
+
for i in {1..30}; do
|
|
185
|
+
if nc -z 127.0.0.1 8000 2>/dev/null; then
|
|
186
|
+
echo "HTTP server is ready"
|
|
187
|
+
break
|
|
188
|
+
fi
|
|
189
|
+
echo "Waiting for HTTP server... ($i/30)"
|
|
190
|
+
sleep 1
|
|
191
|
+
done
|
|
192
|
+
|
|
193
|
+
- name: Run HTTP transport tests
|
|
194
|
+
if: matrix.transport == 'http'
|
|
195
|
+
env:
|
|
196
|
+
CB_CONNECTION_STRING: couchbase://localhost
|
|
197
|
+
CB_MCP_TRANSPORT: http
|
|
198
|
+
CB_MCP_HOST: 127.0.0.1
|
|
199
|
+
CB_MCP_PORT: 8000
|
|
200
|
+
MCP_SERVER_URL: http://127.0.0.1:8000/mcp
|
|
201
|
+
PYTHONPATH: src
|
|
202
|
+
run: |
|
|
203
|
+
echo "Running tests with HTTP transport..."
|
|
204
|
+
uv run pytest tests/ -v --tb=short
|
|
205
|
+
|
|
206
|
+
- name: Stop HTTP server
|
|
207
|
+
if: matrix.transport == 'http' && always()
|
|
208
|
+
run: |
|
|
209
|
+
if [ -n "$SERVER_PID" ]; then
|
|
210
|
+
kill $SERVER_PID 2>/dev/null || true
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
# ============================================
|
|
214
|
+
# SSE Transport Tests
|
|
215
|
+
# ============================================
|
|
216
|
+
- name: Start MCP server (SSE)
|
|
217
|
+
if: matrix.transport == 'sse'
|
|
218
|
+
env:
|
|
219
|
+
CB_CONNECTION_STRING: couchbase://localhost
|
|
220
|
+
CB_MCP_TRANSPORT: sse
|
|
221
|
+
CB_MCP_HOST: 127.0.0.1
|
|
222
|
+
CB_MCP_PORT: 8000
|
|
223
|
+
PYTHONPATH: src
|
|
224
|
+
run: |
|
|
225
|
+
echo "Starting MCP server with SSE transport..."
|
|
226
|
+
uv run python -m mcp_server &
|
|
227
|
+
SERVER_PID=$!
|
|
228
|
+
echo "SERVER_PID=$SERVER_PID" >> $GITHUB_ENV
|
|
229
|
+
|
|
230
|
+
# Wait for server to be ready (check if port is listening)
|
|
231
|
+
echo "Waiting for SSE server to be ready..."
|
|
232
|
+
for i in {1..30}; do
|
|
233
|
+
if nc -z 127.0.0.1 8000 2>/dev/null; then
|
|
234
|
+
echo "SSE server is ready"
|
|
235
|
+
break
|
|
236
|
+
fi
|
|
237
|
+
echo "Waiting for SSE server... ($i/30)"
|
|
238
|
+
sleep 1
|
|
239
|
+
done
|
|
240
|
+
|
|
241
|
+
- name: Run SSE transport tests
|
|
242
|
+
if: matrix.transport == 'sse'
|
|
243
|
+
env:
|
|
244
|
+
CB_CONNECTION_STRING: couchbase://localhost
|
|
245
|
+
CB_MCP_TRANSPORT: sse
|
|
246
|
+
CB_MCP_HOST: 127.0.0.1
|
|
247
|
+
CB_MCP_PORT: 8000
|
|
248
|
+
MCP_SERVER_URL: http://127.0.0.1:8000/sse
|
|
249
|
+
PYTHONPATH: src
|
|
250
|
+
run: |
|
|
251
|
+
echo "Running tests with SSE transport..."
|
|
252
|
+
uv run pytest tests/ -v --tb=short
|
|
253
|
+
|
|
254
|
+
- name: Stop SSE server
|
|
255
|
+
if: matrix.transport == 'sse' && always()
|
|
256
|
+
run: |
|
|
257
|
+
if [ -n "$SERVER_PID" ]; then
|
|
258
|
+
kill $SERVER_PID 2>/dev/null || true
|
|
259
|
+
fi
|
|
260
|
+
|
|
261
|
+
# ============================================
|
|
262
|
+
# Test Summary
|
|
263
|
+
# ============================================
|
|
264
|
+
test-summary:
|
|
265
|
+
name: Test Summary
|
|
266
|
+
permissions: {}
|
|
267
|
+
runs-on: ubuntu-latest
|
|
268
|
+
needs: [integration-tests]
|
|
269
|
+
if: always()
|
|
270
|
+
steps:
|
|
271
|
+
- name: Check test results
|
|
272
|
+
run: |
|
|
273
|
+
echo "=== Test Results Summary ==="
|
|
274
|
+
echo "Integration Tests: ${{ needs.integration-tests.result }}"
|
|
275
|
+
echo ""
|
|
276
|
+
|
|
277
|
+
if [ "${{ needs.integration-tests.result }}" == "failure" ]; then
|
|
278
|
+
echo "❌ Some tests failed"
|
|
279
|
+
exit 1
|
|
280
|
+
elif [ "${{ needs.integration-tests.result }}" == "cancelled" ]; then
|
|
281
|
+
echo "⚠️ Tests were cancelled"
|
|
282
|
+
exit 1
|
|
283
|
+
else
|
|
284
|
+
echo "✅ All tests passed!"
|
|
285
|
+
fi
|
|
@@ -141,7 +141,9 @@ jobs:
|
|
|
141
141
|
|
|
142
142
|
- name: Notify completion
|
|
143
143
|
if: success()
|
|
144
|
+
env:
|
|
145
|
+
VERSION: ${{ steps.version.outputs.version }}
|
|
144
146
|
run: |
|
|
145
|
-
echo "MCP Registry updated successfully for version $
|
|
146
|
-
echo "Docker image: docker.io/couchbaseecosystem/mcp-server-couchbase:$
|
|
147
|
-
echo "PyPI package: couchbase-mcp-server==$
|
|
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"
|
|
@@ -19,12 +19,21 @@ Dockerfile: https://github.com/Couchbase-Ecosystem/mcp-server-couchbase/blob/mai
|
|
|
19
19
|
- Upsert a document by ID to a specified scope and collection
|
|
20
20
|
- Delete a document by ID from a specified scope and collection
|
|
21
21
|
- Run a [SQL++ query](https://www.couchbase.com/sqlplusplus/) on a specified scope
|
|
22
|
+
- Queries are automatically scoped to the specified bucket and scope, so use collection names directly (e.g., use `SELECT * FROM users` instead of `SELECT * FROM bucket.scope.users`)
|
|
22
23
|
- There is an option in the MCP server, `CB_MCP_READ_ONLY_QUERY_MODE` that is set to true by default to disable running SQL++ queries that change the data or the underlying collection structure. Note that the documents can still be updated by ID.
|
|
23
24
|
- Get the status of the MCP server
|
|
24
25
|
- Check the cluster credentials by connecting to the cluster
|
|
25
26
|
- List all indexes in the cluster with their definitions, with optional filtering by bucket, scope, collection and index name.
|
|
26
27
|
- Get index recommendations from Couchbase Index Advisor for a given SQL++ query to optimize query performance
|
|
27
28
|
- Get cluster health status and list of all running services
|
|
29
|
+
- Query performance analysis tools using:
|
|
30
|
+
- Get longest running queries by average service time
|
|
31
|
+
- Get most frequently executed queries
|
|
32
|
+
- Get queries with the largest response sizes
|
|
33
|
+
- Get queries with the largest result counts
|
|
34
|
+
- Get queries that use a primary index (potential performance concern)
|
|
35
|
+
- Get queries that don't use a covering index
|
|
36
|
+
- Get queries that are not selective (index scans return many more documents than final result)
|
|
28
37
|
|
|
29
38
|
## Usage
|
|
30
39
|
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: couchbase-mcp-server
|
|
3
|
+
Version: 0.5.3
|
|
4
|
+
Summary: Couchbase MCP Server - The Developer Data Platform for Critical Applications in Our AI World
|
|
5
|
+
Project-URL: Homepage, https://github.com/Couchbase-Ecosystem/mcp-server-couchbase
|
|
6
|
+
Project-URL: Documentation, https://github.com/Couchbase-Ecosystem/mcp-server-couchbase#readme
|
|
7
|
+
Project-URL: Issues, https://github.com/Couchbase-Ecosystem/mcp-server-couchbase/issues
|
|
8
|
+
Author-email: Nithish Raghunandanan <devadvocates@couchbase.com>
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Database
|
|
14
|
+
Requires-Python: <3.14,>=3.10
|
|
15
|
+
Requires-Dist: click<9.0.0,>=8.2.1
|
|
16
|
+
Requires-Dist: couchbase<5.0.0,>=4.4.0
|
|
17
|
+
Requires-Dist: lark-sqlpp>=0.0.1
|
|
18
|
+
Requires-Dist: mcp[cli]<2.0.0,>=1.20.0
|
|
19
|
+
Requires-Dist: urllib3>=2.0.0
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: pre-commit==4.2.0; extra == 'dev'
|
|
22
|
+
Requires-Dist: pytest-asyncio==0.24.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest==8.3.3; extra == 'dev'
|
|
24
|
+
Requires-Dist: ruff==0.12.5; extra == 'dev'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
1
27
|
# Couchbase MCP Server
|
|
2
28
|
|
|
3
29
|
An [MCP](https://modelcontextprotocol.io/) server implementation of Couchbase that allows LLMs to directly interact with Couchbase clusters.
|
|
@@ -21,12 +47,21 @@ An [MCP](https://modelcontextprotocol.io/) server implementation of Couchbase th
|
|
|
21
47
|
- Upsert a document by ID to a specified scope and collection
|
|
22
48
|
- Delete a document by ID from a specified scope and collection
|
|
23
49
|
- Run a [SQL++ query](https://www.couchbase.com/sqlplusplus/) on a specified scope
|
|
50
|
+
- Queries are automatically scoped to the specified bucket and scope, so use collection names directly (e.g., use `SELECT * FROM users` instead of `SELECT * FROM bucket.scope.users`)
|
|
24
51
|
- There is an option in the MCP server, `CB_MCP_READ_ONLY_QUERY_MODE` that is set to true by default to disable running SQL++ queries that change the data or the underlying collection structure. Note that the documents can still be updated by ID.
|
|
25
52
|
- Get the status of the MCP server
|
|
26
53
|
- Check the cluster credentials by connecting to the cluster
|
|
27
54
|
- List all indexes in the cluster with their definitions, with optional filtering by bucket, scope, collection and index name.
|
|
28
55
|
- Get index recommendations from Couchbase Index Advisor for a given SQL++ query to optimize query performance
|
|
29
56
|
- Get cluster health status and list of all running services
|
|
57
|
+
- Query performance analysis tools:
|
|
58
|
+
- Get longest running queries by average service time
|
|
59
|
+
- Get most frequently executed queries
|
|
60
|
+
- Get queries with the largest response sizes
|
|
61
|
+
- Get queries with the largest result counts
|
|
62
|
+
- Get queries that use a primary index (potential performance concern)
|
|
63
|
+
- Get queries that don't use a covering index
|
|
64
|
+
- Get queries that are not selective (index scans return many more documents than final result)
|
|
30
65
|
|
|
31
66
|
## Prerequisites
|
|
32
67
|
|
|
@@ -409,6 +444,21 @@ The Couchbase MCP server can also be used as a managed server in your agentic ap
|
|
|
409
444
|
- Check the logs for any errors or warnings that may indicate issues with the MCP server. The location of the logs depend on your MCP client.
|
|
410
445
|
- If you are observing issues running your MCP server from source after updating your local MCP server repository, try running `uv sync` to update the [dependencies](https://docs.astral.sh/uv/concepts/projects/sync/#syncing-the-environment).
|
|
411
446
|
|
|
447
|
+
## Integration testing
|
|
448
|
+
|
|
449
|
+
We provide high-level MCP integration tests to verify that the server exposes the expected tools and that they can be invoked against a demo Couchbase cluster.
|
|
450
|
+
|
|
451
|
+
1. Export demo cluster credentials:
|
|
452
|
+
- `CB_CONNECTION_STRING`
|
|
453
|
+
- `CB_USERNAME`
|
|
454
|
+
- `CB_PASSWORD`
|
|
455
|
+
- Optional: `CB_MCP_TEST_BUCKET` (a bucket to probe during the tests)
|
|
456
|
+
2. Run the tests:
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
uv run pytest tests/ -v
|
|
460
|
+
```
|
|
461
|
+
|
|
412
462
|
---
|
|
413
463
|
|
|
414
464
|
## 👩💻 Contributing
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: couchbase-mcp-server
|
|
3
|
-
Version: 0.5.2rc5
|
|
4
|
-
Summary: Couchbase MCP Server - The Developer Data Platform for Critical Applications in Our AI World
|
|
5
|
-
Project-URL: Homepage, https://github.com/Couchbase-Ecosystem/mcp-server-couchbase
|
|
6
|
-
Project-URL: Documentation, https://github.com/Couchbase-Ecosystem/mcp-server-couchbase#readme
|
|
7
|
-
Project-URL: Issues, https://github.com/Couchbase-Ecosystem/mcp-server-couchbase/issues
|
|
8
|
-
Author-email: Nithish Raghunandanan <devadvocates@couchbase.com>
|
|
9
|
-
License-Expression: Apache-2.0
|
|
10
|
-
License-File: LICENSE
|
|
11
|
-
Classifier: Development Status :: 4 - Beta
|
|
12
|
-
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Topic :: Database
|
|
14
|
-
Requires-Python: <3.14,>=3.10
|
|
15
|
-
Requires-Dist: click<9.0.0,>=8.2.1
|
|
16
|
-
Requires-Dist: couchbase<5.0.0,>=4.4.0
|
|
17
|
-
Requires-Dist: lark-sqlpp>=0.0.1
|
|
18
|
-
Requires-Dist: mcp[cli]<2.0.0,>=1.20.0
|
|
19
|
-
Requires-Dist: urllib3>=2.0.0
|
|
20
|
-
Provides-Extra: dev
|
|
21
|
-
Requires-Dist: pre-commit==4.2.0; extra == 'dev'
|
|
22
|
-
Requires-Dist: ruff==0.12.5; extra == 'dev'
|
|
23
|
-
Description-Content-Type: text/markdown
|
|
24
|
-
|
|
25
1
|
# Couchbase MCP Server
|
|
26
2
|
|
|
27
3
|
An [MCP](https://modelcontextprotocol.io/) server implementation of Couchbase that allows LLMs to directly interact with Couchbase clusters.
|
|
@@ -45,12 +21,21 @@ An [MCP](https://modelcontextprotocol.io/) server implementation of Couchbase th
|
|
|
45
21
|
- Upsert a document by ID to a specified scope and collection
|
|
46
22
|
- Delete a document by ID from a specified scope and collection
|
|
47
23
|
- Run a [SQL++ query](https://www.couchbase.com/sqlplusplus/) on a specified scope
|
|
24
|
+
- Queries are automatically scoped to the specified bucket and scope, so use collection names directly (e.g., use `SELECT * FROM users` instead of `SELECT * FROM bucket.scope.users`)
|
|
48
25
|
- There is an option in the MCP server, `CB_MCP_READ_ONLY_QUERY_MODE` that is set to true by default to disable running SQL++ queries that change the data or the underlying collection structure. Note that the documents can still be updated by ID.
|
|
49
26
|
- Get the status of the MCP server
|
|
50
27
|
- Check the cluster credentials by connecting to the cluster
|
|
51
28
|
- List all indexes in the cluster with their definitions, with optional filtering by bucket, scope, collection and index name.
|
|
52
29
|
- Get index recommendations from Couchbase Index Advisor for a given SQL++ query to optimize query performance
|
|
53
30
|
- Get cluster health status and list of all running services
|
|
31
|
+
- Query performance analysis tools:
|
|
32
|
+
- Get longest running queries by average service time
|
|
33
|
+
- Get most frequently executed queries
|
|
34
|
+
- Get queries with the largest response sizes
|
|
35
|
+
- Get queries with the largest result counts
|
|
36
|
+
- Get queries that use a primary index (potential performance concern)
|
|
37
|
+
- Get queries that don't use a covering index
|
|
38
|
+
- Get queries that are not selective (index scans return many more documents than final result)
|
|
54
39
|
|
|
55
40
|
## Prerequisites
|
|
56
41
|
|
|
@@ -433,6 +418,21 @@ The Couchbase MCP server can also be used as a managed server in your agentic ap
|
|
|
433
418
|
- Check the logs for any errors or warnings that may indicate issues with the MCP server. The location of the logs depend on your MCP client.
|
|
434
419
|
- If you are observing issues running your MCP server from source after updating your local MCP server repository, try running `uv sync` to update the [dependencies](https://docs.astral.sh/uv/concepts/projects/sync/#syncing-the-environment).
|
|
435
420
|
|
|
421
|
+
## Integration testing
|
|
422
|
+
|
|
423
|
+
We provide high-level MCP integration tests to verify that the server exposes the expected tools and that they can be invoked against a demo Couchbase cluster.
|
|
424
|
+
|
|
425
|
+
1. Export demo cluster credentials:
|
|
426
|
+
- `CB_CONNECTION_STRING`
|
|
427
|
+
- `CB_USERNAME`
|
|
428
|
+
- `CB_PASSWORD`
|
|
429
|
+
- Optional: `CB_MCP_TEST_BUCKET` (a bucket to probe during the tests)
|
|
430
|
+
2. Run the tests:
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
uv run pytest tests/ -v
|
|
434
|
+
```
|
|
435
|
+
|
|
436
436
|
---
|
|
437
437
|
|
|
438
438
|
## 👩💻 Contributing
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "couchbase-mcp-server"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.3"
|
|
4
4
|
description = "Couchbase MCP Server - The Developer Data Platform for Critical Applications in Our AI World"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10,<3.14"
|
|
@@ -35,6 +35,8 @@ couchbase-mcp-server = "mcp_server:main"
|
|
|
35
35
|
dev = [
|
|
36
36
|
"ruff==0.12.5",
|
|
37
37
|
"pre-commit==4.2.0",
|
|
38
|
+
"pytest==8.3.3",
|
|
39
|
+
"pytest-asyncio==0.24.0",
|
|
38
40
|
]
|
|
39
41
|
|
|
40
42
|
# Ruff configuration
|
|
@@ -124,6 +126,11 @@ indent-style = "space"
|
|
|
124
126
|
skip-magic-trailing-comma = false
|
|
125
127
|
line-ending = "auto"
|
|
126
128
|
|
|
129
|
+
# Pytest configuration
|
|
130
|
+
[tool.pytest.ini_options]
|
|
131
|
+
asyncio_mode = "strict"
|
|
132
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
133
|
+
|
|
127
134
|
# Build system configuration
|
|
128
135
|
[build-system]
|
|
129
136
|
requires = ["hatchling"]
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/Couchbase-Ecosystem/mcp-server-couchbase",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.5.
|
|
9
|
+
"version": "0.5.3",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "pypi",
|
|
13
13
|
"identifier": "couchbase-mcp-server",
|
|
14
|
-
"version": "0.5.
|
|
14
|
+
"version": "0.5.3",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
},
|
|
173
173
|
{
|
|
174
174
|
"registryType": "oci",
|
|
175
|
-
"identifier": "docker.io/couchbaseecosystem/mcp-server-couchbase:0.5.
|
|
175
|
+
"identifier": "docker.io/couchbaseecosystem/mcp-server-couchbase:0.5.3",
|
|
176
176
|
"transport": {
|
|
177
177
|
"type": "stdio"
|
|
178
178
|
},
|
|
@@ -16,6 +16,13 @@ from .kv import (
|
|
|
16
16
|
|
|
17
17
|
# Query tools
|
|
18
18
|
from .query import (
|
|
19
|
+
get_longest_running_queries,
|
|
20
|
+
get_most_frequent_queries,
|
|
21
|
+
get_queries_not_selective,
|
|
22
|
+
get_queries_not_using_covering_index,
|
|
23
|
+
get_queries_using_primary_index,
|
|
24
|
+
get_queries_with_large_result_count,
|
|
25
|
+
get_queries_with_largest_response_sizes,
|
|
19
26
|
get_schema_for_collection,
|
|
20
27
|
run_sql_plus_plus_query,
|
|
21
28
|
)
|
|
@@ -47,6 +54,13 @@ ALL_TOOLS = [
|
|
|
47
54
|
get_index_advisor_recommendations,
|
|
48
55
|
list_indexes,
|
|
49
56
|
get_cluster_health_and_services,
|
|
57
|
+
get_queries_not_selective,
|
|
58
|
+
get_queries_not_using_covering_index,
|
|
59
|
+
get_queries_using_primary_index,
|
|
60
|
+
get_queries_with_large_result_count,
|
|
61
|
+
get_queries_with_largest_response_sizes,
|
|
62
|
+
get_longest_running_queries,
|
|
63
|
+
get_most_frequent_queries,
|
|
50
64
|
]
|
|
51
65
|
|
|
52
66
|
__all__ = [
|
|
@@ -65,6 +79,13 @@ __all__ = [
|
|
|
65
79
|
"get_index_advisor_recommendations",
|
|
66
80
|
"list_indexes",
|
|
67
81
|
"get_cluster_health_and_services",
|
|
82
|
+
"get_queries_not_selective",
|
|
83
|
+
"get_queries_not_using_covering_index",
|
|
84
|
+
"get_queries_using_primary_index",
|
|
85
|
+
"get_queries_with_large_result_count",
|
|
86
|
+
"get_queries_with_largest_response_sizes",
|
|
87
|
+
"get_longest_running_queries",
|
|
88
|
+
"get_most_frequent_queries",
|
|
68
89
|
# Convenience
|
|
69
90
|
"ALL_TOOLS",
|
|
70
91
|
]
|