Skip to content

Commit f8be399

Browse files
committed
feat(scaffold): correct mcp-server template set and release/publish chain [skip version]
mcp-server borns were inheriting cursor-plugin doc/meta boilerplate and a broken release/publish setup. Fix at the generator source: - Type-aware doc templates (CLAUDE, AGENTS, CONTRIBUTING, ROADMAP, site.json, CHANGELOG, .cursorrules, .gitignore): mcp-server output now describes a TypeScript MCP server (src/ layout, provider adapters, tool registration, mcp-tools.json sync, stdio, npx install) with no skills/rules/.mdc/ .cursor-plugin/plugin.json/validate.yml/marketplace language. - Emit ci.yml (build+test on Node 20/22) and a corrected release.yml for mcp-server; the new release.mcp.yml.j2 auto-bumps from conventional commits (npm version keeps package.json + lockfile in sync), updates the README badge, commits with [skip version], and creates the release with a PAT-or-fallback token so publish.yml's release event actually fires. - publish.yml.j2: add workflow_dispatch and an already-published guard so a re-dispatch is idempotent. - build_registry_entry language is now type-aware (TypeScript for mcp-server). - Born-green test asserts the new mcp-server emit set (ci.yml, release.yml) as emitted-but-not-drift-required, so siblings without them do not go red. No STANDARDS_VERSION or VERSION change (scaffolding is decoupled by design). Signed-off-by: fOuttaMyPaint <tmhospitalitystrategies@gmail.com>
1 parent a814f5b commit f8be399

13 files changed

Lines changed: 324 additions & 20 deletions

