@mokoconsulting/mcp-mokogitea-api 1.2.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 (86) hide show
  1. package/.gitattributes +94 -0
  2. package/.gitmessage +9 -0
  3. package/.mokogitea/ISSUE_TEMPLATE/adr.md +110 -0
  4. package/.mokogitea/ISSUE_TEMPLATE/bug_report.md +48 -0
  5. package/.mokogitea/ISSUE_TEMPLATE/config.yml +18 -0
  6. package/.mokogitea/ISSUE_TEMPLATE/documentation.md +52 -0
  7. package/.mokogitea/ISSUE_TEMPLATE/enterprise_support.md +85 -0
  8. package/.mokogitea/ISSUE_TEMPLATE/feature_request.md +51 -0
  9. package/.mokogitea/ISSUE_TEMPLATE/firewall-request.md +190 -0
  10. package/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md +48 -0
  11. package/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md +67 -0
  12. package/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md +49 -0
  13. package/.mokogitea/ISSUE_TEMPLATE/question.md +82 -0
  14. package/.mokogitea/ISSUE_TEMPLATE/rfc.md +126 -0
  15. package/.mokogitea/ISSUE_TEMPLATE/security.md +51 -0
  16. package/.mokogitea/ISSUE_TEMPLATE/version.md +24 -0
  17. package/.mokogitea/auto-assign.yml +76 -0
  18. package/.mokogitea/auto-dev-issue.yml +207 -0
  19. package/.mokogitea/auto-release.yml +337 -0
  20. package/.mokogitea/branch-protection.yml +251 -0
  21. package/.mokogitea/changelog-validation.yml +101 -0
  22. package/.mokogitea/codeql-analysis.yml +115 -0
  23. package/.mokogitea/copilot-agent.yml +44 -0
  24. package/.mokogitea/deploy-demo.yml +734 -0
  25. package/.mokogitea/deploy-dev.yml +700 -0
  26. package/.mokogitea/enterprise-firewall-setup.yml +758 -0
  27. package/.mokogitea/manifest.xml +25 -0
  28. package/.mokogitea/mcp-auto-release.yml +278 -0
  29. package/.mokogitea/mcp-build-test.yml +65 -0
  30. package/.mokogitea/mcp-sdk-check.yml +109 -0
  31. package/.mokogitea/mcp-tool-inventory.yml +61 -0
  32. package/.mokogitea/pr-branch-check.yml +90 -0
  33. package/.mokogitea/repository-cleanup.yml +525 -0
  34. package/.mokogitea/standards-compliance.yml +2614 -0
  35. package/.mokogitea/sync-version-on-merge.yml +133 -0
  36. package/.mokogitea/workflows/auto-assign.yml +76 -0
  37. package/.mokogitea/workflows/auto-bump.yml +66 -0
  38. package/.mokogitea/workflows/auto-dev-issue.yml +207 -0
  39. package/.mokogitea/workflows/auto-release.yml +341 -0
  40. package/.mokogitea/workflows/branch-cleanup.yml +48 -0
  41. package/.mokogitea/workflows/cascade-dev.yml +10 -0
  42. package/.mokogitea/workflows/changelog-validation.yml +101 -0
  43. package/.mokogitea/workflows/ci-generic.yml +204 -0
  44. package/.mokogitea/workflows/cleanup.yml +87 -0
  45. package/.mokogitea/workflows/codeql-analysis.yml +115 -0
  46. package/.mokogitea/workflows/copilot-agent.yml +44 -0
  47. package/.mokogitea/workflows/deploy-manual.yml +126 -0
  48. package/.mokogitea/workflows/enterprise-firewall-setup.yml +758 -0
  49. package/.mokogitea/workflows/gitleaks.yml +96 -0
  50. package/.mokogitea/workflows/issue-branch.yml +73 -0
  51. package/.mokogitea/workflows/mcp-auto-release.yml +280 -0
  52. package/.mokogitea/workflows/mcp-build-test.yml +65 -0
  53. package/.mokogitea/workflows/mcp-sdk-check.yml +109 -0
  54. package/.mokogitea/workflows/mcp-tool-inventory.yml +61 -0
  55. package/.mokogitea/workflows/notify.yml +70 -0
  56. package/.mokogitea/workflows/npm-publish.yml +51 -0
  57. package/.mokogitea/workflows/pr-check.yml +508 -0
  58. package/.mokogitea/workflows/pre-release.yml +11 -0
  59. package/.mokogitea/workflows/repo-health.yml +711 -0
  60. package/.mokogitea/workflows/repository-cleanup.yml +525 -0
  61. package/.mokogitea/workflows/security-audit.yml +82 -0
  62. package/.mokogitea/workflows/standards-compliance.yml +2614 -0
  63. package/.mokogitea/workflows/sync-version-on-merge.yml +130 -0
  64. package/.mokogitea/workflows/update-server.yml +312 -0
  65. package/CHANGELOG.md +145 -0
  66. package/CLAUDE.md +43 -0
  67. package/CONTRIBUTING.md +161 -0
  68. package/README.md +286 -0
  69. package/SECURITY.md +91 -0
  70. package/automation/ci-issue-reporter.sh +237 -0
  71. package/config.example.json +13 -0
  72. package/dist/client.d.ts +15 -0
  73. package/dist/client.js +104 -0
  74. package/dist/config.d.ts +4 -0
  75. package/dist/config.js +48 -0
  76. package/dist/index.d.ts +3 -0
  77. package/dist/index.js +1119 -0
  78. package/dist/types.d.ts +20 -0
  79. package/dist/types.js +16 -0
  80. package/package.json +34 -0
  81. package/scripts/setup.mjs +40 -0
  82. package/src/client.ts +120 -0
  83. package/src/config.ts +58 -0
  84. package/src/index.ts +1712 -0
  85. package/src/types.ts +37 -0
  86. package/tsconfig.json +19 -0
