@mokoconsulting/mcp-mokosuite 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.editorconfig +19 -0
  2. package/.gitattributes +94 -0
  3. package/.gitmessage +9 -0
  4. package/.mokogit/ISSUE_TEMPLATE/adr.md +110 -0
  5. package/.mokogit/ISSUE_TEMPLATE/bug_report.md +48 -0
  6. package/.mokogit/ISSUE_TEMPLATE/config.yml +18 -0
  7. package/.mokogit/ISSUE_TEMPLATE/documentation.md +52 -0
  8. package/.mokogit/ISSUE_TEMPLATE/feature_request.md +51 -0
  9. package/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md +48 -0
  10. package/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md +69 -0
  11. package/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md +50 -0
  12. package/.mokogit/ISSUE_TEMPLATE/question.md +82 -0
  13. package/.mokogit/ISSUE_TEMPLATE/rfc.md +126 -0
  14. package/.mokogit/ISSUE_TEMPLATE/security.md +51 -0
  15. package/.mokogit/ISSUE_TEMPLATE/version.md +24 -0
  16. package/.mokogit/actions/resolve-source-dir/action.yml +108 -0
  17. package/.mokogit/workflows/auto-assign.yml +76 -0
  18. package/.mokogit/workflows/auto-bump.yml +78 -0
  19. package/.mokogit/workflows/auto-dev-issue.yml +207 -0
  20. package/.mokogit/workflows/auto-release.yml +596 -0
  21. package/.mokogit/workflows/branch-cleanup.yml +60 -0
  22. package/.mokogit/workflows/cascade-dev.yml +198 -0
  23. package/.mokogit/workflows/changelog-validation.yml +101 -0
  24. package/.mokogit/workflows/ci-generic.yml +203 -0
  25. package/.mokogit/workflows/ci-issue-reporter.yml +75 -0
  26. package/.mokogit/workflows/cleanup.yml +87 -0
  27. package/.mokogit/workflows/gitleaks.yml +94 -0
  28. package/.mokogit/workflows/issue-branch.yml +81 -0
  29. package/.mokogit/workflows/notify.yml +73 -0
  30. package/.mokogit/workflows/npm-build-test.yml +83 -0
  31. package/.mokogit/workflows/npm-publish.yml +126 -0
  32. package/.mokogit/workflows/npm-sdk-check.yml +110 -0
  33. package/.mokogit/workflows/npm-tool-inventory.yml +80 -0
  34. package/.mokogit/workflows/pr-branch-check.yml +90 -0
  35. package/.mokogit/workflows/pr-check.yml +565 -0
  36. package/.mokogit/workflows/pre-release.yml +413 -0
  37. package/.mokogit/workflows/push-notify.yml +43 -0
  38. package/.mokogit/workflows/rc-revert.yml +72 -0
  39. package/.mokogit/workflows/repo-health.yml +700 -0
  40. package/.mokogit/workflows/repository-cleanup.yml +525 -0
  41. package/.mokogit/workflows/standards-compliance.yml +2507 -0
  42. package/.mokogit/workflows/sync-version-on-merge.yml +130 -0
  43. package/.mokogit/workflows/version-set.yml +131 -0
  44. package/CHANGELOG.md +18 -0
  45. package/CLAUDE.md +52 -0
  46. package/CODE_OF_CONDUCT.md +70 -0
  47. package/CONTRIBUTING.md +161 -0
  48. package/LICENSE +696 -0
  49. package/Makefile +70 -0
  50. package/README.md +83 -0
  51. package/SECURITY.md +34 -0
  52. package/config.example.json +21 -0
  53. package/dist/client.d.ts +22 -0
  54. package/dist/client.js +124 -0
  55. package/dist/config.d.ts +4 -0
  56. package/dist/config.js +53 -0
  57. package/dist/index.d.ts +3 -0
  58. package/dist/index.js +181 -0
  59. package/dist/signing.d.ts +14 -0
  60. package/dist/signing.js +62 -0
  61. package/dist/types.d.ts +44 -0
  62. package/dist/types.js +16 -0
  63. package/docs/API.md +63 -0
  64. package/docs/ARCHITECTURE.md +73 -0
  65. package/docs/INSTALLATION.md +102 -0
  66. package/docs/index.md +12 -0
  67. package/package.json +35 -0
  68. package/src/client.ts +142 -0
  69. package/src/config.ts +63 -0
  70. package/src/index.ts +336 -0
  71. package/src/signing.ts +67 -0
  72. package/src/types.ts +63 -0
  73. package/tsconfig.json +19 -0
