mcp-postgresql-ops 3.4.4__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.
Files changed (79) hide show
  1. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/workflows/pypi-publish.yml +18 -3
  2. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/PKG-INFO +15 -2
  3. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/README.md +14 -1
  4. mcp_postgresql_ops-3.4.5/mcpb/manifest.json +93 -0
  5. mcp_postgresql_ops-3.4.5/mcpb/server.py +7 -0
  6. mcp_postgresql_ops-3.4.5/scripts/build-mcpb.sh +37 -0
  7. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/scripts/publish_release.py +10 -4
  8. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/PKG-INFO +15 -2
  9. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/SOURCES.txt +3 -0
  10. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/scm_file_list.json +3 -0
  11. mcp_postgresql_ops-3.4.5/src/mcp_postgresql_ops.egg-info/scm_version.json +8 -0
  12. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/tests/test_release.py +51 -0
  13. mcp_postgresql_ops-3.4.4/src/mcp_postgresql_ops.egg-info/scm_version.json +0 -8
  14. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.env.example +0 -0
  15. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/CONTRIBUTING.md +0 -0
  16. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/FUNDING.yml +0 -0
  17. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  18. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  19. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  20. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  21. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/ISSUE_TEMPLATE/question.md +0 -0
  22. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/copilot-instructions.md +0 -0
  23. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/dependabot.yml +0 -0
  24. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/pull_request_template.md +0 -0
  25. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.github/workflows/test.yml +0 -0
  26. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.gitignore +0 -0
  27. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.gitleaks.toml +0 -0
  28. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.pre-commit-config.yaml +0 -0
  29. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/.python-version +0 -0
  30. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/Dockerfile.MCP-Server +0 -0
  31. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/Dockerfile.MCPO-Proxy +0 -0
  32. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/LICENSE +0 -0
  33. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/MANIFEST.in +0 -0
  34. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/SECURITY.md +0 -0
  35. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/_config.yml +0 -0
  36. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/_includes/head-custom-google-analytics.html +0 -0
  37. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/build-mcp-server-docker-image.sh +0 -0
  38. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/build-mcpo-server-docker-image.sh +0 -0
  39. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/docker-compose.custom-db.yml +0 -0
  40. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/docker-compose.yml +0 -0
  41. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/img/MCP-Workflow-of-Quickstart-Tutorial.png +0 -0
  42. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/img/screenshot-000.png +0 -0
  43. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/img/screenshot-001.png +0 -0
  44. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/img/screenshot-002.png +0 -0
  45. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/img/screenshot-004.png +0 -0
  46. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/img/screenshot-005.png +0 -0
  47. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/img/screenshot-claude-desktop-airflow-connections-html.png +0 -0
  48. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/img/screenshot-claude-desktop-mermaid-diagram.png +0 -0
  49. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/img/screenshot-claude-desktop-question-001.png +0 -0
  50. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/img/screenshot-swagger-api.png +0 -0
  51. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/mcp-config.json.http +0 -0
  52. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/mcp-config.json.stdio +0 -0
  53. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/pyproject.toml +0 -0
  54. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/run-mcp-inspector-local.sh +0 -0
  55. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/run-mcp-inspector-pypi.sh +0 -0
  56. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/scripts/check_release.py +0 -0
  57. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/scripts/create-test-data.sh +0 -0
  58. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/scripts/create-test-data.sql +0 -0
  59. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/scripts/enable-pgsql-extensions.sh +0 -0
  60. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/scripts/mcp-server-docker-cmd.sh +0 -0
  61. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/setup.cfg +0 -0
  62. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/__init__.py +0 -0
  63. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/__main__.py +0 -0
  64. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/functions.py +0 -0
  65. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/mcp_main.py +0 -0
  66. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/prompt_template.md +0 -0
  67. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops/version_compat.py +0 -0
  68. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/dependency_links.txt +0 -0
  69. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/entry_points.txt +0 -0
  70. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/requires.txt +0 -0
  71. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/src/mcp_postgresql_ops.egg-info/top_level.txt +0 -0
  72. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/tests/__init__.py +0 -0
  73. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/tests/conftest.py +0 -0
  74. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/tests/docker/docker-compose.test.yml +0 -0
  75. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/tests/docker/init-test-db.sql +0 -0
  76. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/tests/test_tool_schema_null_defaults.py +0 -0
  77. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/tests/test_tools_integration.py +0 -0
  78. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/tests/test_version_compat.py +0 -0
  79. {mcp_postgresql_ops-3.4.4 → mcp_postgresql_ops-3.4.5}/uv.lock +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 tool
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.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
- (Recommended) Add to your Claude Desktop configuration file:
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
- (Recommended) Add to your Claude Desktop configuration file:
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,7 @@
1
+ """MCPB entry point: run MCP-PostgreSQL-Ops over stdio."""
2
+
3
+ from mcp_postgresql_ops.mcp_main import main
4
+
5
+
6
+ if __name__ == "__main__":
7
+ main(["--type", "stdio"])
@@ -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(repository: str, tag: str) -> None:
71
- """Create a release once, using the last published release as the baseline."""
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-postgresql-ops
3
- Version: 3.4.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
- (Recommended) Add to your Claude Desktop configuration file:
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
  {
@@ -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",
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "3.4.5",
3
+ "distance": 0,
4
+ "node": "gbbcc181f4e80cf49c2854127bf20b49c7beb2cf2",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-11-11"
8
+ }
@@ -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,8 +0,0 @@
1
- {
2
- "tag": "3.4.4",
3
- "distance": 0,
4
- "node": "gd799028a4b933c2d6569d08aa17de1e559bd1435",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-11-02"
8
- }