@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.
- package/.gitattributes +94 -0
- package/.gitmessage +9 -0
- package/.mokogitea/ISSUE_TEMPLATE/adr.md +110 -0
- package/.mokogitea/ISSUE_TEMPLATE/bug_report.md +48 -0
- package/.mokogitea/ISSUE_TEMPLATE/config.yml +18 -0
- package/.mokogitea/ISSUE_TEMPLATE/documentation.md +52 -0
- package/.mokogitea/ISSUE_TEMPLATE/enterprise_support.md +85 -0
- package/.mokogitea/ISSUE_TEMPLATE/feature_request.md +51 -0
- package/.mokogitea/ISSUE_TEMPLATE/firewall-request.md +190 -0
- package/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md +48 -0
- package/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md +67 -0
- package/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md +49 -0
- package/.mokogitea/ISSUE_TEMPLATE/question.md +82 -0
- package/.mokogitea/ISSUE_TEMPLATE/rfc.md +126 -0
- package/.mokogitea/ISSUE_TEMPLATE/security.md +51 -0
- package/.mokogitea/ISSUE_TEMPLATE/version.md +24 -0
- package/.mokogitea/auto-assign.yml +76 -0
- package/.mokogitea/auto-dev-issue.yml +207 -0
- package/.mokogitea/auto-release.yml +337 -0
- package/.mokogitea/branch-protection.yml +251 -0
- package/.mokogitea/changelog-validation.yml +101 -0
- package/.mokogitea/codeql-analysis.yml +115 -0
- package/.mokogitea/copilot-agent.yml +44 -0
- package/.mokogitea/deploy-demo.yml +734 -0
- package/.mokogitea/deploy-dev.yml +700 -0
- package/.mokogitea/enterprise-firewall-setup.yml +758 -0
- package/.mokogitea/manifest.xml +25 -0
- package/.mokogitea/mcp-auto-release.yml +278 -0
- package/.mokogitea/mcp-build-test.yml +65 -0
- package/.mokogitea/mcp-sdk-check.yml +109 -0
- package/.mokogitea/mcp-tool-inventory.yml +61 -0
- package/.mokogitea/pr-branch-check.yml +90 -0
- package/.mokogitea/repository-cleanup.yml +525 -0
- package/.mokogitea/standards-compliance.yml +2614 -0
- package/.mokogitea/sync-version-on-merge.yml +133 -0
- package/.mokogitea/workflows/auto-assign.yml +76 -0
- package/.mokogitea/workflows/auto-bump.yml +66 -0
- package/.mokogitea/workflows/auto-dev-issue.yml +207 -0
- package/.mokogitea/workflows/auto-release.yml +341 -0
- package/.mokogitea/workflows/branch-cleanup.yml +48 -0
- package/.mokogitea/workflows/cascade-dev.yml +10 -0
- package/.mokogitea/workflows/changelog-validation.yml +101 -0
- package/.mokogitea/workflows/ci-generic.yml +204 -0
- package/.mokogitea/workflows/cleanup.yml +87 -0
- package/.mokogitea/workflows/codeql-analysis.yml +115 -0
- package/.mokogitea/workflows/copilot-agent.yml +44 -0
- package/.mokogitea/workflows/deploy-manual.yml +126 -0
- package/.mokogitea/workflows/enterprise-firewall-setup.yml +758 -0
- package/.mokogitea/workflows/gitleaks.yml +96 -0
- package/.mokogitea/workflows/issue-branch.yml +73 -0
- package/.mokogitea/workflows/mcp-auto-release.yml +280 -0
- package/.mokogitea/workflows/mcp-build-test.yml +65 -0
- package/.mokogitea/workflows/mcp-sdk-check.yml +109 -0
- package/.mokogitea/workflows/mcp-tool-inventory.yml +61 -0
- package/.mokogitea/workflows/notify.yml +70 -0
- package/.mokogitea/workflows/npm-publish.yml +51 -0
- package/.mokogitea/workflows/pr-check.yml +508 -0
- package/.mokogitea/workflows/pre-release.yml +11 -0
- package/.mokogitea/workflows/repo-health.yml +711 -0
- package/.mokogitea/workflows/repository-cleanup.yml +525 -0
- package/.mokogitea/workflows/security-audit.yml +82 -0
- package/.mokogitea/workflows/standards-compliance.yml +2614 -0
- package/.mokogitea/workflows/sync-version-on-merge.yml +130 -0
- package/.mokogitea/workflows/update-server.yml +312 -0
- package/CHANGELOG.md +145 -0
- package/CLAUDE.md +43 -0
- package/CONTRIBUTING.md +161 -0
- package/README.md +286 -0
- package/SECURITY.md +91 -0
- package/automation/ci-issue-reporter.sh +237 -0
- package/config.example.json +13 -0
- package/dist/client.d.ts +15 -0
- package/dist/client.js +104 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.js +48 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1119 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.js +16 -0
- package/package.json +34 -0
- package/scripts/setup.mjs +40 -0
- package/src/client.ts +120 -0
- package/src/config.ts +58 -0
- package/src/index.ts +1712 -0
- package/src/types.ts +37 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
MokoStandards Repository Manifest
|
|
4
|
+
Auto-generated by cleanup script.
|
|
5
|
+
See: https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home
|
|
6
|
+
-->
|
|
7
|
+
<moko-platform xmlns="https://standards.mokoconsulting.tech/moko-platform/1.0" schema-version="1.0">
|
|
8
|
+
<identity>
|
|
9
|
+
<name>gitea-api-mcp</name>
|
|
10
|
+
<org>MokoConsulting</org>
|
|
11
|
+
<description>MCP server for Gitea REST API v1 operations — 61 tools for repos, issues, PRs, releases, branches, actions, orgs, wiki, webhooks, and more</description>
|
|
12
|
+
<license spdx="GPL-3.0-or-later">GNU General Public License v3</license>
|
|
13
|
+
</identity>
|
|
14
|
+
<governance>
|
|
15
|
+
<platform>nodejs</platform>
|
|
16
|
+
<standards-version>04.07.00</standards-version>
|
|
17
|
+
<standards-source>https://git.mokoconsulting.tech/MokoConsulting/moko-platform</standards-source>
|
|
18
|
+
<last-synced>2026-05-10T19:51:11+00:00</last-synced>
|
|
19
|
+
</governance>
|
|
20
|
+
<build>
|
|
21
|
+
<language>TypeScript</language>
|
|
22
|
+
<package-type>mcp-server</package-type>
|
|
23
|
+
<entry-point>src/</entry-point>
|
|
24
|
+
</build>
|
|
25
|
+
</moko-platform>
|
|
@@ -0,0 +1,278 @@
|
|
|
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 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
|
+
env:
|
|
92
|
+
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
|
93
|
+
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
|
|
94
|
+
run: |
|
|
95
|
+
git clone --depth 1 --branch version/04 --quiet \
|
|
96
|
+
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \
|
|
97
|
+
/tmp/mokostandards
|
|
98
|
+
cd /tmp/mokostandards
|
|
99
|
+
composer install --no-dev --no-interaction --quiet
|
|
100
|
+
|
|
101
|
+
- name: Read version from README.md
|
|
102
|
+
id: version
|
|
103
|
+
run: |
|
|
104
|
+
VERSION=$(php /tmp/mokostandards/api/cli/version_read.php --path . 2>/dev/null)
|
|
105
|
+
if [ -z "$VERSION" ]; then
|
|
106
|
+
echo "No VERSION in README.md — skipping release"
|
|
107
|
+
echo "skip=true" >> "$GITHUB_OUTPUT"
|
|
108
|
+
exit 0
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
MAJOR=$(echo "$VERSION" | awk -F. '{print $1}')
|
|
112
|
+
MINOR=$(echo "$VERSION" | awk -F. '{printf "%s.%s", $1, $2}')
|
|
113
|
+
PATCH=$(echo "$VERSION" | awk -F. '{print $3}')
|
|
114
|
+
|
|
115
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
116
|
+
echo "branch=version/${MAJOR}" >> "$GITHUB_OUTPUT"
|
|
117
|
+
echo "major=$MAJOR" >> "$GITHUB_OUTPUT"
|
|
118
|
+
echo "minor=$MINOR" >> "$GITHUB_OUTPUT"
|
|
119
|
+
echo "release_tag=v${MAJOR}" >> "$GITHUB_OUTPUT"
|
|
120
|
+
|
|
121
|
+
if [ "$PATCH" = "00" ]; then
|
|
122
|
+
echo "skip=true" >> "$GITHUB_OUTPUT"
|
|
123
|
+
else
|
|
124
|
+
echo "skip=false" >> "$GITHUB_OUTPUT"
|
|
125
|
+
if [ "$PATCH" = "01" ]; then
|
|
126
|
+
echo "is_first=true" >> "$GITHUB_OUTPUT"
|
|
127
|
+
else
|
|
128
|
+
echo "is_first=false" >> "$GITHUB_OUTPUT"
|
|
129
|
+
fi
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
- name: Check if already released
|
|
133
|
+
if: steps.version.outputs.skip != 'true'
|
|
134
|
+
id: check
|
|
135
|
+
run: |
|
|
136
|
+
TAG="${{ steps.version.outputs.release_tag }}"
|
|
137
|
+
TAG_EXISTS=false
|
|
138
|
+
git rev-parse "$TAG" >/dev/null 2>&1 && TAG_EXISTS=true
|
|
139
|
+
echo "tag_exists=$TAG_EXISTS" >> "$GITHUB_OUTPUT"
|
|
140
|
+
|
|
141
|
+
# ── Release Artifact ─────────────────────────────────────────────
|
|
142
|
+
- name: Package dist
|
|
143
|
+
if: steps.version.outputs.skip != 'true'
|
|
144
|
+
run: |
|
|
145
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
146
|
+
REPO_NAME="${{ github.event.repository.name }}"
|
|
147
|
+
tar -czf "/tmp/${REPO_NAME}-${VERSION}.tar.gz" -C dist .
|
|
148
|
+
echo "artifact=/tmp/${REPO_NAME}-${VERSION}.tar.gz" >> "$GITHUB_OUTPUT"
|
|
149
|
+
|
|
150
|
+
# ── Version Updates ──────────────────────────────────────────────
|
|
151
|
+
- name: Set platform version
|
|
152
|
+
if: >-
|
|
153
|
+
steps.version.outputs.skip != 'true' &&
|
|
154
|
+
steps.check.outputs.tag_exists != 'true'
|
|
155
|
+
run: |
|
|
156
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
157
|
+
php /tmp/mokostandards/api/cli/version_set_platform.php \
|
|
158
|
+
--path . --version "$VERSION" --branch main
|
|
159
|
+
|
|
160
|
+
- name: Update version badges
|
|
161
|
+
if: >-
|
|
162
|
+
steps.version.outputs.skip != 'true' &&
|
|
163
|
+
steps.check.outputs.tag_exists != 'true'
|
|
164
|
+
run: |
|
|
165
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
166
|
+
find . -name "*.md" ! -path "./.git/*" ! -path "./vendor/*" | while read -r f; do
|
|
167
|
+
if grep -q '\[VERSION:' "$f" 2>/dev/null; then
|
|
168
|
+
sed -i "s/\[VERSION:[[:space:]]*[0-9]\{2\}\.[0-9]\{2\}\.[0-9]\{2\}\]/[VERSION: ${VERSION}]/" "$f"
|
|
169
|
+
fi
|
|
170
|
+
done
|
|
171
|
+
|
|
172
|
+
- name: Commit release changes
|
|
173
|
+
if: >-
|
|
174
|
+
steps.version.outputs.skip != 'true' &&
|
|
175
|
+
steps.check.outputs.tag_exists != 'true'
|
|
176
|
+
run: |
|
|
177
|
+
if git diff --quiet && git diff --cached --quiet; then
|
|
178
|
+
echo "No changes to commit"
|
|
179
|
+
exit 0
|
|
180
|
+
fi
|
|
181
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
182
|
+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
|
183
|
+
git config --local user.name "github-actions[bot]"
|
|
184
|
+
git add -A
|
|
185
|
+
git commit -m "chore(release): build ${VERSION} [skip ci]" \
|
|
186
|
+
--author="github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
|
|
187
|
+
git push
|
|
188
|
+
|
|
189
|
+
# ── Version Branch ───────────────────────────────────────────────
|
|
190
|
+
- name: Archive version branch
|
|
191
|
+
if: steps.check.outputs.tag_exists != 'true'
|
|
192
|
+
run: |
|
|
193
|
+
BRANCH="${{ steps.version.outputs.branch }}"
|
|
194
|
+
git push origin HEAD:"$BRANCH" --force
|
|
195
|
+
echo "Updated archive branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY
|
|
196
|
+
|
|
197
|
+
# ── Tag & Release ────────────────────────────────────────────────
|
|
198
|
+
- name: Create git tag
|
|
199
|
+
if: >-
|
|
200
|
+
steps.version.outputs.skip != 'true' &&
|
|
201
|
+
steps.check.outputs.tag_exists != 'true' &&
|
|
202
|
+
steps.version.outputs.is_first == 'true'
|
|
203
|
+
run: |
|
|
204
|
+
TAG="${{ steps.version.outputs.release_tag }}"
|
|
205
|
+
if ! git rev-parse "$TAG" >/dev/null 2>&1; then
|
|
206
|
+
git tag "$TAG"
|
|
207
|
+
git push origin "$TAG"
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
- name: GitHub Release
|
|
211
|
+
if: >-
|
|
212
|
+
steps.version.outputs.skip != 'true' &&
|
|
213
|
+
steps.check.outputs.tag_exists != 'true'
|
|
214
|
+
env:
|
|
215
|
+
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
|
216
|
+
run: |
|
|
217
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
218
|
+
RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
|
|
219
|
+
MAJOR="${{ steps.version.outputs.major }}"
|
|
220
|
+
BRANCH="${{ steps.version.outputs.branch }}"
|
|
221
|
+
TOOL_COUNT="${{ steps.tools.outputs.count }}"
|
|
222
|
+
REPO_NAME="${{ github.event.repository.name }}"
|
|
223
|
+
|
|
224
|
+
# Build release notes
|
|
225
|
+
NOTES=$(php /tmp/mokostandards/api/cli/release_notes.php --path . --version "$VERSION" 2>/dev/null)
|
|
226
|
+
[ -z "$NOTES" ] && NOTES="Release ${VERSION}"
|
|
227
|
+
|
|
228
|
+
{
|
|
229
|
+
echo "$NOTES"
|
|
230
|
+
echo ""
|
|
231
|
+
echo "---"
|
|
232
|
+
echo ""
|
|
233
|
+
echo "### MCP Server Info"
|
|
234
|
+
echo "- **Tools registered**: ${TOOL_COUNT}"
|
|
235
|
+
echo "- **Node.js**: 20+"
|
|
236
|
+
echo "- **MCP SDK**: $(node -p \"require('./package.json').dependencies['@modelcontextprotocol/sdk']\" 2>/dev/null || echo 'unknown')"
|
|
237
|
+
echo ""
|
|
238
|
+
cat /tmp/tool-inventory.md 2>/dev/null || true
|
|
239
|
+
} > /tmp/release_notes.md
|
|
240
|
+
|
|
241
|
+
EXISTING=$(gh release view "$RELEASE_TAG" --json tagName -q .tagName 2>/dev/null || true)
|
|
242
|
+
|
|
243
|
+
ARTIFACT="/tmp/${REPO_NAME}-${VERSION}.tar.gz"
|
|
244
|
+
|
|
245
|
+
if [ -z "$EXISTING" ]; then
|
|
246
|
+
gh release create "$RELEASE_TAG" \
|
|
247
|
+
--title "v${MAJOR} (latest: ${VERSION})" \
|
|
248
|
+
--notes-file /tmp/release_notes.md \
|
|
249
|
+
--target "$BRANCH" \
|
|
250
|
+
"$ARTIFACT"
|
|
251
|
+
echo "Release created: ${RELEASE_TAG} (${VERSION})" >> $GITHUB_STEP_SUMMARY
|
|
252
|
+
else
|
|
253
|
+
gh release edit "$RELEASE_TAG" \
|
|
254
|
+
--title "v${MAJOR} (latest: ${VERSION})" \
|
|
255
|
+
--notes-file /tmp/release_notes.md
|
|
256
|
+
gh release upload "$RELEASE_TAG" "$ARTIFACT" --clobber 2>/dev/null || true
|
|
257
|
+
echo "Release updated: ${RELEASE_TAG} -> ${VERSION}" >> $GITHUB_STEP_SUMMARY
|
|
258
|
+
fi
|
|
259
|
+
|
|
260
|
+
# ── Summary ──────────────────────────────────────────────────────
|
|
261
|
+
- name: Pipeline Summary
|
|
262
|
+
if: always()
|
|
263
|
+
run: |
|
|
264
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
265
|
+
TOOL_COUNT="${{ steps.tools.outputs.count }}"
|
|
266
|
+
if [ "${{ steps.version.outputs.skip }}" = "true" ]; then
|
|
267
|
+
echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY
|
|
268
|
+
else
|
|
269
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
270
|
+
echo "## MCP Release Complete" >> $GITHUB_STEP_SUMMARY
|
|
271
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
272
|
+
echo "| Detail | Value |" >> $GITHUB_STEP_SUMMARY
|
|
273
|
+
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
|
|
274
|
+
echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
|
|
275
|
+
echo "| Tools | ${TOOL_COUNT} |" >> $GITHUB_STEP_SUMMARY
|
|
276
|
+
echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY
|
|
277
|
+
echo "| Tag | \`${{ steps.version.outputs.release_tag }}\` |" >> $GITHUB_STEP_SUMMARY
|
|
278
|
+
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
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
#
|
|
4
|
+
# Enforces branch merge policy:
|
|
5
|
+
# feature/* → dev only
|
|
6
|
+
# fix/* → dev only
|
|
7
|
+
# hotfix/* → dev or main (emergency)
|
|
8
|
+
# dev → main only
|
|
9
|
+
# alpha/* → dev only
|
|
10
|
+
# beta/* → dev only
|
|
11
|
+
# rc/* → main only
|
|
12
|
+
|
|
13
|
+
name: Branch Policy Check
|
|
14
|
+
|
|
15
|
+
on:
|
|
16
|
+
pull_request:
|
|
17
|
+
types: [opened, synchronize, reopened, edited]
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
check-target:
|
|
21
|
+
name: Verify merge target
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- name: Check branch policy
|
|
25
|
+
run: |
|
|
26
|
+
HEAD="${{ github.head_ref }}"
|
|
27
|
+
BASE="${{ github.base_ref }}"
|
|
28
|
+
|
|
29
|
+
echo "PR: ${HEAD} → ${BASE}"
|
|
30
|
+
|
|
31
|
+
ALLOWED=true
|
|
32
|
+
REASON=""
|
|
33
|
+
|
|
34
|
+
case "$HEAD" in
|
|
35
|
+
feature/*|feat/*)
|
|
36
|
+
if [ "$BASE" != "dev" ]; then
|
|
37
|
+
ALLOWED=false
|
|
38
|
+
REASON="Feature branches must target 'dev', not '${BASE}'"
|
|
39
|
+
fi
|
|
40
|
+
;;
|
|
41
|
+
fix/*|bugfix/*)
|
|
42
|
+
if [ "$BASE" != "dev" ]; then
|
|
43
|
+
ALLOWED=false
|
|
44
|
+
REASON="Fix branches must target 'dev', not '${BASE}'"
|
|
45
|
+
fi
|
|
46
|
+
;;
|
|
47
|
+
hotfix/*)
|
|
48
|
+
if [ "$BASE" != "dev" ] && [ "$BASE" != "main" ]; then
|
|
49
|
+
ALLOWED=false
|
|
50
|
+
REASON="Hotfix branches can only target 'dev' or 'main', not '${BASE}'"
|
|
51
|
+
fi
|
|
52
|
+
;;
|
|
53
|
+
alpha/*|beta/*)
|
|
54
|
+
if [ "$BASE" != "dev" ]; then
|
|
55
|
+
ALLOWED=false
|
|
56
|
+
REASON="Pre-release branches must target 'dev', not '${BASE}'"
|
|
57
|
+
fi
|
|
58
|
+
;;
|
|
59
|
+
rc/*)
|
|
60
|
+
if [ "$BASE" != "main" ]; then
|
|
61
|
+
ALLOWED=false
|
|
62
|
+
REASON="Release candidate branches must target 'main', not '${BASE}'"
|
|
63
|
+
fi
|
|
64
|
+
;;
|
|
65
|
+
dev)
|
|
66
|
+
if [ "$BASE" != "main" ]; then
|
|
67
|
+
ALLOWED=false
|
|
68
|
+
REASON="Dev branch can only merge into 'main', not '${BASE}'"
|
|
69
|
+
fi
|
|
70
|
+
;;
|
|
71
|
+
esac
|
|
72
|
+
|
|
73
|
+
if [ "$ALLOWED" = false ]; then
|
|
74
|
+
echo "::error::${REASON}"
|
|
75
|
+
echo ""
|
|
76
|
+
echo "## Branch Policy Violation" >> $GITHUB_STEP_SUMMARY
|
|
77
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
78
|
+
echo "${REASON}" >> $GITHUB_STEP_SUMMARY
|
|
79
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
80
|
+
echo "### Allowed merge paths:" >> $GITHUB_STEP_SUMMARY
|
|
81
|
+
echo "- \`feature/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY
|
|
82
|
+
echo "- \`fix/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY
|
|
83
|
+
echo "- \`hotfix/*\` → \`dev\` or \`main\`" >> $GITHUB_STEP_SUMMARY
|
|
84
|
+
echo "- \`dev\` → \`main\`" >> $GITHUB_STEP_SUMMARY
|
|
85
|
+
echo "- \`rc/*\` → \`main\`" >> $GITHUB_STEP_SUMMARY
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
echo "Branch policy: OK (${HEAD} → ${BASE})"
|
|
90
|
+
echo "## Branch Policy: Passed" >> $GITHUB_STEP_SUMMARY
|