@powerduck/openapi-mcp-server 1.0.0 → 1.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/LICENSE +21 -0
- package/README.md +234 -72
- package/dist/{admin-server-B4fQWUnc.d.cts → admin-server-dcPWB2yO.d.cts} +2 -2
- package/dist/{admin-server-B4fQWUnc.d.ts → admin-server-dcPWB2yO.d.ts} +2 -2
- package/dist/cli.cjs +1 -3702
- package/dist/cli.mjs +1 -3689
- package/dist/index.cjs +1 -3696
- package/dist/index.d.cts +46 -20
- package/dist/index.d.ts +46 -20
- package/dist/index.mjs +1 -3657
- package/dist/server/admin-server.cjs +1 -3569
- package/dist/server/admin-server.d.cts +2 -2
- package/dist/server/admin-server.d.ts +2 -2
- package/dist/server/admin-server.mjs +1 -3556
- package/package.json +38 -5
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.mjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/server/admin-server.cjs.map +0 -1
- package/dist/server/admin-server.mjs.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Powerduck limited
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,116 +1,278 @@
|
|
|
1
|
-
|
|
1
|
+
# @powerduck/openapi-mcp-server
|
|
2
|
+
|
|
3
|
+
A production-oriented TypeScript library and runtime that converts OpenAPI documents into MCP (Model Context Protocol) services. Built on top of `@powerduck/openapi-parser` for robust OpenAPI validation and dereferencing.
|
|
2
4
|
|
|
3
5
|
## Features
|
|
4
6
|
|
|
5
|
-
- Tools generated from OpenAPI operations
|
|
6
|
-
- Prompts generated from API metadata and operations
|
|
7
|
-
- Resources generated from the OpenAPI catalog
|
|
8
|
-
- HTTP and STDIO MCP transports
|
|
9
|
-
- Admin Web UI
|
|
10
|
-
- Persistent runtime state
|
|
11
|
-
-
|
|
12
|
-
-
|
|
7
|
+
- **Tools** generated from OpenAPI operations with full parameter serialization
|
|
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
|
|
13
17
|
|
|
14
18
|
## Install
|
|
15
19
|
|
|
16
20
|
```bash
|
|
17
|
-
npm install
|
|
21
|
+
npm install @powerduck/openapi-mcp-server
|
|
18
22
|
```
|
|
19
23
|
|
|
20
|
-
##
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### CLI Usage
|
|
27
|
+
|
|
28
|
+
#### Web Mode (with Admin UI)
|
|
21
29
|
|
|
22
30
|
```bash
|
|
23
|
-
|
|
31
|
+
openapi-mcp serve \
|
|
32
|
+
--transport web \
|
|
33
|
+
--port 3000 \
|
|
34
|
+
--host 127.0.0.1 \
|
|
35
|
+
--api-key your-admin-key
|
|
24
36
|
```
|
|
25
37
|
|
|
26
|
-
|
|
38
|
+
#### STDIO Mode
|
|
27
39
|
|
|
28
40
|
```bash
|
|
29
|
-
|
|
41
|
+
openapi-mcp serve \
|
|
42
|
+
--transport stdio \
|
|
43
|
+
--spec ./openapi.yaml \
|
|
44
|
+
--base-url https://api.example.com
|
|
30
45
|
```
|
|
31
46
|
|
|
32
|
-
|
|
47
|
+
### Programmatic API
|
|
33
48
|
|
|
34
|
-
|
|
35
|
-
|
|
49
|
+
#### Load and Validate an OpenAPI Document
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { loadOpenApiSpec, parseSpecContent } from "@powerduck/openapi-mcp-server";
|
|
53
|
+
|
|
54
|
+
// Load from file (JSON or YAML)
|
|
55
|
+
const spec = await loadOpenApiSpec("./openapi.yaml");
|
|
56
|
+
|
|
57
|
+
// Parse from string content
|
|
58
|
+
const specFromText = await parseSpecContent(
|
|
59
|
+
'{"openapi": "3.1.0", "info": {...}, "paths": {...}}',
|
|
60
|
+
false, // isYaml
|
|
61
|
+
);
|
|
36
62
|
```
|
|
37
63
|
|
|
38
|
-
|
|
64
|
+
#### Generate MCP Tools
|
|
39
65
|
|
|
40
|
-
```
|
|
41
|
-
|
|
66
|
+
```typescript
|
|
67
|
+
import { generateTools, buildBindingIndex } from "@powerduck/openapi-mcp-server";
|
|
68
|
+
|
|
69
|
+
const tools = generateTools(spec);
|
|
70
|
+
const bindingIndex = buildBindingIndex(spec);
|
|
71
|
+
|
|
72
|
+
// tools is an array of MCP Tool definitions
|
|
73
|
+
// bindingIndex maps operationIds to tool names
|
|
42
74
|
```
|
|
43
75
|
|
|
44
|
-
|
|
76
|
+
#### Generate Prompts and Resources
|
|
45
77
|
|
|
46
|
-
```
|
|
47
|
-
import {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
generateResources,
|
|
52
|
-
buildMcpServer,
|
|
53
|
-
} from "openapi-mcp-production";
|
|
78
|
+
```typescript
|
|
79
|
+
import { generatePrompts, generateResources } from "@powerduck/openapi-mcp-server";
|
|
80
|
+
|
|
81
|
+
const prompts = generatePrompts(spec);
|
|
82
|
+
const resources = generateResources(spec);
|
|
54
83
|
```
|
|
55
84
|
|
|
56
|
-
|
|
85
|
+
#### Build an MCP Server
|
|
57
86
|
|
|
58
|
-
|
|
87
|
+
```typescript
|
|
88
|
+
import { buildMcpServer, startStdioServer, attachSseRoutes } from "@powerduck/openapi-mcp-server";
|
|
89
|
+
import express from "express";
|
|
59
90
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
91
|
+
// Build a server with custom spec and context providers
|
|
92
|
+
const server = buildMcpServer({
|
|
93
|
+
specProvider: async () => spec,
|
|
94
|
+
contextProvider: async () => ({ baseUrl: "https://api.example.com" }),
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// STDIO transport
|
|
98
|
+
await startStdioServer(server);
|
|
99
|
+
|
|
100
|
+
// HTTP/SSE transport
|
|
101
|
+
const app = express();
|
|
102
|
+
attachSseRoutes(app, server, { path: "/mcp" });
|
|
103
|
+
app.listen(3000);
|
|
66
104
|
```
|
|
67
105
|
|
|
68
|
-
|
|
106
|
+
#### Execute Tool Calls
|
|
69
107
|
|
|
70
|
-
```
|
|
71
|
-
openapi-mcp
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
108
|
+
```typescript
|
|
109
|
+
import { executeToolCall } from "@powerduck/openapi-mcp-server";
|
|
110
|
+
|
|
111
|
+
const result = await executeToolCall({
|
|
112
|
+
toolName: "get_user",
|
|
113
|
+
arguments: { id: "123" },
|
|
114
|
+
spec,
|
|
115
|
+
baseUrl: "https://api.example.com",
|
|
116
|
+
headers: { Authorization: "Bearer token" },
|
|
117
|
+
});
|
|
75
118
|
```
|
|
76
119
|
|
|
77
|
-
|
|
120
|
+
#### Spec Utility Functions
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import {
|
|
124
|
+
iterateOperations,
|
|
125
|
+
findOperationById,
|
|
126
|
+
findDuplicateOperationIds,
|
|
127
|
+
assertUniqueOperationIds,
|
|
128
|
+
extractPathTemplateVariables,
|
|
129
|
+
synthesizeOperationId,
|
|
130
|
+
ensureUniqueName,
|
|
131
|
+
collectOperationParameters,
|
|
132
|
+
effectiveStyle,
|
|
133
|
+
effectiveExplode,
|
|
134
|
+
} from "@powerduck/openapi-mcp-server";
|
|
78
135
|
|
|
79
|
-
|
|
136
|
+
// Iterate all operations
|
|
137
|
+
for (const op of iterateOperations(spec)) {
|
|
138
|
+
console.log(op.method, op.path, op.operation?.operationId);
|
|
139
|
+
}
|
|
80
140
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
- rate limits
|
|
84
|
-
- audit logs
|
|
85
|
-
- RBAC
|
|
86
|
-
- secure secret storage
|
|
87
|
-
- upstream host allowlists
|
|
88
|
-
- comprehensive test suites
|
|
89
|
-
- full OpenAPI parameter serialization coverage
|
|
90
|
-
- full requestBody content negotiation support
|
|
141
|
+
// Find operation by ID
|
|
142
|
+
const operation = findOperationById(spec, "getUser");
|
|
91
143
|
|
|
92
|
-
|
|
144
|
+
// Check for duplicate operation IDs
|
|
145
|
+
const duplicates = findDuplicateOperationIds(spec);
|
|
146
|
+
|
|
147
|
+
// Extract path variables
|
|
148
|
+
const vars = extractPathTemplateVariables("/users/{userId}/posts/{postId}");
|
|
149
|
+
// => ["userId", "postId"]
|
|
150
|
+
```
|
|
93
151
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
152
|
+
#### Build HTTP Requests
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { buildRequest } from "@powerduck/openapi-mcp-server";
|
|
156
|
+
|
|
157
|
+
const request = buildRequest({
|
|
158
|
+
operation,
|
|
159
|
+
pathItem,
|
|
160
|
+
arguments: { id: "123", include: ["profile", "posts"] },
|
|
161
|
+
baseUrl: "https://api.example.com",
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// request contains: method, url, headers, body
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### Admin Server and Auth
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { startAdminServer, createAuthMiddleware } from "@powerduck/openapi-mcp-server";
|
|
171
|
+
|
|
172
|
+
const app = await startAdminServer({
|
|
173
|
+
port: 3000,
|
|
174
|
+
host: "127.0.0.1",
|
|
175
|
+
apiKey: "your-admin-key",
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Or use auth middleware in your own Express app
|
|
179
|
+
import express from "express";
|
|
180
|
+
const myApp = express();
|
|
181
|
+
myApp.use("/admin", createAuthMiddleware({ apiKey: "secret" }));
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Project Structure
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
src/
|
|
188
|
+
├── core/
|
|
189
|
+
│ ├── openapi-loader.ts # Spec loading, validation, dereferencing
|
|
190
|
+
│ ├── spec-utils.ts # Operation traversal, parameter normalization
|
|
191
|
+
│ ├── tool-generator.ts # MCP tool generation from operations
|
|
192
|
+
│ ├── request-builder.ts # HTTP request construction with serialization
|
|
193
|
+
│ ├── http-executor.ts # Safe HTTP request execution
|
|
194
|
+
│ └── global-utils.ts # Shared utilities (IDs, error detection)
|
|
195
|
+
├── mcp/
|
|
196
|
+
│ ├── create-server.ts # MCP server construction
|
|
197
|
+
│ ├── transport-stdio.ts # STDIO transport
|
|
198
|
+
│ └── transport-http.ts # HTTP/SSE transport
|
|
199
|
+
├── registry/
|
|
200
|
+
│ ├── prompt-registry.ts # Prompt generation and resolution
|
|
201
|
+
│ └── resource-registry.ts # Resource generation and reading
|
|
202
|
+
├── runtime/
|
|
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
|
|
214
|
+
```
|
|
101
215
|
|
|
102
216
|
## Web UI
|
|
103
217
|
|
|
104
|
-
The UI supports:
|
|
218
|
+
The admin UI supports:
|
|
105
219
|
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
220
|
+
- Upload and paste OpenAPI documents (JSON or YAML)
|
|
221
|
+
- View generated tools, prompts, and resources
|
|
222
|
+
- Inspect running runtime services
|
|
223
|
+
- Stop services
|
|
224
|
+
- Basic MCP debugging hints
|
|
111
225
|
- SSE endpoint discovery
|
|
112
|
-
- STDIO
|
|
226
|
+
- STDIO configuration guidance
|
|
227
|
+
|
|
228
|
+
## Testing
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# Run all tests
|
|
232
|
+
npm test
|
|
233
|
+
|
|
234
|
+
# Run tests in watch mode
|
|
235
|
+
npm run test:watch
|
|
236
|
+
|
|
237
|
+
# Run tests with coverage
|
|
238
|
+
npm run test:coverage
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Test coverage includes:
|
|
242
|
+
|
|
243
|
+
- **Global utilities**: ID generation, abort error detection
|
|
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
|
|
247
|
+
|
|
248
|
+
## Production Notes
|
|
249
|
+
|
|
250
|
+
This version is production-oriented. For full SaaS deployment, consider adding:
|
|
251
|
+
|
|
252
|
+
- Tenant isolation
|
|
253
|
+
- Database-backed project registry
|
|
254
|
+
- Rate limits
|
|
255
|
+
- Audit logs
|
|
256
|
+
- Role-based access control (RBAC)
|
|
257
|
+
- Secure secret storage
|
|
258
|
+
- Upstream host allowlists
|
|
259
|
+
|
|
260
|
+
## Dependencies
|
|
261
|
+
|
|
262
|
+
- `@powerduck/openapi-parser` — OpenAPI validation, dereferencing, and upgrade (replaces `@scalar/openapi-parser`)
|
|
263
|
+
- `@modelcontextprotocol/sdk` — MCP protocol implementation
|
|
264
|
+
- `express` — HTTP server for admin UI and SSE transport
|
|
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
|
|
271
|
+
|
|
272
|
+
## License
|
|
273
|
+
|
|
274
|
+
MIT © Powerduck limited
|
|
113
275
|
|
|
114
|
-
## Important
|
|
276
|
+
## Important Implementation Policy
|
|
115
277
|
|
|
116
|
-
All source comments are written in American English.
|
|
278
|
+
All source comments are written in American English. No Chinese characters are permitted in the codebase.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Express } from 'express';
|
|
2
2
|
import { Server } from 'node:http';
|
|
3
|
-
import {
|
|
3
|
+
import { Oas32Document } from '@powerduck/openapi-parser';
|
|
4
4
|
import { Prompt, PromptArgument, Resource, Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
5
5
|
|
|
6
6
|
/** How the MCP server is exposed to a client. */
|
|
@@ -96,7 +96,7 @@ interface SecurityContext {
|
|
|
96
96
|
}
|
|
97
97
|
/** Mutable runtime state of the loaded specification. */
|
|
98
98
|
interface AppState {
|
|
99
|
-
spec:
|
|
99
|
+
spec: Oas32Document | null;
|
|
100
100
|
baseUrlOverride?: string | undefined;
|
|
101
101
|
specSource?: SpecSource | undefined;
|
|
102
102
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Express } from 'express';
|
|
2
2
|
import { Server } from 'node:http';
|
|
3
|
-
import {
|
|
3
|
+
import { Oas32Document } from '@powerduck/openapi-parser';
|
|
4
4
|
import { Prompt, PromptArgument, Resource, Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
5
5
|
|
|
6
6
|
/** How the MCP server is exposed to a client. */
|
|
@@ -96,7 +96,7 @@ interface SecurityContext {
|
|
|
96
96
|
}
|
|
97
97
|
/** Mutable runtime state of the loaded specification. */
|
|
98
98
|
interface AppState {
|
|
99
|
-
spec:
|
|
99
|
+
spec: Oas32Document | null;
|
|
100
100
|
baseUrlOverride?: string | undefined;
|
|
101
101
|
specSource?: SpecSource | undefined;
|
|
102
102
|
}
|