@402md/skillmd 0.1.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 ADDED
@@ -0,0 +1,279 @@
1
+ # @402md/skillmd
2
+
3
+ **The `package.json` for paid AI agent APIs.**
4
+
5
+ SKILL.md is an open format that describes what an API does, how much it costs, and how to pay — in a single markdown file that both humans and AI agents can read. Think of it as a machine-readable menu for your API.
6
+
7
+ This package parses, validates, generates, and converts SKILL.md files. One dependency (`yaml`). Works in Node, browsers, and edge runtimes.
8
+
9
+ ```bash
10
+ npm install @402md/skillmd
11
+ ```
12
+
13
+ ## Why SKILL.md?
14
+
15
+ AI agents need to discover and pay for APIs autonomously. Today, there's no standard way for an API to say "I cost $0.001 per call, pay me in USDC on Stellar." SKILL.md solves that — one file, readable by any agent framework.
16
+
17
+ - **For API sellers** — Describe your endpoints, set prices, get paid via [x402](https://www.x402.org/)
18
+ - **For agent builders** — Parse any SKILL.md, auto-generate MCP tools, let agents pay and call APIs
19
+ - **For framework authors** — Validate and convert between SKILL.md, OpenAPI, and MCP tool definitions
20
+
21
+ ## Quick Start
22
+
23
+ ### Parse
24
+
25
+ ```typescript
26
+ import { parseSkillMd } from '@402md/skillmd'
27
+
28
+ const manifest = parseSkillMd(`---
29
+ name: weather-api
30
+ description: Real-time weather data
31
+ base_url: https://api.weatherco.com
32
+ type: API
33
+ payment:
34
+ networks: [stellar, base]
35
+ asset: USDC
36
+ payTo: GABC...XYZ
37
+ endpoints:
38
+ - path: /v1/current
39
+ method: POST
40
+ description: Get current weather
41
+ priceUsdc: "0.001"
42
+ ---
43
+
44
+ # Weather API
45
+ `)
46
+
47
+ manifest.name // 'weather-api'
48
+ manifest.payment.networks // ['stellar', 'base']
49
+ manifest.endpoints[0].path // '/v1/current'
50
+ ```
51
+
52
+ From a file:
53
+
54
+ ```typescript
55
+ import { readFileSync } from 'node:fs'
56
+ import { parseSkillMd } from '@402md/skillmd'
57
+
58
+ const manifest = parseSkillMd(readFileSync('./SKILL.md', 'utf-8'))
59
+ ```
60
+
61
+ ### Validate
62
+
63
+ Catch problems before publishing:
64
+
65
+ ```typescript
66
+ import { validateSkillMd } from '@402md/skillmd'
67
+
68
+ const result = validateSkillMd(content)
69
+
70
+ if (!result.valid) {
71
+ result.errors.forEach(e => console.error(`${e.field}: ${e.message}`))
72
+ }
73
+ // Warnings for missing optional fields (version, tags, etc.)
74
+ result.warnings.forEach(w => console.warn(`${w.field}: ${w.message}`))
75
+ ```
76
+
77
+ ### Generate
78
+
79
+ Create a SKILL.md from code:
80
+
81
+ ```typescript
82
+ import { generateSkillMd } from '@402md/skillmd'
83
+
84
+ const skillMd = generateSkillMd({
85
+ name: 'my-api',
86
+ description: 'Does cool things',
87
+ base_url: 'https://api.example.com',
88
+ payment: {
89
+ networks: ['stellar'],
90
+ asset: 'USDC',
91
+ payTo: 'GABC...XYZ'
92
+ },
93
+ endpoints: [
94
+ {
95
+ path: '/v1/run',
96
+ method: 'POST',
97
+ description: 'Run the thing',
98
+ priceUsdc: '0.001'
99
+ }
100
+ ]
101
+ })
102
+ // Returns a complete SKILL.md string with frontmatter + body
103
+ ```
104
+
105
+ ### SKILL.md to MCP Tools
106
+
107
+ Turn any SKILL.md into MCP tool definitions. No `@modelcontextprotocol/sdk` dependency — just the shape your MCP server needs:
108
+
109
+ ```typescript
110
+ import { parseSkillMd, toMcpToolDefinitions } from '@402md/skillmd'
111
+
112
+ const tools = toMcpToolDefinitions(parseSkillMd(content))
113
+ // [
114
+ // {
115
+ // name: 'weather-api_v1_current',
116
+ // description: 'Get current weather (0.001 USDC via stellar)',
117
+ // inputSchema: { type: 'object', properties: { location: { type: 'string' } } }
118
+ // }
119
+ // ]
120
+ ```
121
+
122
+ Each endpoint becomes one tool. `inputSchema` is passed through directly, so MCP clients get full type information.
123
+
124
+ ### OpenAPI Interop
125
+
126
+ Already have a Swagger spec? Convert it to SKILL.md:
127
+
128
+ ```typescript
129
+ import { generateFromOpenAPI } from '@402md/skillmd'
130
+
131
+ const manifest = generateFromOpenAPI(openApiSpec, {
132
+ networks: ['base'],
133
+ asset: 'USDC',
134
+ payTo: '0xabc...def'
135
+ }, {
136
+ pricing: {
137
+ 'GET /pets': '0.001',
138
+ 'POST /pets': '0.05',
139
+ '*': '0.005' // fallback
140
+ }
141
+ })
142
+ ```
143
+
144
+ Going the other way — export any SKILL.md as OpenAPI 3.0 for Swagger UI, Postman, or any OpenAPI tool:
145
+
146
+ ```typescript
147
+ import { toOpenAPI } from '@402md/skillmd'
148
+
149
+ const spec = toOpenAPI(manifest)
150
+ // spec.paths['/v1/current'].post.responses['402'].description = 'Payment Required — 0.001 USDC'
151
+ ```
152
+
153
+ ## SKILL.md Format (v2)
154
+
155
+ ```yaml
156
+ ---
157
+ name: weather-api
158
+ displayName: Weather API
159
+ description: Real-time weather data for any location worldwide
160
+ version: 1.0.0
161
+ author: weatherco
162
+ base_url: https://api.weatherco.com
163
+ type: API
164
+
165
+ payment:
166
+ networks:
167
+ - stellar
168
+ - base
169
+ asset: USDC
170
+ payTo: GABC...XYZ
171
+ facilitator: https://x402.org/facilitator
172
+
173
+ endpoints:
174
+ - path: /v1/current
175
+ method: POST
176
+ description: Get current weather for a location
177
+ priceUsdc: "0.001"
178
+ inputSchema:
179
+ type: object
180
+ properties:
181
+ location:
182
+ type: string
183
+ required: [location]
184
+ outputSchema:
185
+ type: object
186
+ properties:
187
+ temperature:
188
+ type: number
189
+ conditions:
190
+ type: string
191
+
192
+ tags: [weather, geolocation]
193
+ category: data
194
+ sla: "99.9%"
195
+ rateLimit: 1000/hour
196
+ sandbox: https://sandbox.weatherco.com
197
+ ---
198
+
199
+ # Weather API
200
+
201
+ Real-time weather data for any location worldwide.
202
+ ```
203
+
204
+ ### Required fields
205
+
206
+ | Field | Description |
207
+ |-------|-------------|
208
+ | `name` | Unique identifier (kebab-case) |
209
+ | `description` | What the skill does |
210
+ | `base_url` | Base URL of the API |
211
+ | `payment.networks` | Supported chains (`stellar`, `base`, `base-sepolia`, `stellar-testnet`) |
212
+ | `payment.payTo` | Recipient wallet address |
213
+ | `endpoints[].path` | Endpoint path (starts with `/`) |
214
+ | `endpoints[].method` | HTTP method |
215
+ | `endpoints[].description` | What the endpoint does |
216
+ | `endpoints[].priceUsdc` | Price per call in USDC (e.g. `"0.001"`) |
217
+
218
+ ### Optional fields
219
+
220
+ | Field | Description |
221
+ |-------|-------------|
222
+ | `displayName` | Human-readable name |
223
+ | `version` | Semver version |
224
+ | `author` | Author name |
225
+ | `type` | `API` \| `SAAS` \| `PRODUCT` \| `SERVICE` \| `SUBSCRIPTION` \| `CONTENT` |
226
+ | `payment.asset` | Payment asset (default: `USDC`) |
227
+ | `payment.payToEvm` | EVM address fallback |
228
+ | `payment.facilitator` | Facilitator URL |
229
+ | `endpoints[].inputSchema` | JSON Schema for request body |
230
+ | `endpoints[].outputSchema` | JSON Schema for response |
231
+ | `tags` | Discovery tags |
232
+ | `category` | Skill category |
233
+ | `sla` | Uptime guarantee |
234
+ | `rateLimit` | Rate limit |
235
+ | `sandbox` | Free test endpoint URL |
236
+
237
+ ## API Reference
238
+
239
+ ### Parse
240
+
241
+ | Function | Description |
242
+ |----------|-------------|
243
+ | `parseSkillMd(content)` | Parse a SKILL.md string into a `SkillManifest` |
244
+ | `parseFrontmatter(md)` | Extract raw frontmatter (lower-level, v1-compat) |
245
+
246
+ ### Validate
247
+
248
+ | Function | Description |
249
+ |----------|-------------|
250
+ | `validateSkill(manifest)` | Validate a `SkillManifest` object |
251
+ | `validateSkillMd(content)` | Parse + validate a raw SKILL.md string |
252
+
253
+ ### Generate & Convert
254
+
255
+ | Function | Description |
256
+ |----------|-------------|
257
+ | `generateSkillMd(config)` | Generate a SKILL.md string from a `SkillConfig` |
258
+ | `generateFromOpenAPI(spec, payment, options?)` | OpenAPI spec to `SkillManifest` |
259
+ | `toOpenAPI(manifest)` | `SkillManifest` to OpenAPI 3.0 spec |
260
+ | `toMcpToolDefinitions(manifest)` | `SkillManifest` to MCP `McpToolDefinition[]` |
261
+
262
+ ### Schema & Constants
263
+
264
+ | Export | Description |
265
+ |--------|-------------|
266
+ | `SKILLMD_JSON_SCHEMA` | JSON Schema for v2 frontmatter — for external validators (ajv, zod, etc.) |
267
+ | `SKILL_TYPES` | Valid skill types (`['API', 'SAAS', ...]`) |
268
+ | `HTTP_METHODS` | Valid HTTP methods (`['GET', 'POST', ...]`) |
269
+ | `PAYMENT_NETWORKS` | Valid payment networks (`['stellar', 'base', ...]`) |
270
+
271
+ > `SKILLMD_JSON_SCHEMA` is for external consumers who want to validate with ajv or similar. The built-in `validateSkill()` / `validateSkillMd()` use manual validation for better error messages.
272
+
273
+ ## Legacy v1 Support
274
+
275
+ The parser handles v1 SKILL.md files (without the `payment` block). The `price` field on endpoints is mapped to `priceUsdc`, and payment defaults to `{ networks: ['base'], asset: 'USDC', payTo: '' }`.
276
+
277
+ ## License
278
+
279
+ MIT