diff --git a/.github/pages/_config.yml b/.github/pages/_config.yml
deleted file mode 100644
index 67b2fb53c..000000000
--- a/.github/pages/_config.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-title: '@modelcontextprotocol/sdk'
-
-# Include generated files and directories which may start with underscores
-include:
- - '_*'
diff --git a/.github/pages/index.html b/.github/pages/index.html
deleted file mode 100644
index 5dd7adeaf..000000000
--- a/.github/pages/index.html
+++ /dev/null
@@ -1,183 +0,0 @@
----
-# Jekyll front matter to enable Liquid templating
----
-
-
-
-
-
-
- MCP TypeScript SDK - API Documentation
-
-
-
-
-
- MCP TypeScript SDK
-
-
-
- Package Versions
-
-
Loading package versions...
-
-
- All Documentation Versions
- Select a version to view its API documentation:
-
-
-
-
-
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 8c35bc238..20cd67ace 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -109,20 +109,22 @@ jobs:
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- # Generates API documentation for GitHub Pages on any release
- # Supports both simple tags (v1.2.3) and package-scoped tags (@scope/package@1.2.3)
- publish-gh-pages:
+ # Generates API documentation and deploys to GitHub Pages on any release
+ deploy-docs:
runs-on: ubuntu-latest
if: github.event_name == 'release'
needs: [publish]
permissions:
- contents: write
+ pages: write
+ id-token: write
+
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Fetch all history for all branches and tags
- name: Install pnpm
uses: pnpm/action-setup@v4
@@ -137,13 +139,20 @@ jobs:
- name: Install dependencies
run: pnpm install
- - name: Configure Git
- run: |
- git config --global user.name "github-actions[bot]"
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
+ - name: Build packages
+ run: pnpm build:all
- name: Generate documentation
- run: ./scripts/generate-gh-pages.sh "${{ github.ref_name }}"
+ run: pnpm docs
+
+ - name: Configure Pages
+ uses: actions/configure-pages@v5
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: tmp/docs
- - name: Push to gh-pages
- run: git push origin gh-pages
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/scripts/generate-gh-pages.sh b/scripts/generate-gh-pages.sh
deleted file mode 100755
index ac2a6e9d3..000000000
--- a/scripts/generate-gh-pages.sh
+++ /dev/null
@@ -1,186 +0,0 @@
-#!/bin/bash
-set -e
-
-# Generates versioned API documentation and commits to gh-pages branch
-#
-# PURPOSE:
-# This script generates API documentation in the gh-pages branch for a
-# specific version tag while preserving existing versioned documentation.
-# This script is invoked by the publish-gh-pages job in the GitHub Actions
-# workflow (.github/workflows/main.yml) when a release is published.
-#
-# HOW IT WORKS:
-# - Creates isolated git worktrees for the specified tag and gh-pages branch
-# - Generates documentation into gh-pages in a directory based on the tag name (e.g., v1.2.3/)
-# - Generates _data/latest_version.yml for Jekyll template
-# - Generates versions.json manifest showing all package versions
-# - Copies static Jekyll template files from .github/pages/
-# - Commits changes to gh-pages (does not push automatically)
-#
-# WORKFLOW:
-# 1. Run this script with a tag name: `generate-gh-pages.sh v1.2.3`
-# Or with a package-scoped tag: `generate-gh-pages.sh @modelcontextprotocol/client@1.2.3`
-# 2. Script generates docs and commits to local gh-pages branch
-# 3. Push gh-pages branch to deploy: `git push origin gh-pages`
-
-TAG_NAME="${1}"
-
-# Parse semantic version from tag name
-# Supports both simple tags (v1.2.3) and package-scoped tags (@scope/package@1.2.3)
-if [[ "${TAG_NAME}" =~ @[^@]+@([0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?)$ ]]; then
- # Package-scoped tag (e.g., @modelcontextprotocol/client@1.2.3)
- VERSION="v${BASH_REMATCH[1]}"
-elif [[ "${TAG_NAME}" =~ ([0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?)$ ]]; then
- # Simple version tag (e.g., v1.2.3 or 1.2.3)
- VERSION="v${BASH_REMATCH[1]}"
-else
- echo "Error: Must specify a tag name that contains a valid semantic version"
- echo "Usage: ${0} "
- echo "Examples:"
- echo " ${0} 1.2.3"
- echo " ${0} v2.0.0-rc.1"
- echo " ${0} @modelcontextprotocol/client@1.2.3"
- exit 1
-fi
-
-echo "Generating documentation for tag: ${TAG_NAME}"
-echo "Documentation version directory: ${VERSION}"
-
-# Generates documentation for the given source directory.
-#
-# Can modify this function to customize documentation structure.
-# For example, to add guides from ./docs/ and nest API docs under /api:
-# 1. Copy docs/ contents: `cp -r docs/* "${output_dir}/"`
-# 2. Change typedoc output: `npx typedoc --out "${output_dir}/api"`
-generate_docs() {
- local source_dir="${1}"
- local output_dir="${2}"
-
- # Resolve to absolute path (because typedoc runs from source_dir)
- [[ "${output_dir}" != /* ]] && output_dir="$(pwd)/${output_dir}"
-
- echo "Installing dependencies..."
- (cd "${source_dir}" && pnpm install --frozen-lockfile --ignore-scripts)
-
- echo "Generating TypeDoc documentation..."
- (cd "${source_dir}" && pnpm run docs --out "${output_dir}")
-
- # Verify docs were generated
- if [ -z "$(ls -A "${output_dir}")" ]; then
- echo "Error: Documentation was not generated at ${output_dir}"
- exit 1
- fi
-}
-
-# Gets list of public (non-private) package paths from pnpm workspace
-get_public_packages() {
- local source_dir="${1}"
- (cd "${source_dir}" && pnpm list -r --json --depth -1 | node -e '
- const data = JSON.parse(require("fs").readFileSync(0, "utf8"));
- data.filter(p => !p.private).forEach(p => console.log(p.path));
- ')
-}
-
-# Generates versions.json manifest showing all package versions
-# This helps users understand which versions of each package are included
-generate_versions_manifest() {
- local source_dir="${1}"
- local output_dir="${2}"
- local tag_name="${3}"
-
- echo "Generating versions.json manifest..."
-
- # Get list of public packages dynamically from pnpm workspace
- local packages
- packages=$(get_public_packages "${source_dir}")
-
- # Start JSON object
- local json="{\n"
- json+=" \"generated_from_tag\": \"${tag_name}\",\n"
- json+=" \"generated_at\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\n"
- json+=" \"packages\": {\n"
-
- local first=true
- while IFS= read -r pkg_path; do
- local pkg_json="${pkg_path}/package.json"
- if [ -f "${pkg_json}" ]; then
- local pkg_name=$(node -p "require('${pkg_json}').name")
- local pkg_version=$(node -p "require('${pkg_json}').version")
-
- if [ "${first}" = true ]; then
- first=false
- else
- json+=",\n"
- fi
- json+=" \"${pkg_name}\": \"${pkg_version}\""
- fi
- done <<< "${packages}"
-
- json+="\n }\n}"
-
- # Write the manifest
- echo -e "${json}" > "${output_dir}/versions.json"
- echo "Created ${output_dir}/versions.json"
-}
-
-# Create temporary directories for both worktrees
-TAG_WORKTREE_DIR=$(mktemp -d)
-GHPAGES_WORKTREE_DIR=$(mktemp -d)
-
-# Set up trap to clean up both worktrees on exit
-trap 'git worktree remove --force "${TAG_WORKTREE_DIR}" 2>/dev/null || true; \
- git worktree remove --force "${GHPAGES_WORKTREE_DIR}" 2>/dev/null || true' EXIT
-
-echo "Creating worktree for ${TAG_NAME}..."
-git worktree add --quiet "${TAG_WORKTREE_DIR}" "${TAG_NAME}"
-
-# Fetch gh-pages from remote if available (creates local branch if missing)
-git fetch --quiet origin gh-pages:refs/heads/gh-pages 2>/dev/null || true
-
-if git show-ref --verify --quiet refs/heads/gh-pages; then
- echo "Creating worktree for gh-pages branch..."
- git worktree add --quiet "${GHPAGES_WORKTREE_DIR}" gh-pages
-else
- echo "Creating worktree for new orphan gh-pages branch..."
- git worktree add --quiet --detach "${GHPAGES_WORKTREE_DIR}"
- git -C "${GHPAGES_WORKTREE_DIR}" switch --orphan gh-pages
-fi
-
-# Change to gh-pages worktree for all subsequent operations
-cd "${GHPAGES_WORKTREE_DIR}"
-
-# Generate TypeDoc documentation into gh-pages worktree
-mkdir -p "${VERSION}"
-generate_docs "${TAG_WORKTREE_DIR}" "${VERSION}"
-
-# Generate versions manifest showing all package versions
-generate_versions_manifest "${TAG_WORKTREE_DIR}" "${VERSION}" "${TAG_NAME}"
-
-# Generate version data for Jekyll
-echo "Generating _data/latest_version.yml..."
-mkdir -p _data
-LATEST_VERSION="v$(printf '%s\n' */ | grep '^v[0-9]' | sed -e 's/^v//' -e 's:/$::' | sort -Vr | head -1)"
-echo "${LATEST_VERSION}" > _data/latest_version.yml
-
-if [ "${VERSION}" = "${LATEST_VERSION}" ]; then
- echo "${VERSION} is the latest version, updating static files..."
-
- # Clean up old tracked files from gh-pages root (but preserve directories)
- git ls-files -z | grep -zv '/' | xargs -0 rm -f
-
- # Copy static files from .github/pages/
- find "${TAG_WORKTREE_DIR}/.github/pages" -maxdepth 1 -type f -exec cp {} . \;
-else
- echo "${VERSION} is not the latest version (latest is ${LATEST_VERSION})"
-fi
-
-# Commit if there are changes
-git add .
-
-if git diff --staged --quiet; then
- echo "No changes to commit for tag ${TAG_NAME}"
-else
- git commit -m "Add ${VERSION} docs"
- echo "Documentation for tag ${TAG_NAME} committed to gh-pages branch!"
- echo "Push to remote to deploy to GitHub Pages"
-fi