diff --git a/.mokogitea/workflows/mcp-auto-release.yml b/.mokogitea/workflows/mcp-auto-release.yml deleted file mode 100644 index 137dcf7..0000000 --- a/.mokogitea/workflows/mcp-auto-release.yml +++ /dev/null @@ -1,280 +0,0 @@ -# MCP Server Auto-Release -# Copyright (C) 2026 Moko Consulting -# SPDX-License-Identifier: GPL-3.0-or-later -# -# MCP-specific release pipeline that builds TypeScript, runs validation, -# attaches the compiled dist/ as a release artifact, and creates a GitHub -# Release with tool inventory in the release notes. -# -# This replaces the generic auto-release.yml for MCP server repos. - -name: "MCP: Build & Release" - -on: - push: - branches: - - main - paths: - - 'source/**' - - 'package.json' - - 'tsconfig.json' - -env: - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - -permissions: - contents: write - issues: write - -jobs: - build-and-release: - name: Build, Validate & Release - runs-on: ubuntu-latest - if: >- - !contains(github.event.head_commit.message, '[skip ci]') && - github.actor != 'github-actions[bot]' - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - token: ${{ secrets.GH_TOKEN || github.token }} - fetch-depth: 0 - - # ── Build ──────────────────────────────────────────────────────── - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Install dependencies - run: npm ci - - - name: TypeScript compile check - run: npx tsc --noEmit - - - name: Build - run: npm run build - - - name: Verify dist output - run: | - for f in index.js client.js config.js types.js; do - test -f "dist/${f}" || (echo "ERROR: dist/${f} not found" && exit 1) - done - echo "✓ All dist files present" - - # ── Tool Inventory ─────────────────────────────────────────────── - - name: Generate tool inventory - id: tools - run: | - TOOL_COUNT=$(grep -c "server\.tool(" source/index.ts || echo "0") - echo "count=${TOOL_COUNT}" >> "$GITHUB_OUTPUT" - - # Extract tool names - TOOL_LIST=$(grep -oE "'[a-z_]+'" source/index.ts | head -100 | tr -d "'" | sort -u) - echo "Tools registered: ${TOOL_COUNT}" - - # Generate inventory for release notes - echo "## Tool Inventory (${TOOL_COUNT} tools)" > /tmp/tool-inventory.md - echo "" >> /tmp/tool-inventory.md - grep -B0 -A1 "server\.tool(" source/index.ts | grep -oE "'[^']+'" | while IFS= read -r name; do - read -r desc 2>/dev/null || true - CLEAN_NAME=$(echo "$name" | tr -d "'") - CLEAN_DESC=$(echo "$desc" | tr -d "'" | sed 's/,$//') - if [ -n "$CLEAN_NAME" ] && [ -n "$CLEAN_DESC" ]; then - echo "- \`${CLEAN_NAME}\` — ${CLEAN_DESC}" >> /tmp/tool-inventory.md - fi - done - - # ── Version ────────────────────────────────────────────────────── - - name: Setup MokoStandards tools - run: | - if [ -d /opt/mokoplatform/api/cli ] && [ -f /opt/mokoplatform/vendor/autoload.php ]; then - ln -sf /opt/mokoplatform /tmp/mokostandards - echo "Using pre-installed /opt/mokoplatform" - elif [ -d /opt/moko-platform/api/cli ]; then - ln -sf /opt/moko-platform /tmp/mokostandards - echo "Using pre-installed /opt/moko-platform" - else - echo "::warning::MokoStandards tools not found on runner" - echo "MOKO_SKIP=true" >> "$GITHUB_ENV" - fi - - - name: Read version from README.md - id: version - run: | - VERSION=$(php /tmp/mokostandards/api/cli/version_read.php --path . 2>/dev/null) - if [ -z "$VERSION" ]; then - echo "No VERSION in README.md — skipping release" - echo "skip=true" >> "$GITHUB_OUTPUT" - exit 0 - fi - - MAJOR=$(echo "$VERSION" | awk -F. '{print $1}') - MINOR=$(echo "$VERSION" | awk -F. '{printf "%s.%s", $1, $2}') - PATCH=$(echo "$VERSION" | awk -F. '{print $3}') - - echo "version=$VERSION" >> "$GITHUB_OUTPUT" - echo "branch=version/${MAJOR}" >> "$GITHUB_OUTPUT" - echo "major=$MAJOR" >> "$GITHUB_OUTPUT" - echo "minor=$MINOR" >> "$GITHUB_OUTPUT" - echo "release_tag=v${MAJOR}" >> "$GITHUB_OUTPUT" - - if [ "$PATCH" = "00" ]; then - echo "skip=true" >> "$GITHUB_OUTPUT" - else - echo "skip=false" >> "$GITHUB_OUTPUT" - if [ "$PATCH" = "01" ]; then - echo "is_first=true" >> "$GITHUB_OUTPUT" - else - echo "is_first=false" >> "$GITHUB_OUTPUT" - fi - fi - - - name: Check if already released - if: steps.version.outputs.skip != 'true' - id: check - run: | - TAG="${{ steps.version.outputs.release_tag }}" - TAG_EXISTS=false - git rev-parse "$TAG" >/dev/null 2>&1 && TAG_EXISTS=true - echo "tag_exists=$TAG_EXISTS" >> "$GITHUB_OUTPUT" - - # ── Release Artifact ───────────────────────────────────────────── - - name: Package dist - if: steps.version.outputs.skip != 'true' - run: | - VERSION="${{ steps.version.outputs.version }}" - REPO_NAME="${{ github.event.repository.name }}" - tar -czf "/tmp/${REPO_NAME}-${VERSION}.tar.gz" -C dist . - echo "artifact=/tmp/${REPO_NAME}-${VERSION}.tar.gz" >> "$GITHUB_OUTPUT" - - # ── Version Updates ────────────────────────────────────────────── - - name: Set platform version - if: >- - steps.version.outputs.skip != 'true' && - steps.check.outputs.tag_exists != 'true' - run: | - VERSION="${{ steps.version.outputs.version }}" - php /tmp/mokostandards/api/cli/version_set_platform.php \ - --path . --version "$VERSION" --branch main - - - name: Update version badges - if: >- - steps.version.outputs.skip != 'true' && - steps.check.outputs.tag_exists != 'true' - run: | - VERSION="${{ steps.version.outputs.version }}" - find . -name "*.md" ! -path "./.git/*" ! -path "./vendor/*" | while read -r f; do - if grep -q '\[VERSION:' "$f" 2>/dev/null; then - sed -i "s/\[VERSION:[[:space:]]*[0-9]\{2\}\.[0-9]\{2\}\.[0-9]\{2\}\]/[VERSION: ${VERSION}]/" "$f" - fi - done - - - name: Commit release changes - if: >- - steps.version.outputs.skip != 'true' && - steps.check.outputs.tag_exists != 'true' - run: | - if git diff --quiet && git diff --cached --quiet; then - echo "No changes to commit" - exit 0 - fi - VERSION="${{ steps.version.outputs.version }}" - git config --local user.email "github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - git add -A - git commit -m "chore(release): build ${VERSION} [skip ci]" \ - --author="github-actions[bot] " - git push - - # ── Version Branch ─────────────────────────────────────────────── - - name: Archive version branch - if: steps.check.outputs.tag_exists != 'true' - run: | - BRANCH="${{ steps.version.outputs.branch }}" - git push origin HEAD:"$BRANCH" --force - echo "Updated archive branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY - - # ── Tag & Release ──────────────────────────────────────────────── - - name: Create git tag - if: >- - steps.version.outputs.skip != 'true' && - steps.check.outputs.tag_exists != 'true' && - steps.version.outputs.is_first == 'true' - run: | - TAG="${{ steps.version.outputs.release_tag }}" - if ! git rev-parse "$TAG" >/dev/null 2>&1; then - git tag "$TAG" - git push origin "$TAG" - fi - - - name: GitHub Release - if: >- - steps.version.outputs.skip != 'true' && - steps.check.outputs.tag_exists != 'true' - env: - GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }} - run: | - VERSION="${{ steps.version.outputs.version }}" - RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - MAJOR="${{ steps.version.outputs.major }}" - BRANCH="${{ steps.version.outputs.branch }}" - TOOL_COUNT="${{ steps.tools.outputs.count }}" - REPO_NAME="${{ github.event.repository.name }}" - - # Build release notes - NOTES=$(php /tmp/mokostandards/api/cli/release_notes.php --path . --version "$VERSION" 2>/dev/null) - [ -z "$NOTES" ] && NOTES="Release ${VERSION}" - - { - echo "$NOTES" - echo "" - echo "---" - echo "" - echo "### MCP Server Info" - echo "- **Tools registered**: ${TOOL_COUNT}" - echo "- **Node.js**: 20+" - echo "- **MCP SDK**: $(node -p \"require('./package.json').dependencies['@modelcontextprotocol/sdk']\" 2>/dev/null || echo 'unknown')" - echo "" - cat /tmp/tool-inventory.md 2>/dev/null || true - } > /tmp/release_notes.md - - EXISTING=$(gh release view "$RELEASE_TAG" --json tagName -q .tagName 2>/dev/null || true) - - ARTIFACT="/tmp/${REPO_NAME}-${VERSION}.tar.gz" - - if [ -z "$EXISTING" ]; then - gh release create "$RELEASE_TAG" \ - --title "v${MAJOR} (latest: ${VERSION})" \ - --notes-file /tmp/release_notes.md \ - --target "$BRANCH" \ - "$ARTIFACT" - echo "Release created: ${RELEASE_TAG} (${VERSION})" >> $GITHUB_STEP_SUMMARY - else - gh release edit "$RELEASE_TAG" \ - --title "v${MAJOR} (latest: ${VERSION})" \ - --notes-file /tmp/release_notes.md - gh release upload "$RELEASE_TAG" "$ARTIFACT" --clobber 2>/dev/null || true - echo "Release updated: ${RELEASE_TAG} -> ${VERSION}" >> $GITHUB_STEP_SUMMARY - fi - - # ── Summary ────────────────────────────────────────────────────── - - name: Pipeline Summary - if: always() - run: | - VERSION="${{ steps.version.outputs.version }}" - TOOL_COUNT="${{ steps.tools.outputs.count }}" - if [ "${{ steps.version.outputs.skip }}" = "true" ]; then - echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY - else - echo "" >> $GITHUB_STEP_SUMMARY - echo "## MCP Release Complete" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Detail | Value |" >> $GITHUB_STEP_SUMMARY - echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY - echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY - echo "| Tools | ${TOOL_COUNT} |" >> $GITHUB_STEP_SUMMARY - echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY - echo "| Tag | \`${{ steps.version.outputs.release_tag }}\` |" >> $GITHUB_STEP_SUMMARY - fi diff --git a/.mokogitea/workflows/mcp-build-test.yml b/.mokogitea/workflows/mcp-build-test.yml deleted file mode 100644 index 46c8fce..0000000 --- a/.mokogitea/workflows/mcp-build-test.yml +++ /dev/null @@ -1,65 +0,0 @@ -# MCP Server Build & Validation -# Copyright (C) 2026 Moko Consulting -# SPDX-License-Identifier: GPL-3.0-or-later -# -# Builds the MCP server, validates TypeScript compilation, and checks -# that tools are properly registered with valid Zod schemas. - -name: "MCP: Build & Validate" - -on: - push: - branches: [main, dev/**] - paths: ['source/**', 'package.json', 'tsconfig.json'] - pull_request: - branches: [main] - paths: ['source/**', 'package.json', 'tsconfig.json'] - - -permissions: - contents: read - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [20, 22] - - steps: - - uses: actions/checkout@v4 - - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - - - name: Install dependencies - run: npm ci - - - name: TypeScript compile - run: npx tsc --noEmit - - - name: Build - run: npm run build - - - name: Verify dist output exists - run: | - test -f dist/index.js || (echo "ERROR: dist/index.js not found" && exit 1) - test -f dist/client.js || (echo "ERROR: dist/client.js not found" && exit 1) - test -f dist/config.js || (echo "ERROR: dist/config.js not found" && exit 1) - test -f dist/types.js || (echo "ERROR: dist/types.js not found" && exit 1) - echo "✓ All required dist files present" - - - name: Verify shebang in index.js - run: | - head -1 dist/index.js | grep -q "#!/usr/bin/env node" || echo "WARNING: Missing shebang in dist/index.js" - - - name: Count registered tools - run: | - TOOL_COUNT=$(grep -c "server\.tool(" source/index.ts || true) - echo "Registered tools: ${TOOL_COUNT}" - if [ "${TOOL_COUNT}" -eq 0 ]; then - echo "ERROR: No tools registered in source/index.ts" - exit 1 - fi diff --git a/.mokogitea/workflows/mcp-sdk-check.yml b/.mokogitea/workflows/mcp-sdk-check.yml deleted file mode 100644 index 50125c0..0000000 --- a/.mokogitea/workflows/mcp-sdk-check.yml +++ /dev/null @@ -1,109 +0,0 @@ -# MCP SDK Version Check -# Copyright (C) 2026 Moko Consulting -# SPDX-License-Identifier: GPL-3.0-or-later -# -# Weekly check for MCP SDK updates. Creates an issue when a new version -# of @modelcontextprotocol/sdk is available. - -name: "MCP: SDK Version Check" - -on: - schedule: - - cron: '0 9 * * 1' # Every Monday at 9am UTC - workflow_dispatch: - - -permissions: - contents: read - -jobs: - check-sdk: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Check for SDK updates - id: sdk-check - run: | - CURRENT=$(node -p "require('./package.json').dependencies['@modelcontextprotocol/sdk']" | sed 's/[\^~]//') - LATEST=$(npm view @modelcontextprotocol/sdk version 2>/dev/null || echo "unknown") - - echo "current=${CURRENT}" >> $GITHUB_OUTPUT - echo "latest=${LATEST}" >> $GITHUB_OUTPUT - - if [ "${CURRENT}" != "${LATEST}" ] && [ "${LATEST}" != "unknown" ]; then - echo "update_available=true" >> $GITHUB_OUTPUT - echo "MCP SDK update available: ${CURRENT} → ${LATEST}" - else - echo "update_available=false" >> $GITHUB_OUTPUT - echo "MCP SDK is up to date: ${CURRENT}" - fi - - - name: Check for Zod updates - id: zod-check - run: | - CURRENT=$(node -p "require('./package.json').dependencies['zod']" | sed 's/[\^~]//') - LATEST=$(npm view zod version 2>/dev/null || echo "unknown") - - echo "current=${CURRENT}" >> $GITHUB_OUTPUT - echo "latest=${LATEST}" >> $GITHUB_OUTPUT - - if [ "${CURRENT}" != "${LATEST}" ] && [ "${LATEST}" != "unknown" ]; then - echo "update_available=true" >> $GITHUB_OUTPUT - else - echo "update_available=false" >> $GITHUB_OUTPUT - fi - - - name: Create update issue - if: steps.sdk-check.outputs.update_available == 'true' - uses: actions/github-script@v7 - with: - script: | - const title = `chore(deps): update @modelcontextprotocol/sdk ${process.env.CURRENT} → ${process.env.LATEST}`; - const body = [ - '## MCP SDK Update Available', - '', - `| Package | Current | Latest |`, - `|---------|---------|--------|`, - `| @modelcontextprotocol/sdk | ${process.env.CURRENT} | ${process.env.LATEST} |`, - `| zod | ${process.env.ZOD_CURRENT} | ${process.env.ZOD_LATEST} |`, - '', - '### Steps', - '1. Update package.json', - '2. Run `npm install`', - '3. Run `npm run build` to verify compilation', - '4. Test all tools against target API', - '', - '### Changelog', - `https://github.com/modelcontextprotocol/typescript-sdk/releases`, - ].join('\n'); - - // Check for existing open issue - const existing = await github.rest.issues.listForRepo({ - owner: context.repo.owner, - repo: context.repo.repo, - state: 'open', - labels: 'api-change', - }); - - const alreadyExists = existing.data.some(i => i.title.includes('@modelcontextprotocol/sdk')); - if (!alreadyExists) { - await github.rest.issues.create({ - owner: context.repo.owner, - repo: context.repo.repo, - title, - body, - labels: ['api-change', 'chore'], - }); - } - env: - CURRENT: ${{ steps.sdk-check.outputs.current }} - LATEST: ${{ steps.sdk-check.outputs.latest }} - ZOD_CURRENT: ${{ steps.zod-check.outputs.current }} - ZOD_LATEST: ${{ steps.zod-check.outputs.latest }} diff --git a/.mokogitea/workflows/mcp-tool-inventory.yml b/.mokogitea/workflows/mcp-tool-inventory.yml deleted file mode 100644 index dab9433..0000000 --- a/.mokogitea/workflows/mcp-tool-inventory.yml +++ /dev/null @@ -1,61 +0,0 @@ -# MCP Tool Inventory -# Copyright (C) 2026 Moko Consulting -# SPDX-License-Identifier: GPL-3.0-or-later -# -# Generates a tool inventory report on each push to main. -# Extracts tool names, descriptions, and parameter counts from source/index.ts. - -name: "MCP: Tool Inventory" - -on: - push: - branches: [main] - paths: ['source/index.ts'] - workflow_dispatch: - - -permissions: - contents: read - -jobs: - inventory: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Generate tool inventory - run: | - echo "# MCP Tool Inventory" > TOOLS.md - echo "" >> TOOLS.md - echo "Auto-generated from \`source/index.ts\` on $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> TOOLS.md - echo "" >> TOOLS.md - - # Count tools - TOOL_COUNT=$(grep -c "server\.tool(" source/index.ts || true) - echo "**Total tools: ${TOOL_COUNT}**" >> TOOLS.md - echo "" >> TOOLS.md - - # Extract tool names and descriptions - echo "| Tool | Description |" >> TOOLS.md - echo "|------|-------------|" >> TOOLS.md - - grep -A1 "server\.tool(" source/index.ts | grep -E "^\s*'" | while read -r line; do - TOOL_NAME=$(echo "$line" | sed "s/.*'\([^']*\)'.*/\1/") - # Get next line for description - DESC=$(grep -A2 "'${TOOL_NAME}'" source/index.ts | grep -E "^\s*'" | tail -1 | sed "s/.*'\([^']*\)'.*/\1/" || echo "") - echo "| \`${TOOL_NAME}\` | ${DESC} |" >> TOOLS.md - done - - echo "" >> TOOLS.md - echo "---" >> TOOLS.md - echo "*Generated by MCP Tool Inventory workflow*" >> TOOLS.md - - cat TOOLS.md - - - name: Upload inventory artifact - uses: actions/upload-artifact@v4 - with: - name: tool-inventory - path: TOOLS.md - retention-days: 90