Skip to content

Commit 466a01c

Browse files
subomiclaude
andauthored
feat: add MCP Registry publishing step with OIDC support (#321)
* feat: add MCP Registry publishing step with OIDC support Add publish-mcp-registry job to sdk-publish.yaml that runs after npm publish. Supports three auth methods: github-oidc (recommended, tokenless), github (PAT), and dns (private key). Job requests id-token: write permission for OIDC. Installs mcp-publisher CLI, authenticates, and publishes server.json to the official MCP Registry. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: bump sdk-gen-config to v1.57.0 for MCPRegistry support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent fe37b33 commit 466a01c

File tree

5 files changed

+60
-3
lines changed

5 files changed

+60
-3
lines changed

.github/workflows/sdk-publish.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ on:
102102
nuget_api_key:
103103
description: The api key for publishing to Nuget
104104
required: false
105+
mcp_registry_token:
106+
description: Authentication token for publishing to the MCP Registry. For GitHub auth, a GitHub token. For DNS auth, the Ed25519 private key.
107+
required: false
105108
outputs:
106109
python_regenerated:
107110
description: Whether the Python SDK was regenerated
@@ -170,6 +173,8 @@ jobs:
170173
swift_directory: ${{ steps.release.outputs.swift_directory }}
171174
use_sonatype_legacy: ${{ steps.release.outputs.use_sonatype_legacy }}
172175
mcp_release_typescript: ${{ steps.release.outputs.mcp_release_typescript }}
176+
publish_mcp_registry: ${{ steps.release.outputs.publish_mcp_registry }}
177+
mcp_registry_auth: ${{ steps.release.outputs.mcp_registry_auth }}
173178
use_pypi_trusted_publishing: ${{ steps.release.outputs.use_pypi_trusted_publishing }}
174179
steps:
175180
- name: Checkout sdk-generation-action repository
@@ -550,6 +555,50 @@ jobs:
550555
GH_ACTION_VERSION: 6cd5ba5c0f635337847068ad8410ca9a8651e175
551556
GH_ACTION_STEP: ${{ github.job }}
552557
TARGET_TYPE: "mcp"
558+
publish-mcp-registry:
559+
if: ${{ needs.release.outputs.publish_mcp_registry == 'true' && needs.publish-npm-mcp.result == 'success' }}
560+
name: Publish to MCP Registry
561+
runs-on: ${{ ((startsWith(inputs.runs-on, '[') || startsWith(inputs.runs-on, '{') || startsWith(inputs.runs-on, '"')) && fromJSON(inputs.runs-on)) || inputs.runs-on }}
562+
permissions:
563+
id-token: write # Required for github-oidc authentication
564+
contents: read
565+
needs:
566+
- release
567+
- publish-npm-mcp
568+
defaults:
569+
run:
570+
working-directory: ${{ needs.release.outputs.mcp_typescript_directory }}
571+
steps:
572+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
573+
- name: Install mcp-publisher
574+
run: |
575+
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
576+
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
577+
curl -sL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_${OS}_${ARCH}.tar.gz" | tar xz mcp-publisher
578+
sudo mv mcp-publisher /usr/local/bin/
579+
- name: Authenticate with MCP Registry
580+
env:
581+
MCP_REGISTRY_TOKEN: ${{ secrets.mcp_registry_token }}
582+
MCP_REGISTRY_AUTH: ${{ needs.release.outputs.mcp_registry_auth }}
583+
run: |
584+
case "$MCP_REGISTRY_AUTH" in
585+
github-oidc)
586+
mcp-publisher login github-oidc
587+
;;
588+
github)
589+
mcp-publisher login github --token "$MCP_REGISTRY_TOKEN"
590+
;;
591+
dns)
592+
# Extract domain from server name in server.json (e.g., "com.example/server" -> "example.com")
593+
SERVER_NAME=$(jq -r '.name' server.json)
594+
NAMESPACE=${SERVER_NAME%%/*}
595+
# Reverse DNS to domain: com.example -> example.com
596+
DOMAIN=$(echo "$NAMESPACE" | awk -F. '{for(i=NF;i>0;i--) printf "%s%s",$i,(i>1?".":"")}')
597+
mcp-publisher login dns --domain "$DOMAIN" --private-key "$MCP_REGISTRY_TOKEN"
598+
;;
599+
esac
600+
- name: Publish to MCP Registry
601+
run: mcp-publisher publish
553602
publish-java:
554603
if: ${{ needs.release.outputs.java_regenerated == 'true' && needs.release.outputs.publish_java == 'true' }}
555604
name: Publish Java SDK

action.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ outputs:
153153
description: "Whether the CLI target will be published"
154154
publish_mcp_typescript:
155155
description: "Whether the MCP Typescript target will be published to NPM"
156+
publish_mcp_registry:
157+
description: "Whether the MCP Typescript target will be published to the MCP Registry"
156158
cli_regenerated:
157159
description: "true if the CLI target was regenerated"
158160
cli_directory:

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/pb33f/libopenapi v0.15.14
1313
github.com/pkg/errors v0.9.1
1414
github.com/speakeasy-api/git-diff-parser v0.0.3
15-
github.com/speakeasy-api/sdk-gen-config v1.56.0
15+
github.com/speakeasy-api/sdk-gen-config v1.57.0
1616
github.com/speakeasy-api/speakeasy-client-sdk-go/v3 v3.15.4
1717
github.com/speakeasy-api/versioning-reports v0.6.1
1818
github.com/stretchr/testify v1.11.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ github.com/speakeasy-api/git-diff-parser v0.0.3 h1:LL12d+HMtSyj6O/hQqIn/lgDPYI6c
146146
github.com/speakeasy-api/git-diff-parser v0.0.3/go.mod h1:P46HmmVVmwA9P8h2wa0fDpmRM8/grbVQ+uKhWDtpkIY=
147147
github.com/speakeasy-api/openapi v1.6.4 h1:WLoZYEK9xZQVb2JNkbXWS0HBwHYQ3GNqf+8Q3E/kXmA=
148148
github.com/speakeasy-api/openapi v1.6.4/go.mod h1:fy+CvRcKj+HDU0QNdnyG6UkfJOEjhqCuNC7o4AtLPAk=
149-
github.com/speakeasy-api/sdk-gen-config v1.56.0 h1:1tVW8mV/7o9/iFwHd7cGGZ7UCxCcU12QN9zOMwb/zCI=
150-
github.com/speakeasy-api/sdk-gen-config v1.56.0/go.mod h1:kD0NPNX5yaG4j+dcCpLL0hHKQbFk6X93obp+v1XlK5E=
149+
github.com/speakeasy-api/sdk-gen-config v1.57.0 h1:JQ2XcDbZkmYZhsQoQ9BH9TJR4KiO1uN+GVOOc0EGMA8=
150+
github.com/speakeasy-api/sdk-gen-config v1.57.0/go.mod h1:kD0NPNX5yaG4j+dcCpLL0hHKQbFk6X93obp+v1XlK5E=
151151
github.com/speakeasy-api/speakeasy-client-sdk-go/v3 v3.15.4 h1:lPVNakwHrrRWRaNIdIHE6BK7RI6B/jpdwbtvI/xPEYo=
152152
github.com/speakeasy-api/speakeasy-client-sdk-go/v3 v3.15.4/go.mod h1:b4fiZ1Wid0JHwwiYqhaPifDwjmC15uiN7A8Cmid+9kw=
153153
github.com/speakeasy-api/versioning-reports v0.6.1 h1:pvuvA1IFO7PVlpdFh7J2Y3hENDzhISFdNy0NVg/Cxb4=

internal/run/run.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,4 +368,10 @@ func AddTargetPublishOutputs(target workflow.Target, outputs map[string]string,
368368
target.Publishing.PyPi.UseTrustedPublishing != nil && *target.Publishing.PyPi.UseTrustedPublishing {
369369
outputs["use_pypi_trusted_publishing"] = "true"
370370
}
371+
372+
if lang == "mcp-typescript" && target.Publishing != nil && target.Publishing.MCPRegistry != nil &&
373+
target.Publishing.MCPRegistry.Auth != "" {
374+
outputs["publish_mcp_registry"] = "true"
375+
outputs["mcp_registry_auth"] = target.Publishing.MCPRegistry.Auth
376+
}
371377
}

0 commit comments

Comments
 (0)