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
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI specification parser and indexer
|
|
3
|
+
*
|
|
4
|
+
* Why indexing: Large OpenAPI specs (GitLab has ~200 operations) need fast lookup.
|
|
5
|
+
* Pre-indexing by operationId and path avoids linear search on every tool call.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'fs/promises';
|
|
8
|
+
import { parse as parseYaml } from 'yaml';
|
|
9
|
+
import { ConfigurationError } from './errors.js';
|
|
10
|
+
export class OpenAPIParser {
|
|
11
|
+
spec;
|
|
12
|
+
index;
|
|
13
|
+
async load(specPath) {
|
|
14
|
+
const content = await fs.readFile(specPath, 'utf-8');
|
|
15
|
+
// Parse YAML or JSON based on extension
|
|
16
|
+
if (specPath.endsWith('.yaml') || specPath.endsWith('.yml')) {
|
|
17
|
+
this.spec = parseYaml(content);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
this.spec = JSON.parse(content);
|
|
21
|
+
}
|
|
22
|
+
this.buildIndex();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Build search index from OpenAPI spec
|
|
26
|
+
*
|
|
27
|
+
* Why upfront: Trading startup time for runtime performance. Index creation
|
|
28
|
+
* happens once; lookups happen on every tool call.
|
|
29
|
+
*/
|
|
30
|
+
buildIndex() {
|
|
31
|
+
if (!this.spec)
|
|
32
|
+
throw new ConfigurationError('OpenAPI spec not loaded. Call loadSpec() first.');
|
|
33
|
+
const operations = new Map();
|
|
34
|
+
const paths = new Map();
|
|
35
|
+
for (const [path, pathItem] of Object.entries(this.spec.paths || {})) {
|
|
36
|
+
if (!pathItem)
|
|
37
|
+
continue;
|
|
38
|
+
const pathOperations = {};
|
|
39
|
+
for (const method of ['get', 'post', 'put', 'patch', 'delete', 'head', 'options']) {
|
|
40
|
+
const operation = pathItem[method];
|
|
41
|
+
if (!operation)
|
|
42
|
+
continue;
|
|
43
|
+
const operationInfo = this.extractOperationInfo(path, method, operation);
|
|
44
|
+
if (operationInfo.operationId) {
|
|
45
|
+
operations.set(operationInfo.operationId, operationInfo);
|
|
46
|
+
}
|
|
47
|
+
pathOperations[method] = operationInfo;
|
|
48
|
+
}
|
|
49
|
+
paths.set(path, { path, operations: pathOperations });
|
|
50
|
+
}
|
|
51
|
+
this.index = {
|
|
52
|
+
spec: this.spec,
|
|
53
|
+
operations,
|
|
54
|
+
paths,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
extractOperationInfo(path, method, operation) {
|
|
58
|
+
return {
|
|
59
|
+
operationId: operation.operationId || `${method}_${path}`,
|
|
60
|
+
method: method.toUpperCase(),
|
|
61
|
+
path,
|
|
62
|
+
summary: operation.summary,
|
|
63
|
+
description: operation.description,
|
|
64
|
+
parameters: this.extractParameters(operation),
|
|
65
|
+
requestBody: this.extractRequestBody(operation),
|
|
66
|
+
tags: operation.tags,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
extractParameters(operation) {
|
|
70
|
+
if (!operation.parameters)
|
|
71
|
+
return [];
|
|
72
|
+
return operation.parameters
|
|
73
|
+
.map(p => {
|
|
74
|
+
// Resolve $ref to parameter definition
|
|
75
|
+
if ('$ref' in p) {
|
|
76
|
+
return this.resolveParameter(p.$ref);
|
|
77
|
+
}
|
|
78
|
+
return p;
|
|
79
|
+
})
|
|
80
|
+
.filter((p) => p !== null)
|
|
81
|
+
.map(param => ({
|
|
82
|
+
name: param.name,
|
|
83
|
+
in: param.in,
|
|
84
|
+
required: param.required ?? false,
|
|
85
|
+
schema: this.extractSchema(param.schema),
|
|
86
|
+
description: param.description,
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Resolve $ref to parameter definition
|
|
91
|
+
*
|
|
92
|
+
* Why: GitLab spec uses shared parameter definitions (e.g., ProjectIdOrPath).
|
|
93
|
+
* Need to resolve these refs to get actual parameter details.
|
|
94
|
+
*/
|
|
95
|
+
resolveParameter(ref) {
|
|
96
|
+
if (!this.spec)
|
|
97
|
+
return null;
|
|
98
|
+
// Extract ref path: #/components/parameters/ProjectIdOrPath => ProjectIdOrPath
|
|
99
|
+
const refName = ref.split('/').pop();
|
|
100
|
+
if (!refName)
|
|
101
|
+
return null;
|
|
102
|
+
const param = this.spec.components?.parameters?.[refName];
|
|
103
|
+
if (!param || '$ref' in param)
|
|
104
|
+
return null;
|
|
105
|
+
return param;
|
|
106
|
+
}
|
|
107
|
+
extractRequestBody(operation) {
|
|
108
|
+
if (!operation.requestBody || '$ref' in operation.requestBody)
|
|
109
|
+
return undefined;
|
|
110
|
+
const body = operation.requestBody;
|
|
111
|
+
const content = {};
|
|
112
|
+
for (const [mediaType, mediaTypeObj] of Object.entries(body.content || {})) {
|
|
113
|
+
if (mediaTypeObj.schema) {
|
|
114
|
+
content[mediaType] = {
|
|
115
|
+
schema: this.extractSchema(mediaTypeObj.schema),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
required: body.required ?? false,
|
|
121
|
+
content,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
extractSchema(schema) {
|
|
125
|
+
if (!schema)
|
|
126
|
+
return {};
|
|
127
|
+
if ('$ref' in schema)
|
|
128
|
+
return { type: 'object' }; // Simplified: don't resolve refs
|
|
129
|
+
const result = {
|
|
130
|
+
type: schema.type,
|
|
131
|
+
format: schema.format,
|
|
132
|
+
enum: schema.enum,
|
|
133
|
+
default: schema.default,
|
|
134
|
+
};
|
|
135
|
+
if (schema.type === 'array' && schema.items && !('$ref' in schema.items)) {
|
|
136
|
+
result.items = this.extractSchema(schema.items);
|
|
137
|
+
}
|
|
138
|
+
if (schema.type === 'object' && schema.properties) {
|
|
139
|
+
result.properties = {};
|
|
140
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
141
|
+
result.properties[key] = this.extractSchema(propSchema);
|
|
142
|
+
}
|
|
143
|
+
result.required = schema.required;
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
getOperation(operationId) {
|
|
148
|
+
return this.index?.operations.get(operationId);
|
|
149
|
+
}
|
|
150
|
+
getPath(path) {
|
|
151
|
+
return this.index?.paths.get(path);
|
|
152
|
+
}
|
|
153
|
+
getBaseUrl() {
|
|
154
|
+
const servers = this.spec?.servers;
|
|
155
|
+
return servers?.[0]?.url || '';
|
|
156
|
+
}
|
|
157
|
+
getAllOperations() {
|
|
158
|
+
return Array.from(this.index?.operations.values() || []);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get first security scheme from OpenAPI spec
|
|
162
|
+
*
|
|
163
|
+
* Why: When no profile is provided, we need to infer auth configuration from OpenAPI spec.
|
|
164
|
+
* Returns the first security scheme defined in spec.security or components.securitySchemes.
|
|
165
|
+
*
|
|
166
|
+
* Returns undefined if no security is defined (public API).
|
|
167
|
+
*/
|
|
168
|
+
getSecurityScheme() {
|
|
169
|
+
if (!this.spec)
|
|
170
|
+
return undefined;
|
|
171
|
+
// Check if security is required at spec level
|
|
172
|
+
const globalSecurity = this.spec.security;
|
|
173
|
+
if (!globalSecurity || globalSecurity.length === 0) {
|
|
174
|
+
return undefined; // No security required
|
|
175
|
+
}
|
|
176
|
+
// Get first security requirement
|
|
177
|
+
const firstSecurityReq = globalSecurity[0];
|
|
178
|
+
const securitySchemeName = Object.keys(firstSecurityReq)[0];
|
|
179
|
+
if (!securitySchemeName)
|
|
180
|
+
return undefined;
|
|
181
|
+
// Resolve security scheme definition
|
|
182
|
+
const securitySchemes = this.spec.components?.securitySchemes;
|
|
183
|
+
if (!securitySchemes)
|
|
184
|
+
return undefined;
|
|
185
|
+
const scheme = securitySchemes[securitySchemeName];
|
|
186
|
+
if (!scheme || '$ref' in scheme)
|
|
187
|
+
return undefined;
|
|
188
|
+
// Map OpenAPI security scheme to our auth config format
|
|
189
|
+
const schemeObj = scheme;
|
|
190
|
+
switch (schemeObj.type) {
|
|
191
|
+
case 'http':
|
|
192
|
+
// http: bearer, basic, etc.
|
|
193
|
+
return {
|
|
194
|
+
type: schemeObj.scheme || 'bearer',
|
|
195
|
+
scheme: schemeObj.scheme,
|
|
196
|
+
};
|
|
197
|
+
case 'apiKey':
|
|
198
|
+
// apiKey: in header, query, or cookie
|
|
199
|
+
return {
|
|
200
|
+
type: 'apiKey',
|
|
201
|
+
name: schemeObj.name,
|
|
202
|
+
in: schemeObj.in,
|
|
203
|
+
};
|
|
204
|
+
case 'oauth2':
|
|
205
|
+
case 'openIdConnect':
|
|
206
|
+
// OAuth2/OIDC typically use bearer tokens
|
|
207
|
+
return {
|
|
208
|
+
type: 'bearer',
|
|
209
|
+
scheme: 'bearer',
|
|
210
|
+
};
|
|
211
|
+
default:
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=openapi-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi-parser.js","sourceRoot":"","sources":["../../src/openapi-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile configuration loader and validator
|
|
3
|
+
*
|
|
4
|
+
* Why validation: Profile config comes from user files. Invalid config would
|
|
5
|
+
* cause runtime errors. Validate upfront with clear error messages.
|
|
6
|
+
*
|
|
7
|
+
* ✅ Schemas are now auto-generated from TypeScript types!
|
|
8
|
+
* When adding fields to src/types/profile.ts:
|
|
9
|
+
* 1. Update TypeScript interface (compile-time checking)
|
|
10
|
+
* 2. Run `npm run generate-schemas` (auto-generates JSON + Zod schemas)
|
|
11
|
+
* 3. That's it! No manual sync needed.
|
|
12
|
+
*
|
|
13
|
+
* See IMPLEMENTATION.md for details.
|
|
14
|
+
*/
|
|
15
|
+
import type { Profile } from './types/profile.js';
|
|
16
|
+
import type { OpenAPIParser } from './openapi-parser.js';
|
|
17
|
+
export declare class ProfileLoader {
|
|
18
|
+
load(profilePath: string): Promise<Profile>;
|
|
19
|
+
/**
|
|
20
|
+
* Validate semantic rules beyond schema
|
|
21
|
+
*
|
|
22
|
+
* Why separate: Some rules can't be expressed in JSON Schema (e.g.,
|
|
23
|
+
* "if composite=true then steps must exist"). Fail fast with clear messages.
|
|
24
|
+
*/
|
|
25
|
+
private validateLogic;
|
|
26
|
+
/**
|
|
27
|
+
* Generate helpful suggestions for invalid operation keys
|
|
28
|
+
*/
|
|
29
|
+
private generateOperationKeySuggestions;
|
|
30
|
+
/**
|
|
31
|
+
* Validate composite steps form a DAG (no circular dependencies)
|
|
32
|
+
*
|
|
33
|
+
* Why: Circular dependencies would cause infinite loops or deadlocks.
|
|
34
|
+
* We use DFS with color-coding to detect cycles.
|
|
35
|
+
*/
|
|
36
|
+
private validateCompositeStepsDAG;
|
|
37
|
+
/**
|
|
38
|
+
* Create a default profile with auto-generated tools from OpenAPI spec
|
|
39
|
+
*
|
|
40
|
+
* Why: Allows running server without profile for quick exploration.
|
|
41
|
+
* Generates simple pass-through tools for all operations.
|
|
42
|
+
*
|
|
43
|
+
* Auth Strategy:
|
|
44
|
+
* 1. Parse security scheme from OpenAPI spec
|
|
45
|
+
* 2. If found, generate auth interceptor
|
|
46
|
+
* 3. Fallback to bearer token from API_TOKEN env var
|
|
47
|
+
*/
|
|
48
|
+
static createDefaultProfile(profileName: string, parser: OpenAPIParser): Profile;
|
|
49
|
+
/**
|
|
50
|
+
* Generate auth interceptor from OpenAPI security scheme
|
|
51
|
+
*
|
|
52
|
+
* Strategy:
|
|
53
|
+
* 1. Parse security scheme from OpenAPI spec
|
|
54
|
+
* 2. If not found, check for force auth override via env vars
|
|
55
|
+
* 3. Map to profile auth interceptor format
|
|
56
|
+
* 4. Use env var name from AUTH_ENV_VAR or default to API_TOKEN
|
|
57
|
+
*
|
|
58
|
+
* Returns empty object if no security scheme found (public API) and no force override
|
|
59
|
+
*/
|
|
60
|
+
private static generateAuthInterceptor;
|
|
61
|
+
/**
|
|
62
|
+
* Generate a simple tool from an OpenAPI operation
|
|
63
|
+
*
|
|
64
|
+
* Creates a tool with parameters based on the operation's path/query/header parameters
|
|
65
|
+
* and request body. Uses operationId as tool name and summary/description for tool description.
|
|
66
|
+
*/
|
|
67
|
+
private static generateToolFromOperation;
|
|
68
|
+
/**
|
|
69
|
+
* Map OpenAPI schema to parameter type
|
|
70
|
+
*/
|
|
71
|
+
private static mapOpenAPISchemaToParameterType;
|
|
72
|
+
/**
|
|
73
|
+
* Recursively flatten schema properties to parameters
|
|
74
|
+
*/
|
|
75
|
+
private static flattenSchemaToParameters;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=profile-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-loader.d.ts","sourceRoot":"","sources":["../../src/profile-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAiCzD,qBAAa,aAAa;IAClB,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYjD;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IA6FrB;;OAEG;IACH,OAAO,CAAC,+BAA+B;IAsCvC;;;;;OAKG;IACH,OAAO,CAAC,yBAAyB;IAsEjC;;;;;;;;;;OAUG;IACH,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO;IA6ChF;;;;;;;;;;OAUG;IACH,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAqHtC;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,yBAAyB;IA8DxC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,+BAA+B;IAmB9C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,yBAAyB;CAgBzC"}
|