skillmds 0.1.1 → 1.0.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/README.md CHANGED
@@ -1,15 +1,43 @@
1
+ <p align="center">
2
+ <img src="https://skillmd.com/skillmd-banner.jpg" alt="SkillMD" width="640">
3
+ </p>
4
+
1
5
  # skillmds
2
6
 
3
7
  [![npm version](https://img.shields.io/npm/v/skillmds.svg)](https://www.npmjs.com/package/skillmds)
4
8
  [![npm downloads](https://img.shields.io/npm/dm/skillmds.svg)](https://www.npmjs.com/package/skillmds)
5
9
  [![license](https://img.shields.io/npm/l/skillmds.svg)](#license)
6
10
 
7
- > The official MCP server for **[SkillMD](https://skillmd.com)** — the open, verified registry of Agent Skills.
11
+ > SkillMD for agents — the official **MCP server** *and* the **`skillmd` CLI** for **[SkillMD](https://skillmd.com)**, the open, verified registry of Agent Skills.
12
+
13
+ This one package ships two tools:
14
+
15
+ - **`skillmds`** — an MCP server so any MCP-capable agent (Claude Code, Claude Desktop, Cursor, …) can search, fetch, validate, and install `SKILL.md` skills with no copy-paste.
16
+ - **`skillmd`** — a CLI that lints and security-scans skills before installing or publishing them. *The registry that lints.*
17
+
18
+ ---
19
+
20
+ ## CLI quick start
8
21
 
9
- Search, fetch, and install Agent Skills (`SKILL.md` files) from one open library, straight inside any MCP-capable agent — Claude Code, Claude Desktop, Cursor, and more. No copy-paste, no manual downloads.
22
+ ```bash
23
+ npm i -g skillmds # installs the `skillmd` command (and `skillmds`)
24
+
25
+ skillmd lint ./my-skill # validate against the spec + quality score
26
+ skillmd lint . --format sarif # SARIF for GitHub Code Scanning
27
+ skillmd scan . --deny executes_scripts
28
+ skillmd search pdf --verified
29
+ skillmd add anthropic/pdf -a claude-code -g # lints before installing
30
+ skillmd init my-skill
31
+ skillmd login && skillmd publish ./my-skill # refuses to publish on lint errors
32
+ ```
33
+
34
+ Without a global install, run a one-off with `npx -p skillmds skillmd lint .`.
35
+ Commands: `lint`/`check`, `scan`, `rules`, `init`, `search`, `add`, `list`, `remove`, `update`, `publish`, `login`. All support `--json`.
10
36
 
11
37
  ---
12
38
 
39
+ ## MCP server
40
+
13
41
  ## Install
14
42
 
15
43
  **Claude Code** (one line):
@@ -55,6 +83,7 @@ The agent picks the right tool, fetches the skill from SkillMD, and writes it in
55
83
  | `skillmd_trending` | – | Top skills on the leaderboard (`30d` or `all`, optional category). |
56
84
  | `skillmd_recommend` | – | Skills similar to one you give, or trending if none. |
57
85
  | `skillmd_list_saved` | token | Your saved skills (requires `SKILLMD_TOKEN`). |
86
+ | `skillmd_lint` | – | Validate a SKILL.md against the spec; returns diagnostics, security flags, and a quality score (0-100). Pass `content` or a `slug`. |
58
87
 
59
88
  By default, `skillmd_install` writes to `~/.claude/skills/<name>/SKILL.md`. Pass a `dest` to target another directory.
60
89
 
@@ -14,6 +14,14 @@ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprot
14
14
  import { mkdir, writeFile } from "node:fs/promises";
15
15
  import { homedir } from "node:os";
16
16
  import { join, resolve } from "node:path";
17
+ // Shared validation engine, bundled into ./vendor at publish time (npm run build).
18
+ // Falls back gracefully if the vendor build is absent (e.g. running from source).
19
+ let lint = null;
20
+ try {
21
+ ({ lint } = await import("../vendor/index.js"));
22
+ } catch {
23
+ /* skillmd_lint will report that validation is unavailable */
24
+ }
17
25
 
18
26
  const API = process.env.SKILLMD_API || "https://skillmd-api.vinoor.workers.dev";
19
27
  const TOKEN = process.env.SKILLMD_TOKEN || "";
@@ -86,6 +94,18 @@ const TOOLS = [
86
94
  description: "List the signed-in user's saved skills. Requires SKILLMD_TOKEN to be set.",
87
95
  inputSchema: { type: "object", properties: {} },
88
96
  },
97
+ {
98
+ name: "skillmd_lint",
99
+ description:
100
+ "Validate a SKILL.md against the SkillMD spec and return diagnostics, security flags, and a quality score (0-100). Pass raw SKILL.md content, or a registry slug (owner/name) to fetch and lint.",
101
+ inputSchema: {
102
+ type: "object",
103
+ properties: {
104
+ content: { type: "string", description: "Raw SKILL.md content to validate" },
105
+ slug: { type: "string", description: "Registry slug owner/name to fetch and validate" },
106
+ },
107
+ },
108
+ },
89
109
  ];
90
110
 
91
111
  function reconstructSkillMd(skill) {
@@ -134,6 +154,20 @@ async function handleCall(name, args) {
134
154
  const r = await api(`/api/favorites`);
135
155
  return text(r.items ?? []);
136
156
  }
157
+ case "skillmd_lint": {
158
+ if (!lint) return text("Validation engine unavailable — run `npm run build` in the skillmds package.");
159
+ let raw = args.content;
160
+ let slug;
161
+ if (!raw && args.slug) {
162
+ const [owner, slugName] = String(args.slug).split("/");
163
+ const skill = await api(`/api/skills/${owner}/${slugName}`);
164
+ raw = reconstructSkillMd(skill);
165
+ slug = slugName;
166
+ }
167
+ if (!raw) return text("Provide `content` (raw SKILL.md) or `slug` (owner/name).");
168
+ const result = lint(raw, slug ? { slug } : {});
169
+ return text({ ok: result.ok, score: result.score, diagnostics: result.diagnostics, security: result.security });
170
+ }
137
171
  case "skillmd_install": {
138
172
  const [owner, slugName] = String(args.slug).split("/");
139
173
  const skill = await api(`/api/skills/${owner}/${slugName}`);
@@ -153,7 +187,7 @@ async function handleCall(name, args) {
153
187
  }
154
188
  }
155
189
 
156
- const server = new Server({ name: "skillmd", version: "0.1.0" }, { capabilities: { tools: {} } });
190
+ const server = new Server({ name: "skillmd", version: "1.0.0" }, { capabilities: { tools: {} } });
157
191
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
158
192
  server.setRequestHandler(CallToolRequestSchema, async (req) => {
159
193
  try {
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ // The `skillmd` CLI, shipped inside the `skillmds` package.
3
+ import("../dist/cli.js");