mcp4openapi 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.
Files changed (209) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +489 -0
  3. package/dist/composite-executor.d.ts +65 -0
  4. package/dist/composite-executor.d.ts.map +1 -0
  5. package/dist/composite-executor.js +147 -0
  6. package/dist/composite-executor.js.map +1 -0
  7. package/dist/constants.d.ts +36 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +36 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/http-transport.d.ts +195 -0
  12. package/dist/http-transport.d.ts.map +1 -0
  13. package/dist/http-transport.js +760 -0
  14. package/dist/http-transport.js.map +1 -0
  15. package/dist/interceptors.d.ts +74 -0
  16. package/dist/interceptors.d.ts.map +1 -0
  17. package/dist/interceptors.js +220 -0
  18. package/dist/interceptors.js.map +1 -0
  19. package/dist/logger.d.ts +81 -0
  20. package/dist/logger.d.ts.map +1 -0
  21. package/dist/logger.js +264 -0
  22. package/dist/logger.js.map +1 -0
  23. package/dist/mcp-server.d.ts +110 -0
  24. package/dist/mcp-server.d.ts.map +1 -0
  25. package/dist/mcp-server.js +568 -0
  26. package/dist/mcp-server.js.map +1 -0
  27. package/dist/metrics.d.ts +86 -0
  28. package/dist/metrics.d.ts.map +1 -0
  29. package/dist/metrics.js +229 -0
  30. package/dist/metrics.js.map +1 -0
  31. package/dist/openapi-parser.d.ts +35 -0
  32. package/dist/openapi-parser.d.ts.map +1 -0
  33. package/dist/openapi-parser.js +160 -0
  34. package/dist/openapi-parser.js.map +1 -0
  35. package/dist/profile-loader.d.ts +25 -0
  36. package/dist/profile-loader.d.ts.map +1 -0
  37. package/dist/profile-loader.js +134 -0
  38. package/dist/profile-loader.js.map +1 -0
  39. package/dist/schema-validator.d.ts +32 -0
  40. package/dist/schema-validator.d.ts.map +1 -0
  41. package/dist/schema-validator.js +126 -0
  42. package/dist/schema-validator.js.map +1 -0
  43. package/dist/scripts/validate-profile.d.ts +9 -0
  44. package/dist/scripts/validate-profile.d.ts.map +1 -0
  45. package/dist/scripts/validate-profile.js +289 -0
  46. package/dist/scripts/validate-profile.js.map +1 -0
  47. package/dist/scripts/validate-schema.d.ts +9 -0
  48. package/dist/scripts/validate-schema.d.ts.map +1 -0
  49. package/dist/scripts/validate-schema.js +84 -0
  50. package/dist/scripts/validate-schema.js.map +1 -0
  51. package/dist/src/composite-executor.d.ts +75 -0
  52. package/dist/src/composite-executor.d.ts.map +1 -0
  53. package/dist/src/composite-executor.js +175 -0
  54. package/dist/src/composite-executor.js.map +1 -0
  55. package/dist/src/constants.d.ts +36 -0
  56. package/dist/src/constants.d.ts.map +1 -0
  57. package/dist/src/constants.js +36 -0
  58. package/dist/src/constants.js.map +1 -0
  59. package/dist/src/dag-executor.d.ts +49 -0
  60. package/dist/src/dag-executor.d.ts.map +1 -0
  61. package/dist/src/dag-executor.js +138 -0
  62. package/dist/src/dag-executor.js.map +1 -0
  63. package/dist/src/errors.d.ts +47 -0
  64. package/dist/src/errors.d.ts.map +1 -0
  65. package/dist/src/errors.js +99 -0
  66. package/dist/src/errors.js.map +1 -0
  67. package/dist/src/generated-schemas.d.ts +661 -0
  68. package/dist/src/generated-schemas.d.ts.map +1 -0
  69. package/dist/src/generated-schemas.js +66 -0
  70. package/dist/src/generated-schemas.js.map +1 -0
  71. package/dist/src/http-client-factory.d.ts +62 -0
  72. package/dist/src/http-client-factory.d.ts.map +1 -0
  73. package/dist/src/http-client-factory.js +121 -0
  74. package/dist/src/http-client-factory.js.map +1 -0
  75. package/dist/src/http-transport.d.ts +194 -0
  76. package/dist/src/http-transport.d.ts.map +1 -0
  77. package/dist/src/http-transport.js +851 -0
  78. package/dist/src/http-transport.js.map +1 -0
  79. package/dist/src/index.d.ts +8 -0
  80. package/dist/src/index.d.ts.map +1 -0
  81. package/dist/src/index.js +59 -0
  82. package/dist/src/index.js.map +1 -0
  83. package/dist/src/interceptors.d.ts +78 -0
  84. package/dist/src/interceptors.d.ts.map +1 -0
  85. package/dist/src/interceptors.js +252 -0
  86. package/dist/src/interceptors.js.map +1 -0
  87. package/dist/src/jsonrpc-validator.d.ts +27 -0
  88. package/dist/src/jsonrpc-validator.d.ts.map +1 -0
  89. package/dist/src/jsonrpc-validator.js +58 -0
  90. package/dist/src/jsonrpc-validator.js.map +1 -0
  91. package/dist/src/lib.d.ts +8 -0
  92. package/dist/src/lib.d.ts.map +1 -0
  93. package/dist/src/lib.js +7 -0
  94. package/dist/src/lib.js.map +1 -0
  95. package/dist/src/logger.d.ts +81 -0
  96. package/dist/src/logger.d.ts.map +1 -0
  97. package/dist/src/logger.js +264 -0
  98. package/dist/src/logger.js.map +1 -0
  99. package/dist/src/mcp-server.d.ts +117 -0
  100. package/dist/src/mcp-server.d.ts.map +1 -0
  101. package/dist/src/mcp-server.js +621 -0
  102. package/dist/src/mcp-server.js.map +1 -0
  103. package/dist/src/metrics.d.ts +86 -0
  104. package/dist/src/metrics.d.ts.map +1 -0
  105. package/dist/src/metrics.js +229 -0
  106. package/dist/src/metrics.js.map +1 -0
  107. package/dist/src/naming-warnings.d.ts +23 -0
  108. package/dist/src/naming-warnings.d.ts.map +1 -0
  109. package/dist/src/naming-warnings.js +83 -0
  110. package/dist/src/naming-warnings.js.map +1 -0
  111. package/dist/src/naming.d.ts +58 -0
  112. package/dist/src/naming.d.ts.map +1 -0
  113. package/dist/src/naming.js +510 -0
  114. package/dist/src/naming.js.map +1 -0
  115. package/dist/src/openapi-parser.d.ts +49 -0
  116. package/dist/src/openapi-parser.d.ts.map +1 -0
  117. package/dist/src/openapi-parser.js +216 -0
  118. package/dist/src/openapi-parser.js.map +1 -0
  119. package/dist/src/profile-loader.d.ts +77 -0
  120. package/dist/src/profile-loader.d.ts.map +1 -0
  121. package/dist/src/profile-loader.js +443 -0
  122. package/dist/src/profile-loader.js.map +1 -0
  123. package/dist/src/schema-validator.d.ts +30 -0
  124. package/dist/src/schema-validator.d.ts.map +1 -0
  125. package/dist/src/schema-validator.js +115 -0
  126. package/dist/src/schema-validator.js.map +1 -0
  127. package/dist/src/testing/fixtures.d.ts +268 -0
  128. package/dist/src/testing/fixtures.d.ts.map +1 -0
  129. package/dist/src/testing/fixtures.js +210 -0
  130. package/dist/src/testing/fixtures.js.map +1 -0
  131. package/dist/src/testing/mock-gitlab-server.d.ts +34 -0
  132. package/dist/src/testing/mock-gitlab-server.d.ts.map +1 -0
  133. package/dist/src/testing/mock-gitlab-server.js +351 -0
  134. package/dist/src/testing/mock-gitlab-server.js.map +1 -0
  135. package/dist/src/testing/mock-utils.d.ts +41 -0
  136. package/dist/src/testing/mock-utils.d.ts.map +1 -0
  137. package/dist/src/testing/mock-utils.js +59 -0
  138. package/dist/src/testing/mock-utils.js.map +1 -0
  139. package/dist/src/testing/test-http-utils.d.ts +52 -0
  140. package/dist/src/testing/test-http-utils.d.ts.map +1 -0
  141. package/dist/src/testing/test-http-utils.js +109 -0
  142. package/dist/src/testing/test-http-utils.js.map +1 -0
  143. package/dist/src/testing/test-types.d.ts +76 -0
  144. package/dist/src/testing/test-types.d.ts.map +1 -0
  145. package/dist/src/testing/test-types.js +7 -0
  146. package/dist/src/testing/test-types.js.map +1 -0
  147. package/dist/src/tool-generator.d.ts +43 -0
  148. package/dist/src/tool-generator.d.ts.map +1 -0
  149. package/dist/src/tool-generator.js +123 -0
  150. package/dist/src/tool-generator.js.map +1 -0
  151. package/dist/src/types/http-transport.d.ts +45 -0
  152. package/dist/src/types/http-transport.d.ts.map +1 -0
  153. package/dist/src/types/http-transport.js +8 -0
  154. package/dist/src/types/http-transport.js.map +1 -0
  155. package/dist/src/types/openapi.d.ts +50 -0
  156. package/dist/src/types/openapi.d.ts.map +1 -0
  157. package/dist/src/types/openapi.js +9 -0
  158. package/dist/src/types/openapi.js.map +1 -0
  159. package/dist/src/types/profile.d.ts +80 -0
  160. package/dist/src/types/profile.d.ts.map +1 -0
  161. package/dist/src/types/profile.js +9 -0
  162. package/dist/src/types/profile.js.map +1 -0
  163. package/dist/src/validation-utils.d.ts +15 -0
  164. package/dist/src/validation-utils.d.ts.map +1 -0
  165. package/dist/src/validation-utils.js +25 -0
  166. package/dist/src/validation-utils.js.map +1 -0
  167. package/dist/testing/fixtures.d.ts +186 -0
  168. package/dist/testing/fixtures.d.ts.map +1 -0
  169. package/dist/testing/fixtures.js +135 -0
  170. package/dist/testing/fixtures.js.map +1 -0
  171. package/dist/testing/http-integration.test.d.ts +7 -0
  172. package/dist/testing/http-integration.test.d.ts.map +1 -0
  173. package/dist/testing/http-integration.test.js +383 -0
  174. package/dist/testing/http-integration.test.js.map +1 -0
  175. package/dist/testing/http-multiuser.test.d.ts +10 -0
  176. package/dist/testing/http-multiuser.test.d.ts.map +1 -0
  177. package/dist/testing/http-multiuser.test.js +255 -0
  178. package/dist/testing/http-multiuser.test.js.map +1 -0
  179. package/dist/testing/integration.test.d.ts +8 -0
  180. package/dist/testing/integration.test.d.ts.map +1 -0
  181. package/dist/testing/integration.test.js +247 -0
  182. package/dist/testing/integration.test.js.map +1 -0
  183. package/dist/testing/mock-gitlab-server.d.ts +34 -0
  184. package/dist/testing/mock-gitlab-server.d.ts.map +1 -0
  185. package/dist/testing/mock-gitlab-server.js +224 -0
  186. package/dist/testing/mock-gitlab-server.js.map +1 -0
  187. package/dist/testing/test-types.d.ts +59 -0
  188. package/dist/testing/test-types.d.ts.map +1 -0
  189. package/dist/testing/test-types.js +7 -0
  190. package/dist/testing/test-types.js.map +1 -0
  191. package/dist/tool-generator.d.ts +43 -0
  192. package/dist/tool-generator.d.ts.map +1 -0
  193. package/dist/tool-generator.js +123 -0
  194. package/dist/tool-generator.js.map +1 -0
  195. package/dist/tsconfig.tsbuildinfo +1 -0
  196. package/dist/types/http-transport.d.ts +39 -0
  197. package/dist/types/http-transport.d.ts.map +1 -0
  198. package/dist/types/http-transport.js +8 -0
  199. package/dist/types/http-transport.js.map +1 -0
  200. package/dist/types/openapi.d.ts +50 -0
  201. package/dist/types/openapi.d.ts.map +1 -0
  202. package/dist/types/openapi.js +9 -0
  203. package/dist/types/openapi.js.map +1 -0
  204. package/dist/types/profile.d.ts +76 -0
  205. package/dist/types/profile.d.ts.map +1 -0
  206. package/dist/types/profile.js +9 -0
  207. package/dist/types/profile.js.map +1 -0
  208. package/package.json +84 -0
  209. package/profile-schema.json +369 -0
