api2ai 0.2.1 → 0.2.4
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 +108 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,6 +27,7 @@ OpenAPI specs are easy to write and organize your code and have [100s of tools a
|
|
|
27
27
|
- 🎨 **UI Widgets** - Compatible with ChatGPT Apps SDK and MCP-UI
|
|
28
28
|
- 🔐 **Auth Support** - Bearer tokens, API keys, custom headers
|
|
29
29
|
- ✨ **Zod Schemas** - Type-safe parameter validation
|
|
30
|
+
- 🛡️ **Security Hardening** - Risk classification, policy enforcement, HTTP guardrails
|
|
30
31
|
- 🐳 **Production Ready** - Docker, PM2, and Kubernetes ready
|
|
31
32
|
|
|
32
33
|
## Quick Start
|
|
@@ -54,10 +55,14 @@ Open http://localhost:3000/inspector to test your tools!
|
|
|
54
55
|
node generate-mcp-use-server.js <openapi-spec> [output-folder] [options]
|
|
55
56
|
|
|
56
57
|
Options:
|
|
57
|
-
--name <name>
|
|
58
|
-
--base-url <url>
|
|
59
|
-
--port <port>
|
|
60
|
-
--
|
|
58
|
+
--name <name> Server name (default: api-mcp-server)
|
|
59
|
+
--base-url <url> Override API base URL
|
|
60
|
+
--port <port> Server port (default: 3000)
|
|
61
|
+
--allow-mutations Enable POST/PUT/PATCH/DELETE tools by default
|
|
62
|
+
--include-tags <tags> Only include tools with these tags (comma-separated)
|
|
63
|
+
--exclude-tags <tags> Exclude tools with these tags (comma-separated)
|
|
64
|
+
--approve-writes Disable approval requirement for restricted tools
|
|
65
|
+
--help Show help
|
|
61
66
|
```
|
|
62
67
|
|
|
63
68
|
### Examples
|
|
@@ -80,6 +85,20 @@ node generate-mcp-use-server.js \
|
|
|
80
85
|
./petstore.json \
|
|
81
86
|
./petstore \
|
|
82
87
|
--base-url https://petstore.example.com/v3
|
|
88
|
+
|
|
89
|
+
# Include only read-only tools tagged "public"
|
|
90
|
+
node generate-mcp-use-server.js \
|
|
91
|
+
./api.json \
|
|
92
|
+
./readonly-server \
|
|
93
|
+
--include-tags public \
|
|
94
|
+
--exclude-tags admin,internal
|
|
95
|
+
|
|
96
|
+
# Enable writes (mutations) explicitly
|
|
97
|
+
node generate-mcp-use-server.js \
|
|
98
|
+
./api.json \
|
|
99
|
+
./full-server \
|
|
100
|
+
--allow-mutations \
|
|
101
|
+
--approve-writes
|
|
83
102
|
```
|
|
84
103
|
|
|
85
104
|
### Programmatic Usage
|
|
@@ -95,6 +114,9 @@ const result = await generateMcpServer(
|
|
|
95
114
|
serverName: 'my-api',
|
|
96
115
|
baseUrl: 'https://api.example.com/v1',
|
|
97
116
|
port: 3000,
|
|
117
|
+
allowMutations: false, // block POST/PUT/PATCH/DELETE by default
|
|
118
|
+
includeTags: ['public'], // only include tools tagged "public"
|
|
119
|
+
excludeTags: ['admin'], // exclude tools tagged "admin"
|
|
98
120
|
}
|
|
99
121
|
);
|
|
100
122
|
|
|
@@ -103,11 +125,48 @@ console.log(`Generated ${result.toolCount} tools`);
|
|
|
103
125
|
// Or just extract tools for custom processing
|
|
104
126
|
const spec = await loadOpenApiSpec('./my-spec.json');
|
|
105
127
|
const tools = extractTools(spec, {
|
|
106
|
-
filterFn: (tool) => tool.
|
|
107
|
-
excludeOperationIds: ['deleteUser'],
|
|
128
|
+
filterFn: (tool) => tool.riskLevel === 'low', // only safe read-only tools
|
|
129
|
+
excludeOperationIds: ['deleteUser'],
|
|
108
130
|
});
|
|
109
131
|
```
|
|
110
132
|
|
|
133
|
+
## Security
|
|
134
|
+
|
|
135
|
+
The generator enforces a three-layer security model in every generated server.
|
|
136
|
+
|
|
137
|
+
### Layer 1 — Generation-time risk classification
|
|
138
|
+
|
|
139
|
+
Every tool is classified during generation and the result is baked into `src/tools-config.js`:
|
|
140
|
+
|
|
141
|
+
| Risk level | When assigned | Default behavior |
|
|
142
|
+
|------------|---------------|------------------|
|
|
143
|
+
| `low` | `GET`, `HEAD`, `OPTIONS` with no dangerous keywords | Enabled, no approval required |
|
|
144
|
+
| `medium` | Any mutating method (`POST`, `PUT`, `PATCH`, `DELETE`) | Blocked unless `ALLOW_RESTRICTED_TOOLS=true` |
|
|
145
|
+
| `high` | Any operation matching admin, auth, billing, payments, tokens, secrets, user management patterns | Blocked, approval required |
|
|
146
|
+
|
|
147
|
+
Use `--allow-mutations` at generation time to promote medium-risk tools to enabled-by-default, or override at runtime with env vars.
|
|
148
|
+
|
|
149
|
+
### Layer 2 — Runtime policy enforcement
|
|
150
|
+
|
|
151
|
+
`checkToolPolicy()` runs before every outbound API call, reading env vars at call-time so you can change policy without regenerating:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
ALLOW_RESTRICTED_TOOLS=true # unlock medium/high-risk tools
|
|
155
|
+
REQUIRE_APPROVALS=false # bypass per-call approval gate
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Layer 3 — HTTP hardening
|
|
159
|
+
|
|
160
|
+
The generated HTTP client enforces these on every request:
|
|
161
|
+
|
|
162
|
+
- **Timeouts** — configurable via `REQUEST_TIMEOUT_MS` (default 30 s)
|
|
163
|
+
- **Response size cap** — configurable via `MAX_RESPONSE_BYTES` (default 10 MB)
|
|
164
|
+
- **No redirects** — `redirect: 'error'` prevents host-pivot attacks
|
|
165
|
+
- **Credential header protection** — tool arguments cannot override `Authorization`, `Cookie`, `X-API-Key`, or other credential headers; env-configured auth always wins
|
|
166
|
+
- **Host allowlist** — `ALLOWED_API_HOSTS` restricts outbound calls to specific hostnames
|
|
167
|
+
|
|
168
|
+
> **Inspector note**: The built-in inspector at `/inspector` exposes all registered tools. In production, restrict access using a reverse proxy or firewall rule.
|
|
169
|
+
|
|
111
170
|
## Generated Output
|
|
112
171
|
|
|
113
172
|
```
|
|
@@ -118,9 +177,10 @@ my-mcp-server/
|
|
|
118
177
|
├── package.json
|
|
119
178
|
├── README.md # Generated documentation
|
|
120
179
|
└── src/
|
|
121
|
-
├── index.js
|
|
122
|
-
├── http-client.js
|
|
123
|
-
|
|
180
|
+
├── index.js # Main server with tool registrations
|
|
181
|
+
├── http-client.js # Hardened HTTP client
|
|
182
|
+
├── tools-config.js # Tool configurations with risk metadata
|
|
183
|
+
└── policy.js # Runtime security policy
|
|
124
184
|
```
|
|
125
185
|
|
|
126
186
|
## Generated Server Features
|
|
@@ -136,16 +196,32 @@ my-mcp-server/
|
|
|
136
196
|
|
|
137
197
|
### Environment Variables
|
|
138
198
|
|
|
139
|
-
| Variable | Description |
|
|
140
|
-
|
|
141
|
-
| `PORT` | Server port |
|
|
142
|
-
| `NODE_ENV` | development/production |
|
|
143
|
-
| `API_BASE_URL` | Base URL for API calls |
|
|
144
|
-
| `API_KEY` | Bearer token auth |
|
|
145
|
-
| `API_AUTH_HEADER` | Custom header (`Name:value`) |
|
|
146
|
-
| `MCP_URL` | Public URL for widgets |
|
|
147
|
-
| `ALLOWED_ORIGINS` | CORS origins (production) |
|
|
148
|
-
|
|
199
|
+
| Variable | Description | Default |
|
|
200
|
+
|----------|-------------|---------|
|
|
201
|
+
| `PORT` | Server port | `3000` |
|
|
202
|
+
| `NODE_ENV` | `development` / `production` | `development` |
|
|
203
|
+
| `API_BASE_URL` | Base URL for API calls | From spec |
|
|
204
|
+
| `API_KEY` | Bearer token auth | — |
|
|
205
|
+
| `API_AUTH_HEADER` | Custom header (`Name:value`) | — |
|
|
206
|
+
| `MCP_URL` | Public URL for widgets | — |
|
|
207
|
+
| `ALLOWED_ORIGINS` | CORS origins (production) | — |
|
|
208
|
+
| `ALLOW_RESTRICTED_TOOLS` | Allow medium/high-risk tools | `false` |
|
|
209
|
+
| `REQUIRE_APPROVALS` | Require approval for restricted tools | `true` |
|
|
210
|
+
| `ALLOWED_API_HOSTS` | Comma-separated allowed API hostnames | (spec's host) |
|
|
211
|
+
| `REQUEST_TIMEOUT_MS` | Outbound request timeout in ms | `30000` |
|
|
212
|
+
| `MAX_RESPONSE_BYTES` | Maximum response body size in bytes | `10485760` |
|
|
213
|
+
|
|
214
|
+
### Connect to Claude Desktop
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"mcpServers": {
|
|
219
|
+
"my-api": {
|
|
220
|
+
"url": "http://localhost:3000/mcp"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
149
225
|
|
|
150
226
|
### Connect to ChatGPT
|
|
151
227
|
|
|
@@ -153,6 +229,14 @@ The generated server supports the OpenAI Apps SDK out of the box.
|
|
|
153
229
|
|
|
154
230
|
## Advanced Options
|
|
155
231
|
|
|
232
|
+
### Filter by risk level
|
|
233
|
+
|
|
234
|
+
```javascript
|
|
235
|
+
const result = await generateMcpServer(specUrl, outputDir, {
|
|
236
|
+
filterFn: (tool) => tool.riskLevel === 'low',
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
156
240
|
### Filter Tools by Method
|
|
157
241
|
|
|
158
242
|
```javascript
|
|
@@ -186,14 +270,13 @@ const result = await generateMcpServer(specUrl, outputDir, {
|
|
|
186
270
|
```javascript
|
|
187
271
|
const result = await generateMcpServer(specUrl, outputDir, {
|
|
188
272
|
excludeOperationIds: ['deleteUser'],
|
|
273
|
+
allowMutations: false,
|
|
189
274
|
filterFn: (tool) =>
|
|
190
|
-
tool.
|
|
275
|
+
tool.riskLevel === 'low' &&
|
|
191
276
|
tool.pathTemplate.includes('/public/'),
|
|
192
277
|
});
|
|
193
278
|
```
|
|
194
279
|
|
|
195
|
-
|
|
196
|
-
|
|
197
280
|
## Comparison with Raw MCP SDK
|
|
198
281
|
|
|
199
282
|
| Feature | This Generator | Raw SDK |
|
|
@@ -203,4 +286,7 @@ const result = await generateMcpServer(specUrl, outputDir, {
|
|
|
203
286
|
| UI Widgets | ✅ Supported | ❌ Manual |
|
|
204
287
|
| Zod validation | ✅ Generated | ❌ Manual |
|
|
205
288
|
| Authentication | ✅ Configured | ❌ Manual |
|
|
289
|
+
| Risk classification | ✅ Automatic | ❌ Manual |
|
|
290
|
+
| Runtime policy | ✅ Generated | ❌ Manual |
|
|
291
|
+
| HTTP hardening | ✅ Built-in | ❌ Manual |
|
|
206
292
|
| Production ready | ✅ Yes | ⚠️ Requires work |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "api2ai",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Generate production-ready MCP servers from any OpenAPI specification using the highly-used and convenient [mcp-use](https://mcp-use.com) framework",
|
|
5
5
|
"license": "rights.institute/prosper",
|
|
6
6
|
"author": "vtempest",
|