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.
Files changed (2) hide show
  1. package/README.md +108 -22
  2. 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> Server name (default: api-mcp-server)
58
- --base-url <url> Override API base URL
59
- --port <port> Server port (default: 3000)
60
- --help Show help
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.method === 'get', // Only GET endpoints
107
- excludeOperationIds: ['deleteUser'], // Exclude specific operations
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 # Main server with tool registrations
122
- ├── http-client.js # HTTP utilities
123
- └── tools-config.js # Tool configurations
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.method === 'get' &&
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.1",
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",