mcp-postgresql-ops 3.4.3__tar.gz → 3.4.5__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.
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/workflows/pypi-publish.yml +18 -3
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/PKG-INFO +15 -2
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/README.md +14 -1
- mcp_postgresql_ops-3.4.5/mcpb/manifest.json +93 -0
- mcp_postgresql_ops-3.4.5/mcpb/server.py +7 -0
- mcp_postgresql_ops-3.4.5/scripts/build-mcpb.sh +37 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/scripts/publish_release.py +10 -4
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/PKG-INFO +15 -2
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/SOURCES.txt +3 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/scm_file_list.json +3 -0
- mcp_postgresql_ops-3.4.5/src/mcp_postgresql_ops.egg-info/scm_version.json +8 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/tests/test_release.py +51 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/uv.lock +24 -23
- mcp_postgresql_ops-3.4.3/src/mcp_postgresql_ops.egg-info/scm_version.json +0 -8
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.env.example +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/CONTRIBUTING.md +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/FUNDING.yml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/copilot-instructions.md +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/dependabot.yml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/pull_request_template.md +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/workflows/test.yml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.gitignore +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.gitleaks.toml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.pre-commit-config.yaml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.python-version +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/Dockerfile.MCP-Server +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/Dockerfile.MCPO-Proxy +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/LICENSE +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/MANIFEST.in +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/SECURITY.md +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/_config.yml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/_includes/head-custom-google-analytics.html +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/build-mcp-server-docker-image.sh +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/build-mcpo-server-docker-image.sh +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/docker-compose.custom-db.yml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/docker-compose.yml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/MCP-Workflow-of-Quickstart-Tutorial.png +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/screenshot-000.png +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/screenshot-001.png +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/screenshot-002.png +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/screenshot-004.png +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/screenshot-005.png +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/screenshot-claude-desktop-airflow-connections-html.png +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/screenshot-claude-desktop-mermaid-diagram.png +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/screenshot-claude-desktop-question-001.png +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/screenshot-swagger-api.png +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/mcp-config.json.http +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/mcp-config.json.stdio +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/pyproject.toml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/run-mcp-inspector-local.sh +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/run-mcp-inspector-pypi.sh +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/scripts/check_release.py +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/scripts/create-test-data.sh +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/scripts/create-test-data.sql +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/scripts/enable-pgsql-extensions.sh +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/scripts/mcp-server-docker-cmd.sh +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/setup.cfg +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/__init__.py +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/__main__.py +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/functions.py +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/mcp_main.py +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/prompt_template.md +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/version_compat.py +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/dependency_links.txt +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/entry_points.txt +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/requires.txt +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/top_level.txt +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/tests/__init__.py +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/tests/conftest.py +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/tests/docker/docker-compose.test.yml +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/tests/docker/init-test-db.sql +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/tests/test_tool_schema_null_defaults.py +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/tests/test_tools_integration.py +0 -0
- {mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/tests/test_version_compat.py +0 -0
|
@@ -18,8 +18,10 @@ jobs:
|
|
|
18
18
|
- uses: actions/setup-python@v7
|
|
19
19
|
with:
|
|
20
20
|
python-version: "3.12.x"
|
|
21
|
-
- name: Install build
|
|
22
|
-
run: pip install --upgrade build
|
|
21
|
+
- name: Install build and release test tools
|
|
22
|
+
run: pip install --upgrade build pytest
|
|
23
|
+
- name: Test release automation
|
|
24
|
+
run: python -m pytest -q tests/test_release.py
|
|
23
25
|
- name: Build distributions
|
|
24
26
|
run: python -m build
|
|
25
27
|
- name: Verify tag and distribution versions
|
|
@@ -31,6 +33,15 @@ jobs:
|
|
|
31
33
|
name: dist
|
|
32
34
|
path: dist/
|
|
33
35
|
if-no-files-found: error
|
|
36
|
+
- name: Build Claude Desktop bundle
|
|
37
|
+
env:
|
|
38
|
+
RELEASE_TAG: ${{ github.ref_name }}
|
|
39
|
+
run: scripts/build-mcpb.sh "$RELEASE_TAG" mcpb-dist
|
|
40
|
+
- uses: actions/upload-artifact@v7
|
|
41
|
+
with:
|
|
42
|
+
name: mcpb
|
|
43
|
+
path: mcpb-dist/
|
|
44
|
+
if-no-files-found: error
|
|
34
45
|
|
|
35
46
|
publish-to-testpypi:
|
|
36
47
|
name: Publish to TestPyPI
|
|
@@ -94,5 +105,9 @@ jobs:
|
|
|
94
105
|
- uses: actions/setup-python@v7
|
|
95
106
|
with:
|
|
96
107
|
python-version: "3.12.x"
|
|
108
|
+
- uses: actions/download-artifact@v8
|
|
109
|
+
with:
|
|
110
|
+
name: mcpb
|
|
111
|
+
path: mcpb-dist/
|
|
97
112
|
- name: Publish release with commit messages
|
|
98
|
-
run: python -m scripts.publish_release "$RELEASE_TAG"
|
|
113
|
+
run: python -m scripts.publish_release "$RELEASE_TAG" mcpb-dist/*.mcpb
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-postgresql-ops
|
|
3
|
-
Version: 3.4.
|
|
3
|
+
Version: 3.4.5
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Author-email: JungJungIn <call518@gmail.com>
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -283,7 +283,20 @@ The `create-test-data.sql` script is executed by the `postgres-init-extensions`
|
|
|
283
283
|
## Usage Examples
|
|
284
284
|
|
|
285
285
|
### Claude Desktop Integration
|
|
286
|
-
|
|
286
|
+
|
|
287
|
+
#### Desktop extension bundle (recommended)
|
|
288
|
+
|
|
289
|
+
1. Download `mcp-postgresql-ops-<version>.mcpb` from the latest
|
|
290
|
+
[GitHub Release](https://github.com/call518/MCP-PostgreSQL-Ops/releases).
|
|
291
|
+
2. In Claude Desktop, open **Settings > Extensions > Advanced settings >
|
|
292
|
+
Install Extension…** and select the downloaded file.
|
|
293
|
+
3. Enter the PostgreSQL host, port, user, password, and default database in the
|
|
294
|
+
extension settings.
|
|
295
|
+
|
|
296
|
+
#### PyPI package with uvx
|
|
297
|
+
|
|
298
|
+
Alternatively, add the following entry to your Claude Desktop configuration
|
|
299
|
+
file:
|
|
287
300
|
|
|
288
301
|
```json
|
|
289
302
|
{
|
|
@@ -265,7 +265,20 @@ The `create-test-data.sql` script is executed by the `postgres-init-extensions`
|
|
|
265
265
|
## Usage Examples
|
|
266
266
|
|
|
267
267
|
### Claude Desktop Integration
|
|
268
|
-
|
|
268
|
+
|
|
269
|
+
#### Desktop extension bundle (recommended)
|
|
270
|
+
|
|
271
|
+
1. Download `mcp-postgresql-ops-<version>.mcpb` from the latest
|
|
272
|
+
[GitHub Release](https://github.com/call518/MCP-PostgreSQL-Ops/releases).
|
|
273
|
+
2. In Claude Desktop, open **Settings > Extensions > Advanced settings >
|
|
274
|
+
Install Extension…** and select the downloaded file.
|
|
275
|
+
3. Enter the PostgreSQL host, port, user, password, and default database in the
|
|
276
|
+
extension settings.
|
|
277
|
+
|
|
278
|
+
#### PyPI package with uvx
|
|
279
|
+
|
|
280
|
+
Alternatively, add the following entry to your Claude Desktop configuration
|
|
281
|
+
file:
|
|
269
282
|
|
|
270
283
|
```json
|
|
271
284
|
{
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifest_version": "0.4",
|
|
3
|
+
"name": "mcp-postgresql-ops",
|
|
4
|
+
"display_name": "PostgreSQL Ops",
|
|
5
|
+
"version": "0.0.0",
|
|
6
|
+
"description": "Monitor and operate a PostgreSQL server with MCP tools.",
|
|
7
|
+
"long_description": "Runs MCP-PostgreSQL-Ops locally over stdio. Claude Desktop installs Python and the locked dependencies with uv.",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "JungJungIn",
|
|
10
|
+
"url": "https://github.com/call518"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/call518/MCP-PostgreSQL-Ops"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/call518/MCP-PostgreSQL-Ops",
|
|
17
|
+
"documentation": "https://github.com/call518/MCP-PostgreSQL-Ops#claude-desktop-integration",
|
|
18
|
+
"support": "https://github.com/call518/MCP-PostgreSQL-Ops/issues",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"keywords": [
|
|
21
|
+
"postgresql",
|
|
22
|
+
"database",
|
|
23
|
+
"operations",
|
|
24
|
+
"monitoring"
|
|
25
|
+
],
|
|
26
|
+
"server": {
|
|
27
|
+
"type": "uv",
|
|
28
|
+
"entry_point": "server.py",
|
|
29
|
+
"mcp_config": {
|
|
30
|
+
"command": "uv",
|
|
31
|
+
"args": [
|
|
32
|
+
"run",
|
|
33
|
+
"--directory",
|
|
34
|
+
"${__dirname}",
|
|
35
|
+
"server.py"
|
|
36
|
+
],
|
|
37
|
+
"env": {
|
|
38
|
+
"SETUPTOOLS_SCM_PRETEND_VERSION": "0.0.0",
|
|
39
|
+
"POSTGRES_HOST": "${user_config.postgres_host}",
|
|
40
|
+
"POSTGRES_PORT": "${user_config.postgres_port}",
|
|
41
|
+
"POSTGRES_USER": "${user_config.postgres_user}",
|
|
42
|
+
"POSTGRES_PASSWORD": "${user_config.postgres_password}",
|
|
43
|
+
"POSTGRES_DB": "${user_config.postgres_db}"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"user_config": {
|
|
48
|
+
"postgres_host": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"title": "PostgreSQL host (POSTGRES_HOST)",
|
|
51
|
+
"description": "Host name or IP address of the PostgreSQL server",
|
|
52
|
+
"required": true
|
|
53
|
+
},
|
|
54
|
+
"postgres_port": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"title": "PostgreSQL port (POSTGRES_PORT)",
|
|
57
|
+
"description": "PostgreSQL server port",
|
|
58
|
+
"default": "5432",
|
|
59
|
+
"required": true
|
|
60
|
+
},
|
|
61
|
+
"postgres_user": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"title": "PostgreSQL user (POSTGRES_USER)",
|
|
64
|
+
"description": "PostgreSQL connection user",
|
|
65
|
+
"default": "postgres",
|
|
66
|
+
"required": true
|
|
67
|
+
},
|
|
68
|
+
"postgres_password": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"title": "PostgreSQL password (POSTGRES_PASSWORD)",
|
|
71
|
+
"description": "PostgreSQL password, stored securely by Claude Desktop",
|
|
72
|
+
"sensitive": true,
|
|
73
|
+
"required": true
|
|
74
|
+
},
|
|
75
|
+
"postgres_db": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"title": "Default database (POSTGRES_DB)",
|
|
78
|
+
"description": "Default database for PostgreSQL operations",
|
|
79
|
+
"default": "postgres",
|
|
80
|
+
"required": true
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"compatibility": {
|
|
84
|
+
"platforms": [
|
|
85
|
+
"darwin",
|
|
86
|
+
"win32",
|
|
87
|
+
"linux"
|
|
88
|
+
],
|
|
89
|
+
"runtimes": {
|
|
90
|
+
"python": ">=3.12"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Build the Claude Desktop MCP Bundle (.mcpb) from an explicit file allowlist.
|
|
3
|
+
# Usage: scripts/build-mcpb.sh <version> [output-dir]
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
VERSION="${1:?usage: scripts/build-mcpb.sh <version> [output-dir]}"
|
|
7
|
+
OUT_DIR="${2:-dist}"
|
|
8
|
+
MCPB_CLI="@anthropic-ai/mcpb@2.1.2"
|
|
9
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
10
|
+
STAGE="$(mktemp -d)"
|
|
11
|
+
trap 'rm -rf "$STAGE"' EXIT
|
|
12
|
+
|
|
13
|
+
cp "$ROOT/mcpb/server.py" "$ROOT/pyproject.toml" "$ROOT/uv.lock" \
|
|
14
|
+
"$ROOT/README.md" "$ROOT/LICENSE" "$STAGE/"
|
|
15
|
+
mkdir -p "$STAGE/src"
|
|
16
|
+
cp -R "$ROOT/src/mcp_postgresql_ops" "$STAGE/src/"
|
|
17
|
+
find "$STAGE/src" -name '__pycache__' -type d -prune -exec rm -rf {} +
|
|
18
|
+
|
|
19
|
+
# The bundle has no Git metadata, so provide its release version to setuptools-scm.
|
|
20
|
+
python3 - "$ROOT/mcpb/manifest.json" "$STAGE/manifest.json" "$VERSION" <<'EOF'
|
|
21
|
+
import json
|
|
22
|
+
import sys
|
|
23
|
+
|
|
24
|
+
source, target, version = sys.argv[1:]
|
|
25
|
+
with open(source, encoding="utf-8") as source_file:
|
|
26
|
+
manifest = json.load(source_file)
|
|
27
|
+
manifest["version"] = version
|
|
28
|
+
manifest["server"]["mcp_config"]["env"]["SETUPTOOLS_SCM_PRETEND_VERSION"] = version
|
|
29
|
+
with open(target, "w", encoding="utf-8") as target_file:
|
|
30
|
+
json.dump(manifest, target_file, indent=2)
|
|
31
|
+
EOF
|
|
32
|
+
|
|
33
|
+
mkdir -p "$OUT_DIR"
|
|
34
|
+
OUTPUT="$(cd "$OUT_DIR" && pwd)/mcp-postgresql-ops-$VERSION.mcpb"
|
|
35
|
+
npx -y "$MCPB_CLI" validate "$STAGE/manifest.json"
|
|
36
|
+
npx -y "$MCPB_CLI" pack "$STAGE" "$OUTPUT"
|
|
37
|
+
echo "Built $OUTPUT"
|
|
@@ -67,9 +67,14 @@ def release_notes(repository: str, tag: str, previous: str | None) -> str:
|
|
|
67
67
|
return "\n".join(notes) + "\n"
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
def publish_release(
|
|
71
|
-
|
|
70
|
+
def publish_release(
|
|
71
|
+
repository: str, tag: str, assets: tuple[str, ...] = ()
|
|
72
|
+
) -> None:
|
|
73
|
+
"""Create a release once and attach assets after package publication."""
|
|
72
74
|
release_version(tag)
|
|
75
|
+
missing = [asset for asset in assets if not Path(asset).is_file()]
|
|
76
|
+
if missing:
|
|
77
|
+
raise ValueError(f"Release assets not found: {', '.join(missing)}")
|
|
73
78
|
current = command("git", "rev-parse", "--verify", f"refs/tags/{tag}^{{commit}}")
|
|
74
79
|
remote = command("gh", "api", f"repos/{repository}/commits/{tag}", "--jq", ".sha")
|
|
75
80
|
if current != remote or current != command("git", "rev-parse", "HEAD"):
|
|
@@ -117,7 +122,7 @@ def publish_release(repository: str, tag: str) -> None:
|
|
|
117
122
|
"--notes-file",
|
|
118
123
|
str(path),
|
|
119
124
|
]
|
|
120
|
-
command(*args)
|
|
125
|
+
command(*args, *assets)
|
|
121
126
|
print(f"Published GitHub Release {tag} (previous release: {previous or 'none'}).")
|
|
122
127
|
|
|
123
128
|
|
|
@@ -125,9 +130,10 @@ def main() -> None:
|
|
|
125
130
|
"""Publish only when explicitly called by the final release job."""
|
|
126
131
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
127
132
|
parser.add_argument("tag")
|
|
133
|
+
parser.add_argument("assets", nargs="*", help="Files to attach to the release")
|
|
128
134
|
args = parser.parse_args()
|
|
129
135
|
try:
|
|
130
|
-
publish_release(os.environ["GITHUB_REPOSITORY"], args.tag)
|
|
136
|
+
publish_release(os.environ["GITHUB_REPOSITORY"], args.tag, tuple(args.assets))
|
|
131
137
|
except subprocess.CalledProcessError as error:
|
|
132
138
|
parser.exit(1, f"Release command failed: {error.stderr or error}\n")
|
|
133
139
|
except (ValueError, KeyError, OSError) as error:
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-postgresql-ops
|
|
3
|
-
Version: 3.4.
|
|
3
|
+
Version: 3.4.5
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Author-email: JungJungIn <call518@gmail.com>
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -283,7 +283,20 @@ The `create-test-data.sql` script is executed by the `postgres-init-extensions`
|
|
|
283
283
|
## Usage Examples
|
|
284
284
|
|
|
285
285
|
### Claude Desktop Integration
|
|
286
|
-
|
|
286
|
+
|
|
287
|
+
#### Desktop extension bundle (recommended)
|
|
288
|
+
|
|
289
|
+
1. Download `mcp-postgresql-ops-<version>.mcpb` from the latest
|
|
290
|
+
[GitHub Release](https://github.com/call518/MCP-PostgreSQL-Ops/releases).
|
|
291
|
+
2. In Claude Desktop, open **Settings > Extensions > Advanced settings >
|
|
292
|
+
Install Extension…** and select the downloaded file.
|
|
293
|
+
3. Enter the PostgreSQL host, port, user, password, and default database in the
|
|
294
|
+
extension settings.
|
|
295
|
+
|
|
296
|
+
#### PyPI package with uvx
|
|
297
|
+
|
|
298
|
+
Alternatively, add the following entry to your Claude Desktop configuration
|
|
299
|
+
file:
|
|
287
300
|
|
|
288
301
|
```json
|
|
289
302
|
{
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/SOURCES.txt
RENAMED
|
@@ -43,6 +43,9 @@ img/screenshot-claude-desktop-airflow-connections-html.png
|
|
|
43
43
|
img/screenshot-claude-desktop-mermaid-diagram.png
|
|
44
44
|
img/screenshot-claude-desktop-question-001.png
|
|
45
45
|
img/screenshot-swagger-api.png
|
|
46
|
+
mcpb/manifest.json
|
|
47
|
+
mcpb/server.py
|
|
48
|
+
scripts/build-mcpb.sh
|
|
46
49
|
scripts/check_release.py
|
|
47
50
|
scripts/create-test-data.sh
|
|
48
51
|
scripts/create-test-data.sql
|
|
@@ -41,9 +41,12 @@
|
|
|
41
41
|
"img/screenshot-swagger-api.png",
|
|
42
42
|
"mcp-config.json.http",
|
|
43
43
|
"mcp-config.json.stdio",
|
|
44
|
+
"mcpb/manifest.json",
|
|
45
|
+
"mcpb/server.py",
|
|
44
46
|
"pyproject.toml",
|
|
45
47
|
"run-mcp-inspector-local.sh",
|
|
46
48
|
"run-mcp-inspector-pypi.sh",
|
|
49
|
+
"scripts/build-mcpb.sh",
|
|
47
50
|
"scripts/check_release.py",
|
|
48
51
|
"scripts/create-test-data.sh",
|
|
49
52
|
"scripts/create-test-data.sql",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import io
|
|
4
4
|
import json
|
|
5
|
+
import re
|
|
5
6
|
import sys
|
|
6
7
|
import tarfile
|
|
7
8
|
import zipfile
|
|
@@ -86,6 +87,24 @@ def test_first_release_creation():
|
|
|
86
87
|
assert "--latest=false" not in args
|
|
87
88
|
|
|
88
89
|
|
|
90
|
+
def test_release_creation_attaches_assets(tmp_path):
|
|
91
|
+
bundle = tmp_path / "mcp-postgresql-ops-1.2.3.mcpb"
|
|
92
|
+
bundle.write_bytes(b"bundle")
|
|
93
|
+
with patch("scripts.publish_release.command") as command:
|
|
94
|
+
command.side_effect = ["sha", "sha", "sha", "[[]]", "sha", "", ""]
|
|
95
|
+
publish_release("owner/repo", "1.2.3", (str(bundle),))
|
|
96
|
+
assert command.call_args.args[-1] == str(bundle)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def test_missing_release_asset_stops_publication(tmp_path):
|
|
100
|
+
with patch("scripts.publish_release.command") as command:
|
|
101
|
+
with pytest.raises(ValueError, match="assets not found"):
|
|
102
|
+
publish_release(
|
|
103
|
+
"owner/repo", "1.2.3", (str(tmp_path / "missing.mcpb"),)
|
|
104
|
+
)
|
|
105
|
+
command.assert_not_called()
|
|
106
|
+
|
|
107
|
+
|
|
89
108
|
def test_remote_tag_mismatch_stops_publication():
|
|
90
109
|
with patch("scripts.publish_release.command") as command:
|
|
91
110
|
command.side_effect = ["local", "remote"]
|
|
@@ -100,3 +119,35 @@ def test_invalid_tag_stops_publication(tag):
|
|
|
100
119
|
with pytest.raises(ValueError):
|
|
101
120
|
publish_release("owner/repo", tag)
|
|
102
121
|
command.assert_not_called()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_mcpb_manifest_matches_server_configuration():
|
|
125
|
+
root = Path(__file__).resolve().parents[1]
|
|
126
|
+
manifest = json.loads((root / "mcpb" / "manifest.json").read_text())
|
|
127
|
+
server = manifest["server"]
|
|
128
|
+
env = server["mcp_config"]["env"]
|
|
129
|
+
config = manifest["user_config"]
|
|
130
|
+
|
|
131
|
+
used = {
|
|
132
|
+
match
|
|
133
|
+
for value in env.values()
|
|
134
|
+
for match in re.findall(r"\$\{user_config\.(\w+)\}", value)
|
|
135
|
+
}
|
|
136
|
+
assert used == set(config)
|
|
137
|
+
assert config["postgres_password"]["sensitive"] is True
|
|
138
|
+
assert server["type"] == "uv"
|
|
139
|
+
assert server["entry_point"] == "server.py"
|
|
140
|
+
assert server["mcp_config"]["args"][-1] == "server.py"
|
|
141
|
+
assert (root / "mcpb" / "server.py").is_file()
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def test_release_workflow_builds_and_attaches_mcpb():
|
|
145
|
+
root = Path(__file__).resolve().parents[1]
|
|
146
|
+
workflow = (root / ".github/workflows/pypi-publish.yml").read_text()
|
|
147
|
+
assert 'scripts/build-mcpb.sh "$RELEASE_TAG" mcpb-dist' in workflow
|
|
148
|
+
assert "python -m pytest -q tests/test_release.py" in workflow
|
|
149
|
+
assert "name: mcpb" in workflow
|
|
150
|
+
assert (
|
|
151
|
+
'python -m scripts.publish_release "$RELEASE_TAG" mcpb-dist/*.mcpb'
|
|
152
|
+
in workflow
|
|
153
|
+
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
version = 1
|
|
2
|
-
revision =
|
|
2
|
+
revision = 5
|
|
3
3
|
requires-python = ">=3.12"
|
|
4
4
|
resolution-markers = [
|
|
5
5
|
"python_full_version >= '3.14' and sys_platform == 'win32'",
|
|
@@ -77,14 +77,15 @@ wheels = [
|
|
|
77
77
|
|
|
78
78
|
[[package]]
|
|
79
79
|
name = "authlib"
|
|
80
|
-
version = "1.
|
|
80
|
+
version = "1.9.1"
|
|
81
81
|
source = { registry = "https://pypi.org/simple" }
|
|
82
82
|
dependencies = [
|
|
83
83
|
{ name = "cryptography" },
|
|
84
|
+
{ name = "joserfc" },
|
|
84
85
|
]
|
|
85
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
86
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c9/dc/087c08741a98d234c9b98beef8a28d3c309f814d14b6156422c5815bf6d6/authlib-1.9.1.tar.gz", hash = "sha256:5c7d9848f47cac340f060f76ae0bc09b59f5c8e89cc1bb032d4370a0c55b5974", size = 182700, upload-time = "2026-10-14T14:17:52.307Z" }
|
|
86
87
|
wheels = [
|
|
87
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
88
|
+
{ url = "https://files.pythonhosted.org/packages/39/44/a46089266de32a0d809023b6bf31b80a1f26a46954446a7ce695a565cbea/authlib-1.9.1-py2.py3-none-any.whl", hash = "sha256:8b9be8b1e5174dcbf5520e984f1a22dc2edae5b6e40a61d4cedbf86b97e9e69b", size = 266042, upload-time = "2026-10-14T14:17:50.695Z" },
|
|
88
89
|
]
|
|
89
90
|
|
|
90
91
|
[[package]]
|
|
@@ -340,11 +341,11 @@ wheels = [
|
|
|
340
341
|
|
|
341
342
|
[[package]]
|
|
342
343
|
name = "dnspython"
|
|
343
|
-
version = "2.
|
|
344
|
+
version = "2.9.0"
|
|
344
345
|
source = { registry = "https://pypi.org/simple" }
|
|
345
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
346
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ef/4a/50822184bd67cc6493f0fb6a880749158fcd31ab3fa07409acfd91f9fc85/dnspython-2.9.0.tar.gz", hash = "sha256:b44dc6b18f07a8b1c56676a19fbfdb5209415b046a9cece286baafa87ff3f7f1", size = 423560, upload-time = "2026-10-09T00:07:24.352Z" }
|
|
346
347
|
wheels = [
|
|
347
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
348
|
+
{ url = "https://files.pythonhosted.org/packages/10/02/cdcc9b7c051786a103c3b09e1003a82fa0c66bcb91ffbdabcfbf7b4163b9/dnspython-2.9.0-py3-none-any.whl", hash = "sha256:9a4aedb833c3c1b49214d04d44d3032ab7a9135f7c1d29a549b4ff78fd82fda9", size = 354822, upload-time = "2026-10-09T00:07:22.622Z" },
|
|
348
349
|
]
|
|
349
350
|
|
|
350
351
|
[[package]]
|
|
@@ -913,10 +914,10 @@ resolution-markers = [
|
|
|
913
914
|
"python_full_version < '3.14' and sys_platform != 'win32'",
|
|
914
915
|
]
|
|
915
916
|
dependencies = [
|
|
916
|
-
{ name = "annotated-types"
|
|
917
|
-
{ name = "pydantic-core", version = "2.33.2", source = { registry = "https://pypi.org/simple" }
|
|
918
|
-
{ name = "typing-extensions"
|
|
919
|
-
{ name = "typing-inspection", version = "0.4.1", source = { registry = "https://pypi.org/simple" }
|
|
917
|
+
{ name = "annotated-types" },
|
|
918
|
+
{ name = "pydantic-core", version = "2.33.2", source = { registry = "https://pypi.org/simple" } },
|
|
919
|
+
{ name = "typing-extensions" },
|
|
920
|
+
{ name = "typing-inspection", version = "0.4.1", source = { registry = "https://pypi.org/simple" } },
|
|
920
921
|
]
|
|
921
922
|
sdist = { url = "https://files.pythonhosted.org/packages/ff/5d/09a551ba512d7ca404d785072700d3f6727a02f6f3c24ecfd081c7cf0aa8/pydantic-2.11.9.tar.gz", hash = "sha256:6b8ffda597a14812a7975c90b82a8a2e777d9257aba3453f973acd3c032a18e2", size = 788495, upload-time = "2025-09-13T11:26:39.325Z" }
|
|
922
923
|
wheels = [
|
|
@@ -925,7 +926,7 @@ wheels = [
|
|
|
925
926
|
|
|
926
927
|
[package.optional-dependencies]
|
|
927
928
|
email = [
|
|
928
|
-
{ name = "email-validator"
|
|
929
|
+
{ name = "email-validator" },
|
|
929
930
|
]
|
|
930
931
|
|
|
931
932
|
[[package]]
|
|
@@ -937,10 +938,10 @@ resolution-markers = [
|
|
|
937
938
|
"python_full_version >= '3.14' and sys_platform != 'win32'",
|
|
938
939
|
]
|
|
939
940
|
dependencies = [
|
|
940
|
-
{ name = "annotated-types"
|
|
941
|
-
{ name = "pydantic-core", version = "2.46.4", source = { registry = "https://pypi.org/simple" }
|
|
942
|
-
{ name = "typing-extensions"
|
|
943
|
-
{ name = "typing-inspection", version = "0.4.2", source = { registry = "https://pypi.org/simple" }
|
|
941
|
+
{ name = "annotated-types" },
|
|
942
|
+
{ name = "pydantic-core", version = "2.46.4", source = { registry = "https://pypi.org/simple" } },
|
|
943
|
+
{ name = "typing-extensions" },
|
|
944
|
+
{ name = "typing-inspection", version = "0.4.2", source = { registry = "https://pypi.org/simple" } },
|
|
944
945
|
]
|
|
945
946
|
sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" }
|
|
946
947
|
wheels = [
|
|
@@ -949,7 +950,7 @@ wheels = [
|
|
|
949
950
|
|
|
950
951
|
[package.optional-dependencies]
|
|
951
952
|
email = [
|
|
952
|
-
{ name = "email-validator"
|
|
953
|
+
{ name = "email-validator" },
|
|
953
954
|
]
|
|
954
955
|
|
|
955
956
|
[[package]]
|
|
@@ -961,7 +962,7 @@ resolution-markers = [
|
|
|
961
962
|
"python_full_version < '3.14' and sys_platform != 'win32'",
|
|
962
963
|
]
|
|
963
964
|
dependencies = [
|
|
964
|
-
{ name = "typing-extensions"
|
|
965
|
+
{ name = "typing-extensions" },
|
|
965
966
|
]
|
|
966
967
|
sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" }
|
|
967
968
|
wheels = [
|
|
@@ -1007,7 +1008,7 @@ resolution-markers = [
|
|
|
1007
1008
|
"python_full_version >= '3.14' and sys_platform != 'win32'",
|
|
1008
1009
|
]
|
|
1009
1010
|
dependencies = [
|
|
1010
|
-
{ name = "typing-extensions"
|
|
1011
|
+
{ name = "typing-extensions" },
|
|
1011
1012
|
]
|
|
1012
1013
|
sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" }
|
|
1013
1014
|
wheels = [
|
|
@@ -1376,8 +1377,8 @@ name = "secretstorage"
|
|
|
1376
1377
|
version = "3.5.0"
|
|
1377
1378
|
source = { registry = "https://pypi.org/simple" }
|
|
1378
1379
|
dependencies = [
|
|
1379
|
-
{ name = "cryptography"
|
|
1380
|
-
{ name = "jeepney"
|
|
1380
|
+
{ name = "cryptography" },
|
|
1381
|
+
{ name = "jeepney" },
|
|
1381
1382
|
]
|
|
1382
1383
|
sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" }
|
|
1383
1384
|
wheels = [
|
|
@@ -1450,7 +1451,7 @@ resolution-markers = [
|
|
|
1450
1451
|
"python_full_version < '3.14' and sys_platform != 'win32'",
|
|
1451
1452
|
]
|
|
1452
1453
|
dependencies = [
|
|
1453
|
-
{ name = "typing-extensions"
|
|
1454
|
+
{ name = "typing-extensions" },
|
|
1454
1455
|
]
|
|
1455
1456
|
sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" }
|
|
1456
1457
|
wheels = [
|
|
@@ -1466,7 +1467,7 @@ resolution-markers = [
|
|
|
1466
1467
|
"python_full_version >= '3.14' and sys_platform != 'win32'",
|
|
1467
1468
|
]
|
|
1468
1469
|
dependencies = [
|
|
1469
|
-
{ name = "typing-extensions"
|
|
1470
|
+
{ name = "typing-extensions" },
|
|
1470
1471
|
]
|
|
1471
1472
|
sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
|
|
1472
1473
|
wheels = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/documentation.md
RENAMED
|
File without changes
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/feature_request.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/_includes/head-custom-google-analytics.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/MCP-Workflow-of-Quickstart-Tutorial.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/img/screenshot-claude-desktop-question-001.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/prompt_template.md
RENAMED
|
File without changes
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/version_compat.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/requires.txt
RENAMED
|
File without changes
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_postgresql_ops-3.4.3 → mcp_postgresql_ops-3.4.5}/tests/test_tool_schema_null_defaults.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|