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.
- package/LICENSE.md +7 -0
- package/README.md +489 -0
- package/dist/composite-executor.d.ts +65 -0
- package/dist/composite-executor.d.ts.map +1 -0
- package/dist/composite-executor.js +147 -0
- package/dist/composite-executor.js.map +1 -0
- package/dist/constants.d.ts +36 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +36 -0
- package/dist/constants.js.map +1 -0
- package/dist/http-transport.d.ts +195 -0
- package/dist/http-transport.d.ts.map +1 -0
- package/dist/http-transport.js +760 -0
- package/dist/http-transport.js.map +1 -0
- package/dist/interceptors.d.ts +74 -0
- package/dist/interceptors.d.ts.map +1 -0
- package/dist/interceptors.js +220 -0
- package/dist/interceptors.js.map +1 -0
- package/dist/logger.d.ts +81 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +264 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp-server.d.ts +110 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +568 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/metrics.d.ts +86 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +229 -0
- package/dist/metrics.js.map +1 -0
- package/dist/openapi-parser.d.ts +35 -0
- package/dist/openapi-parser.d.ts.map +1 -0
- package/dist/openapi-parser.js +160 -0
- package/dist/openapi-parser.js.map +1 -0
- package/dist/profile-loader.d.ts +25 -0
- package/dist/profile-loader.d.ts.map +1 -0
- package/dist/profile-loader.js +134 -0
- package/dist/profile-loader.js.map +1 -0
- package/dist/schema-validator.d.ts +32 -0
- package/dist/schema-validator.d.ts.map +1 -0
- package/dist/schema-validator.js +126 -0
- package/dist/schema-validator.js.map +1 -0
- package/dist/scripts/validate-profile.d.ts +9 -0
- package/dist/scripts/validate-profile.d.ts.map +1 -0
- package/dist/scripts/validate-profile.js +289 -0
- package/dist/scripts/validate-profile.js.map +1 -0
- package/dist/scripts/validate-schema.d.ts +9 -0
- package/dist/scripts/validate-schema.d.ts.map +1 -0
- package/dist/scripts/validate-schema.js +84 -0
- package/dist/scripts/validate-schema.js.map +1 -0
- package/dist/src/composite-executor.d.ts +75 -0
- package/dist/src/composite-executor.d.ts.map +1 -0
- package/dist/src/composite-executor.js +175 -0
- package/dist/src/composite-executor.js.map +1 -0
- package/dist/src/constants.d.ts +36 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +36 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/dag-executor.d.ts +49 -0
- package/dist/src/dag-executor.d.ts.map +1 -0
- package/dist/src/dag-executor.js +138 -0
- package/dist/src/dag-executor.js.map +1 -0
- package/dist/src/errors.d.ts +47 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +99 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/generated-schemas.d.ts +661 -0
- package/dist/src/generated-schemas.d.ts.map +1 -0
- package/dist/src/generated-schemas.js +66 -0
- package/dist/src/generated-schemas.js.map +1 -0
- package/dist/src/http-client-factory.d.ts +62 -0
- package/dist/src/http-client-factory.d.ts.map +1 -0
- package/dist/src/http-client-factory.js +121 -0
- package/dist/src/http-client-factory.js.map +1 -0
- package/dist/src/http-transport.d.ts +194 -0
- package/dist/src/http-transport.d.ts.map +1 -0
- package/dist/src/http-transport.js +851 -0
- package/dist/src/http-transport.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +59 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interceptors.d.ts +78 -0
- package/dist/src/interceptors.d.ts.map +1 -0
- package/dist/src/interceptors.js +252 -0
- package/dist/src/interceptors.js.map +1 -0
- package/dist/src/jsonrpc-validator.d.ts +27 -0
- package/dist/src/jsonrpc-validator.d.ts.map +1 -0
- package/dist/src/jsonrpc-validator.js +58 -0
- package/dist/src/jsonrpc-validator.js.map +1 -0
- package/dist/src/lib.d.ts +8 -0
- package/dist/src/lib.d.ts.map +1 -0
- package/dist/src/lib.js +7 -0
- package/dist/src/lib.js.map +1 -0
- package/dist/src/logger.d.ts +81 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +264 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/mcp-server.d.ts +117 -0
- package/dist/src/mcp-server.d.ts.map +1 -0
- package/dist/src/mcp-server.js +621 -0
- package/dist/src/mcp-server.js.map +1 -0
- package/dist/src/metrics.d.ts +86 -0
- package/dist/src/metrics.d.ts.map +1 -0
- package/dist/src/metrics.js +229 -0
- package/dist/src/metrics.js.map +1 -0
- package/dist/src/naming-warnings.d.ts +23 -0
- package/dist/src/naming-warnings.d.ts.map +1 -0
- package/dist/src/naming-warnings.js +83 -0
- package/dist/src/naming-warnings.js.map +1 -0
- package/dist/src/naming.d.ts +58 -0
- package/dist/src/naming.d.ts.map +1 -0
- package/dist/src/naming.js +510 -0
- package/dist/src/naming.js.map +1 -0
- package/dist/src/openapi-parser.d.ts +49 -0
- package/dist/src/openapi-parser.d.ts.map +1 -0
- package/dist/src/openapi-parser.js +216 -0
- package/dist/src/openapi-parser.js.map +1 -0
- package/dist/src/profile-loader.d.ts +77 -0
- package/dist/src/profile-loader.d.ts.map +1 -0
- package/dist/src/profile-loader.js +443 -0
- package/dist/src/profile-loader.js.map +1 -0
- package/dist/src/schema-validator.d.ts +30 -0
- package/dist/src/schema-validator.d.ts.map +1 -0
- package/dist/src/schema-validator.js +115 -0
- package/dist/src/schema-validator.js.map +1 -0
- package/dist/src/testing/fixtures.d.ts +268 -0
- package/dist/src/testing/fixtures.d.ts.map +1 -0
- package/dist/src/testing/fixtures.js +210 -0
- package/dist/src/testing/fixtures.js.map +1 -0
- package/dist/src/testing/mock-gitlab-server.d.ts +34 -0
- package/dist/src/testing/mock-gitlab-server.d.ts.map +1 -0
- package/dist/src/testing/mock-gitlab-server.js +351 -0
- package/dist/src/testing/mock-gitlab-server.js.map +1 -0
- package/dist/src/testing/mock-utils.d.ts +41 -0
- package/dist/src/testing/mock-utils.d.ts.map +1 -0
- package/dist/src/testing/mock-utils.js +59 -0
- package/dist/src/testing/mock-utils.js.map +1 -0
- package/dist/src/testing/test-http-utils.d.ts +52 -0
- package/dist/src/testing/test-http-utils.d.ts.map +1 -0
- package/dist/src/testing/test-http-utils.js +109 -0
- package/dist/src/testing/test-http-utils.js.map +1 -0
- package/dist/src/testing/test-types.d.ts +76 -0
- package/dist/src/testing/test-types.d.ts.map +1 -0
- package/dist/src/testing/test-types.js +7 -0
- package/dist/src/testing/test-types.js.map +1 -0
- package/dist/src/tool-generator.d.ts +43 -0
- package/dist/src/tool-generator.d.ts.map +1 -0
- package/dist/src/tool-generator.js +123 -0
- package/dist/src/tool-generator.js.map +1 -0
- package/dist/src/types/http-transport.d.ts +45 -0
- package/dist/src/types/http-transport.d.ts.map +1 -0
- package/dist/src/types/http-transport.js +8 -0
- package/dist/src/types/http-transport.js.map +1 -0
- package/dist/src/types/openapi.d.ts +50 -0
- package/dist/src/types/openapi.d.ts.map +1 -0
- package/dist/src/types/openapi.js +9 -0
- package/dist/src/types/openapi.js.map +1 -0
- package/dist/src/types/profile.d.ts +80 -0
- package/dist/src/types/profile.d.ts.map +1 -0
- package/dist/src/types/profile.js +9 -0
- package/dist/src/types/profile.js.map +1 -0
- package/dist/src/validation-utils.d.ts +15 -0
- package/dist/src/validation-utils.d.ts.map +1 -0
- package/dist/src/validation-utils.js +25 -0
- package/dist/src/validation-utils.js.map +1 -0
- package/dist/testing/fixtures.d.ts +186 -0
- package/dist/testing/fixtures.d.ts.map +1 -0
- package/dist/testing/fixtures.js +135 -0
- package/dist/testing/fixtures.js.map +1 -0
- package/dist/testing/http-integration.test.d.ts +7 -0
- package/dist/testing/http-integration.test.d.ts.map +1 -0
- package/dist/testing/http-integration.test.js +383 -0
- package/dist/testing/http-integration.test.js.map +1 -0
- package/dist/testing/http-multiuser.test.d.ts +10 -0
- package/dist/testing/http-multiuser.test.d.ts.map +1 -0
- package/dist/testing/http-multiuser.test.js +255 -0
- package/dist/testing/http-multiuser.test.js.map +1 -0
- package/dist/testing/integration.test.d.ts +8 -0
- package/dist/testing/integration.test.d.ts.map +1 -0
- package/dist/testing/integration.test.js +247 -0
- package/dist/testing/integration.test.js.map +1 -0
- package/dist/testing/mock-gitlab-server.d.ts +34 -0
- package/dist/testing/mock-gitlab-server.d.ts.map +1 -0
- package/dist/testing/mock-gitlab-server.js +224 -0
- package/dist/testing/mock-gitlab-server.js.map +1 -0
- package/dist/testing/test-types.d.ts +59 -0
- package/dist/testing/test-types.d.ts.map +1 -0
- package/dist/testing/test-types.js +7 -0
- package/dist/testing/test-types.js.map +1 -0
- package/dist/tool-generator.d.ts +43 -0
- package/dist/tool-generator.d.ts.map +1 -0
- package/dist/tool-generator.js +123 -0
- package/dist/tool-generator.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/http-transport.d.ts +39 -0
- package/dist/types/http-transport.d.ts.map +1 -0
- package/dist/types/http-transport.js +8 -0
- package/dist/types/http-transport.js.map +1 -0
- package/dist/types/openapi.d.ts +50 -0
- package/dist/types/openapi.d.ts.map +1 -0
- package/dist/types/openapi.js +9 -0
- package/dist/types/openapi.js.map +1 -0
- package/dist/types/profile.d.ts +76 -0
- package/dist/types/profile.d.ts.map +1 -0
- package/dist/types/profile.js +9 -0
- package/dist/types/profile.js.map +1 -0
- package/package.json +84 -0
- 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"}
|