Skills Registry
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Skills Registrysearch for a skill that helps write API documentation"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Skills Registry
A personal, read-only MCP skill registry: one GitHub repository, one Cloudflare Worker, four stable MCP tools. Every approved push builds and deploys a validated snapshot; every client keeps the same endpoint URL.
Architecture
Deployment-time publishing, not runtime GitHub fetching:
flowchart TD
G["GitHub repository"] --> V["CI validation and snapshot build"]
V --> D["Deploy Worker at stable URL"]
C["AI clients"] --> A["MCP authentication"]
A --> W["Worker: four registry tools"]
D --> W
W --> S["Bundled index and skill files"]
V --> F["Validation failure: retain existing deployment"]The Worker embeds a generated catalog (src/generated/catalog.json) built
from one exact Git commit. It answers MCP requests with no GitHub API
calls, no database, and no session state — see src/worker.ts.
Related MCP server: skillet
Repository layout
Path | Purpose |
| Metadata (YAML frontmatter) + primary instructions |
| Supporting Markdown/text, explicitly allowlisted per skill |
| Supporting shell/Python/JS/TS source, same allowlist rules, never executed by the registry |
| Schema, allowed file types, size limits, search/pagination defaults |
| Worker, GitHub token check, MCP dispatch, tools, search, registry loader |
|
|
| Contract, search, retrieval, revision, security, auth tests |
| Per-client connection steps and the shared bootstrap instruction |
|
|
src/generated/ is a build output (gitignored), regenerated by CI from the
exact checked-out commit. It is never a second source of truth.
Authoring a skill
Create
skills/<id>/SKILL.mdwith frontmatter:--- schema_version: 1 id: your-skill-id name: Human Readable Name description: One sentence, used in search and listings. version: 1.0.0 tags: [development] keywords: [relevant, terms] requires: [] # capabilities the client needs; does not grant them files: [] # explicit retrieval allowlist, relative to the skill dir required_zdr: false # true = only served to callers cleared for Zero Data Retention (see "Data handling") --- # When to use ... # Instructions ...idmust be a stable lowercase slug matching the directory name (^[a-z0-9]+(-[a-z0-9]+)*$) — treat renaming it as a breaking change.List every supporting file under
files; anything on disk that isn't listed fails validation, and anything listed that doesn't exist also fails.Bump
version(semver) whenever the body or a supporting file changes — CI computes a content hash against the base branch and fails if the version didn't move.Run
npm run validatelocally before pushing.If a skill's instructions genuinely need a local script, put it under
scripts/(.sh,.py,.js,.ts,.rb— seeregistry.config.jsonallowed_script_extensions) and declare it infileslike any other supporting file. It is served as plain text viaskills_get_filewithexecutable: true; the registry never runs it. State plainly in the skill's own instructions that the client must read the script before running it under its own local execution permissions.If a skill's content must never leave a Zero-Data-Retention-cleared provider, set
required_zdr: true. See "Data handling" below — this is an access-control decision, not a content-type decision, so it applies regardless of file type.
Local development
npm install
npm run validate # metadata, duplicate IDs, file allowlist, size, version bumps
npm run build # generates src/generated/catalog.json from the working tree
npm run typecheck
npm test # unit tests against fixture catalogs, independent of build output
npm run dev # wrangler dev, serves the just-built snapshot locallyMCP interface
Four tools, all read-only/non-destructive, all returning api_version,
registry_sha, and published_at:
Tool | Purpose |
| Paginated metadata, optional |
| Ranked keyword/tag search with match reasons and excerpts |
| Metadata, primary instructions, supporting-file manifest for one skill |
| Bounded, paginated text from one allowlisted supporting file |
revision means the registry's Git SHA, not a skill's semantic version. An
omitted revision targets the active snapshot; a stale one returns
REVISION_UNAVAILABLE naming the active SHA so a client restarts discovery
instead of mixing revisions. Application errors (SKILL_NOT_FOUND,
FILE_NOT_FOUND, INVALID_PATH, REVISION_UNAVAILABLE, INVALID_CURSOR)
come back as a normal tool result with isError: true, never disguised as
an empty search result. Malformed arguments are JSON-RPC -32602 errors.
Search is deterministic keyword/tag matching (src/search.ts): exact
id/name match ranks highest, then tag, then keyword, then description
substring, tie-broken by id. No embeddings, no invented relevance.
Every skill's metadata carries required_zdr (see "Data handling"), and
every file manifest entry carries executable (true for anything under
scripts/). A caller not cleared for required_zdr skills doesn't see
them at all — skills_list/skills_search omit them, skills_get/
skills_get_file return SKILL_NOT_FOUND rather than a permission error,
so their existence isn't leaked to callers who can't read them.
Authentication
Decision: direct GitHub personal-access-token validation, no OAuth App,
no redirect flow. A client sends a GitHub PAT as its bearer token; the
Worker asks GitHub who it belongs to (one call to api.github.com/user,
see src/github.ts) and checks the returned login against
ALLOWED_GITHUB_LOGINS. See src/worker.ts's resolveCaller.
This replaced an earlier full OAuth-provider design (GitHub OAuth App +
/authorize + /github/callback + @cloudflare/workers-oauth-provider
issuing its own per-client tokens). For a single-operator personal registry
where every client can be configured with a static bearer/API-key header
(Claude Code, Codex, OpenCode all support this), that was more machinery
than the problem needed: no OAuth App to register, no callback URL, no KV
namespace for grant storage, no DCR/CIMD/PKCE surface to maintain. The
tradeoff is Claude Web / ChatGPT Web connectors, which are generally built
around an interactive "Authorize" redirect button rather than a pasted
token field — verify each one actually has a usable auth field before
relying on it (see "Open questions still unresolved").
Setup required before this works (not done yet — Cloudflare account secrets were just added, GitHub PAT/allowlist still need setting):
Create a GitHub personal access token (github.com → Settings → Developer settings → Personal access tokens). No scopes are required — this only reads the token owner's public identity via
/user.wrangler secret put ALLOWED_GITHUB_LOGINS— your GitHub username(s), comma-separated. OptionallyZDR_GITHUB_LOGINS(see "Data handling").Configure each client with
Authorization: Bearer <your PAT>— seedocs/client-setup.md.
Optional service-token path. A static bearer token
(SKILLS_READ_TOKENS) is checked first, before the GitHub lookup, so
automation (the deploy workflow's smoke test, a script) doesn't need to
hold your actual GitHub credential. It's equivalent in privilege to a
GitHub-authenticated call, not a separate tier.
Cloudflare deployment credentials (CLOUDFLARE_API_TOKEN,
CLOUDFLARE_ACCOUNT_ID) live only in CI secrets — never in client
configuration or tool responses. Your GitHub PAT lives only in your own
client configs and is never sent anywhere but GitHub's API and this Worker.
Data handling: required_zdr
Some skills may describe workflows unsuitable for disclosure to every
connected AI provider (per your answer to the open question below). Those
skills set required_zdr: true in frontmatter. A caller — a GitHub
identity or a static token — is cleared to see them only if it's in
ZDR_GITHUB_LOGINS or SKILLS_ZDR_TOKENS respectively; both default to
empty, so clearance is opt-in and fails closed. This is configured per
client, exactly as asked: a client whose connected provider has no ZDR
agreement simply never gets a login/token added to those lists, and the
skill doesn't exist as far as it can tell (see "MCP interface" above for
why that's SKILL_NOT_FOUND, not a permission error).
required_zdr is an access-control flag, not a content-type flag — it
applies the same way to a Markdown instruction file or a scripts/ file.
Publishing
Edit a skill, bump its version.
Push/merge to
main.validate.ymlruns on PRs and pushes;deploy.ymlruns only on push tomain: validate → build snapshot from the exact commit → typecheck → test →wrangler deploy→ smoke test.A failed step leaves the previous deployment live. Deploys are serialized (
concurrency: production-deploy) so an older build can never overwrite a newer one.Rollback: re-run
deploy.ymlfrom a previous green commit (orwrangler rollbackif using Cloudflare's built-in version history).
"Latest" means latest successfully deployed commit, not necessarily branch HEAD.
Security notes
Skill files are restricted to
.md/.txt(or, underscripts/,.sh/.py/.js/.ts/.rb) under configured size limits; retrieval rejects path traversal, absolute paths, and anything outside a skill's declaredfilesallowlist (src/tools.ts, tested intests/tools.test.ts).No skill script is ever executed by validation, the build, or retrieval —
scripts/files are served as inert text with anexecutableflag; a client chooses whether to run one, under its own local permission model.requiresin frontmatter documents what a skill's instructions assume a client has access to — it grants nothing by itself.Retrieved content still enters the connected AI provider's context. Don't put secrets or incident-specific sensitive detail into a skill.
Registry instructions are not higher priority than system instructions, user authorization, or local access controls — the bootstrap text in
docs/client-setup.mdsays this explicitly so it travels with every client's standing instructions.
Resolved decisions
Auth mechanism: direct GitHub PAT validation against
api.github.com, no OAuth App, no redirect flow — see "Authentication" above. (An earlier pass built a full OAuth-provider design; it was replaced once a simpler option was pointed out — see git history if you want the OAuth version.)Client surfaces: all of them — Claude Web, Claude Code, Codex CLI and hosted surfaces, OpenCode, and ChatGPT Web. Claude Code, Codex, and OpenCode all take a static bearer/API-key header in their MCP config, so a pasted GitHub PAT works directly. Claude Web and ChatGPT Web connectors are generally built around an interactive OAuth "Authorize" redirect rather than a pasted-token field — confirm each actually has a usable auth field for this before relying on it (see "Open questions still unresolved"). If one doesn't, the OAuth-provider design is the fallback.
Publish freshness: "publish after CI finishes" is fine as-is; no change made.
Local scripts/binaries: text scripts (
.sh/.py/.js/.ts/.rb) are now supported underscripts/, served as plain text with anexecutableflag, never run by the registry — see "Authoring a skill" step 6. Compiled/binary assets remain out of scope. A binary can't be reviewed by a human or model before a client runs it, which defeats the trust model this whole registry depends on (retrieval never grants execution); it also adds integrity/signing and storage concerns this registry doesn't currently handle. If a real skill turns out to need a binary, the right shape is a separate, explicitly-confirmed release channel with signed artifacts — notskills_get_file— and should be designed against a concrete skill that needs it, not speculatively.Long-running tasks spanning a deploy: staying with active-snapshot- only for now. The existing
REVISION_UNAVAILABLEbehavior already keeps a client from silently mixing revisions mid-task — it just has to restart discovery. No evidence yet that this is a real problem for any actual task; revisit with historical-revision serving only if one shows up.ZDR-sensitive skills: yes, some may need this — see
required_zdrunder "Data handling" above.
Open questions still unresolved
Does the Claude Web and ChatGPT Web connector UI actually expose a field for a static bearer token / API key, or only an OAuth "Authorize" button? Not yet verified — no live deployment exists yet to test against.
Explicitly out of scope for now
Embeddings/full-text search, a database, an admin UI, remote execution, automatic native-skill installation, write tools, one-tool-per-skill registration, runtime GitHub sync, historical-revision retrieval, and compiled/binary skill assets.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Read-only MCP tools for AI agent discovery, structured resources, and NIULAI information.
A registry of 5,900+ peer-authored skills any MCP agent can search and load on demand.
Governed AI agent skills — one library, distributed to devs and exposed to remote agents over MCP.
Search and discover Agent Skills from the skills.sh registry. Powered by HAPI MCP server.
Related MCP Servers
- AlicenseAqualityCmaintenanceConverts AI Skills (following Claude Skills format) into MCP server resources, enabling LLM applications to discover, access, and utilize self-contained skill directories through the Model Context Protocol. Provides tools to list available skills, retrieve skill details and content, and read supporting files with security protections.327Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to discover, install, and manage SKILL.md skills from a Git-backed registry via MCP tools for search, install, and list operations.171MIT
- AlicenseNot gradedqualityAmaintenanceAn MCP server that enables AI agents to interact with the SkillShare registry, including searching, reading, creating, and managing resources like skills, MCP configurations, and notes.MIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to infer and resolve skills from text, normalize skill names, perform semantic taxonomy searches, and inspect lifecycle governance.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ashwnn/skills'
If you have feedback or need assistance with the MCP directory API, please join our Discord server