GitHub OSS, trust signals that get you stars
README structure, SECURITY.md, CI badge, OpenSSF Scorecard, npm provenance via OIDC, Dependabot. The trust stack that gets your repo past skeptical reviewers.
GitHub OSS, trust signals that get you stars
A new MCP server on GitHub starts at zero trust. Reviewers (devs deciding whether to install your thing into their AI workflow) scan in 30 seconds for signals: is this maintained, is the code reviewed, is the install safe? This recipe is the trust-signal stack that says "yes" to all three without you having to write a marketing page.
Schritt 1: README, the first 30 seconds
Reviewers scan top-down. The first three sections decide:
# your-mcp-server
[](https://github.com/you/your-mcp-server/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/your-mcp-server)
[](LICENSE)
[](https://scorecard.dev/viewer/?uri=github.com/you/your-mcp-server)
> **What it does in one sentence.**
## Install
\`\`\`bash
claude mcp add your-mcp-server -s user -- npx -y your-mcp-server
\`\`\`
That's it. Run \`claude\` and the server is available.
## Tools
| Tool | Purpose |
|---|---|
| \`your_list_things\` | List the things, optionally filtered. |
| \`your_create_thing\` | Create a new thing. Returns the ID. |
Five trust signals in the first screen:
- CI badge (green = currently building), proves the project actually compiles.
- npm badge (recent version), proves it's published and recently updated.
- License badge, instantly answers "can I use this".
- OpenSSF Scorecard badge (if set up. Step 4), security-conscious reviewers love this.
- One-line install, proves you take install ergonomics seriously.
Detailed README pattern in 9.5.
Schritt 2: LICENSE file
# MIT (most permissive, most common for MCP servers)
curl -L https://raw.githubusercontent.com/licenses/license-templates/master/templates/mit.txt > LICENSE
Edit the year + holder, commit. GitHub auto-detects it and adds the license badge to your repo's right sidebar.
For paid SaaS-only code (like aiguide), use a proprietary LICENSE, see this repo's LICENSE for the template.
Schritt 3: SECURITY.md
Tells security researchers how to report vulnerabilities responsibly. Lives at SECURITY.md or .github/SECURITY.md:
# Security Policy
## Reporting a Vulnerability
Please **do not** open a public issue. Instead:
1. Email: [email protected] (PGP: optional, key fingerprint here)
2. Or: GitHub's private security advisory form at https://github.com/you/your-mcp-server/security/advisories/new
We'll acknowledge within 48 hours and aim to ship a fix within 7 days for critical issues.
## Supported Versions
| Version | Supported |
|---|---|
| 1.x | ✅ Active |
| 0.x | ❌ End of life |
## Scope
In-scope: code in this repository, the published npm package, the hosted endpoint at https://your-mcp.io.
Out-of-scope: third-party dependencies (report to their respective projects).
Without SECURITY.md, well-meaning researchers will open public issues for vulnerabilities. With it, you get private reports and a chance to fix before disclosure.
Schritt 4: OpenSSF Scorecard
Free automated security audit. Gives your repo a 0-10 score across criteria like dependency pinning, branch protection, code review, etc.
Setup:
# .github/workflows/scorecard.yml
name: Scorecard supply-chain security
on:
branch_protection_rule:
schedule: [ { cron: '20 7 * * 1' } ] # weekly Monday
push: { branches: [main] }
permissions: read-all
jobs:
analysis:
runs-on: ubuntu-latest
permissions:
security-events: write
id-token: write
steps:
- uses: actions/checkout@v4
with: { persist-credentials: false }
- uses: ossf/[email protected]
with:
results_file: results.sarif
results_format: sarif
publish_results: true
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
After first run, your repo appears at https://scorecard.dev/viewer/?uri=github.com/you/your-mcp-server with a score breakdown. Aim for 7+. Common easy wins: enable branch protection on main, pin dependencies, add SECURITY.md (you just did).
The badge in your README pulls live from the Scorecard API.
Schritt 5: Dependabot
Auto-PRs for dependency updates. One file:
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule: { interval: "weekly" }
groups:
minor-and-patch:
update-types: ["minor", "patch"]
- package-ecosystem: "github-actions"
directory: "/"
schedule: { interval: "monthly" }
Dependabot opens grouped PRs (one PR for all minor/patch updates per week). Reduces alert fatigue, keeps deps current.
Schritt 6: CI workflow
# .github/workflows/ci.yml
name: CI
on:
push: { branches: [main] }
pull_request: { branches: [main] }
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix: { node-version: [18, 20, 22] }
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '${{ matrix.node-version }}', cache: 'npm' }
- run: npm ci
- run: npm run build
- run: npm test
Three Node versions on every PR. Catches "works on my machine" bugs.
The CI badge in your README pulls from this workflow's status.
cat package.json 2>/dev/null | python3 -c "import json,sys; p=json.load(sys.stdin); deps=list((p.get(\"dependencies\") or {}).keys()); print(\"sdk:\", \"@modelcontextprotocol/sdk\" in deps); print(\"bin:\", bool(p.get(\"bin\"))); print(\"main:\", bool(p.get(\"main\")))" 2>/dev/null || echo "no package.json in cwd"Schritt 7: Branch protection
GitHub Settings → Branches → Add rule for main:
- ✅ Require pull request reviews before merging (1+)
- ✅ Require status checks to pass (select your CI jobs)
- ✅ Require branches to be up to date
- ✅ Include administrators (disable if you're solo and need to push fixes fast)
Branch protection is one of the OpenSSF Scorecard criteria, turning it on is +1 to your score immediately.
Schritt 8: CONTRIBUTING.md (optional but high-signal)
Not strictly required, but signals an actively maintained project:
# Contributing
Thanks for your interest! Quick orientation:
## Setup
\`\`\`bash
git clone <repo>
npm install
npm test
\`\`\`
## Tests
All PRs need at least one test. Run \`npm test\` locally before pushing.
## Style
- TypeScript strict, no \`any\`.
- Logger uses stderr only (see \`src/lib/logger.ts\`).
- New tools live in \`src/tools/\`, follow the pattern in existing files.
## PR process
1. Fork + branch from main.
2. Make your change with a test.
3. Open a PR. CI runs on push.
4. We aim to review within 7 days.
Even a short CONTRIBUTING.md tells reviewers "yes, we accept PRs" without them having to ask.
Schritt 9: Verify
Run academy_validate_step. The validator checks package.json is wired.
Manual check, visit your repo as a fresh visitor:
- [ ] README first screen has install command + 1-sentence purpose
- [ ] Green CI badge
- [ ] License badge + LICENSE file present
- [ ] SECURITY.md visible (GitHub shows "Security policy" tab)
- [ ] OpenSSF Scorecard badge with score 7+
- [ ] Recent commits (within last 30 days)
- [ ] Dependabot PRs opening weekly
If you'd install your own server based on this 30-second scan, others will too.
Common traps
- README first screen is a list of features instead of an install command, reviewer can't tell if this thing actually works. Install command first, features second.
- No CI, the project might not even build. Add a 5-minute CI workflow.
- No tests, even one test signals "we care about correctness". Even a smoke test.
SECURITY.mdmissing, researchers open public issues, your CVEs are public before you can fix them.dist/committed, pollutes diffs, makes the repo look unmaintained.- No license, many corporate users can't install MIT-license-unknown packages.
- Stale repo, last commit > 6 months ago. Reviewers assume abandoned. Even tiny periodic commits (dep updates) help.
What good looks like
A reviewer lands on your repo, scans for 30 seconds, and decides "yes, install". That's the bar. Trust signals are cheap to add (1-2 hours total for the whole stack) and pay off forever, every star, every install, every PR is downstream of that 30-second scan.
The combo of README first-screen install command + green CI badge + OpenSSF Scorecard 7+ + recent commit activity covers 80% of trust. Everything else (CONTRIBUTING.md, ROADMAP.md, contributors page) is polish.