Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Wrong or outdated claim
about: A claim, step or link in the skill is wrong, or the audit script misbehaves
about: A claim, step or link in the skill is wrong, or the audit checks misbehave
labels: bug
---

Expand Down
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Link or dated observation for any new claim, and its label (verified, observed o

## Checklist

- [ ] `python3 scripts/validate_skill.py` prints `ok`
- [ ] CI is green
- [ ] Evals updated if trigger behaviour changed
- [ ] `CHANGELOG.md` updated
- [ ] No client names, domains or private data
58 changes: 55 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,61 @@ jobs:
with:
python-version: "3.13"
- name: Validate skill, evals, manifests and links
run: python3 scripts/validate_skill.py
- name: Compile the audit script
run: python3 -m py_compile skills/github-seo/scripts/check_repo_seo.py
# Inline, because the plugin directory refuses script files from this repo.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the inlined validator: I extracted the heredoc body and ran it against the checkout — prints ok, exit 0 — and it is behaviorally equivalent to the deleted validate_skill.py on this repo (only the nicer relative_to(ROOT) error paths are lost). One gap: CONTRIBUTING.md now says only "CI checks … on each pull request", so contributors must push to discover a failure. Consider pasting the same python3 - <<'EOF' … block into CONTRIBUTING as a local pre-push step — YAML/markdown files are allowed by the portal list, so no conflict with the reason this was inlined.

run: |
python3 - <<'EOF'
import json, re, sys
from pathlib import Path

ROOT = Path(".")
errors = []
for skill_md in sorted(ROOT.glob("skills/*/SKILL.md")):
d = skill_md.parent
m = re.match(r"^---\n(.*?)\n---\n", skill_md.read_text(), flags=re.S)
if not m:
errors.append(f"{skill_md}: missing frontmatter")
continue
fm = dict(
line.split(":", 1) for line in m.group(1).splitlines() if ":" in line and not line.startswith(" ")
)
fm = {k.strip(): v.strip() for k, v in fm.items()}
name = fm.get("name", "")
if name != d.name:
errors.append(f"{skill_md}: name '{name}' must equal directory '{d.name}'")
if not re.fullmatch(r"[a-z0-9]+(-[a-z0-9]+)*", name):
errors.append(f"{skill_md}: name must be lowercase-hyphenated")
desc = fm.get("description", "")
if not desc:
errors.append(f"{skill_md}: description is empty")
elif len(desc) > 1024:
errors.append(f"{skill_md}: description is {len(desc)} chars, limit 1024")
evals = d / "evals" / "evals.json"
if not evals.exists():
errors.append(f"{d}: missing evals/evals.json")
else:
cases = json.loads(evals.read_text()).get("cases", [])
kinds = {c.get("type") for c in cases}
for needed in ("should_trigger", "should_not_trigger", "quality"):
if needed not in kinds:
errors.append(f"{evals}: no '{needed}' cases")
for c in cases:
if c.get("type") == "quality" and not c.get("expected_behavior"):
errors.append(f"{evals}: quality case without expected_behavior: {c.get('prompt')}")
for manifest in (".claude-plugin/plugin.json", ".claude-plugin/marketplace.json"):
try:
json.loads((ROOT / manifest).read_text())
except Exception as e:
errors.append(f"{manifest}: {e}")
link = re.compile(r"\]\((?!https?:|#|mailto:)([^)#\s]+)")
for md in ROOT.rglob("*.md"):
if ".git" in md.parts:
continue
for target in link.findall(md.read_text()):
if not (md.parent / target).exists():
errors.append(f"{md}: broken link '{target}'")
print("\n".join(errors) or "ok")
sys.exit(1 if errors else 0)
EOF

skills-sh:
runs-on: ubuntu-latest
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ All notable changes are listed here. The format follows [Keep a Changelog](https

## [Unreleased]

### Changed
- MCP distribution facts (2026-11-02): Official MCP Registry `_meta` 4 KB limit and npm version timing, Glama listing claim, awesome-mcp-servers requirements, Claude plugin directory rules.
- MCP distribution facts (2026-11-03): Glama build config and stale listings, awesome-mcp-servers bot and entry rules, Claude plugin preparation.
- Retired platforms (2026-11-05): one table in `references/mcp-registry-checklist.md`; guidance for retired platforms removed.
- Claude plugin directory (2026-11-11): the file types and components the directory accepts from an organisation that is not Verified, and commands that list the files the directory is likely to refuse.
- Claude plugin directory (2026-11-05): a "Decide first" check for plugins that return third-party personal data, keep plugin files when not submitting, and two more documented holds (brand name, MCP server command).

### Added
- `references/audit-checks.md`: the repo audit and the listing checks as read-only GitHub CLI commands and tables. The audit flags files and README lines that name a retired platform. The listing checks cover the Official MCP Registry entry, its npm or Docker Hub package, Glama and awesome-mcp-servers.

### Removed
- `skills/github-seo/scripts/check_repo_seo.py`, `scripts/validate_skill.py` and the SVG assets. The Claude plugin directory accepts only Markdown, text, JSON, YAML and PNG, JPEG, GIF, WebP or ICO files from an organisation that is not Verified. CI runs the validator checks inline.

## [0.2.0] - 2026-11-02

### Added
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Thanks for helping. The most valuable contribution is a correction or addition b

1. Fork and branch from `main`.
2. Make the change.
3. Run `python3 scripts/validate_skill.py`. It must print `ok`.
3. CI checks the skill frontmatter, the evals, the manifests and the internal links on each pull request.
4. If you changed when the skill should trigger, update `skills/github-seo/evals/evals.json`.
5. Add a line to `CHANGELOG.md` under an Unreleased heading.
6. Open a pull request and fill in the template.
Expand Down
23 changes: 10 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
GitHub SEO Skill is an Agent Skill for Claude Code that gets open-source GitHub repos found on
Google and GitHub search. It audits a repo's name, description, topics and README, writes a
search-ready README, runs a pre-publish secret and client-data check, and walks MCP servers
through registry submissions such as the Official MCP Registry, Smithery, Glama and mcp.so.
through registry submissions such as the Official MCP Registry, Glama and mcp.so.

It works with any tool that supports the [Agent Skills](https://agentskills.io) format.

Expand Down Expand Up @@ -44,27 +44,25 @@ Then ask in plain words, for example "audit github.com/you/your-repo for search
| Stage | What you get |
|---|---|
| Safety pass | Full-history secret scan and client-data check before anything goes public |
| Audit | A read-only script scores the description, topics, homepage, license, README shape and community files |
| Audit | Read-only GitHub CLI checks score the description, topics, homepage, license, README shape and community files |
| README | An eight-section template aimed at the search snippet, 400 to 700 words |
| Metadata | Repo slug, About text, topics, Website field and social preview guidance |
| Launch | A tested order: repo, write-up, community, wider channels, template galleries |
| MCP servers | A registry-by-registry checklist built around the Official MCP Registry |

## Run the audit yourself

Needs the [GitHub CLI](https://cli.github.com) logged in. The script changes nothing.
Needs the [GitHub CLI](https://cli.github.com) logged in. The checks change nothing.

```bash
python3 skills/github-seo/scripts/check_repo_seo.py owner/repo
```

It prints `PASS`, `WARN` or `FAIL` per check and exits non-zero on any `FAIL`. The social preview
image cannot be read or set through the CLI, so it is listed as a manual step.
Follow [audit-checks.md](skills/github-seo/references/audit-checks.md): four `gh` commands read the
repo, and a table gives pass, warn or fail for each check. The social preview image cannot be read
or set through the CLI, so it is listed as a manual step.

## Network access and data

This repo collects no data and runs no server. The audit script only calls the GitHub CLI (`gh`)
you have logged in, using read-only requests. When the skill guides an MCP server submission, it
This repo collects no data and runs no server. The audit only calls the GitHub CLI (`gh`)
you have logged in, using read-only requests. The listing checks read public pages of the Official
MCP Registry, npm, Docker Hub and Glama. When the skill guides an MCP server submission, it

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The listing checks read public pages of the Official MCP Registry, npm, Docker Hub and Glama" — audit-checks.md's listing checks also read punkpeye/awesome-mcp-servers (README via gh api + PR search). Add it so the README matches the reference this PR introduces.

tells you to look up a server on the Official MCP Registry
(`https://registry.modelcontextprotocol.io`), and the publishing steps use the `mcp-publisher`
tool, which sends your server metadata to that registry. Nothing is sent unless you run those steps.
Expand All @@ -82,9 +80,8 @@ The skill is built to repeat those labels when it reports back, instead of prese
## Repository layout

```
skills/github-seo/ # the skill: SKILL.md, references/, scripts/, evals/
skills/github-seo/ # the skill: SKILL.md, references/, evals/
.claude-plugin/ # plugin and marketplace manifests
scripts/validate_skill.py # checks frontmatter, evals, manifests and links (runs in CI)
```

## Related projects
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
Please do not open a public issue. Use GitHub's private reporting instead:
[Report a vulnerability](https://github.com/devkindhq/github-seo-skill/security/advisories/new).

Relevant reports include the audit script running unintended commands, or skill instructions that
Relevant reports include the audit checks running unintended commands, or skill instructions that
could lead an agent to leak secrets or publish private data.

## Scope

This project contains documentation and one read-only Python script that calls the GitHub CLI.
This project contains documentation and read-only commands that call the GitHub CLI.
It has no runtime service and stores no data.
6 changes: 0 additions & 6 deletions assets/icon.svg

This file was deleted.

16 changes: 0 additions & 16 deletions assets/social-preview.svg

This file was deleted.

67 changes: 0 additions & 67 deletions scripts/validate_skill.py

This file was deleted.

24 changes: 11 additions & 13 deletions skills/github-seo/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: github-seo
description: Makes an open-source GitHub repo discoverable and safe to publish. Audits the repo name, description, topics and README for search, writes a search-ready README, runs a pre-publish secret and client-data check, and guides the launch sequence. Covers MCP server registry submissions (Official MCP Registry, Smithery, Glama, mcp.so). Use when the user wants more stars, traffic or search visibility for a repo, is about to open-source a project, asks for GitHub SEO or repo SEO, or wants to publish an MCP server. Not for general website SEO.
description: Makes an open-source GitHub repo discoverable and safe to publish. Audits the repo name, description, topics and README for search, writes a search-ready README, runs a pre-publish secret and client-data check, and guides the launch sequence. Covers MCP server registry submissions (Official MCP Registry, Glama, mcp.so) and the Claude plugin directory. Use when the user wants more stars, traffic or search visibility for a repo, is about to open-source a project, asks for GitHub SEO or repo SEO, or wants to publish an MCP server. Not for general website SEO.
license: MIT
---

Expand Down Expand Up @@ -44,14 +44,10 @@ Details and the publish-or-not framework: `references/publish-safety.md`.

## Step 2: audit what exists

Run the read-only audit. It needs the GitHub CLI (`gh`) logged in.
Run the read-only repo audit in `references/audit-checks.md`. It needs the GitHub CLI (`gh`) logged in.

```bash
python3 scripts/check_repo_seo.py owner/repo
```

It reports pass, warn or fail for the description, topics, homepage, license, README shape,
and community files, and prints the one lever it cannot check (the social preview image).
It gives pass, warn or fail for the description, topics, homepage, license, README shape,
community files and retired-platform leftovers, and names the one lever no command can check (the social preview image).
Fix failures first, then warnings.

## Step A: plain repo checklist
Expand All @@ -78,19 +74,21 @@ Fix failures first, then warnings.
produces the artifact the next needs.
9. **Upstream galleries and awesome-lists** only once the repo is complete and has real stars.
Maintainers reject cold, thin submissions.
10. **Claude plugin directory.** If the repo ships a Claude plugin, follow
`references/claude-plugin-directory.md` for the submission portal, Validate findings and
the other plugin distribution routes.
10. **Claude plugin directory.** If the repo ships or could ship a Claude plugin, start with
"Decide first" in `references/claude-plugin-directory.md`. It says whether to submit, then
covers the submission portal, Validate findings and the other plugin distribution routes.

## Step B: MCP server checklist (after Step A)

Start with `references/mcp-install-and-metadata.md`: choose the package type (npm, PyPI, OCI and
others each have their own ownership check), complete `server.json` including `websiteUrl`, and
lay out the README install routes per client. Then use `references/mcp-registry-checklist.md`. It covers the Official MCP Registry (`server.json`
plus the `mcp-publisher` CLI), Smithery, Glama, mcp.so, mcpservers.org, Cursor Directory, which
plus the `mcp-publisher` CLI), Glama, mcp.so, mcpservers.org, Cursor Directory, which
registries auto-ingest from the Official one, and common gotchas (stale listings under a personal
account, publish order, domain presence). Pitfalls from real runs (org namespace 403, OCI
account, the Glama build config, publish order, domain presence). Pitfalls from real runs (org namespace 403, OCI
build and label, leaked-history scrub) are in the install reference.
Submit only to the registries in that checklist, never to one in its "Retired platforms" table.
After you submit, confirm each listing with the listing checks in `references/audit-checks.md`.

## What not to do

Expand Down
4 changes: 2 additions & 2 deletions skills/github-seo/evals/evals.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{ "type": "should_trigger", "prompt": "what topics and description should I put on this repo so people find it" },
{ "type": "should_trigger", "prompt": "plan the launch for our new open source tool, reddit, hn, the lot" },
{ "type": "should_trigger", "prompt": "is it safe to make this private repo public" },
{ "type": "should_trigger", "prompt": "submit my mcp server to smithery and glama" },
{ "type": "should_trigger", "prompt": "submit my mcp server to glama and mcp.so" },
{ "type": "should_trigger", "prompt": "audit the discoverability of github.com/acme/widget-cli" },
{ "type": "should_not_trigger", "prompt": "improve the SEO of my marketing website" },
{ "type": "should_not_trigger", "prompt": "write a blog post about our product" },
Expand All @@ -34,7 +34,7 @@
"type": "quality",
"prompt": "Audit github.com/acme/widget-cli for search visibility",
"expected_behavior": [
"runs scripts/check_repo_seo.py rather than guessing at the repo state",
"runs the repo audit in references/audit-checks.md rather than guessing at the repo state",
"reports failures before warnings",
"tells the owner the social preview image must be uploaded manually in Settings",
"does not add inaccurate topics or keyword-stuff the description"
Expand Down
Loading
Loading