package/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2025 David Ruzicka
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,489 @@
1
+ # MCP from OpenAPI
2
+
3
+ Universal MCP server that generates tools from any OpenAPI specification.
4
+
5
+ ## Why This Project?
6
+
7
+ Transform any OpenAPI specification into MCP tools **without writing code**.
8
+ Configure everything via MCP profiles, reduce LLM context pollution, and get production-ready features out of the box.
9
+
10
+ ```
11
+ +-------------------+
12
+ | MCP Client |
13
+ | (Claude/IDE etc.) |
14
+ +---------+---------+
15
+ |
16
+ v
17
+ +--+------+---------+
18
+ | | MCP Profile |
19
+ | | (autogenerated |
20
+ | | if missing) |
21
+ | +----------------+
22
+ | |
23
+ | MCP Server |
24
+ | |
25
+ | +----------------+
26
+ | | OpenAPI Spec |
27
+ | | (YAML/JSON) |
28
+ +--+------+---------+
29
+ |
30
+ v
31
+ +---------+---------+
32
+ | Service API |
33
+ +-------------------+
34
+ ```
35
+
36
+ ## Use Cases
37
+
38
+ 1. **Less Context Pollution**: Fewer tools with filtered response fields through profiles = more relevant context for LLM
39
+ 2. **Multi-Environment**: Same server, different profiles (dev/staging/prod)
40
+ 3. **Custom Workflows**: Composite tools for common multi-step operations
41
+
42
+ More about profiles: [docs/PROFILE-GUIDE.md](https://github.com/davidruzicka/mcp4openapi/blob/main/docs/PROFILE-GUIDE.md).
43
+
44
+ ## Key Features
45
+
46
+ ### Core
47
+ - **Any OpenAPI API**: Works with OpenAPI 3.x specifications
48
+ - **Profiles**: Create JSON configuration transforming API to MCP tools LLM friendly in profiles
49
+ - **Tool Aggregation**: Reduce tool clutter - group related operations in profiles
50
+ - **Composite Actions**: Chain API calls into workflows in profiles
51
+ - **Observability**: Structured logging (console/JSON) with profile-aware token redaction, Prometheus metrics
52
+
53
+ Check example profiles in [profiles/](https://github.com/davidruzicka/mcp4openapi/tree/main/profiles).
54
+
55
+ ## Quick Start
56
+
57
+ ### Configuration File Locations
58
+
59
+ **Cursor:**
60
+ - **Project-Specific:** `.cursor/mcp.json` in your project root
61
+ - **Global:** `~/.cursor/mcp.json` in your home directory (platform-dependent; use `⚙` → `Tools & MCP` → `New MCP Server`)
62
+
63
+ **VS Code + Copilot:**
64
+ - **Project-Specific:** `.vscode/mcp.json` in your project root
65
+ - **Global:** `~/.config/Code/User/mcp.json` in your home directory (platform-dependent; use `Ctrl+Shift+P` → `MCP: Open User Configuration`)
66
+
67
+ **JetBrains IDEs + Copilot:**
68
+ - **Project-Specific:** `.idea/mcp.json` in your project root
69
+ - **Global:** `~/.config/github-copilot/intellij/mcp.json` (platform-dependent; use GitHub Copilot icon bottom right → `Edit Setting...` → `Model Context Protocol (MCP)` → `Configure`)
70
+
71
+ **Claude Code:**
72
+ - **Project-Specific:** `.claude/mcp.json` in your project root
73
+ - **Global:** `~/.claude/mcp.json` in your home directory (platform-dependent)
74
+
75
+ ### Option A: npx
76
+
77
+ No installation required.
78
+
79
+ **VS Code + Copilot example:**
80
+
81
+
82
+ Use VS Code dialog to enter access token (recommended for security):
83
+
84
+ ```json
85
+ {
86
+ "servers": {
87
+ "mcp4openapi": {
88
+ "command": "npx",
89
+ "args": ["mcp4openapi"],
90
+ "env": {
91
+ "OPENAPI_SPEC_PATH": "path/to/openapi.yaml",
92
+ "API_TOKEN": "${input:api_token}",
93
+ "API_BASE_URL": "https://api.example.com",
94
+ "MCP_PROFILE_PATH": "path/to/mcp-profile.json" //optional
95
+ }
96
+ },
97
+ "inputs": [
98
+ {
99
+ "type": "promptString",
100
+ "id": "api_token",
101
+ "description": "API Authorization Token",
102
+ "password": true
103
+ }
104
+ ]
105
+ }
106
+ }
107
+ ```
108
+
109
+ _`inputs` section prompts you for the token when the server starts, so environment variables are not needed._
110
+
111
+ **Cursor example:**
112
+
113
+ ```json
114
+ {
115
+ "mcpServers": {
116
+ "mcp4openapi": {
117
+ "command": "npx",
118
+ "args": ["mcp4openapi"],
119
+ "env": {
120
+ "OPENAPI_SPEC_PATH": "path/to/openapi.yaml",
121
+ "API_TOKEN": "${env:API_TOKEN}", // uses environment variable
122
+ "API_BASE_URL": "https://api.example.com",
123
+ "MCP_PROFILE_PATH": "path/to/mcp-profile.json" //optional
124
+ }
125
+ }
126
+ }
127
+ }
128
+ ```
129
+
130
+ _Environment variables are used to pass tokens to the server when it starts, so you don't need to pass them as plain text._
131
+
132
+ **Claude Code example:**
133
+
134
+ ```bash
135
+ claude mcp add --transport stdio mcp4openapi \
136
+ --env API_TOKEN="${API_TOKEN}" \
137
+ --env OPENAPI_SPEC_PATH=path/to/openapi.yaml \
138
+ --env API_BASE_URL=https://api.example.com \
139
+ --env MCP_PROFILE_PATH=path/to/mcp-profile.json \
140
+ -- npx mcp4openapi
141
+ # expects API_TOKEN environment variable to be set
142
+ ```
143
+
144
+ **JetBrains IDEs + Copilot example:**
145
+
146
+ ```json
147
+ {
148
+ "servers": {
149
+ "mcp4openapi": {
150
+ "command": "npx",
151
+ "args": ["mcp4openapi"],
152
+ "env": {
153
+ "OPENAPI_SPEC_PATH": "path/to/openapi.yaml",
154
+ "API_TOKEN": "<api_token>", // doesn't accept ${API_TOKEN} environment variable
155
+ "API_BASE_URL": "https://api.example.com",
156
+ "MCP_PROFILE_PATH": "path/to/mcp-profile.json" //optional
157
+ }
158
+ }
159
+ }
160
+ }
161
+ ```
162
+
163
+ ### Option B: Docker
164
+
165
+ See [docs/DOCKER.md](./docs/DOCKER.md) for build, run, authentication modes, production deployment, and security.
166
+
167
+ ## Local Development
168
+
169
+ **1. Clone & Install:**
170
+ ```bash
171
+ git clone https://github.com/davidruzicka/mcp4openapi.git
172
+ cd mcp4openapi
173
+ npm install
174
+ ```
175
+
176
+ **2. Build:**
177
+ ```bash
178
+ npm run build
179
+ ```
180
+
181
+ **3. Configure:**
182
+ ```bash
183
+ cp .env.example .env
184
+ # Edit .env with your settings
185
+ ```
186
+
187
+ **4. Run:**
188
+ ```bash
189
+ npm start
190
+ ```
191
+
192
+ See [docs/HTTP-TRANSPORT.md](./docs/HTTP-TRANSPORT.md) for transport options (stdio vs HTTP) and authentication modes.
193
+
194
+ ## Custom CA Certificates
195
+
196
+ Node.js has a fixed list of certificate authorities. If your MCP server uses self-signed certificates, you need to configure Node.js to trust them.
197
+
198
+ ### Linux
199
+
200
+ **Option 1: Disable certificate validation (test only)**
201
+
202
+ ```bash
203
+ export NODE_TLS_REJECT_UNAUTHORIZED=0
204
+ # Persist for current user
205
+ echo 'export NODE_TLS_REJECT_UNAUTHORIZED=0' >> $HOME/.profile
206
+ ```
207
+
208
+ **Option 2: Add custom CA to Node.js**
209
+
210
+ ```bash
211
+ export NODE_EXTRA_CA_CERTS=$HOME/ca-bundle.pem
212
+ # Persist for current user
213
+ echo 'export NODE_EXTRA_CA_CERTS="$HOME/ca-bundle.pem"' >> $HOME/.profile
214
+ ```
215
+
216
+ ### Windows (PowerShell)
217
+
218
+ **Option 1: Disable certificate validation (test only)**
219
+
220
+ ```powershell
221
+ # Session only
222
+ $env:NODE_TLS_REJECT_UNAUTHORIZED = "0"
223
+ # Persist for current user
224
+ setx NODE_TLS_REJECT_UNAUTHORIZED 0
225
+ ```
226
+
227
+ **Option 2: Add custom CA to Node.js**
228
+
229
+ ```powershell
230
+ # Session only
231
+ $env:NODE_EXTRA_CA_CERTS = "$env:USERPROFILE\ca-bundle.pem"
232
+ # Persist for current user
233
+ setx NODE_EXTRA_CA_CERTS "%USERPROFILE%\ca-bundle.pem"
234
+ ```
235
+
236
+ ### macOS (zsh/bash)
237
+
238
+ **Option 1: Disable certificate validation (test only)**
239
+
240
+ ```bash
241
+ # Session only
242
+ export NODE_TLS_REJECT_UNAUTHORIZED=0
243
+ # Persist for current user (zsh)
244
+ echo 'export NODE_TLS_REJECT_UNAUTHORIZED=0' >> $HOME/.zshrc
245
+ # or for bash
246
+ echo 'export NODE_TLS_REJECT_UNAUTHORIZED=0' >> $HOME/.bash_profile
247
+ ```
248
+
249
+ **Option 2: Add custom CA to Node.js**
250
+
251
+ ```bash
252
+ # Session only
253
+ export NODE_EXTRA_CA_CERTS="$HOME/ca-bundle.pem"
254
+ # Persist for current user (zsh)
255
+ echo 'export NODE_EXTRA_CA_CERTS="$HOME/ca-bundle.pem"' >> $HOME/.zshrc
256
+ # or for bash
257
+ echo 'export NODE_EXTRA_CA_CERTS="$HOME/ca-bundle.pem"' >> $HOME/.bash_profile
258
+ ```
259
+
260
+ ## Environment Variables
261
+
262
+ ### Required
263
+ - `OPENAPI_SPEC_PATH`: Path to OpenAPI spec (YAML/JSON)
264
+ - `API_TOKEN`: API token (default env var name; customizable via `AUTH_ENV_VAR`)
265
+ - **Required for stdio** mode with authenticated APIs
266
+ - **Optional for HTTP** mode with per-session tokens
267
+ - When using no profile mode, auth type is auto-detected from OpenAPI `security` schemes
268
+
269
+ ### Optional - Core
270
+ - `MCP_PROFILE_PATH`: Profile JSON path (default: auto-generate tools from OpenAPI spec; warning logged if tool exceeds 60 parameters)
271
+ - `MCP_TRANSPORT`: `stdio` (default) or `http`
272
+ - `API_BASE_URL`: Override OpenAPI server URL
273
+
274
+ ### Optional - Authentication (No-Profile Mode)
275
+ When running without a profile, authentication is automatically configured from OpenAPI spec's `security` schemes:
276
+
277
+ - `AUTH_ENV_VAR`: Environment variable name for auth token (default: `API_TOKEN`)
278
+
279
+ **Supported OpenAPI Security Types:**
280
+ - **Bearer Token** (`http` with `scheme: bearer`): Uses `Authorization: Bearer <token>` header
281
+ - **API Key in Header** (`apiKey` with `in: header`): Uses custom header (e.g., `X-API-Key: <token>`)
282
+ - **API Key in Query** (`apiKey` with `in: query`): Adds token to query string (e.g., `?api_key=<token>`)
283
+ - **OAuth2/OpenID Connect**: Mapped to bearer token authentication
284
+ - **Public APIs**: No authentication if OpenAPI spec has no `security` defined
285
+
286
+ **Example**: Use custom env var for GitLab token:
287
+ ```bash
288
+ export AUTH_ENV_VAR=GITLAB_TOKEN
289
+ export GITLAB_TOKEN=glpat-xxxxxxxxxxxx
290
+ export OPENAPI_SPEC_PATH=path/to/openapi.yaml
291
+ npm start
292
+ ```
293
+
294
+ #### Force Authentication Override
295
+ For APIs with incomplete OpenAPI specs (missing `security` definition but requiring authentication):
296
+
297
+ - `AUTH_FORCE`: Enable force auth override (`true|false`, default: `false`)
298
+ - `AUTH_TYPE`: Authentication type: `bearer|query|custom-header` (default: `bearer`)
299
+ - `AUTH_HEADER_NAME`: Custom header name (required when `AUTH_TYPE=custom-header`)
300
+ - `AUTH_QUERY_PARAM`: Query parameter name (required when `AUTH_TYPE=query`)
301
+
302
+ **Example**: Force bearer authentication for incomplete spec:
303
+ ```bash
304
+ export AUTH_FORCE=true
305
+ export AUTH_TYPE=bearer
306
+ export API_TOKEN=your_token_here
307
+ export OPENAPI_SPEC_PATH=./incomplete-spec.yaml
308
+ npm start
309
+ ```
310
+
311
+ **Example**: Force custom header authentication:
312
+ ```bash
313
+ export AUTH_FORCE=true
314
+ export AUTH_TYPE=custom-header
315
+ export AUTH_HEADER_NAME=X-API-Key
316
+ export API_TOKEN=your_api_key_here
317
+ npm start
318
+ ```
319
+
320
+ **Note**: If OpenAPI spec has `security` defined, it takes precedence over force auth settings.
321
+
322
+ ### Optional - Tool Name Shortening
323
+ When generating tools from OpenAPI without a profile, long operation IDs may exceed limits. Configure automatic shortening:
324
+
325
+ - `MCP_TOOLNAME_MAX`: Maximum tool name length (default: `45`)
326
+ - `MCP_TOOLNAME_STRATEGY`: Shortening strategy: `none|balanced|iterative|hash|auto` (default: `none`)
327
+ - `none`: No shortening, only warnings
328
+ - `balanced`: Add parts by importance until unique & meaningful (recommended)
329
+ - `iterative`: Progressively remove noise until under limit (conservative)
330
+ - `hash`: Use verb + resource + hash for guaranteed uniqueness
331
+ - `auto`: Try strategies in order: balanced → iterative → hash
332
+ - `MCP_TOOLNAME_WARN_ONLY`: Only warn, don't shorten: `true|false` (default: `true`)
333
+ - `MCP_TOOLNAME_MIN_PARTS`: Minimum parts for balanced strategy (default: `3`)
334
+ - `MCP_TOOLNAME_MIN_LENGTH`: Minimum length in chars for balanced strategy (default: `20`)
335
+
336
+ **Example**: Apply balanced shortening (recommended):
337
+ ```bash
338
+ export MCP_TOOLNAME_STRATEGY=balanced
339
+ export MCP_TOOLNAME_WARN_ONLY=false
340
+ ```
341
+
342
+ **Result** for balanced strategy:
343
+ ```
344
+ putApiV4ProjectsIdAlertManagementAlertsAlertIidMetricImagesMetricImageId
345
+ → put_alert_management_image (26 chars)
346
+ deleteApiV4ProjectsIdAlertManagementAlertsAlertIidMetricImagesMetricImageId
347
+ → delete_alert_management_image (26 chars)
348
+ ```
349
+
350
+ **Example**: Apply iterative shortening with 30 char limit:
351
+ ```bash
352
+ export MCP_TOOLNAME_STRATEGY=iterative
353
+ export MCP_TOOLNAME_WARN_ONLY=false
354
+ export MCP_TOOLNAME_MAX=30
355
+ ```
356
+
357
+ ### Optional - HTTP Transport
358
+ - `MCP_HOST`: Bind address (default: `127.0.0.1`; warning logged if non-localhost with empty `ALLOWED_ORIGINS`)
359
+ - `MCP_PORT`: Port (default: `3003`)
360
+ - `ALLOWED_ORIGINS`: Comma-separated origins (default: empty; supports exact, wildcard `*.domain.com`, CIDR `192.168.1.0/24`)
361
+ - `SESSION_TIMEOUT_MS`: Session timeout (default: `1800000` = 30min)
362
+ - `HEARTBEAT_ENABLED`: SSE heartbeat (default: `false`)
363
+ - `HEARTBEAT_INTERVAL_MS`: Heartbeat interval (default: `30000` = 30s)
364
+ - `TOKEN_MAX_LENGTH`: Maximum token length in characters (default: `1000`)
365
+
366
+ #### HTTP Rate Limiting (Security)
367
+ Protect against DoS attacks by limiting request rates per endpoint:
368
+
369
+ - `HTTP_RATE_LIMIT_ENABLED`: Enable rate limiting (`true|false`, default: `true`)
370
+ - `HTTP_RATE_LIMIT_WINDOW_MS`: Rate limit window in milliseconds (default: `60000` = 1 minute)
371
+ - `HTTP_RATE_LIMIT_MAX_REQUESTS`: Max requests per window for `/mcp`, `/sse`, `/health` (default: `100`)
372
+ - `HTTP_RATE_LIMIT_METRICS_MAX`: Max requests per window for `/metrics` (default: `10`)
373
+
374
+ **Example**: Enable rate limiting with custom limits:
375
+ ```bash
376
+ export HTTP_RATE_LIMIT_ENABLED=true
377
+ export HTTP_RATE_LIMIT_MAX_REQUESTS=200 # 200 req/min for MCP endpoints
378
+ export HTTP_RATE_LIMIT_METRICS_MAX=20 # 20 req/min for metrics
379
+ ```
380
+
381
+ **Example**: Disable rate limiting (not recommended for production):
382
+ ```bash
383
+ export HTTP_RATE_LIMIT_ENABLED=false
384
+ ```
385
+
386
+ **Response when rate limit exceeded**:
387
+ ```json
388
+ {
389
+ "error": "Too Many Requests",
390
+ "message": "Rate limit exceeded. Max 100 requests per 60 seconds."
391
+ }
392
+ ```
393
+ HTTP status: `429 Too Many Requests` with `RateLimit-*` headers.
394
+
395
+ ### Optional - Observability
396
+ - `LOG_LEVEL`: `debug`, `info` (default), `warn`, `error`
397
+ - `LOG_FORMAT`: `console` (default) or `json`
398
+ - `METRICS_ENABLED`: Enable Prometheus metrics (default: `false`)
399
+ - `METRICS_PATH`: Metrics endpoint (default: `/metrics`)
400
+
401
+ **Security Note**:
402
+ - Sensitive auth tokens are automatically redacted from logs based on your profile's auth configuration (bearer, query, or custom-header)
403
+ - All errors returned to clients are sanitized to generic messages (`Internal error`) while full details are logged server-side
404
+
405
+ ## Profile System
406
+
407
+ Profile defines which MCP tools from OpenAPI spec are exposed and how to aggregate them.
408
+ **Start with existing profiles** from `profiles/` (e.g., GitLab).
409
+
410
+ **Features:**
411
+ - Tool aggregation (group related operations)
412
+ - Response field filtering (reduce LLM context)
413
+ - Composite actions (chain API calls)
414
+ - Rate limiting & retry logic
415
+
416
+ **Create your own profiles**: See [docs/PROFILE-GUIDE.md](./docs/PROFILE-GUIDE.md)
417
+
418
+ ## Testing & Validation
419
+
420
+ ### Validate Profile
421
+ ```bash
422
+ npm run validate
423
+ # Checks: JSON syntax, schema, logic, OpenAPI operations
424
+ ```
425
+
426
+ ### Validate Schema
427
+ ```bash
428
+ npm run validate:schema
429
+ # Validates profile-schema.json itself
430
+ ```
431
+
432
+ ### Run Tests
433
+ ```bash
434
+ npm test
435
+ ```
436
+
437
+ ## Troubleshooting MCP
438
+
439
+ **Cursor:**
440
+ 1. Open "Output" panel (Ctrl+Shift+U / Cmd+Shift+U)
441
+ 2. Select "MCP Logs" from dropdown
442
+ 3. Check for connection errors or authentication issues
443
+
444
+ **VS Code:**
445
+ 1. Open "Output" from View menu
446
+ 2. Select problematic MCP server from dropdown
447
+ 3. Review MCP tool logs for errors
448
+
449
+ **JetBrains IDEs:**
450
+ 1. Open "Help" → "Show Log in <your_explorer>" → "mcp" directory to access MCP log files
451
+ 2. Check `<your_mcp_server>.log` for MCP-related errors
452
+
453
+ **Common Issues:**
454
+ - **Connection refused:** Check if MCP server is running and accessible
455
+ - **Authentication failed:** Verify token is correct and has required permissions
456
+ - **Certificate errors:** Configure Node.js to trust custom CA certificates (see [Custom CA Certificates](#custom-ca-certificates))
457
+ - **Tool not found:** Verify OpenAPI spec path and profile configuration
458
+
459
+ ## IDE-Specific Documentation
460
+
461
+ - **Cursor:** [Cursor MCP Guide](https://docs.cursor.com/en/context/mcp)
462
+ - **VS Code + Copilot:** [VS Code MCP Servers](https://code.visualstudio.com/docs/copilot/customization/mcp-servers), [GitHub Copilot MCP Guide](https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp/extend-copilot-chat-with-mcp?tool=vscode)
463
+ - **JetBrains IDEs + Copilot:** [JetBrains+Copilot MCP Guide](https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp/extend-copilot-chat-with-mcp?tool=jetbrains)
464
+
465
+ ## Documentation
466
+
467
+ - **[docs/EXAMPLE-GITLAB.md](./docs/EXAMPLE-GITLAB.md)** - Complete GitLab API example with curl commands
468
+ - **[docs/PROFILE-GUIDE.md](./docs/PROFILE-GUIDE.md)** - Guide for creating custom profiles
469
+ - **[docs/HTTP-TRANSPORT.md](./docs/HTTP-TRANSPORT.md)** - HTTP transport setup and usage
470
+ - **[docs/DOCKER.md](./docs/DOCKER.md)** - Docker deployment guide
471
+ - **`profiles/`** - Example profiles for OpenAPI specs
472
+ - **`profile-schema.json`** - JSON Schema for IDE autocomplete
473
+
474
+ ## Project Status
475
+
476
+ - Core MCP server with tool generation
477
+ - stdio transport (MCP SDK)
478
+ - HTTP Streamable transport (MCP Spec 2025-03-26)
479
+ - Session management & SSE resumability
480
+ - Profile system with validation
481
+ - Prometheus metrics (HTTP, sessions, tools, API calls)
482
+
483
+ ## Contributing
484
+
485
+ See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for development guidelines.
486
+
487
+ ## License
488
+
489
+ [MIT](./LICENSE.md)
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Composite action executor for chaining API calls
3
+ *
4
+ * Why: Reduces roundtrips by fetching related data in sequence (e.g., MR + comments).
5
+ * Aggregates results into single JSON structure as defined by store_as paths.
6
+ */
7
+ import type { CompositeStep } from './types/profile.js';
8
+ import type { HttpClient } from './interceptors.js';
9
+ import { OpenAPIParser } from './openapi-parser.js';
10
+ export interface CompositeResult {
11
+ data: Record<string, unknown>;
12
+ completed_steps: number;
13
+ total_steps: number;
14
+ errors?: StepError[];
15
+ }
16
+ export interface StepError {
17
+ step_index: number;
18
+ step_call: string;
19
+ error: string;
20
+ timestamp: string;
21
+ }
22
+ export declare class CompositeExecutor {
23
+ private parser;
24
+ private httpClient?;
25
+ constructor(parser: OpenAPIParser, httpClient?: HttpClient);
26
+ /**
27
+ * Execute a series of API calls and merge results
28
+ *
29
+ * Why sequential: Steps may depend on previous results (e.g., get MR ID, then fetch comments).
30
+ * Could parallelize independent steps in future optimization.
31
+ *
32
+ * Supports partial results: If allowPartial=true, continues after errors and returns
33
+ * what was completed. Useful for composite actions where some data is better than none.
34
+ */
35
+ execute(steps: CompositeStep[], args: Record<string, unknown>, allowPartial?: boolean, httpClient?: HttpClient): Promise<CompositeResult>;
36
+ /**
37
+ * Parse composite step call syntax
38
+ *
39
+ * Format: "GET /projects/{id}/merge_requests/{iid}"
40
+ */
41
+ private parseCall;
42
+ /**
43
+ * Resolve path template with actual values
44
+ *
45
+ * Example: "/projects/{id}" + {id: "123"} => "/projects/123"
46
+ */
47
+ private resolvePath;
48
+ /**
49
+ * Extract query parameters from args based on operation definition
50
+ */
51
+ private extractQueryParams;
52
+ /**
53
+ * Store value at JSONPath-like location
54
+ *
55
+ * Why nested: Allows semantic structure (comments belong under merge_request object).
56
+ *
57
+ * Examples:
58
+ * - "merge_request" => { merge_request: value }
59
+ * - "merge_request.comments" => { merge_request: { comments: value } }
60
+ *
61
+ * Validates path navigation to prevent overwriting non-object values.
62
+ */
63
+ private storeResult;
64
+ }
65
+ //# sourceMappingURL=composite-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composite-executor.d.ts","sourceRoot":"","sources":["../src/composite-executor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU,CAAC;gBADX,MAAM,EAAE,aAAa,EACrB,UAAU,CAAC,EAAE,UAAU;IAGjC;;;;;;;;OAQG;IACG,OAAO,CACX,KAAK,EAAE,aAAa,EAAE,EACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,YAAY,GAAE,OAAe,EAC7B,UAAU,CAAC,EAAE,UAAU,GACtB,OAAO,CAAC,eAAe,CAAC;IAoE3B;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAQjB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAUnB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,WAAW;CAwBpB"}