Skip to content

Commit b70f142

Browse files
Yuan325rahulpinto19
authored andcommitted
feat(mcp-registry): publish custom tools server to mcp-registry (#1834)
## Description This PR adds a new [github action](https://github.com/modelcontextprotocol/registry/blob/main/docs/guides/publishing/github-actions.md) workflow to publish Toolbox to mcp-registry. This only publishes the custom tools server, prebuilt-tools will be added in a different PR once this is successful. The workflow will be triggered on (1) any new release tag (v*) or (2) manually via GHA workflow dispatch. It will grab the version number from the `server.json` file. The server.json file will be updated by release please during every release. Note: server that are published in the mcp-registry is immutable. In cases where we successfully published a server and would like to make an update, we will have to update the `version` field in `.registry/server.json` and manually publish another server with a new version. ## PR Checklist > Thank you for opening a Pull Request! Before submitting your PR, there are a > few things you can do to make sure it goes smoothly: - [x] Make sure you reviewed [CONTRIBUTING.md](https://github.com/googleapis/genai-toolbox/blob/main/CONTRIBUTING.md) - [x] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/genai-toolbox/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [x] Ensure the tests and linter pass - [x] Code coverage does not decrease (if any source code was changed) - [x] Appropriate docs were updated (if necessary) - [x] Make sure to add `!` if this involve a breaking change 🛠️ Fixes #1659 Issue at mcp-registry to support GAR ([#427](modelcontextprotocol/registry#427))
1 parent 43fe0e6 commit b70f142

File tree

3 files changed

+155
-1
lines changed

3 files changed

+155
-1
lines changed

.github/release-please.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,14 @@ extraFiles: [
3838
"docs/en/how-to/connect-ide/neo4j_mcp.md",
3939
"docs/en/how-to/connect-ide/sqlite_mcp.md",
4040
"gemini-extension.json",
41-
]
41+
{
42+
"type": "json",
43+
"path": ".registry/server.json",
44+
"jsonpath": "$.version"
45+
},
46+
{
47+
"type": "json",
48+
"path": ".registry/server.json",
49+
"jsonpath": "$.packages[0].identifier"
50+
},
51+
]

.github/workflows/publish-mcp.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: Publish to MCP Registry
16+
17+
on:
18+
push:
19+
tags: ["v*"] # Triggers on version tags like v1.0.0
20+
# allow manual triggering with no inputs required
21+
workflow_dispatch:
22+
23+
jobs:
24+
publish:
25+
runs-on: ubuntu-latest
26+
permissions:
27+
id-token: write # Required for OIDC authentication
28+
contents: read
29+
30+
steps:
31+
- name: Checkout code
32+
uses: actions/checkout@v5
33+
34+
- name: Wait for image in Artifact Registry
35+
shell: bash
36+
run: |
37+
MAX_ATTEMPTS=10
38+
VERSION=$(jq -r '.version' server.json)
39+
REGISTRY_URL="https://us-central1-docker.pkg.dev/v2/database-toolbox/toolbox/toolbox/manifests/${VERSION}"
40+
41+
# initially sleep time to wait for the version release
42+
sleep 3m
43+
44+
for i in $(seq 1 ${MAX_ATTEMPTS}); do
45+
echo "Attempt $i: Checking for image ${REGISTRY_URL}..."
46+
# Use curl to check the manifest header
47+
# Using -I to fetch headers only, -s silent, -f fail fast on errors.
48+
curl -Isf "${REGISTRY_URL}" > /dev/null
49+
50+
if [ $? -eq 0 ]; then
51+
echo "✅ Image found! Continuing to next steps."
52+
exit 0
53+
else
54+
echo "❌ Image not found (likely 404 error) on attempt $i."
55+
if [ $i -lt ${MAX_ATTEMPTS} ]; then
56+
echo "Sleeping for 5 minutes before next attempt..."
57+
sleep 2m
58+
else
59+
echo "Maximum attempts reached. Image not found."
60+
exit 1
61+
fi
62+
fi
63+
done
64+
65+
- name: Install MCP Publisher
66+
run: |
67+
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
68+
69+
- name: Login to MCP Registry
70+
run: ./mcp-publisher login github-oidc
71+
72+
- name: Publish to MCP Registry
73+
run: ./mcp-publisher publish --file=.registry/server.json

.registry/server.json

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
3+
"name": "io.github.googleapis/genai-toolbox",
4+
"description": "MCP Toolbox for Databases enables your agent to connect to your database.",
5+
"title": "MCP Toolbox",
6+
"websiteUrl": "https://github.com/googleapis/genai-toolbox",
7+
"icons": [
8+
{
9+
"src": "https://github.com/googleapis/genai-toolbox/blob/main/.hugo/assets/icons/logo.svg",
10+
"mimeType": "image/svg+xml"
11+
}
12+
],
13+
"repository": {
14+
"url": "https://github.com/googleapis/genai-toolbox",
15+
"source": "github"
16+
},
17+
"version": "0.19.1",
18+
"packages": [
19+
{
20+
"registryType": "oci",
21+
"registryBaseUrl": "https://artifactregistry.googleapis.com",
22+
"identifier": "us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:0.19.1",
23+
"transport": {
24+
"type": "streamable-http",
25+
"url": "http://{host}:{port}/mcp"
26+
},
27+
"runtimeArguments": [
28+
{
29+
"type": "named",
30+
"name": "--tools-file",
31+
"description": "File path specifying the tool configuration.",
32+
"default": "tools.yaml",
33+
"isRequired": false
34+
},
35+
{
36+
"type": "named",
37+
"name": "--address",
38+
"description": "Address of the interface the server will listen on.",
39+
"value": "{host}",
40+
"variables": {
41+
"host": {
42+
"description": "ip address",
43+
"isRequired": true,
44+
"default": "127.0.0.1"
45+
}
46+
}
47+
},
48+
{
49+
"type": "named",
50+
"name": "--port",
51+
"description": "Port the server will listen on.",
52+
"value": "{port}",
53+
"variables": {
54+
"port": {
55+
"description": "port",
56+
"isRequired": true,
57+
"default": "5000"
58+
}
59+
}
60+
},
61+
{
62+
"type": "named",
63+
"name": "--log-level",
64+
"description": "Specify the minimum level logged.",
65+
"default": "info",
66+
"choices": ["debug", "info", "warn", "error"]
67+
}
68+
]
69+
}
70+
]
71+
}

0 commit comments

Comments
 (0)