skillmds 0.1.1 → 1.0.1
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 +31 -2
- package/bin/skillmd-mcp.mjs +35 -1
- package/bin/skillmd.mjs +3 -0
- package/dist/cli.js +933 -0
- package/package.json +23 -5
- package/vendor/index.js +297 -0
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
|
[](https://www.npmjs.com/package/skillmds)
|
|
4
8
|
[](https://www.npmjs.com/package/skillmds)
|
|
5
9
|
[](#license)
|
|
6
10
|
|
|
7
|
-
>
|
|
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
|
-
|
|
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
|
|
package/bin/skillmd-mcp.mjs
CHANGED
|
@@ -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
|
|
190
|
+
const server = new Server({ name: "skillmd", version: "1.0.1" }, { capabilities: { tools: {} } });
|
|
157
191
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
158
192
|
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
159
193
|
try {
|
package/bin/skillmd.mjs
ADDED