@@ -0,0 +1,96 @@
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: Gitea.Workflow
7
+ # INGROUP: MokoStandards.Security
8
+ # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards-API
9
+ # PATH: /templates/workflows/gitleaks.yml.template
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
+ pull_request:
29
+ branches:
30
+ - main
31
+ - 'dev/**'
32
+ schedule:
33
+ - cron: '0 5 * * 1' # Weekly Monday 05:00 UTC
34
+ workflow_dispatch:
35
+
36
+ permissions:
37
+ contents: read
38
+
39
+ env:
40
+ NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
41
+ NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }}
42
+
43
+ jobs:
44
+ gitleaks:
45
+ name: Gitleaks Secret Scan
46
+ runs-on: ubuntu-latest
47
+
48
+ steps:
49
+ - name: Checkout
50
+ uses: actions/checkout@v4
51
+ with:
52
+ fetch-depth: 0
53
+
54
+ - name: Install Gitleaks
55
+ run: |
56
+ GITLEAKS_VERSION="8.21.2"
57
+ curl -sSL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
58
+ | tar -xz -C /usr/local/bin gitleaks
59
+ gitleaks version
60
+
61
+ - name: Scan for secrets
62
+ id: scan
63
+ run: |
64
+ echo "### Secret Scanning" >> $GITHUB_STEP_SUMMARY
65
+ ARGS="--source . --verbose --report-format json --report-path /tmp/gitleaks-report.json"
66
+
67
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
68
+ # Scan only PR commits
69
+ ARGS="$ARGS --log-opts=${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}"
70
+ echo "Scanning PR commits only" >> $GITHUB_STEP_SUMMARY
71
+ else
72
+ echo "Full repository scan" >> $GITHUB_STEP_SUMMARY
73
+ fi
74
+
75
+ if gitleaks detect $ARGS 2>&1; then
76
+ echo "result=clean" >> "$GITHUB_OUTPUT"
77
+ echo "**No secrets detected.**" >> $GITHUB_STEP_SUMMARY
78
+ else
79
+ echo "result=found" >> "$GITHUB_OUTPUT"
80
+ FINDINGS=$(jq length /tmp/gitleaks-report.json 2>/dev/null || echo "unknown")
81
+ echo "**${FINDINGS} potential secret(s) detected.**" >> $GITHUB_STEP_SUMMARY
82
+ echo "" >> $GITHUB_STEP_SUMMARY
83
+ echo "Review the findings and rotate any exposed credentials immediately." >> $GITHUB_STEP_SUMMARY
84
+ exit 1
85
+ fi
86
+
87
+ - name: Notify on findings
88
+ if: failure() && steps.scan.outputs.result == 'found'
89
+ run: |
90
+ REPO="${{ github.event.repository.name }}"
91
+ curl -sS \
92
+ -H "Title: ${REPO} — secrets detected in code" \
93
+ -H "Tags: rotating_light,key" \
94
+ -H "Priority: urgent" \
95
+ -d "Gitleaks found potential secrets. Review and rotate credentials immediately." \
96
+ "${NTFY_URL}/${NTFY_TOPIC}" || true
@@ -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: Gitea.Workflow
7
+ # INGROUP: moko-platform.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
+ GITEA_URL: ${{ vars.GITEA_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
+ run: |
31
+ TOKEN="${{ secrets.GA_TOKEN }}"
32
+ API="${GITEA_URL}/api/v1/repos/${{ github.repository }}"
33
+ ISSUE_NUM="${{ github.event.issue.number }}"
34
+ ISSUE_TITLE="${{ github.event.issue.title }}"
35
+
36
+ # Build slug from title: lowercase, replace non-alnum with dash, trim
37
+ SLUG=$(echo "${ISSUE_TITLE}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' | cut -c1-40)
38
+ BRANCH="feature/${ISSUE_NUM}-${SLUG}"
39
+
40
+ # Check dev branch exists
41
+ DEV_EXISTS=$(curl -sf -o /dev/null -w '%{http_code}' \
42
+ -H "Authorization: token ${TOKEN}" \
43
+ "${API}/branches/dev" 2>/dev/null || echo "000")
44
+
45
+ if [ "${DEV_EXISTS}" != "200" ]; then
46
+ echo "No dev branch -- skipping"
47
+ exit 0
48
+ fi
49
+
50
+ # Create branch from dev
51
+ HTTP=$(curl -sf -o /dev/null -w '%{http_code}' -X POST \
52
+ -H "Authorization: token ${TOKEN}" \
53
+ -H "Content-Type: application/json" \
54
+ "${API}/branches" \
55
+ -d "{\"new_branch_name\":\"${BRANCH}\",\"old_branch_name\":\"dev\"}" 2>/dev/null || echo "000")
56
+
57
+ if [ "${HTTP}" = "201" ]; then
58
+ echo "Created branch: ${BRANCH}"
59
+
60
+ # Comment on issue with branch link
61
+ REPO_URL="${GITEA_URL}/${{ github.repository }}"
62
+ BODY="Branch created: [\`${BRANCH}\`](${REPO_URL}/src/branch/${BRANCH})\n\n\`\`\`bash\ngit fetch origin\ngit checkout ${BRANCH}\n\`\`\`"
63
+
64
+ curl -sf -X POST \
65
+ -H "Authorization: token ${TOKEN}" \
66
+ -H "Content-Type: application/json" \
67
+ "${API}/issues/${ISSUE_NUM}/comments" \
68
+ -d "{\"body\":\"${BODY}\"}" > /dev/null 2>&1
69
+
70
+ echo "Commented on issue #${ISSUE_NUM}"
71
+ else
72
+ echo "Failed to create branch (HTTP ${HTTP}) -- may already exist"
73
+ fi
@@ -0,0 +1,280 @@
1
+ # MCP Server Auto-Release
2
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+ #
5
+ # MCP-specific release pipeline that builds TypeScript, runs validation,
6
+ # attaches the compiled dist/ as a release artifact, and creates a GitHub
7
+ # Release with tool inventory in the release notes.
8
+ #
9
+ # This replaces the generic auto-release.yml for MCP server repos.
10
+
11
+ name: "MCP: Build & Release"
12
+
13
+ on:
14
+ push:
15
+ branches:
16
+ - main
17
+ paths:
18
+ - 'src/**'
19
+ - 'package.json'
20
+ - 'tsconfig.json'
21
+
22
+ env:
23
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
24
+
25
+ permissions:
26
+ contents: write
27
+ issues: write
28
+
29
+ jobs:
30
+ build-and-release:
31
+ name: Build, Validate & Release
32
+ runs-on: ubuntu-latest
33
+ if: >-
34
+ !contains(github.event.head_commit.message, '[skip ci]') &&
35
+ github.actor != 'github-actions[bot]'
36
+
37
+ steps:
38
+ - name: Checkout repository
39
+ uses: actions/checkout@v4
40
+ with:
41
+ token: ${{ secrets.GH_TOKEN || github.token }}
42
+ fetch-depth: 0
43
+
44
+ # ── Build ────────────────────────────────────────────────────────
45
+ - name: Setup Node.js
46
+ uses: actions/setup-node@v4
47
+ with:
48
+ node-version: 20
49
+
50
+ - name: Install dependencies
51
+ run: npm ci
52
+
53
+ - name: TypeScript compile check
54
+ run: npx tsc --noEmit
55
+
56
+ - name: Build
57
+ run: npm run build
58
+
59
+ - name: Verify dist output
60
+ run: |
61
+ for f in index.js client.js config.js types.js; do
62
+ test -f "dist/${f}" || (echo "ERROR: dist/${f} not found" && exit 1)
63
+ done
64
+ echo "✓ All dist files present"
65
+
66
+ # ── Tool Inventory ───────────────────────────────────────────────
67
+ - name: Generate tool inventory
68
+ id: tools
69
+ run: |
70
+ TOOL_COUNT=$(grep -c "server\.tool(" src/index.ts || echo "0")
71
+ echo "count=${TOOL_COUNT}" >> "$GITHUB_OUTPUT"
72
+
73
+ # Extract tool names
74
+ TOOL_LIST=$(grep -oE "'[a-z_]+'" src/index.ts | head -100 | tr -d "'" | sort -u)
75
+ echo "Tools registered: ${TOOL_COUNT}"
76
+
77
+ # Generate inventory for release notes
78
+ echo "## Tool Inventory (${TOOL_COUNT} tools)" > /tmp/tool-inventory.md
79
+ echo "" >> /tmp/tool-inventory.md
80
+ grep -B0 -A1 "server\.tool(" src/index.ts | grep -oE "'[^']+'" | while IFS= read -r name; do
81
+ read -r desc 2>/dev/null || true
82
+ CLEAN_NAME=$(echo "$name" | tr -d "'")
83
+ CLEAN_DESC=$(echo "$desc" | tr -d "'" | sed 's/,$//')
84
+ if [ -n "$CLEAN_NAME" ] && [ -n "$CLEAN_DESC" ]; then
85
+ echo "- \`${CLEAN_NAME}\` — ${CLEAN_DESC}" >> /tmp/tool-inventory.md
86
+ fi
87
+ done
88
+
89
+ # ── Version ──────────────────────────────────────────────────────
90
+ - name: Setup MokoStandards tools
91
+ run: |
92
+ if [ -d /opt/mokoplatform/api/cli ] && [ -f /opt/mokoplatform/vendor/autoload.php ]; then
93
+ ln -sf /opt/mokoplatform /tmp/mokostandards
94
+ echo "Using pre-installed /opt/mokoplatform"
95
+ elif [ -d /opt/moko-platform/api/cli ]; then
96
+ ln -sf /opt/moko-platform /tmp/mokostandards
97
+ echo "Using pre-installed /opt/moko-platform"
98
+ else
99
+ echo "::warning::MokoStandards tools not found on runner"
100
+ echo "MOKO_SKIP=true" >> "$GITHUB_ENV"
101
+ fi
102
+
103
+ - name: Read version from README.md
104
+ id: version
105
+ run: |
106
+ VERSION=$(php /tmp/mokostandards/api/cli/version_read.php --path . 2>/dev/null)
107
+ if [ -z "$VERSION" ]; then
108
+ echo "No VERSION in README.md — skipping release"
109
+ echo "skip=true" >> "$GITHUB_OUTPUT"
110
+ exit 0
111
+ fi
112
+
113
+ MAJOR=$(echo "$VERSION" | awk -F. '{print $1}')
114
+ MINOR=$(echo "$VERSION" | awk -F. '{printf "%s.%s", $1, $2}')
115
+ PATCH=$(echo "$VERSION" | awk -F. '{print $3}')
116
+
117
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
118
+ echo "branch=version/${MAJOR}" >> "$GITHUB_OUTPUT"
119
+ echo "major=$MAJOR" >> "$GITHUB_OUTPUT"
120
+ echo "minor=$MINOR" >> "$GITHUB_OUTPUT"
121
+ echo "release_tag=v${MAJOR}" >> "$GITHUB_OUTPUT"
122
+
123
+ if [ "$PATCH" = "00" ]; then
124
+ echo "skip=true" >> "$GITHUB_OUTPUT"
125
+ else
126
+ echo "skip=false" >> "$GITHUB_OUTPUT"
127
+ if [ "$PATCH" = "01" ]; then
128
+ echo "is_first=true" >> "$GITHUB_OUTPUT"
129
+ else
130
+ echo "is_first=false" >> "$GITHUB_OUTPUT"
131
+ fi
132
+ fi
133
+
134
+ - name: Check if already released
135
+ if: steps.version.outputs.skip != 'true'
136
+ id: check
137
+ run: |
138
+ TAG="${{ steps.version.outputs.release_tag }}"
139
+ TAG_EXISTS=false
140
+ git rev-parse "$TAG" >/dev/null 2>&1 && TAG_EXISTS=true
141
+ echo "tag_exists=$TAG_EXISTS" >> "$GITHUB_OUTPUT"
142
+
143
+ # ── Release Artifact ─────────────────────────────────────────────
144
+ - name: Package dist
145
+ if: steps.version.outputs.skip != 'true'
146
+ run: |
147
+ VERSION="${{ steps.version.outputs.version }}"
148
+ REPO_NAME="${{ github.event.repository.name }}"
149
+ tar -czf "/tmp/${REPO_NAME}-${VERSION}.tar.gz" -C dist .
150
+ echo "artifact=/tmp/${REPO_NAME}-${VERSION}.tar.gz" >> "$GITHUB_OUTPUT"
151
+
152
+ # ── Version Updates ──────────────────────────────────────────────
153
+ - name: Set platform version
154
+ if: >-
155
+ steps.version.outputs.skip != 'true' &&
156
+ steps.check.outputs.tag_exists != 'true'
157
+ run: |
158
+ VERSION="${{ steps.version.outputs.version }}"
159
+ php /tmp/mokostandards/api/cli/version_set_platform.php \
160
+ --path . --version "$VERSION" --branch main
161
+
162
+ - name: Update version badges
163
+ if: >-
164
+ steps.version.outputs.skip != 'true' &&
165
+ steps.check.outputs.tag_exists != 'true'
166
+ run: |
167
+ VERSION="${{ steps.version.outputs.version }}"
168
+ find . -name "*.md" ! -path "./.git/*" ! -path "./vendor/*" | while read -r f; do
169
+ if grep -q '\[VERSION:' "$f" 2>/dev/null; then
170
+ sed -i "s/\[VERSION:[[:space:]]*[0-9]\{2\}\.[0-9]\{2\}\.[0-9]\{2\}\]/[VERSION: ${VERSION}]/" "$f"
171
+ fi
172
+ done
173
+
174
+ - name: Commit release changes
175
+ if: >-
176
+ steps.version.outputs.skip != 'true' &&
177
+ steps.check.outputs.tag_exists != 'true'
178
+ run: |
179
+ if git diff --quiet && git diff --cached --quiet; then
180
+ echo "No changes to commit"
181
+ exit 0
182
+ fi
183
+ VERSION="${{ steps.version.outputs.version }}"
184
+ git config --local user.email "github-actions[bot]@users.noreply.github.com"
185
+ git config --local user.name "github-actions[bot]"
186
+ git add -A
187
+ git commit -m "chore(release): build ${VERSION} [skip ci]" \
188
+ --author="github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
189
+ git push
190
+
191
+ # ── Version Branch ───────────────────────────────────────────────
192
+ - name: Archive version branch
193
+ if: steps.check.outputs.tag_exists != 'true'
194
+ run: |
195
+ BRANCH="${{ steps.version.outputs.branch }}"
196
+ git push origin HEAD:"$BRANCH" --force
197
+ echo "Updated archive branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY
198
+
199
+ # ── Tag & Release ────────────────────────────────────────────────
200
+ - name: Create git tag
201
+ if: >-
202
+ steps.version.outputs.skip != 'true' &&
203
+ steps.check.outputs.tag_exists != 'true' &&
204
+ steps.version.outputs.is_first == 'true'
205
+ run: |
206
+ TAG="${{ steps.version.outputs.release_tag }}"
207
+ if ! git rev-parse "$TAG" >/dev/null 2>&1; then
208
+ git tag "$TAG"
209
+ git push origin "$TAG"
210
+ fi
211
+
212
+ - name: GitHub Release
213
+ if: >-
214
+ steps.version.outputs.skip != 'true' &&
215
+ steps.check.outputs.tag_exists != 'true'
216
+ env:
217
+ GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
218
+ run: |
219
+ VERSION="${{ steps.version.outputs.version }}"
220
+ RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
221
+ MAJOR="${{ steps.version.outputs.major }}"
222
+ BRANCH="${{ steps.version.outputs.branch }}"
223
+ TOOL_COUNT="${{ steps.tools.outputs.count }}"
224
+ REPO_NAME="${{ github.event.repository.name }}"
225
+
226
+ # Build release notes
227
+ NOTES=$(php /tmp/mokostandards/api/cli/release_notes.php --path . --version "$VERSION" 2>/dev/null)
228
+ [ -z "$NOTES" ] && NOTES="Release ${VERSION}"
229
+
230
+ {
231
+ echo "$NOTES"
232
+ echo ""
233
+ echo "---"
234
+ echo ""
235
+ echo "### MCP Server Info"
236
+ echo "- **Tools registered**: ${TOOL_COUNT}"
237
+ echo "- **Node.js**: 20+"
238
+ echo "- **MCP SDK**: $(node -p \"require('./package.json').dependencies['@modelcontextprotocol/sdk']\" 2>/dev/null || echo 'unknown')"
239
+ echo ""
240
+ cat /tmp/tool-inventory.md 2>/dev/null || true
241
+ } > /tmp/release_notes.md
242
+
243
+ EXISTING=$(gh release view "$RELEASE_TAG" --json tagName -q .tagName 2>/dev/null || true)
244
+
245
+ ARTIFACT="/tmp/${REPO_NAME}-${VERSION}.tar.gz"
246
+
247
+ if [ -z "$EXISTING" ]; then
248
+ gh release create "$RELEASE_TAG" \
249
+ --title "v${MAJOR} (latest: ${VERSION})" \
250
+ --notes-file /tmp/release_notes.md \
251
+ --target "$BRANCH" \
252
+ "$ARTIFACT"
253
+ echo "Release created: ${RELEASE_TAG} (${VERSION})" >> $GITHUB_STEP_SUMMARY
254
+ else
255
+ gh release edit "$RELEASE_TAG" \
256
+ --title "v${MAJOR} (latest: ${VERSION})" \
257
+ --notes-file /tmp/release_notes.md
258
+ gh release upload "$RELEASE_TAG" "$ARTIFACT" --clobber 2>/dev/null || true
259
+ echo "Release updated: ${RELEASE_TAG} -> ${VERSION}" >> $GITHUB_STEP_SUMMARY
260
+ fi
261
+
262
+ # ── Summary ──────────────────────────────────────────────────────
263
+ - name: Pipeline Summary
264
+ if: always()
265
+ run: |
266
+ VERSION="${{ steps.version.outputs.version }}"
267
+ TOOL_COUNT="${{ steps.tools.outputs.count }}"
268
+ if [ "${{ steps.version.outputs.skip }}" = "true" ]; then
269
+ echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY
270
+ else
271
+ echo "" >> $GITHUB_STEP_SUMMARY
272
+ echo "## MCP Release Complete" >> $GITHUB_STEP_SUMMARY
273
+ echo "" >> $GITHUB_STEP_SUMMARY
274
+ echo "| Detail | Value |" >> $GITHUB_STEP_SUMMARY
275
+ echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
276
+ echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
277
+ echo "| Tools | ${TOOL_COUNT} |" >> $GITHUB_STEP_SUMMARY
278
+ echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY
279
+ echo "| Tag | \`${{ steps.version.outputs.release_tag }}\` |" >> $GITHUB_STEP_SUMMARY
280
+ fi
@@ -0,0 +1,65 @@
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: ['src/**', 'package.json', 'tsconfig.json']
14
+ pull_request:
15
+ branches: [main]
16
+ paths: ['src/**', 'package.json', 'tsconfig.json']
17
+
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ jobs:
23
+ build:
24
+ runs-on: ubuntu-latest
25
+ strategy:
26
+ matrix:
27
+ node-version: [20, 22]
28
+
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+
32
+ - name: Setup Node.js ${{ matrix.node-version }}
33
+ uses: actions/setup-node@v4
34
+ with:
35
+ node-version: ${{ matrix.node-version }}
36
+
37
+ - name: Install dependencies
38
+ run: npm ci
39
+
40
+ - name: TypeScript compile
41
+ run: npx tsc --noEmit
42
+
43
+ - name: Build
44
+ run: npm run build
45
+
46
+ - name: Verify dist output exists
47
+ run: |
48
+ test -f dist/index.js || (echo "ERROR: dist/index.js not found" && exit 1)
49
+ test -f dist/client.js || (echo "ERROR: dist/client.js not found" && exit 1)
50
+ test -f dist/config.js || (echo "ERROR: dist/config.js not found" && exit 1)
51
+ test -f dist/types.js || (echo "ERROR: dist/types.js not found" && exit 1)
52
+ echo "✓ All required dist files present"
53
+
54
+ - name: Verify shebang in index.js
55
+ run: |
56
+ head -1 dist/index.js | grep -q "#!/usr/bin/env node" || echo "WARNING: Missing shebang in dist/index.js"
57
+
58
+ - name: Count registered tools
59
+ run: |
60
+ TOOL_COUNT=$(grep -c "server\.tool(" src/index.ts || true)
61
+ echo "Registered tools: ${TOOL_COUNT}"
62
+ if [ "${TOOL_COUNT}" -eq 0 ]; then
63
+ echo "ERROR: No tools registered in src/index.ts"
64
+ exit 1
65
+ fi
@@ -0,0 +1,109 @@
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
+
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+
26
+ - name: Setup Node.js
27
+ uses: actions/setup-node@v4
28
+ with:
29
+ node-version: 20
30
+
31
+ - name: Check for SDK updates
32
+ id: sdk-check
33
+ run: |
34
+ CURRENT=$(node -p "require('./package.json').dependencies['@modelcontextprotocol/sdk']" | sed 's/[\^~]//')
35
+ LATEST=$(npm view @modelcontextprotocol/sdk version 2>/dev/null || echo "unknown")
36
+
37
+ echo "current=${CURRENT}" >> $GITHUB_OUTPUT
38
+ echo "latest=${LATEST}" >> $GITHUB_OUTPUT
39
+
40
+ if [ "${CURRENT}" != "${LATEST}" ] && [ "${LATEST}" != "unknown" ]; then
41
+ echo "update_available=true" >> $GITHUB_OUTPUT
42
+ echo "MCP SDK update available: ${CURRENT} → ${LATEST}"
43
+ else
44
+ echo "update_available=false" >> $GITHUB_OUTPUT
45
+ echo "MCP SDK is up to date: ${CURRENT}"
46
+ fi
47
+
48
+ - name: Check for Zod updates
49
+ id: zod-check
50
+ run: |
51
+ CURRENT=$(node -p "require('./package.json').dependencies['zod']" | sed 's/[\^~]//')
52
+ LATEST=$(npm view zod version 2>/dev/null || echo "unknown")
53
+
54
+ echo "current=${CURRENT}" >> $GITHUB_OUTPUT
55
+ echo "latest=${LATEST}" >> $GITHUB_OUTPUT
56
+
57
+ if [ "${CURRENT}" != "${LATEST}" ] && [ "${LATEST}" != "unknown" ]; then
58
+ echo "update_available=true" >> $GITHUB_OUTPUT
59
+ else
60
+ echo "update_available=false" >> $GITHUB_OUTPUT
61
+ fi
62
+
63
+ - name: Create update issue
64
+ if: steps.sdk-check.outputs.update_available == 'true'
65
+ uses: actions/github-script@v7
66
+ with:
67
+ script: |
68
+ const title = `chore(deps): update @modelcontextprotocol/sdk ${process.env.CURRENT} → ${process.env.LATEST}`;
69
+ const body = [
70
+ '## MCP SDK Update Available',
71
+ '',
72
+ `| Package | Current | Latest |`,
73
+ `|---------|---------|--------|`,
74
+ `| @modelcontextprotocol/sdk | ${process.env.CURRENT} | ${process.env.LATEST} |`,
75
+ `| zod | ${process.env.ZOD_CURRENT} | ${process.env.ZOD_LATEST} |`,
76
+ '',
77
+ '### Steps',
78
+ '1. Update package.json',
79
+ '2. Run `npm install`',
80
+ '3. Run `npm run build` to verify compilation',
81
+ '4. Test all tools against target API',
82
+ '',
83
+ '### Changelog',
84
+ `https://github.com/modelcontextprotocol/typescript-sdk/releases`,
85
+ ].join('\n');
86
+
87
+ // Check for existing open issue
88
+ const existing = await github.rest.issues.listForRepo({
89
+ owner: context.repo.owner,
90
+ repo: context.repo.repo,
91
+ state: 'open',
92
+ labels: 'api-change',
93
+ });
94
+
95
+ const alreadyExists = existing.data.some(i => i.title.includes('@modelcontextprotocol/sdk'));
96
+ if (!alreadyExists) {
97
+ await github.rest.issues.create({
98
+ owner: context.repo.owner,
99
+ repo: context.repo.repo,
100
+ title,
101
+ body,
102
+ labels: ['api-change', 'chore'],
103
+ });
104
+ }
105
+ env:
106
+ CURRENT: ${{ steps.sdk-check.outputs.current }}
107
+ LATEST: ${{ steps.sdk-check.outputs.latest }}
108
+ ZOD_CURRENT: ${{ steps.zod-check.outputs.current }}
109
+ ZOD_LATEST: ${{ steps.zod-check.outputs.latest }}
@@ -0,0 +1,61 @@
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: ['src/index.ts']
14
+ workflow_dispatch:
15
+
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ jobs:
21
+ inventory:
22
+ runs-on: ubuntu-latest
23
+
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+
27
+ - name: Generate tool inventory
28
+ run: |
29
+ echo "# MCP Tool Inventory" > TOOLS.md
30
+ echo "" >> TOOLS.md
31
+ echo "Auto-generated from \`src/index.ts\` on $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> TOOLS.md
32
+ echo "" >> TOOLS.md
33
+
34
+ # Count tools
35
+ TOOL_COUNT=$(grep -c "server\.tool(" src/index.ts || true)
36
+ echo "**Total tools: ${TOOL_COUNT}**" >> TOOLS.md
37
+ echo "" >> TOOLS.md
38
+
39
+ # Extract tool names and descriptions
40
+ echo "| Tool | Description |" >> TOOLS.md
41
+ echo "|------|-------------|" >> TOOLS.md
42
+
43
+ grep -A1 "server\.tool(" src/index.ts | grep -E "^\s*'" | while read -r line; do
44
+ TOOL_NAME=$(echo "$line" | sed "s/.*'\([^']*\)'.*/\1/")
45
+ # Get next line for description
46
+ DESC=$(grep -A2 "'${TOOL_NAME}'" src/index.ts | grep -E "^\s*'" | tail -1 | sed "s/.*'\([^']*\)'.*/\1/" || echo "")
47
+ echo "| \`${TOOL_NAME}\` | ${DESC} |" >> TOOLS.md
48
+ done
49
+
50
+ echo "" >> TOOLS.md
51
+ echo "---" >> TOOLS.md
52
+ echo "*Generated by MCP Tool Inventory workflow*" >> TOOLS.md
53
+
54
+ cat TOOLS.md
55
+
56
+ - name: Upload inventory artifact
57
+ uses: actions/upload-artifact@v4
58
+ with:
59
+ name: tool-inventory
60
+ path: TOOLS.md
61
+ retention-days: 90