@powerduck/openapi-mcp-server 1.1.0 → 1.2.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 +336 -191
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,278 +1,423 @@
|
|
|
1
1
|
# @powerduck/openapi-mcp-server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Turn any OpenAPI 3.2 document into a fully functional MCP (Model Context Protocol) server. Automatically generates tools, prompts, and resources from your API spec. Supports both stdio and HTTP (SSE) transports.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@powerduck/openapi-mcp-server)
|
|
6
|
+
[](https://github.com/PowerDuckie/openapi-mcp-server/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
## Links
|
|
9
|
+
|
|
10
|
+
- [Official Website](https://www.powerduck.com/opensource/openapi-mcp-server.html)
|
|
11
|
+
- [Documentation](https://www.powerduck.com/docs/openapi-mcp-server/introduction)
|
|
12
|
+
- [Live Demo](https://www.powerduck.com/demo/openapi-mcp-server.html)
|
|
13
|
+
- [GitHub](https://github.com/PowerDuckie/openapi-mcp-server)
|
|
14
|
+
- [npm](https://www.npmjs.com/package/@powerduck/openapi-mcp-server)
|
|
6
15
|
|
|
7
|
-
|
|
8
|
-
- **Prompts** generated from API metadata and operations
|
|
9
|
-
- **Resources** generated from the OpenAPI catalog
|
|
10
|
-
- **HTTP (SSE)** and **STDIO** MCP transports
|
|
11
|
-
- **Admin Web UI** for managing specs and services
|
|
12
|
-
- **Persistent runtime state** with config storage
|
|
13
|
-
- **Strong validation** and safer request execution
|
|
14
|
-
- **Dual module support**: ESM and CommonJS
|
|
15
|
-
- **TypeScript-first** with full type definitions
|
|
16
|
-
- **91+ tests** covering core utilities, spec loading, and module exports
|
|
16
|
+
---
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### Install
|
|
19
21
|
|
|
20
22
|
```bash
|
|
21
23
|
npm install @powerduck/openapi-mcp-server
|
|
22
24
|
```
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
### Run as a stdio server (CLI)
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
```bash
|
|
29
|
+
npx @powerduck/openapi-mcp-server serve --spec ./openapi.json
|
|
30
|
+
```
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
### Run as an HTTP server (CLI)
|
|
29
33
|
|
|
30
34
|
```bash
|
|
31
|
-
openapi-mcp serve \
|
|
32
|
-
--
|
|
35
|
+
npx @powerduck/openapi-mcp-server serve \
|
|
36
|
+
--spec ./openapi.json \
|
|
37
|
+
--transport http \
|
|
33
38
|
--port 3000 \
|
|
34
|
-
--
|
|
35
|
-
--api-key your-admin-key
|
|
39
|
+
--route-prefix /mcp
|
|
36
40
|
```
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
### Programmatic stdio server
|
|
39
43
|
|
|
40
|
-
```
|
|
41
|
-
openapi-mcp
|
|
42
|
-
--transport stdio \
|
|
43
|
-
--spec ./openapi.yaml \
|
|
44
|
-
--base-url https://api.example.com
|
|
45
|
-
```
|
|
44
|
+
```typescript
|
|
45
|
+
import { startStdioServer } from "@powerduck/openapi-mcp-server";
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
await startStdioServer({
|
|
48
|
+
specPath: "./openapi.json",
|
|
49
|
+
serverName: "My API MCP Server",
|
|
50
|
+
serverVersion: "1.0.0",
|
|
51
|
+
});
|
|
52
|
+
```
|
|
48
53
|
|
|
49
|
-
|
|
54
|
+
### Programmatic HTTP server (Express)
|
|
50
55
|
|
|
51
56
|
```typescript
|
|
52
|
-
import
|
|
57
|
+
import express from "express";
|
|
58
|
+
import { attachSseRoutes } from "@powerduck/openapi-mcp-server";
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
const spec = await loadOpenApiSpec("./openapi.yaml");
|
|
60
|
+
const app = express();
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
attachSseRoutes(
|
|
63
|
+
app,
|
|
64
|
+
() => "./openapi.json", // spec provider: path, URL, or parsed document
|
|
65
|
+
() => ({ userId: "user-123" }), // context provider (optional)
|
|
66
|
+
(req) => req.headers["x-api-key"] === "secret", // route guard (optional)
|
|
61
67
|
);
|
|
68
|
+
|
|
69
|
+
app.listen(3000, () => {
|
|
70
|
+
console.log("MCP SSE server running at http://localhost:3000/mcp");
|
|
71
|
+
});
|
|
62
72
|
```
|
|
63
73
|
|
|
64
|
-
|
|
74
|
+
### Generate tools from a spec
|
|
65
75
|
|
|
66
76
|
```typescript
|
|
67
|
-
import {
|
|
77
|
+
import { loadOpenApiSpec, generateTools } from "@powerduck/openapi-mcp-server";
|
|
68
78
|
|
|
79
|
+
const spec = await loadOpenApiSpec("./openapi.json");
|
|
69
80
|
const tools = generateTools(spec);
|
|
70
|
-
const bindingIndex = buildBindingIndex(spec);
|
|
71
81
|
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
console.log(`Generated ${tools.length} tools:`);
|
|
83
|
+
for (const tool of tools) {
|
|
84
|
+
console.log(`- ${tool.name}: ${tool.description}`);
|
|
85
|
+
}
|
|
74
86
|
```
|
|
75
87
|
|
|
76
|
-
|
|
88
|
+
---
|
|
77
89
|
|
|
78
|
-
|
|
79
|
-
|
|
90
|
+
## Features
|
|
91
|
+
|
|
92
|
+
- **Automatic tool generation** — every operation becomes an MCP tool with a JSON Schema input schema derived from parameters and request body
|
|
93
|
+
- **Prompt generation** — operations with `x-mcp-prompt` become MCP prompts with templated messages
|
|
94
|
+
- **Resource generation** — operations marked with `x-mcp-resource` become readable MCP resources
|
|
95
|
+
- **Two transports** — stdio for local CLI tools and IDEs, HTTP (SSE) for remote servers and web clients
|
|
96
|
+
- **Authentication** — Bearer token, API key, and custom auth middleware for HTTP transport
|
|
97
|
+
- **Admin server** — optional REST admin API for health checks, spec reload, and diagnostics
|
|
98
|
+
- **Context injection** — per-request context provider for user IDs, tenant info, etc.
|
|
99
|
+
- **Route guards** — custom authorization function for HTTP transport
|
|
100
|
+
- **Spec loading** — load from file path, URL, or parsed object; JSON and YAML supported
|
|
101
|
+
- **Built on `@powerduck/openapi-request`** — full OpenAPI parameter serialization for tool execution
|
|
102
|
+
- **Dual ESM/CJS builds** — works with `import` and `require`
|
|
80
103
|
|
|
81
|
-
|
|
82
|
-
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## CLI Usage
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
openapi-mcp serve [options]
|
|
110
|
+
|
|
111
|
+
Options:
|
|
112
|
+
--spec <path> Path or URL to OpenAPI 3.2 spec (required)
|
|
113
|
+
--transport <mode> Transport mode: stdio or http (default: stdio)
|
|
114
|
+
--port <number> HTTP server port (default: 3000)
|
|
115
|
+
--host <string> HTTP server host (default: 0.0.0.0)
|
|
116
|
+
--route-prefix <path> HTTP route prefix for MCP endpoints (default: /mcp)
|
|
117
|
+
--server-name <name> MCP server name (default: OpenAPI MCP Server)
|
|
118
|
+
--server-version <ver> MCP server version (default: 1.0.0)
|
|
119
|
+
--admin Enable admin REST API
|
|
120
|
+
--admin-port <number> Admin server port (default: 3001)
|
|
121
|
+
--auth-type <type> Auth type: bearer, apikey, or none (default: none)
|
|
122
|
+
--auth-token <token> Bearer token or API key value
|
|
123
|
+
--auth-header <name> API key header name (default: x-api-key)
|
|
124
|
+
-h, --help Show help
|
|
125
|
+
-v, --version Show version
|
|
83
126
|
```
|
|
84
127
|
|
|
85
|
-
|
|
128
|
+
---
|
|
86
129
|
|
|
87
|
-
|
|
88
|
-
import { buildMcpServer, startStdioServer, attachSseRoutes } from "@powerduck/openapi-mcp-server";
|
|
89
|
-
import express from "express";
|
|
130
|
+
## MCP Extensions
|
|
90
131
|
|
|
91
|
-
|
|
92
|
-
const server = buildMcpServer({
|
|
93
|
-
specProvider: async () => spec,
|
|
94
|
-
contextProvider: async () => ({ baseUrl: "https://api.example.com" }),
|
|
95
|
-
});
|
|
132
|
+
Control how operations are exposed to MCP clients using OpenAPI extensions:
|
|
96
133
|
|
|
97
|
-
|
|
98
|
-
await startStdioServer(server);
|
|
134
|
+
### `x-mcp-tool`
|
|
99
135
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
136
|
+
Mark an operation as an MCP tool (all operations are tools by default):
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"paths": {
|
|
141
|
+
"/users/{id}": {
|
|
142
|
+
"get": {
|
|
143
|
+
"operationId": "getUser",
|
|
144
|
+
"x-mcp-tool": {
|
|
145
|
+
"name": "get_user",
|
|
146
|
+
"description": "Fetch a user by ID"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
104
152
|
```
|
|
105
153
|
|
|
106
|
-
|
|
154
|
+
### `x-mcp-prompt`
|
|
155
|
+
|
|
156
|
+
Mark an operation as an MCP prompt:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"paths": {
|
|
161
|
+
"/search": {
|
|
162
|
+
"get": {
|
|
163
|
+
"operationId": "search",
|
|
164
|
+
"x-mcp-prompt": {
|
|
165
|
+
"name": "search_docs",
|
|
166
|
+
"description": "Search the documentation",
|
|
167
|
+
"arguments": [
|
|
168
|
+
{ "name": "query", "description": "Search query", "required": true }
|
|
169
|
+
],
|
|
170
|
+
"messages": [
|
|
171
|
+
{ "role": "user", "content": "Search for: {{query}}" }
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
107
179
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
180
|
+
### `x-mcp-resource`
|
|
181
|
+
|
|
182
|
+
Mark an operation as a readable MCP resource:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"paths": {
|
|
187
|
+
"/docs/{slug}": {
|
|
188
|
+
"get": {
|
|
189
|
+
"operationId": "getDoc",
|
|
190
|
+
"x-mcp-resource": {
|
|
191
|
+
"uriTemplate": "docs://{slug}",
|
|
192
|
+
"name": "Documentation page",
|
|
193
|
+
"mimeType": "text/markdown"
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
118
199
|
```
|
|
119
200
|
|
|
120
|
-
|
|
201
|
+
### `x-mcp-ignore`
|
|
121
202
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
effectiveExplode,
|
|
134
|
-
} from "@powerduck/openapi-mcp-server";
|
|
135
|
-
|
|
136
|
-
// Iterate all operations
|
|
137
|
-
for (const op of iterateOperations(spec)) {
|
|
138
|
-
console.log(op.method, op.path, op.operation?.operationId);
|
|
203
|
+
Exclude an operation from MCP entirely:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"paths": {
|
|
208
|
+
"/internal/debug": {
|
|
209
|
+
"get": {
|
|
210
|
+
"x-mcp-ignore": true
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
139
214
|
}
|
|
215
|
+
```
|
|
140
216
|
|
|
141
|
-
|
|
142
|
-
const operation = findOperationById(spec, "getUser");
|
|
217
|
+
---
|
|
143
218
|
|
|
144
|
-
|
|
145
|
-
const duplicates = findDuplicateOperationIds(spec);
|
|
219
|
+
## Programmatic API
|
|
146
220
|
|
|
147
|
-
|
|
148
|
-
const vars = extractPathTemplateVariables("/users/{userId}/posts/{postId}");
|
|
149
|
-
// => ["userId", "postId"]
|
|
150
|
-
```
|
|
221
|
+
### `loadOpenApiSpec(input)`
|
|
151
222
|
|
|
152
|
-
|
|
223
|
+
Loads an OpenAPI spec from a file path, URL, or parsed object. Returns the parsed document.
|
|
153
224
|
|
|
154
225
|
```typescript
|
|
155
|
-
|
|
226
|
+
const spec = await loadOpenApiSpec("./openapi.json");
|
|
227
|
+
const specFromUrl = await loadOpenApiSpec("https://api.example.com/openapi.json");
|
|
228
|
+
const specFromObject = await loadOpenApiSpec({ openapi: "3.2.0", ... });
|
|
229
|
+
```
|
|
156
230
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
231
|
+
### `generateTools(spec)`
|
|
232
|
+
|
|
233
|
+
Generates an array of MCP tool definitions from the spec.
|
|
234
|
+
|
|
235
|
+
### `generateToolsDetailed(spec)`
|
|
236
|
+
|
|
237
|
+
Generates tools with additional metadata (operationId, path, method).
|
|
238
|
+
|
|
239
|
+
### `generatePrompts(spec)`
|
|
240
|
+
|
|
241
|
+
Generates MCP prompt definitions from operations with `x-mcp-prompt`.
|
|
242
|
+
|
|
243
|
+
### `generateResources(spec)`
|
|
244
|
+
|
|
245
|
+
Generates MCP resource definitions from operations with `x-mcp-resource`.
|
|
163
246
|
|
|
164
|
-
|
|
247
|
+
### `executeToolCall(spec, toolName, arguments, context?)`
|
|
248
|
+
|
|
249
|
+
Executes a tool by name, passing the arguments and optional context. Returns the tool result.
|
|
250
|
+
|
|
251
|
+
### `buildMcpServer(options)`
|
|
252
|
+
|
|
253
|
+
Builds an MCP server instance (transport-agnostic).
|
|
254
|
+
|
|
255
|
+
### `startStdioServer(options)`
|
|
256
|
+
|
|
257
|
+
Starts a stdio MCP server. Blocks until the server is closed.
|
|
258
|
+
|
|
259
|
+
### `attachSseRoutes(app, specProvider, contextProvider?, routeGuard?)`
|
|
260
|
+
|
|
261
|
+
Attaches MCP SSE routes to an Express-compatible app. This is the public API for HTTP transport.
|
|
262
|
+
|
|
263
|
+
| Parameter | Type | Description |
|
|
264
|
+
|---|---|---|
|
|
265
|
+
| `app` | `Express` | Express app instance |
|
|
266
|
+
| `specProvider` | `() => string \| object \| Promise<string \| object>` | Returns spec path, URL, or parsed document |
|
|
267
|
+
| `contextProvider` | `(req) => Record<string, unknown> \| Promise<Record<string, unknown>>` | Optional. Returns per-request context |
|
|
268
|
+
| `routeGuard` | `(req) => boolean \| Promise<boolean>` | Optional. Returns true if the request is authorized |
|
|
269
|
+
|
|
270
|
+
### `startAdminServer(options)`
|
|
271
|
+
|
|
272
|
+
Starts an optional admin REST API server for health checks and diagnostics.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Authentication
|
|
277
|
+
|
|
278
|
+
### Bearer token (HTTP)
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import { createAuthMiddleware } from "@powerduck/openapi-mcp-server";
|
|
282
|
+
|
|
283
|
+
app.use("/mcp", createAuthMiddleware({
|
|
284
|
+
type: "bearer",
|
|
285
|
+
token: "your-secret-token",
|
|
286
|
+
}));
|
|
165
287
|
```
|
|
166
288
|
|
|
167
|
-
|
|
289
|
+
### API key (HTTP)
|
|
168
290
|
|
|
169
291
|
```typescript
|
|
170
|
-
|
|
292
|
+
app.use("/mcp", createAuthMiddleware({
|
|
293
|
+
type: "apikey",
|
|
294
|
+
token: "your-api-key",
|
|
295
|
+
headerName: "x-api-key",
|
|
296
|
+
}));
|
|
297
|
+
```
|
|
171
298
|
|
|
172
|
-
|
|
173
|
-
port: 3000,
|
|
174
|
-
host: "127.0.0.1",
|
|
175
|
-
apiKey: "your-admin-key",
|
|
176
|
-
});
|
|
299
|
+
### Custom auth
|
|
177
300
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
301
|
+
Use the `routeGuard` parameter of `attachSseRoutes`:
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
attachSseRoutes(
|
|
305
|
+
app,
|
|
306
|
+
specProvider,
|
|
307
|
+
contextProvider,
|
|
308
|
+
(req) => {
|
|
309
|
+
return verifyJwt(req.headers.authorization);
|
|
310
|
+
},
|
|
311
|
+
);
|
|
182
312
|
```
|
|
183
313
|
|
|
184
|
-
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Context Injection
|
|
317
|
+
|
|
318
|
+
Pass per-request context (user ID, tenant, etc.) to tool executions:
|
|
185
319
|
|
|
320
|
+
```typescript
|
|
321
|
+
attachSseRoutes(
|
|
322
|
+
app,
|
|
323
|
+
() => "./openapi.json",
|
|
324
|
+
(req) => ({
|
|
325
|
+
userId: req.headers["x-user-id"],
|
|
326
|
+
tenantId: req.headers["x-tenant-id"],
|
|
327
|
+
}),
|
|
328
|
+
);
|
|
186
329
|
```
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
│ └── service-registry.ts # Runtime service management
|
|
204
|
-
├── server/
|
|
205
|
-
│ ├── admin-server.ts # Admin HTTP server with Web UI
|
|
206
|
-
│ └── auth.ts # Authentication middleware
|
|
207
|
-
├── config/
|
|
208
|
-
│ └── config-store.ts # Persistent configuration storage
|
|
209
|
-
├── webui/
|
|
210
|
-
│ └── index.html # Admin Web UI
|
|
211
|
-
├── types.ts # Shared TypeScript types
|
|
212
|
-
├── cli.ts # CLI entry point
|
|
213
|
-
└── index.ts # Library exports
|
|
330
|
+
|
|
331
|
+
The context is available in tool execution and can be used for authorization or data scoping.
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Admin Server
|
|
336
|
+
|
|
337
|
+
Enable the admin REST API with `--admin` or programmatically:
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
import { startAdminServer } from "@powerduck/openapi-mcp-server";
|
|
341
|
+
|
|
342
|
+
await startAdminServer({
|
|
343
|
+
port: 3001,
|
|
344
|
+
specPath: "./openapi.json",
|
|
345
|
+
});
|
|
214
346
|
```
|
|
215
347
|
|
|
216
|
-
|
|
348
|
+
### Endpoints
|
|
217
349
|
|
|
218
|
-
|
|
350
|
+
| Method | Path | Description |
|
|
351
|
+
|---|---|---|
|
|
352
|
+
| `GET` | `/health` | Health check |
|
|
353
|
+
| `GET` | `/spec` | Current loaded spec info |
|
|
354
|
+
| `POST` | `/reload` | Reload the spec from disk |
|
|
355
|
+
| `GET` | `/tools` | List generated tools |
|
|
356
|
+
| `GET` | `/prompts` | List generated prompts |
|
|
357
|
+
| `GET` | `/resources` | List generated resources |
|
|
219
358
|
|
|
220
|
-
|
|
221
|
-
- View generated tools, prompts, and resources
|
|
222
|
-
- Inspect running runtime services
|
|
223
|
-
- Stop services
|
|
224
|
-
- Basic MCP debugging hints
|
|
225
|
-
- SSE endpoint discovery
|
|
226
|
-
- STDIO configuration guidance
|
|
359
|
+
---
|
|
227
360
|
|
|
228
|
-
##
|
|
361
|
+
## MCP Client Configuration (Claude Desktop)
|
|
229
362
|
|
|
230
|
-
|
|
231
|
-
# Run all tests
|
|
232
|
-
npm test
|
|
363
|
+
Add to your `claude_desktop_config.json`:
|
|
233
364
|
|
|
234
|
-
|
|
235
|
-
|
|
365
|
+
```json
|
|
366
|
+
{
|
|
367
|
+
"mcpServers": {
|
|
368
|
+
"my-api": {
|
|
369
|
+
"command": "npx",
|
|
370
|
+
"args": ["@powerduck/openapi-mcp-server", "serve", "--spec", "/path/to/openapi.json"]
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
For HTTP transport:
|
|
236
377
|
|
|
237
|
-
|
|
238
|
-
|
|
378
|
+
```json
|
|
379
|
+
{
|
|
380
|
+
"mcpServers": {
|
|
381
|
+
"my-api": {
|
|
382
|
+
"url": "http://localhost:3000/mcp"
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
239
386
|
```
|
|
240
387
|
|
|
241
|
-
|
|
388
|
+
---
|
|
242
389
|
|
|
243
|
-
|
|
244
|
-
- **Spec utilities**: operation iteration, parameter normalization, name uniqueness
|
|
245
|
-
- **OpenAPI loader**: JSON/YAML parsing, validation, dereferencing, error handling
|
|
246
|
-
- **Module exports**: all public API surface verification
|
|
390
|
+
## Development
|
|
247
391
|
|
|
248
|
-
|
|
392
|
+
```bash
|
|
393
|
+
# Install dependencies
|
|
394
|
+
npm install
|
|
249
395
|
|
|
250
|
-
|
|
396
|
+
# Type check
|
|
397
|
+
npm run typecheck
|
|
251
398
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
- Rate limits
|
|
255
|
-
- Audit logs
|
|
256
|
-
- Role-based access control (RBAC)
|
|
257
|
-
- Secure secret storage
|
|
258
|
-
- Upstream host allowlists
|
|
399
|
+
# Build (ESM + CJS + type declarations)
|
|
400
|
+
npm run build
|
|
259
401
|
|
|
260
|
-
|
|
402
|
+
# Run tests
|
|
403
|
+
npm test
|
|
261
404
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
- `axios` — HTTP client for tool execution
|
|
266
|
-
- `commander` — CLI framework
|
|
267
|
-
- `js-yaml` — YAML parsing
|
|
268
|
-
- `multer` — File upload handling
|
|
269
|
-
- `cors` — CORS middleware
|
|
270
|
-
- `terser` — Minification for embedded assets
|
|
405
|
+
# Watch mode
|
|
406
|
+
npx vitest watch
|
|
407
|
+
```
|
|
271
408
|
|
|
272
|
-
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## Related Packages
|
|
273
412
|
|
|
274
|
-
|
|
413
|
+
- [`@powerduck/openapi-parser`](https://www.npmjs.com/package/@powerduck/openapi-parser) — OpenAPI 3.2 parser, validator, and upgrader
|
|
414
|
+
- [`@powerduck/openapi-request`](https://www.npmjs.com/package/@powerduck/openapi-request) — Execute OpenAPI operations with full parameter serialization
|
|
415
|
+
- [`@powerduck/openapi-codegen`](https://www.npmjs.com/package/@powerduck/openapi-codegen) — Generate runnable request examples in 21 languages
|
|
416
|
+
- [`@powerduck/openapi-cli`](https://www.npmjs.com/package/@powerduck/openapi-cli) — CI-ready batch testing for OpenAPI documents
|
|
417
|
+
- [`@powerduck/x-to-openapi`](https://www.npmjs.com/package/@powerduck/x-to-openapi) — Convert curl commands and Postman Collections to OpenAPI 3.2
|
|
275
418
|
|
|
276
|
-
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## License
|
|
277
422
|
|
|
278
|
-
|
|
423
|
+
MIT
|
package/package.json
CHANGED