-
Notifications
You must be signed in to change notification settings - Fork 276
feat: package DBHub as a Claude Desktop MCP Bundle (.mcpb) #356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
7b56026
feat: package DBHub as a Claude Desktop MCP Bundle (.mcpb)
tianzhou 70bbadf
fix: harden mcpb smoke test error paths per review
tianzhou fe5bce0
docs: describe .mcpb as an open, multi-client format, not Claude Desk…
tianzhou 62d2172
fix: bootstrap npm upgrade in mcpb-release workflow
tianzhou File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| # Workflow for publishing the DBHub MCP Bundle (.mcpb) as a GitHub release asset. | ||
| # | ||
| # The .mcpb bundle is a self-contained package (server + database drivers + | ||
| # read-only TOML config) that installs with one click into MCPB-compatible | ||
| # clients (Claude Desktop, Claude Code, MCP for Windows), running locally over | ||
| # stdio — no remote HTTP endpoint or OAuth setup needed. | ||
| # | ||
| # Trigger modes (mirrors npm-publish.yml): | ||
| # 1. Automatic: on push to main that modifies package.json — builds and attaches | ||
| # the bundle to the GitHub release v<version>, creating the release if needed. | ||
| # Skips if that release already has the asset. | ||
| # 2. Manual (workflow_dispatch): force a rebuild and re-upload of the asset for | ||
| # the current package.json version. | ||
|
|
||
| name: Publish MCP Bundle | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
|
|
||
| push: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - "package.json" | ||
|
|
||
| jobs: | ||
| build-and-release: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write # create releases and upload assets | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| # Decide before installing anything — a skipped run costs only this step | ||
| # (jq and gh are preinstalled on ubuntu-latest). | ||
| - name: Determine version and whether to publish | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| VERSION=$(jq -r '.version' package.json) | ||
| ASSET="dbhub-${VERSION}.mcpb" | ||
|
|
||
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | ||
| # Manual trigger: always rebuild and re-upload | ||
| SHOULD_PUBLISH="true" | ||
| echo "Manual trigger: publishing ${ASSET}" | ||
| elif gh release view "v${VERSION}" --json assets --jq '.assets[].name' 2>/dev/null | grep -qx "${ASSET}"; then | ||
| echo "Release v${VERSION} already has ${ASSET}. Skipping." | ||
| SHOULD_PUBLISH="false" | ||
| else | ||
| echo "Publishing ${ASSET} to release v${VERSION}" | ||
| SHOULD_PUBLISH="true" | ||
| fi | ||
|
|
||
| echo "VERSION=${VERSION}" >> $GITHUB_ENV | ||
| echo "ASSET=${ASSET}" >> $GITHUB_ENV | ||
| echo "SHOULD_PUBLISH=${SHOULD_PUBLISH}" >> $GITHUB_ENV | ||
|
|
||
| # pnpm must be on PATH before setup-node can use the pnpm store cache | ||
| - name: Install pnpm | ||
| if: env.SHOULD_PUBLISH == 'true' | ||
| uses: pnpm/action-setup@v3 | ||
| with: | ||
| version: 10.17.1 | ||
|
|
||
| - name: Setup Node.js | ||
| if: env.SHOULD_PUBLISH == 'true' | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "22" | ||
| cache: "pnpm" | ||
|
|
||
| # build-mcpb.mjs stages the bundle's node_modules with `npm install`, and | ||
| # Node 22.22.2 ships with broken npm (missing promise-retry) — bootstrap a | ||
| # working npm without invoking the broken one, same as npm-publish.yml. | ||
| - name: Upgrade npm | ||
| if: env.SHOULD_PUBLISH == 'true' | ||
| run: | | ||
| npm_tarball=$(curl -fsSL https://registry.npmjs.org/npm/latest | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).dist.tarball") | ||
| curl -fsSL "$npm_tarball" | tar xz -C /tmp | ||
| node /tmp/package/bin/npm-cli.js install -g npm@latest | ||
| rm -rf /tmp/package | ||
| echo "npm version: $(npm --version)" | ||
|
|
||
| - name: Install dependencies | ||
| if: env.SHOULD_PUBLISH == 'true' | ||
| run: pnpm install --frozen-lockfile | ||
|
|
||
| - name: Build MCP Bundle | ||
| if: env.SHOULD_PUBLISH == 'true' | ||
| run: pnpm run build:mcpb | ||
|
|
||
| - name: Smoke test MCP Bundle | ||
| if: env.SHOULD_PUBLISH == 'true' | ||
| run: pnpm run test:mcpb | ||
|
|
||
| - name: Create release and upload asset | ||
| if: env.SHOULD_PUBLISH == 'true' | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| # Create the release if it doesn't exist yet | ||
| if ! gh release view "v${VERSION}" > /dev/null 2>&1; then | ||
| PRERELEASE_FLAG="" | ||
| case "${VERSION}" in | ||
| *-*) PRERELEASE_FLAG="--prerelease" ;; | ||
| esac | ||
| gh release create "v${VERSION}" \ | ||
| --title "v${VERSION}" \ | ||
| --generate-notes \ | ||
| ${PRERELEASE_FLAG} | ||
| fi | ||
|
|
||
| gh release upload "v${VERSION}" "dist-mcpb/${ASSET}" --clobber | ||
| echo "✅ Uploaded ${ASSET} to release v${VERSION}" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| --- | ||
| title: "MCP Bundle" | ||
| description: "One-click, read-only install via .mcpb for Claude Desktop and other MCPB clients" | ||
| --- | ||
|
|
||
| The [MCP Bundle](https://github.com/modelcontextprotocol/mcpb) (`.mcpb`) is a one-click installation path — no Node.js install, no JSON config editing, and no remote HTTP endpoint or OAuth setup. It is an open format governed by the Model Context Protocol project; clients that install it directly include **Claude Desktop**, **Claude Code**, and **MCP for Windows**. It is the recommended way to give **non-technical users** curated database access. | ||
|
|
||
| ## Install | ||
|
|
||
| 1. Download `dbhub-<version>.mcpb` from the [latest GitHub release](https://github.com/bytebase/dbhub/releases/latest). | ||
| 2. Install it in your client — in Claude Desktop, double-click the file (or drag it into **Settings → Extensions**). | ||
| 3. Enter your database connection string when prompted, e.g. `postgres://user:password@host:5432/dbname`. It is stored in the OS keychain, not in a config file. | ||
|
|
||
| The bundle includes drivers for PostgreSQL, MySQL, MariaDB, SQL Server, and SQLite, and runs locally over stdio. Clients without native `.mcpb` support (Cursor, VS Code, ...) can still run the unpacked bundle as a plain stdio MCP server: `node server/index.js --transport stdio --config dbhub.toml` with `DBHUB_DSN` set. | ||
|
|
||
| ## Read-only by design | ||
|
|
||
| The bundled configuration sets `readonly = true` and `max_rows = 1000` on `execute_sql`: mutating statements are rejected, and the database session is additionally set to read-only at the engine level. Still, connect with a least-privilege, read-only database account — defense in depth beats configuration alone. | ||
|
|
||
| <Note> | ||
| The machine running the MCP client connects **directly** to the database, so the database must be reachable from it (VPN or network allow-list). AWS IAM and Azure AD authentication are not included in the bundle; repackage with those drivers added if you need them. | ||
| </Note> | ||
|
|
||
| ## Packaging your own bundle | ||
|
|
||
| To ship a different policy — multiple sources, custom tools, a baked-in DSN so users have nothing to configure — edit `mcpb/dbhub.toml` (and `mcpb/manifest.json` if you change `user_config`) and rebuild: | ||
|
|
||
| ```bash | ||
| git clone https://github.com/bytebase/dbhub.git && cd dbhub | ||
| pnpm install | ||
| # Edit mcpb/dbhub.toml (tool policy) and mcpb/manifest.json (user settings) | ||
| pnpm run build:mcpb # produces dist-mcpb/dbhub-<version>.mcpb | ||
| pnpm run test:mcpb # smoke-tests the packed bundle over stdio | ||
| ``` | ||
|
|
||
| Anything in a `[[sources]]` or `[[tools]]` section of the [TOML configuration](/config/toml) works in the bundle, including `${ENV_VAR}` interpolation — the stock bundle uses `dsn = "${DBHUB_DSN}"`, with `DBHUB_DSN` supplied by the client from the user's extension settings. | ||
|
|
||
| <Warning> | ||
| If you bake a DSN into your own bundle, remember that anyone can unzip an `.mcpb` and read it. Only embed credentials for a curated, read-only, least-privilege account. | ||
| </Warning> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # DBHub configuration for the MCP Bundle (.mcpb) distribution. | ||
| # | ||
| # The connection string is supplied by the MCP client (e.g. Claude Desktop) | ||
| # from the user's extension settings — stored in the OS keychain — and passed | ||
| # to the server via the DBHUB_DSN environment variable declared in | ||
| # manifest.json. It is interpolated into the `dsn` field below at load time. | ||
| # | ||
| # This bundle is read-only by design: execute_sql rejects mutating statements | ||
| # and the database session is additionally set to read-only at the engine | ||
| # level. Pair it with a least-privilege, read-only database account. | ||
| # | ||
| # To ship a different policy (multiple sources, custom tools, write access), | ||
| # repackage the bundle with your own dbhub.toml — see | ||
| # https://dbhub.ai/mcpb for the recipe. | ||
|
|
||
| [[sources]] | ||
| id = "default" | ||
| dsn = "${DBHUB_DSN}" | ||
|
|
||
| [[tools]] | ||
| name = "execute_sql" | ||
| source = "default" | ||
| readonly = true | ||
| max_rows = 1000 | ||
|
|
||
| [[tools]] | ||
| name = "search_objects" | ||
| source = "default" |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| { | ||
| "manifest_version": "0.3", | ||
| "name": "dbhub", | ||
| "display_name": "DBHub", | ||
| "version": "0.0.0", | ||
| "description": "Minimal, token-efficient database MCP server. Read-only access to PostgreSQL, MySQL, MariaDB, SQL Server, and SQLite.", | ||
| "long_description": "DBHub bridges your AI assistant with your database through just two tools: `execute_sql` and `search_objects`. This bundle is configured read-only by design — writes are rejected by the SQL classifier and the database session is additionally set to read-only at the engine level — making it safe to hand to non-technical users for data exploration, reporting, and debugging. Connect it to PostgreSQL, MySQL, MariaDB, SQL Server, or SQLite by entering a single connection string.", | ||
| "author": { | ||
| "name": "Bytebase", | ||
| "url": "https://www.bytebase.com" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/bytebase/dbhub" | ||
| }, | ||
| "homepage": "https://dbhub.ai", | ||
| "documentation": "https://dbhub.ai/mcpb", | ||
| "support": "https://github.com/bytebase/dbhub/issues", | ||
| "icon": "icon.png", | ||
| "license": "MIT", | ||
| "keywords": [ | ||
| "database", | ||
| "sql", | ||
| "postgres", | ||
| "postgresql", | ||
| "mysql", | ||
| "mariadb", | ||
| "sqlserver", | ||
| "sqlite", | ||
| "read-only" | ||
| ], | ||
| "server": { | ||
| "type": "node", | ||
| "entry_point": "server/index.js", | ||
| "mcp_config": { | ||
| "command": "node", | ||
| "args": [ | ||
| "${__dirname}/server/index.js", | ||
| "--transport", | ||
| "stdio", | ||
| "--config", | ||
| "${__dirname}/dbhub.toml" | ||
| ], | ||
| "env": { | ||
| "DBHUB_DSN": "${user_config.dsn}" | ||
| } | ||
| } | ||
| }, | ||
| "user_config": { | ||
| "dsn": { | ||
| "type": "string", | ||
| "title": "Database connection string (DSN)", | ||
| "description": "Examples: postgres://user:password@localhost:5432/dbname | mysql://user:password@localhost:3306/dbname | mariadb://user:password@localhost:3306/dbname | sqlserver://user:password@localhost:1433/dbname | sqlite:///path/to/database.db. Append ?sslmode=require for SSL. Use a least-privilege, read-only database account.", | ||
| "sensitive": true, | ||
| "required": true | ||
| } | ||
| }, | ||
| "tools": [ | ||
| { | ||
| "name": "execute_sql", | ||
| "description": "Execute SQL against the connected database (read-only: SELECT and other non-mutating statements only)" | ||
| }, | ||
| { | ||
| "name": "search_objects", | ||
| "description": "Search and list database objects (schemas, tables, columns, indexes, procedures) with progressive detail levels" | ||
| } | ||
| ], | ||
| "compatibility": { | ||
| "platforms": ["darwin", "win32", "linux"], | ||
| "runtimes": { | ||
| "node": ">=22.5.0" | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.