@@ -0,0 +1,94 @@
1
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+ #
5
+ # FILE INFORMATION
6
+ # DEFGROUP: MokoGIT.Workflow
7
+ # INGROUP: MokoCLI.Security
8
+ # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
9
+ # PATH: /.mokogit/workflows/gitleaks.yml
10
+ # VERSION: 01.00.00
11
+ # BRIEF: Secret scanning — detect leaked credentials, API keys, and tokens
12
+ #
13
+ # +========================================================================+
14
+ # | SECRET SCANNING |
15
+ # +========================================================================+
16
+ # | |
17
+ # | Scans commits for leaked secrets using Gitleaks. |
18
+ # | |
19
+ # | - PR scan: only new commits in the PR |
20
+ # | - Scheduled: full repo scan weekly |
21
+ # | - Alerts via ntfy on findings |
22
+ # | |
23
+ # +========================================================================+
24
+
25
+ name: "Universal: Secret Scanning"
26
+
27
+ on:
28
+ schedule:
29
+ - cron: '0 5 * * 1' # Weekly Monday 05:00 UTC
30
+ workflow_dispatch:
31
+
32
+ permissions:
33
+ contents: read
34
+
35
+ env:
36
+ NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
37
+ NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-security' }}
38
+ NTFY_TOKEN: ${{ secrets.NTFY_TOKEN }}
39
+
40
+ jobs:
41
+ gitleaks:
42
+ name: Gitleaks Secret Scan
43
+ runs-on: ubuntu-latest
44
+
45
+ steps:
46
+ - name: Checkout
47
+ uses: actions/checkout@v4
48
+ with:
49
+ fetch-depth: 0
50
+
51
+ - name: Install Gitleaks
52
+ run: |
53
+ GITLEAKS_VERSION="8.21.2"
54
+ curl -sSL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
55
+ | tar -xz -C /usr/local/bin gitleaks
56
+ gitleaks version
57
+
58
+ - name: Scan for secrets
59
+ id: scan
60
+ run: |
61
+ echo "### Secret Scanning" >> $GITHUB_STEP_SUMMARY
62
+ ARGS="--source . --verbose --report-format json --report-path /tmp/gitleaks-report.json"
63
+
64
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
65
+ # Scan only PR commits
66
+ ARGS="$ARGS --log-opts=${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}"
67
+ echo "Scanning PR commits only" >> $GITHUB_STEP_SUMMARY
68
+ else
69
+ echo "Full repository scan" >> $GITHUB_STEP_SUMMARY
70
+ fi
71
+
72
+ if gitleaks detect $ARGS 2>&1; then
73
+ echo "result=clean" >> "$GITHUB_OUTPUT"
74
+ echo "**No secrets detected.**" >> $GITHUB_STEP_SUMMARY
75
+ else
76
+ echo "result=found" >> "$GITHUB_OUTPUT"
77
+ FINDINGS=$(jq length /tmp/gitleaks-report.json 2>/dev/null || echo "unknown")
78
+ echo "**${FINDINGS} potential secret(s) detected.**" >> $GITHUB_STEP_SUMMARY
79
+ echo "" >> $GITHUB_STEP_SUMMARY
80
+ echo "Review the findings and rotate any exposed credentials immediately." >> $GITHUB_STEP_SUMMARY
81
+ exit 1
82
+ fi
83
+
84
+ - name: Notify on findings
85
+ if: failure() && steps.scan.outputs.result == 'found'
86
+ run: |
87
+ REPO="${{ github.event.repository.name }}"
88
+ curl -sS \
89
+ -H "Title: ${REPO} — secrets detected in code" \
90
+ -H "Tags: rotating_light,key" \
91
+ -H "Priority: urgent" \
92
+ -d "Gitleaks found potential secrets. Review and rotate credentials immediately." \
93
+ -H "Authorization: Bearer ${NTFY_TOKEN}" \
94
+ "${NTFY_URL}/${NTFY_TOPIC}" || true
@@ -0,0 +1,81 @@
1
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+ #
5
+ # FILE INFORMATION
6
+ # DEFGROUP: MokoGIT.Workflow
7
+ # INGROUP: MokoCLI.Automation
8
+ # VERSION: 01.00.00
9
+ # BRIEF: Auto-create feature branch when an issue is opened
10
+
11
+ name: "Universal: Issue Branch"
12
+
13
+ on:
14
+ issues:
15
+ types: [opened]
16
+
17
+ permissions:
18
+ contents: write
19
+ issues: write
20
+
21
+ env:
22
+ MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }}
23
+
24
+ jobs:
25
+ create-branch:
26
+ name: Create feature branch
27
+ runs-on: ubuntu-latest
28
+ steps:
29
+ - name: Create branch and comment
30
+ # SECURITY: never interpolate github.event.* into a run: script — the
31
+ # Actions engine splices the raw value into the shell source (command
32
+ # injection via a crafted issue title). Pass everything through env so
33
+ # the values arrive as ordinary shell variables that are not re-parsed.
34
+ env:
35
+ MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
36
+ REPO: ${{ github.repository }}
37
+ ISSUE_NUM: ${{ github.event.issue.number }}
38
+ ISSUE_TITLE: ${{ github.event.issue.title }}
39
+ run: |
40
+ TOKEN="${MOKOGIT_TOKEN}"
41
+ API="${MOKOGIT_URL}/api/v1/repos/${REPO}"
42
+
43
+ # Build slug from title: lowercase, replace non-alnum with dash, trim.
44
+ # printf (not echo) so a title beginning with "-" is not read as flags.
45
+ SLUG=$(printf '%s' "${ISSUE_TITLE}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' | cut -c1-40)
46
+ BRANCH="feature/${ISSUE_NUM}-${SLUG}"
47
+
48
+ # Check dev branch exists
49
+ DEV_EXISTS=$(curl -sf -o /dev/null -w '%{http_code}' \
50
+ -H "Authorization: token ${TOKEN}" \
51
+ "${API}/branches/dev" 2>/dev/null || echo "000")
52
+
53
+ if [ "${DEV_EXISTS}" != "200" ]; then
54
+ echo "No dev branch -- skipping"
55
+ exit 0
56
+ fi
57
+
58
+ # Create branch from dev
59
+ HTTP=$(curl -sf -o /dev/null -w '%{http_code}' -X POST \
60
+ -H "Authorization: token ${TOKEN}" \
61
+ -H "Content-Type: application/json" \
62
+ "${API}/branches" \
63
+ -d "{\"new_branch_name\":\"${BRANCH}\",\"old_branch_name\":\"dev\"}" 2>/dev/null || echo "000")
64
+
65
+ if [ "${HTTP}" = "201" ]; then
66
+ echo "Created branch: ${BRANCH}"
67
+
68
+ # Comment on issue with branch link
69
+ REPO_URL="${MOKOGIT_URL}/${REPO}"
70
+ BODY="Branch created: [\`${BRANCH}\`](${REPO_URL}/src/branch/${BRANCH})\n\n\`\`\`bash\ngit fetch origin\ngit checkout ${BRANCH}\n\`\`\`"
71
+
72
+ curl -sf -X POST \
73
+ -H "Authorization: token ${TOKEN}" \
74
+ -H "Content-Type: application/json" \
75
+ "${API}/issues/${ISSUE_NUM}/comments" \
76
+ -d "{\"body\":\"${BODY}\"}" > /dev/null 2>&1
77
+
78
+ echo "Commented on issue #${ISSUE_NUM}"
79
+ else
80
+ echo "Failed to create branch (HTTP ${HTTP}) -- may already exist"
81
+ fi
@@ -0,0 +1,73 @@
1
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+ #
5
+ # FILE INFORMATION
6
+ # DEFGROUP: MokoGIT.Workflow
7
+ # INGROUP: MokoCLI.Notifications
8
+ # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
9
+ # PATH: /.mokogit/workflows/notify.yml
10
+ # VERSION: 01.00.00
11
+ # BRIEF: Push notifications via ntfy on release success or workflow failure
12
+
13
+ name: "Universal: Notifications"
14
+
15
+ on:
16
+ workflow_run:
17
+ workflows:
18
+ - "Universal: Build & Release"
19
+ - "Joomla: Extension CI"
20
+ - "Generic: Project CI"
21
+ types:
22
+ - completed
23
+
24
+ permissions:
25
+ contents: read
26
+
27
+ env:
28
+ NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
29
+ NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-releases' }}
30
+ NTFY_TOKEN: ${{ secrets.NTFY_TOKEN }}
31
+
32
+ jobs:
33
+ notify:
34
+ name: Send Notification
35
+ runs-on: ubuntu-latest
36
+ if: >-
37
+ github.event.workflow_run.conclusion == 'success' ||
38
+ github.event.workflow_run.conclusion == 'failure'
39
+
40
+ steps:
41
+ - name: Notify on success (releases only)
42
+ if: >-
43
+ github.event.workflow_run.conclusion == 'success' &&
44
+ contains(github.event.workflow_run.name, 'Release')
45
+ run: |
46
+ REPO="${{ github.event.repository.name }}"
47
+ WORKFLOW="${{ github.event.workflow_run.name }}"
48
+ URL="${{ github.event.workflow_run.html_url }}"
49
+
50
+ curl -sS --retry 3 --retry-connrefused --retry-delay 2 --max-time 20 \
51
+ -H "Title: ${REPO} released" \
52
+ -H "Tags: white_check_mark,package" \
53
+ -H "Priority: default" \
54
+ -H "Click: ${URL}" \
55
+ -d "${WORKFLOW} completed successfully." \
56
+ -H "Authorization: Bearer ${NTFY_TOKEN}" \
57
+ "${NTFY_URL}/${NTFY_TOPIC}" || echo "::warning::ntfy notification could not be delivered (non-fatal)"
58
+
59
+ - name: Notify on failure
60
+ if: github.event.workflow_run.conclusion == 'failure'
61
+ run: |
62
+ REPO="${{ github.event.repository.name }}"
63
+ WORKFLOW="${{ github.event.workflow_run.name }}"
64
+ URL="${{ github.event.workflow_run.html_url }}"
65
+
66
+ curl -sS --retry 3 --retry-connrefused --retry-delay 2 --max-time 20 \
67
+ -H "Title: ${REPO} workflow failed" \
68
+ -H "Tags: x,warning" \
69
+ -H "Priority: high" \
70
+ -H "Click: ${URL}" \
71
+ -d "${WORKFLOW} failed. Check the run for details." \
72
+ -H "Authorization: Bearer ${NTFY_TOKEN}" \
73
+ "${NTFY_URL}/${NTFY_TOPIC}" || echo "::warning::ntfy notification could not be delivered (non-fatal)"
@@ -0,0 +1,83 @@
1
+ # MCP Server Build & Validation
2
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+ #
5
+ # Builds the MCP server, validates TypeScript compilation, and checks
6
+ # that tools are properly registered with valid Zod schemas.
7
+
8
+ name: "MCP: Build & Validate"
9
+
10
+ on:
11
+ push:
12
+ branches: [main, dev/**]
13
+ paths: ['source/**', 'src/**', 'package.json', 'tsconfig.json']
14
+ pull_request:
15
+ branches: [main]
16
+ paths: ['source/**', 'src/**', 'package.json', 'tsconfig.json']
17
+
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ env:
23
+ MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }}
24
+ GIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }}
25
+ GIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }}
26
+
27
+ jobs:
28
+ build:
29
+ runs-on: ubuntu-latest
30
+ if: ${{ !startsWith(github.event.repository.name, 'Template-') }}
31
+ strategy:
32
+ matrix:
33
+ node-version: [20, 22]
34
+
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+
38
+ - name: Resolve source dir
39
+ id: srcdir
40
+ uses: ./.mokogit/actions/resolve-source-dir
41
+ with:
42
+ mokogit_token: ${{ secrets.MOKOGIT_TOKEN }}
43
+ strict: 'false'
44
+
45
+ - name: Setup Node.js ${{ matrix.node-version }}
46
+ uses: actions/setup-node@v4
47
+ with:
48
+ node-version: ${{ matrix.node-version }}
49
+
50
+ - name: Install dependencies
51
+ run: npm ci
52
+
53
+ - name: TypeScript compile
54
+ run: npx tsc --noEmit
55
+
56
+ - name: Build
57
+ run: npm run build
58
+
59
+ - name: Verify dist output exists
60
+ run: |
61
+ test -f dist/index.js || (echo "ERROR: dist/index.js not found" && exit 1)
62
+ test -f dist/client.js || (echo "ERROR: dist/client.js not found" && exit 1)
63
+ test -f dist/config.js || (echo "ERROR: dist/config.js not found" && exit 1)
64
+ test -f dist/types.js || (echo "ERROR: dist/types.js not found" && exit 1)
65
+ echo "✓ All required dist files present"
66
+
67
+ - name: Verify shebang in index.js
68
+ run: |
69
+ head -1 dist/index.js | grep -q "#!/usr/bin/env node" || echo "WARNING: Missing shebang in dist/index.js"
70
+
71
+ - name: Count registered tools
72
+ run: |
73
+ INDEX_FILE="${{ steps.srcdir.outputs.source_dir }}index.ts"
74
+ if [ ! -f "${INDEX_FILE}" ]; then
75
+ echo "::warning::resolved entrypoint ${INDEX_FILE} missing; falling back to src/index.ts"
76
+ INDEX_FILE="src/index.ts"
77
+ fi
78
+ TOOL_COUNT=$(grep -c "server\.tool(" "${INDEX_FILE}" || true)
79
+ echo "Registered tools in ${INDEX_FILE}: ${TOOL_COUNT}"
80
+ if [ "${TOOL_COUNT}" -eq 0 ]; then
81
+ echo "ERROR: No tools registered in ${INDEX_FILE}"
82
+ exit 1
83
+ fi
@@ -0,0 +1,126 @@
1
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+ #
5
+ # FILE INFORMATION
6
+ # DEFGROUP: MokoGIT.Workflow
7
+ # INGROUP: MokoCLI.Release
8
+ # REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-NPM
9
+ # PATH: /.mokogit/workflows/npm-publish.yml
10
+ # VERSION: 02.00.00
11
+ # BRIEF: Build + publish shim. The shared release engine (pre-release.yml /
12
+ # auto-release.yml) owns version bump, tag, changelog and release
13
+ # object; this workflow only builds and publishes the version the
14
+ # engine has already written to package.json. It never bumps or
15
+ # writes the version.
16
+
17
+ name: "Publish to npm"
18
+
19
+ on:
20
+ push:
21
+ branches:
22
+ - main
23
+ workflow_dispatch:
24
+
25
+ jobs:
26
+ publish:
27
+ runs-on: release
28
+ if: >-
29
+ !contains(github.event.head_commit.message, '[skip ci]') &&
30
+ !contains(github.event.head_commit.message, '[skip publish]') &&
31
+ !startsWith(github.event.repository.name, 'Template-')
32
+ steps:
33
+ - name: Checkout
34
+ uses: actions/checkout@v4
35
+ with:
36
+ fetch-depth: 2
37
+
38
+ - name: Resolve source dir
39
+ id: srcdir
40
+ uses: ./.mokogit/actions/resolve-source-dir
41
+ with:
42
+ mokogit_token: ${{ secrets.MOKOGIT_TOKEN }}
43
+ strict: 'true'
44
+
45
+ - name: Detect publishable changes
46
+ id: detect
47
+ run: |
48
+ set -euo pipefail
49
+
50
+ # workflow_dispatch has no diff base — always treat as changed.
51
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
52
+ echo "::notice::workflow_dispatch — forcing changed=true"
53
+ echo "changed=true" >> "$GITHUB_OUTPUT"
54
+ exit 0
55
+ fi
56
+
57
+ # Build the source-dir alternative from the resolved dir (escape ERE metachars).
58
+ # Class lists ] first and [ last to avoid a [. collating-symbol parse; the
59
+ # \\\\& replacement reaches sed as \\& = literal backslash + matched char.
60
+ SRC_DIR='${{ steps.srcdir.outputs.source_dir }}'
61
+ SRC_RE=$(printf '%s' "$SRC_DIR" | sed 's/[].^$*+?(){}|[]/\\\\&/g')
62
+ PATTERN="^(${SRC_RE}|package\.json$|package-lock\.json$|tsconfig\.json$|README\.md$)"
63
+ echo "Detect pattern: ${PATTERN}"
64
+
65
+ BEFORE="${{ github.event.before }}"
66
+ if [ -z "${BEFORE}" ] || ! git cat-file -e "${BEFORE}^{commit}" 2>/dev/null; then
67
+ BEFORE=$(git rev-parse HEAD^ 2>/dev/null || echo "")
68
+ fi
69
+ if [ -n "${BEFORE}" ]; then
70
+ FILES=$(git diff --name-only "${BEFORE}" HEAD)
71
+ else
72
+ FILES=$(git show --name-only --pretty=format: HEAD)
73
+ fi
74
+
75
+ if printf '%s\n' "${FILES}" | grep -Eq "${PATTERN}"; then
76
+ echo "changed=true" >> "$GITHUB_OUTPUT"
77
+ else
78
+ echo "::notice::No publishable changes under '${SRC_DIR}'. Files: ${FILES}"
79
+ echo "changed=false" >> "$GITHUB_OUTPUT"
80
+ fi
81
+
82
+ - name: Setup Node.js
83
+ if: steps.detect.outputs.changed == 'true'
84
+ uses: actions/setup-node@v4
85
+ with:
86
+ node-version: '20'
87
+
88
+ - name: Install dependencies
89
+ if: steps.detect.outputs.changed == 'true'
90
+ run: npm install --no-audit --no-fund
91
+
92
+ - name: Build
93
+ if: steps.detect.outputs.changed == 'true'
94
+ run: npm run build
95
+
96
+ - name: Read version to publish
97
+ id: version
98
+ if: steps.detect.outputs.changed == 'true'
99
+ run: |
100
+ set -euo pipefail
101
+ # READ-ONLY. The shared release engine (pre-release.yml / auto-release.yml)
102
+ # has already bumped and written this version into package.json and created
103
+ # the tag + release object. This shim only publishes it — it never bumps or
104
+ # writes the version.
105
+ VERSION=$(node -p "require('./package.json').version")
106
+ echo "Publishing version ${VERSION} (set by the shared release engine)."
107
+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
108
+
109
+ - name: Publish to npmjs.org + git.mokoconsulting.tech
110
+ if: steps.detect.outputs.changed == 'true'
111
+ run: |
112
+ set -uo pipefail
113
+ {
114
+ echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}"
115
+ echo "//git.mokoconsulting.tech/api/packages/MokoConsulting/npm/:_authToken=${MOKOGIT_TOKEN}"
116
+ } >> .npmrc
117
+ VER=$(node -p "require('./package.json').version")
118
+ rc=0
119
+ echo "Publishing ${VER} -> npmjs.org"
120
+ npm publish --access public --registry https://registry.npmjs.org/ || { echo "::warning::npmjs.org publish failed (version ${VER} may already exist)"; rc=$((rc+1)); }
121
+ echo "Publishing ${VER} -> git.mokoconsulting.tech"
122
+ npm publish --access public --registry https://git.mokoconsulting.tech/api/packages/MokoConsulting/npm/ || { echo "::warning::git.mokoconsulting.tech publish failed (version ${VER} may already exist)"; rc=$((rc+1)); }
123
+ [ "$rc" -lt 2 ]
124
+ env:
125
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
126
+ MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
@@ -0,0 +1,110 @@
1
+ # MCP SDK Version Check
2
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+ #
5
+ # Weekly check for MCP SDK updates. Creates an issue when a new version
6
+ # of @modelcontextprotocol/sdk is available.
7
+
8
+ name: "MCP: SDK Version Check"
9
+
10
+ on:
11
+ schedule:
12
+ - cron: '0 9 * * 1' # Every Monday at 9am UTC
13
+ workflow_dispatch:
14
+
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ check-sdk:
21
+ runs-on: ubuntu-latest
22
+ if: ${{ !startsWith(github.event.repository.name, 'Template-') }}
23
+
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+
27
+ - name: Setup Node.js
28
+ uses: actions/setup-node@v4
29
+ with:
30
+ node-version: 20
31
+
32
+ - name: Check for SDK updates
33
+ id: sdk-check
34
+ run: |
35
+ CURRENT=$(node -p "require('./package.json').dependencies['@modelcontextprotocol/sdk']" | sed 's/[\^~]//')
36
+ LATEST=$(npm view @modelcontextprotocol/sdk version 2>/dev/null || echo "unknown")
37
+
38
+ echo "current=${CURRENT}" >> $GITHUB_OUTPUT
39
+ echo "latest=${LATEST}" >> $GITHUB_OUTPUT
40
+
41
+ if [ "${CURRENT}" != "${LATEST}" ] && [ "${LATEST}" != "unknown" ]; then
42
+ echo "update_available=true" >> $GITHUB_OUTPUT
43
+ echo "MCP SDK update available: ${CURRENT} → ${LATEST}"
44
+ else
45
+ echo "update_available=false" >> $GITHUB_OUTPUT
46
+ echo "MCP SDK is up to date: ${CURRENT}"
47
+ fi
48
+
49
+ - name: Check for Zod updates
50
+ id: zod-check
51
+ run: |
52
+ CURRENT=$(node -p "require('./package.json').dependencies['zod']" | sed 's/[\^~]//')
53
+ LATEST=$(npm view zod version 2>/dev/null || echo "unknown")
54
+
55
+ echo "current=${CURRENT}" >> $GITHUB_OUTPUT
56
+ echo "latest=${LATEST}" >> $GITHUB_OUTPUT
57
+
58
+ if [ "${CURRENT}" != "${LATEST}" ] && [ "${LATEST}" != "unknown" ]; then
59
+ echo "update_available=true" >> $GITHUB_OUTPUT
60
+ else
61
+ echo "update_available=false" >> $GITHUB_OUTPUT
62
+ fi
63
+
64
+ - name: Create update issue
65
+ if: steps.sdk-check.outputs.update_available == 'true'
66
+ uses: actions/github-script@v7
67
+ with:
68
+ script: |
69
+ const title = `chore(deps): update @modelcontextprotocol/sdk ${process.env.CURRENT} → ${process.env.LATEST}`;
70
+ const body = [
71
+ '## MCP SDK Update Available',
72
+ '',
73
+ `| Package | Current | Latest |`,
74
+ `|---------|---------|--------|`,
75
+ `| @modelcontextprotocol/sdk | ${process.env.CURRENT} | ${process.env.LATEST} |`,
76
+ `| zod | ${process.env.ZOD_CURRENT} | ${process.env.ZOD_LATEST} |`,
77
+ '',
78
+ '### Steps',
79
+ '1. Update package.json',
80
+ '2. Run `npm install`',
81
+ '3. Run `npm run build` to verify compilation',
82
+ '4. Test all tools against target API',
83
+ '',
84
+ '### Changelog',
85
+ `https://github.com/modelcontextprotocol/typescript-sdk/releases`,
86
+ ].join('\n');
87
+
88
+ // Check for existing open issue
89
+ const existing = await github.rest.issues.listForRepo({
90
+ owner: context.repo.owner,
91
+ repo: context.repo.repo,
92
+ state: 'open',
93
+ labels: 'api-change',
94
+ });
95
+
96
+ const alreadyExists = existing.data.some(i => i.title.includes('@modelcontextprotocol/sdk'));
97
+ if (!alreadyExists) {
98
+ await github.rest.issues.create({
99
+ owner: context.repo.owner,
100
+ repo: context.repo.repo,
101
+ title,
102
+ body,
103
+ labels: ['api-change', 'chore'],
104
+ });
105
+ }
106
+ env:
107
+ CURRENT: ${{ steps.sdk-check.outputs.current }}
108
+ LATEST: ${{ steps.sdk-check.outputs.latest }}
109
+ ZOD_CURRENT: ${{ steps.zod-check.outputs.current }}
110
+ ZOD_LATEST: ${{ steps.zod-check.outputs.latest }}
@@ -0,0 +1,80 @@
1
+ # MCP Tool Inventory
2
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+ #
5
+ # Generates a tool inventory report on each push to main.
6
+ # Extracts tool names, descriptions, and parameter counts from src/index.ts.
7
+
8
+ name: "MCP: Tool Inventory"
9
+
10
+ on:
11
+ push:
12
+ branches: [main]
13
+ paths: ['source/index.ts', 'src/index.ts']
14
+ workflow_dispatch:
15
+
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ env:
21
+ MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }}
22
+ GIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }}
23
+ GIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }}
24
+
25
+ jobs:
26
+ inventory:
27
+ runs-on: ubuntu-latest
28
+
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+
32
+ - name: Resolve source dir
33
+ id: srcdir
34
+ uses: ./.mokogit/actions/resolve-source-dir
35
+ with:
36
+ mokogit_token: ${{ secrets.MOKOGIT_TOKEN }}
37
+ strict: 'false'
38
+
39
+ - name: Generate tool inventory
40
+ run: |
41
+ INDEX_FILE="${{ steps.srcdir.outputs.source_dir }}index.ts"
42
+ if [ ! -f "${INDEX_FILE}" ]; then
43
+ echo "::warning::resolved entrypoint ${INDEX_FILE} missing; falling back to src/index.ts"
44
+ INDEX_FILE="src/index.ts"
45
+ fi
46
+ [ -r "${INDEX_FILE}" ] || { echo "::error::entry file ${INDEX_FILE} unreadable"; exit 1; }
47
+
48
+ echo "# MCP Tool Inventory" > TOOLS.md
49
+ echo "" >> TOOLS.md
50
+ echo "Auto-generated from \`${INDEX_FILE}\` on $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> TOOLS.md
51
+ echo "" >> TOOLS.md
52
+
53
+ # Count tools
54
+ TOOL_COUNT=$(grep -c "server\.tool(" "${INDEX_FILE}" || true)
55
+ echo "**Total tools: ${TOOL_COUNT}**" >> TOOLS.md
56
+ echo "" >> TOOLS.md
57
+
58
+ # Extract tool names and descriptions
59
+ echo "| Tool | Description |" >> TOOLS.md
60
+ echo "|------|-------------|" >> TOOLS.md
61
+
62
+ grep -A1 "server\.tool(" "${INDEX_FILE}" | grep -E "^\s*'" | while read -r line; do
63
+ TOOL_NAME=$(echo "$line" | sed "s/.*'\([^']*\)'.*/\1/")
64
+ # Get next line for description
65
+ DESC=$(grep -A2 "'${TOOL_NAME}'" "${INDEX_FILE}" | grep -E "^\s*'" | tail -1 | sed "s/.*'\([^']*\)'.*/\1/" || echo "")
66
+ echo "| \`${TOOL_NAME}\` | ${DESC} |" >> TOOLS.md
67
+ done
68
+
69
+ echo "" >> TOOLS.md
70
+ echo "---" >> TOOLS.md
71
+ echo "*Generated by MCP Tool Inventory workflow*" >> TOOLS.md
72
+
73
+ cat TOOLS.md
74
+
75
+ - name: Upload inventory artifact
76
+ uses: actions/upload-artifact@v4
77
+ with:
78
+ name: tool-inventory
79
+ path: TOOLS.md
80
+ retention-days: 90