skills/maintainer/triage-issues/references/maintainer-playbook.md
This playbook aligns on a consistent process for maintaining MCP Toolbox, ensuring quality, and providing a positive experience for contributors.
Our team maintains the MCP Toolbox family of open source repositories on GitHub:
This playbook establishes our guidelines for maintaining our repositories, aiming to bring clarity, efficiency, and predictability to our open-source operations.
This section outlines the end-to-end pipeline for how a bug or feature request moves from initial report to a final release. Each step links to a more detailed section later in this playbook.
Identify Issue: An issue is opened in one of our GitHub repositories by a community member or a team member.
Triage: A team member acknowledges the issue, applies appropriate labels for categorization and priority, and verifies the report.
Resolution: The issue is assigned and work begins.
Review & Merge: The PR undergoes a thorough review by the team. Once approved and all checks pass, a maintainer merges it into the main branch.
Release: The merged changes are bundled into the next versioned release and published.
We track open issues and PRs across all repositories so maintainers have visibility into what needs attention. Each team should monitor incoming work against the team's response and closure targets (SLOs).
There are 3 primary types of work that need to be addressed, in prioritized order:
While we want to immediately remediate anything that is out of SLO, ideally issues and PRs would not get to that point.
Everyone should check their open issues/PRs at least once a week.
Current SLO targets:
| Type | Priority | Metric | Objective |
|---|---|---|---|
| Feature Request | P0 | Response | 5 days |
| Process | P0 | Response | 5 days |
| Bug / Customer Issue | P0 | Response | 2 days |
| Closure | 14 days | ||
| P1 | Response | 7 days | |
| Closure | 90 days | ||
| P2 | Response | 30 days |
* Response requires at least a response from the reviewer
* Closure requires the issue/PR to be closed.
Once you have identified a bug, assess it and provide it with an initial acknowledgement.
Priority <>, Type <>, and Product <> (if applicable) labels on the GitHub Issue / PR as deemed appropriate. SLOs are based on the "Priority" label. Add the Status <> label if applicable.labels.yaml if one is missing.Here are some sample templates:
Acknowledging a Feature Request:
Thanks for suggesting this feature! We appreciate you taking the time to provide this feedback. We've added this to our backlog for consideration. We can't provide a specific timeline for implementation right now, but we will update this issue with any progress. In the meantime, we welcome pull requests from the community if you are interested in contributing this feature yourself.
Needs More Information:
Thanks for opening this issue! We are having trouble reproducing your problem with the information provided.
To help us investigate further, could you please provide:
- A minimal, reproducible code sample that demonstrates the issue.
- The full error message and stack trace.
We will close this issue in 14 days if we don't hear back. Thanks!
For bugs, this involves writing code to fix the problem. For features, it involves implementation. For PRs, it involves assessment and review of the features being added.
After triage, the issue should be assigned to a team member for resolution. If an external contributor expresses interest in working on an issue, assign it to them to prevent duplicate work.
Flaky tests that we don't own will not be the priority. We should prioritize tests we own. Try to push work back to the upstream product teams. If third-party tests are constantly flaky, consider removing them from the test suites and escalate to the appropriate point of contact.
If we are opening a PR for a Feature Request or a Bug, make sure to link the issue in the description.
For auto-generated PRs (e.g. dependency updates and release automation), make sure the tests and PR checks pass and merge them.
If you are reviewing a PR, here are a few things to consider:
README.md or relevant documentation updated?release candidate label if it needs to be in the next release.All the pre-submit tests should pass and the documentation change should be reviewed before approval.
Documentation preview links are generated automatically for PRs from branches within the main repository. For PRs from external forks, previews are disabled for security reasons, so a maintainer must deploy the preview:
.github/workflows/ directory.docs: deploy-preview label to the PR to
deploy a documentation preview.For release mechanics — release types, the version-cut steps, supported binaries, and npm/PyPI publishing — see Releasing.
Once the PR is merged, make sure you leave a comment on the open issue making external contributors aware that the fix should be available in the upcoming version.
Here's an example:
This has been resolved in PR #[PR number]. The fix will be available in our next release (vX.Y.Z). Thanks again to @[contributor-username] for the contribution! Closing this issue now.
Release PRs are created by release automation and assigned to a team member. Keep an eye out for those or re-assign them to another team member as necessary.
Release plan:
Team @googleapis/senseai-eco has been set as
CODEOWNERS. The GitHub TeamSync tool is used to create
this team from MDB Group, senseai-eco. Additionally, database-specific GitHub
teams (e.g., @googleapis/toolbox-alloydb) have been created from MDB groups to
manage code ownership and review for individual database products.
Toolbox has two types of releases: versioned and continuous. It uses Google
Cloud project, database-toolbox.
latest.
The release process is defined in
versioned.release.cloudbuild.yaml..github/release-please.yml automatically creates GitHub
Releases and release PRs.git commit -m "chore: release 0.1.0" -m "Release-As: 0.1.0" --allow-empty[[params.versions]] block for the new version to both hugo.toml
and hugo.cloudflare.toml.[[params.versions]] block from
hugo.cloudflare.toml, and delete that version's directory in the
cloudflare-pages branch. This is required because Cloudflare only allows
20,000 files per deployment.Run the following command (from the root directory):
export VERSION="v0.0.0"
.ci/generate_release_table.sh
Copy the table output
In the GitHub UI, navigate to Releases and click the edit button.
Paste the table at the bottom of release note and click Update release.
The following operating systems and architectures are supported for binary releases:
The following base container images are supported for container image releases:
MCP Toolbox is available as an npm package: @toolbox-sdk/server.
[!NOTE] npm releases are automated through the OSS Exit Gate via the
publish-npm-to-arandtrigger-exit-gatesteps in .ci/versioned.release.cloudbuild.yaml. The versioned release pipeline pushes all six packages to the Exit Gate Artifact Registry (us-npm.pkg.dev/oss-exit-gate-prod/mcp-toolbox--npm) and uploads apublish_all: truemanifest togs://oss-exit-gate-prod-projects-bucket/mcp-toolbox/npm/manifests/, which triggers Exit Gate to publish externally to npmjs.org.If the npm portion fails after the Go binaries are already in GCS, retry just the npm steps without rebuilding binaries via .ci/npm_retry.cloudbuild.yaml (invocation instructions are in the file header). The retry is idempotent — already- published packages are skipped.
PyPI releases are automated through the same Exit Gate via the
publish-pypi-to-arandtrigger-exit-gate-pypisteps. Each release builds five platform-tagged wheels (one per OS/arch) via pypi/setup.py withTOOLBOX_PLATFORMset per wheel, uploads them all tous-python.pkg.dev/oss-exit-gate-prod/mcp-toolbox--pypi, then drops a manifest atgs://oss-exit-gate-prod-projects-bucket/mcp-toolbox/pypi/manifests/so Exit Gate publishes them to pypi.org via trusted publishing. PyPI-only retries: .ci/pypi_retry.cloudbuild.yaml. Idempotency is handled bytwine upload --skip-existing.The manual procedure below is retained as a fallback for when the automation is broken.
To release a new version manually, follow these steps:
Pre-requisites
@toolbox-sdk/ organization by pinging the current maintainers.Preparation
darwin/arm64 -> server-darwin-arm64darwin/x64 -> server-darwin-x64linux/x64 -> server-linux-x64win32/arm64 -> server-win32-arm64win32/x64 -> server-win32-x64Phase A: Release Platform-Specific Packages
Repeat the following steps for each of the 5 combinations listed above.
cd npm/server-<os>-<arch>
cmd/version.txt at the repo root (the release-please versionFile); downloadBinary.js reads it from there during prepack. Verify it reflects the version to be released.package.json and verify that the "version" field matches cmd/version.txt.npm install --force
rm -rf bin/
npm pack .
npm publish --access public
https://www.npmjs.com/package/@toolbox-sdk/server-<os>-<arch> before moving to the next package.Phase B: Release Main Package (@toolbox-sdk/server)
Once all platform-specific packages are live, release the main wrapper package.
cd ../server
package.json and verify the "version" field reflects the target version."optionalDependencies" match the new version for all 5 packages.npm install --package-lock-only
package-lock.json.Sync Lockfile command to generate a new lockfile.npm pack .
npm publish --access public
https://www.npmjs.com/package/@toolbox-sdk/server.Committing changes to the repo
Once all packages have been successfully published, please create a Pull Request containing the updated package-lock.json files from all npm/ subdirectories. Ensure that any additional changes made during the release process are also included in this PR. Finally, set the title of the PR to: chore(main): release npm vX.Y.Z.
[!IMPORTANT] Do not commit the binaries to the repo.
Troubleshooting
npm login. If the registry is not https://registry.npmjs.org/, update it via npm config set registry https://registry.npmjs.org/ or by modifying your .npmrc.npm deprecate <package_name>@<version> "critical bug fixed in vX.Y.Z".npm unpublish <package-name>@<version>. Note that this permanently burns the version number.Integration and unit tests are automatically triggered via Cloud Build on each pull request. Integration tests run on merge and nightly.
On-merge and nightly tests that fail have notification setup via Cloud Build Failure Reporter GitHub Actions Workflow.
Configure a Cloud Build trigger using the UI or gcloud with the following
settings:
^main$