scaffold/generator.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ def _render_repo(output_dir: Path, ctx: dict, *, verbose: bool) -> None:
192192
# repos do NOT get cursor-plugin-specific validate.yml / release.yml.
193193
if repo_type == "mcp-server":
194194
write_file(output_dir, ".github/workflows/publish.yml", render_template(env, "publish.yml.j2", ctx), verbose=verbose)
195+
write_file(output_dir, ".github/workflows/ci.yml", render_template(env, "ci.yml.j2", ctx), verbose=verbose)
196+
write_file(output_dir, ".github/workflows/release.yml", render_template(env, "release.mcp.yml.j2", ctx), verbose=verbose)
195197
write_file(output_dir, ".github/workflows/pages.yml", render_template(env, "pages.mcp.yml.j2", ctx), verbose=verbose)
196198
else:
197199
write_file(output_dir, ".github/workflows/validate.yml", render_template(env, "validate.yml.j2", ctx), verbose=verbose)
@@ -297,7 +299,7 @@ def build_registry_entry(
297299
"extras": {},
298300
"topics": [repo_type, "developer-tools"],
299301
"status": "active",
300-
"language": "Python",
302+
"language": "TypeScript" if repo_type == "mcp-server" else "Python",
301303
"license": SPDX[license_key],
302304
"pagesType": "static",
303305
"hasCI": True,

scaffold/templates/AGENTS.md.j2

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ This is a Cursor IDE plugin for {{ name | replace(' Developer Tools', '') | repl
2121
This is an MCP server. It contains:
2222

2323
- **`src/`** -- TypeScript source code
24+
- **`src/providers/`** -- provider adapters implementing the `Provider` interface, wired into `ProviderManager`
25+
- **`src/tools/`** -- the registered MCP tools (stdio transport only)
2426
- **`package.json`** -- npm package manifest (version source of truth)
27+
- **`mcp-tools.json`** -- enumerates the MCP tools this server exposes
28+
- **`docs/`** -- documentation and GitHub Pages site
29+
- **`CHANGELOG.md`** -- release history
2530
{% endif %}
2631

2732
## Branching and commit model
@@ -35,10 +40,10 @@ This is an MCP server. It contains:
3540

3641
## CI/CD workflows
3742

43+
{% if type == 'cursor-plugin' %}
3844
### `validate.yml` (runs on PR and push to main)
3945

4046
Checks:
41-
{% if type == 'cursor-plugin' %}
4247
- JSON validity for plugin.json{% if has_mcp %}, mcp.json{% endif %}
4348

4449
- Plugin manifest required fields, kebab-case name, skill/rule file existence
@@ -47,20 +52,11 @@ Checks:
4752
{% if has_mcp %}
4853
- Python syntax for MCP server modules
4954
{% endif %}
50-
{% else %}
51-
- TypeScript compilation
52-
- Lint checks
53-
- Test suite
54-
{% endif %}
5555

5656
### `release.yml` (runs on push to main, ignores docs/md changes)
5757

5858
Automatic flow:
59-
{% if type == 'cursor-plugin' %}
6059
1. Reads current version from `plugin.json`
61-
{% else %}
62-
1. Reads current version from `package.json`
63-
{% endif %}
6460
2. Determines bump type from conventional commit messages since last tag
6561
3. Computes new semver version
6662
4. Updates version files and README badge
@@ -73,6 +69,37 @@ Builds and deploys the documentation site on push to main.
7369
### `stale.yml`
7470

7571
Marks issues/PRs as stale after 30 days of inactivity.
72+
{% else %}
73+
### `ci.yml` (runs on PR and push to main)
74+
75+
Builds and runs the test suite on Node 20 and 22:
76+
- TypeScript build (`npm run build`)
77+
- Test suite (`npm test`, vitest, offline)
78+
79+
### `release.yml` (runs on push to main)
80+
81+
Conventional-commit auto-bump: determines the bump type from commit messages since the last tag, updates `package.json`, creates a git tag and GitHub Release.
82+
83+
### `publish.yml` (runs on release published or workflow_dispatch)
84+
85+
Publishes the package to npm.
86+
87+
### `drift-check.yml`
88+
89+
Checks this repo against the ecosystem standards for drift.
90+
91+
### `pages.yml` (deploys docs/ to GitHub Pages)
92+
93+
Builds and deploys the documentation site on push to main.
94+
95+
### `stale.yml`
96+
97+
Marks issues/PRs as stale after 30 days of inactivity.
98+
99+
### `label-sync.yml`
100+
101+
Keeps repository labels in sync.
102+
{% endif %}
76103

77104
## Version management
78105

@@ -86,9 +113,15 @@ Marks issues/PRs as stale after 30 days of inactivity.
86113

87114
## Code conventions
88115

116+
{% if type == 'cursor-plugin' %}
89117
- No hardcoded credentials -- CI scans for password/token/api_key patterns.
90118
- Skills must have YAML frontmatter starting with `---`.
91119
- Rules use `.mdc` extension with frontmatter.
120+
{% else %}
121+
- No hardcoded credentials -- CI scans for password/token/api_key patterns.
122+
- Conventional commits; never hand-edit the version.
123+
- Keep `mcp-tools.json` in sync with the tools registered in `src/tools/`.
124+
{% endif %}
92125

93126
## Adding content
94127

@@ -105,6 +138,19 @@ Marks issues/PRs as stale after 30 days of inactivity.
105138
1. Create `rules/<name>.mdc` with frontmatter (`description`, `globs`, `alwaysApply`)
106139
2. Add the path to `plugin.json` under `"rules"`
107140
3. Use `feat:` commit prefix
141+
{% else %}
142+
### New provider adapter
143+
144+
1. Implement the `Provider` interface in `src/providers/`
145+
2. Register the adapter in `ProviderManager`
146+
3. Use `feat:` commit prefix
147+
148+
### New tool
149+
150+
1. Register the tool in `src/tools/`
151+
2. Add it to `mcp-tools.json`
152+
3. Add vitest tests
153+
4. Use `feat:` commit prefix
108154
{% endif %}
109155

110156
## License

scaffold/templates/CHANGELOG.md.j2

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
2020
- MCP server scaffold
2121
{% endif %}
2222
{% endif %}
23+
{% if type == 'cursor-plugin' %}
2324
- CI/CD workflows (validate, release, pages, stale)
25+
{% else %}
26+
- CI/CD workflows (ci, release, publish, drift-check, pages, stale, label-sync)
27+
{% endif %}
2428
- GitHub Pages documentation site

scaffold/templates/CLAUDE.md.j2

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,32 @@ This file provides guidance for Claude Code when working in this repository.
2323
- MCP tools: `mcp-server/tools/`
2424
{% endif %}
2525
{% else %}
26-
- Source: `src/`
27-
- Package manifest: `package.json`
26+
- Source: `src/` (TypeScript)
27+
- Provider adapters: `src/providers/` (implement the `Provider` interface, wired into `ProviderManager`)
28+
- Tools: `src/tools/`
29+
- Package manifest: `package.json` (version source of truth)
30+
- Tool list: `mcp-tools.json` (enumerates the MCP tools)
2831
{% endif %}
2932
- Docs site: `docs/`
3033
- CI workflows: `.github/workflows/`
3134

3235
## Conventions
3336

37+
{% if type == 'cursor-plugin' %}
3438
- Use conventional commits (`feat:`, `fix:`, `chore:`, `docs:`)
35-
- Never manually edit the version in {% if type == 'cursor-plugin' %}plugin.json{% else %}package.json{% endif %} -- CI handles it
39+
- Never manually edit the version in plugin.json -- CI handles it
3640
- All skills need YAML frontmatter with title, description, globs
3741
- All rules need frontmatter with description, globs, alwaysApply
42+
{% else %}
43+
- Use conventional commits (`feat:`, `fix:`, `chore:`, `docs:`)
44+
- Never manually edit the version in `package.json` -- CI auto-bumps it
45+
- Provider adapters live in `src/providers/` and implement the `Provider` interface, wired into `ProviderManager`; tools live in `src/tools/`
46+
- Keep `mcp-tools.json` in sync with the registered tools
47+
{% endif %}
3848

3949
## Testing
4050

51+
{% if type == 'cursor-plugin' %}
4152
{% if has_mcp %}
4253
```bash
4354
cd mcp-server && pip install -r requirements.txt
@@ -49,3 +60,10 @@ python3 -m py_compile server.py
4960
python3 -c "import json; json.load(open('.cursor-plugin/plugin.json'))"
5061
```
5162
{% endif %}
63+
{% else %}
64+
```bash
65+
npm run build
66+
npm test
67+
npm run typecheck
68+
```
69+
{% endif %}

scaffold/templates/CONTRIBUTING.md.j2

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Thank you for your interest in contributing.
1515

1616
Use [Conventional Commits](https://www.conventionalcommits.org/):
1717

18+
{% if type == 'cursor-plugin' %}
1819
- `feat:` -- new feature, skill, rule, or MCP tool
1920
- `fix:` -- bug fix
2021
- `docs:` -- documentation changes
@@ -38,6 +39,32 @@ Use [Conventional Commits](https://www.conventionalcommits.org/):
3839
1. Ensure CI passes (the `validate.yml` workflow checks structure and quality)
3940
2. Update `CHANGELOG.md` if the change is user-facing
4041
3. Use a descriptive PR title following conventional commit format
42+
{% else %}
43+
- `feat:` -- new feature, provider adapter, or tool
44+
- `fix:` -- bug fix
45+
- `docs:` -- documentation changes
46+
- `chore:` -- maintenance, dependency updates
47+
- `refactor:` -- code restructuring
48+
49+
### Provider adapters
50+
51+
- Implement the `Provider` interface in `src/providers/`
52+
- Register the adapter in `ProviderManager`
53+
54+
### Tools
55+
56+
- Register the tool in `src/tools/`
57+
- Add it to `mcp-tools.json`
58+
- Add vitest tests
59+
60+
Never hand-edit the version; CI auto-bumps `package.json`.
61+
62+
## Pull Request Process
63+
64+
1. Ensure CI passes (`npm run build`, `npm test`, `npm run typecheck`)
65+
2. Update `CHANGELOG.md` if the change is user-facing
66+
3. Use a descriptive PR title following conventional commit format
67+
{% endif %}
4168

4269
## Inbound license grant and DCO
4370

@@ -52,7 +79,7 @@ By submitting a contribution to this repository, you certify that you have the r
5279
Every commit in a pull request must carry a `Signed-off-by:` trailer matching the commit author. Sign at commit time with the `-s` flag:
5380

5481
```bash
55-
git commit -s -m "feat: add new skill"
82+
{% if type == 'cursor-plugin' %}git commit -s -m "feat: add new skill"{% else %}git commit -s -m "feat: add new tool"{% endif %}
5683
```
5784

5885
This appends a line like `Signed-off-by: Jane Developer <jane@example.com>` to the commit message. The GitHub DCO App enforces this on every PR.

scaffold/templates/ROADMAP.md.j2

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
## {{ name }}
88

9+
{% if type == 'cursor-plugin' %}
910
### v0.1.x -- Foundation
1011

1112
- [ ] Initial skills and rules
@@ -30,3 +31,24 @@
3031
- [ ] Full test coverage
3132
- [ ] Marketplace listing
3233
- [ ] Complete documentation
34+
{% else %}
35+
### v0.1.x -- Foundation
36+
37+
- [x] Core provider adapters
38+
- [x] Initial tool surface
39+
- [x] stdio transport
40+
- [ ] CI/CD workflows
41+
- [ ] GitHub Pages documentation site
42+
43+
### v0.2.0 -- Expansion
44+
45+
- [ ] Additional provider adapters
46+
- [ ] Richer tooling
47+
- [ ] Streaming support
48+
49+
### v1.0.0 -- Stable Release
50+
51+
- [ ] Broader provider coverage
52+
- [ ] Full test coverage
53+
- [ ] Complete documentation
54+
{% endif %}

scaffold/templates/ci.yml.j2

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{% raw %}name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
build-and-test:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
matrix:
17+
node-version: [20, 22]
18+
steps:
19+
- uses: actions/checkout@v6
20+
- name: Use Node.js ${{ matrix.node-version }}
21+
uses: actions/setup-node@v6
22+
with:
23+
node-version: ${{ matrix.node-version }}
24+
cache: npm
25+
- run: npm ci
26+
- run: npm run build
27+
- run: npm test
28+
{% endraw %}

scaffold/templates/cursorrules.j2

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,14 @@ This is a {{ type }} repository for {{ name | replace(' Developer Tools', '') |
1919

2020
## Conventions
2121

22+
{% if type == 'cursor-plugin' %}
2223
- Use conventional commits (feat:, fix:, chore:, docs:)
2324
- Never manually edit the version -- CI handles it
2425
- Skills need YAML frontmatter: title, description, globs
2526
- Rules need frontmatter: description, globs, alwaysApply
27+
{% else %}
28+
- Use conventional commits (feat:, fix:, chore:, docs:)
29+
- Never manually edit the version -- CI auto-bumps package.json
30+
- Keep mcp-tools.json in sync with the registered tools
31+
- Provider adapters live in src/providers/; tools live in src/tools/
32+
{% endif %}

scaffold/templates/gitignore.j2

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{% if type == 'cursor-plugin' %}
12
__pycache__/
23
*.pyc
34
*.pyo
@@ -11,3 +12,12 @@ build/
1112
Thumbs.db
1213
node_modules/
1314
*.log
15+
{% else %}
16+
node_modules/
17+
dist/
18+
build/
19+
.env
20+
.DS_Store
21+
Thumbs.db
22+
*.log
23+
{% endif %}

scaffold/templates/publish.yml.j2

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
name: Publish to npm
1+
{% raw %}name: Publish to npm
22

33
on:
44
release:
55
types: [published]
6+
workflow_dispatch: {}
67

78
permissions:
89
contents: read
@@ -22,8 +23,23 @@ jobs:
2223
- run: npm ci
2324
- run: npm run build
2425
- run: npm test
25-
{% raw %}
26-
- run: npm publish --provenance --access public
26+
27+
- name: Check if this version is already published
28+
id: pub
29+
run: |
30+
set -euo pipefail
31+
name=$(node -p "require('./package.json').name")
32+
ver=$(node -p "require('./package.json').version")
33+
if npm view "$name@$ver" version >/dev/null 2>&1; then
34+
echo "skip=true" >> "$GITHUB_OUTPUT"
35+
echo "$name@$ver is already on npm; skipping publish (idempotent re-dispatch)."
36+
else
37+
echo "skip=false" >> "$GITHUB_OUTPUT"
38+
fi
39+
40+
- name: Publish to npm
41+
if: steps.pub.outputs.skip == 'false'
42+
run: npm publish --provenance --access public
2743
env:
2844
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
29-
{% endraw %}
45+
{% endraw %}

0 commit comments

Comments
 (0)