@frontmcp/adapters 0.3.1 → 0.4.1

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.
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Test fixtures and mocks for OpenAPI adapter tests
3
+ */
4
+ import type { OpenAPIV3 } from 'openapi-types';
5
+ /**
6
+ * Basic OpenAPI spec without security
7
+ */
8
+ export declare const basicOpenApiSpec: OpenAPIV3.Document;
9
+ /**
10
+ * OpenAPI spec with Bearer authentication
11
+ */
12
+ export declare const bearerAuthSpec: OpenAPIV3.Document;
13
+ /**
14
+ * OpenAPI spec with multiple security schemes
15
+ */
16
+ export declare const multiAuthSpec: OpenAPIV3.Document;
17
+ /**
18
+ * Mock AuthInfo for testing
19
+ */
20
+ export declare const mockAuthInfo: {
21
+ token: string;
22
+ user: {
23
+ id: string;
24
+ email: string;
25
+ githubToken: string;
26
+ slackToken: string;
27
+ apiKey: string;
28
+ };
29
+ };
30
+ /**
31
+ * Mock context for tool execution
32
+ */
33
+ export declare const mockContext: {
34
+ authInfo: {
35
+ token: string;
36
+ user: {
37
+ id: string;
38
+ email: string;
39
+ githubToken: string;
40
+ slackToken: string;
41
+ apiKey: string;
42
+ };
43
+ };
44
+ };
45
+ /**
46
+ * Mock fetch responses
47
+ */
48
+ export declare const mockFetchSuccess: (data: unknown) => Promise<Response>;
49
+ export declare const mockFetchError: (status: number, message: string) => Promise<Response>;
50
+ /**
51
+ * Spy on console methods for testing logs
52
+ */
53
+ export declare const spyOnConsole: () => {
54
+ restore: () => void;
55
+ log: jest.SpyInstance<void, [message?: any, ...optionalParams: any[]], any>;
56
+ error: jest.SpyInstance<void, [message?: any, ...optionalParams: any[]], any>;
57
+ warn: jest.SpyInstance<void, [message?: any, ...optionalParams: any[]], any>;
58
+ };
@@ -0,0 +1,286 @@
1
+ "use strict";
2
+ /// <reference types="jest" />
3
+ /**
4
+ * Test fixtures and mocks for OpenAPI adapter tests
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.spyOnConsole = exports.mockFetchError = exports.mockFetchSuccess = exports.mockContext = exports.mockAuthInfo = exports.multiAuthSpec = exports.bearerAuthSpec = exports.basicOpenApiSpec = void 0;
8
+ /**
9
+ * Basic OpenAPI spec without security
10
+ */
11
+ exports.basicOpenApiSpec = {
12
+ openapi: '3.0.0',
13
+ info: {
14
+ title: 'Test API',
15
+ version: '1.0.0',
16
+ },
17
+ paths: {
18
+ '/users/{id}': {
19
+ get: {
20
+ operationId: 'getUser',
21
+ summary: 'Get user by ID',
22
+ parameters: [
23
+ {
24
+ name: 'id',
25
+ in: 'path',
26
+ required: true,
27
+ schema: { type: 'string' },
28
+ },
29
+ ],
30
+ responses: {
31
+ '200': {
32
+ description: 'Success',
33
+ content: {
34
+ 'application/json': {
35
+ schema: {
36
+ type: 'object',
37
+ properties: {
38
+ id: { type: 'string' },
39
+ name: { type: 'string' },
40
+ },
41
+ },
42
+ },
43
+ },
44
+ },
45
+ },
46
+ },
47
+ post: {
48
+ operationId: 'createUser',
49
+ summary: 'Create a new user',
50
+ requestBody: {
51
+ required: true,
52
+ content: {
53
+ 'application/json': {
54
+ schema: {
55
+ type: 'object',
56
+ properties: {
57
+ name: { type: 'string' },
58
+ email: { type: 'string' },
59
+ },
60
+ required: ['name', 'email'],
61
+ },
62
+ },
63
+ },
64
+ },
65
+ responses: {
66
+ '201': {
67
+ description: 'Created',
68
+ content: {
69
+ 'application/json': {
70
+ schema: {
71
+ type: 'object',
72
+ properties: {
73
+ id: { type: 'string' },
74
+ name: { type: 'string' },
75
+ email: { type: 'string' },
76
+ },
77
+ },
78
+ },
79
+ },
80
+ },
81
+ },
82
+ },
83
+ },
84
+ },
85
+ };
86
+ /**
87
+ * OpenAPI spec with Bearer authentication
88
+ */
89
+ exports.bearerAuthSpec = {
90
+ openapi: '3.0.0',
91
+ info: {
92
+ title: 'Authenticated API',
93
+ version: '1.0.0',
94
+ },
95
+ components: {
96
+ securitySchemes: {
97
+ BearerAuth: {
98
+ type: 'http',
99
+ scheme: 'bearer',
100
+ bearerFormat: 'JWT',
101
+ },
102
+ },
103
+ },
104
+ security: [{ BearerAuth: [] }],
105
+ paths: {
106
+ '/protected': {
107
+ get: {
108
+ operationId: 'getProtected',
109
+ summary: 'Get protected resource',
110
+ responses: {
111
+ '200': {
112
+ description: 'Success',
113
+ content: {
114
+ 'application/json': {
115
+ schema: {
116
+ type: 'object',
117
+ properties: {
118
+ message: { type: 'string' },
119
+ },
120
+ },
121
+ },
122
+ },
123
+ },
124
+ },
125
+ },
126
+ },
127
+ },
128
+ };
129
+ /**
130
+ * OpenAPI spec with multiple security schemes
131
+ */
132
+ exports.multiAuthSpec = {
133
+ openapi: '3.0.0',
134
+ info: {
135
+ title: 'Multi-Auth API',
136
+ version: '1.0.0',
137
+ },
138
+ components: {
139
+ securitySchemes: {
140
+ GitHubAuth: {
141
+ type: 'http',
142
+ scheme: 'bearer',
143
+ description: 'GitHub OAuth token',
144
+ },
145
+ SlackAuth: {
146
+ type: 'http',
147
+ scheme: 'bearer',
148
+ description: 'Slack OAuth token',
149
+ },
150
+ ApiKeyAuth: {
151
+ type: 'apiKey',
152
+ in: 'header',
153
+ name: 'X-API-Key',
154
+ },
155
+ },
156
+ },
157
+ paths: {
158
+ '/github/repos': {
159
+ get: {
160
+ operationId: 'github_getRepos',
161
+ summary: 'Get GitHub repos',
162
+ security: [{ GitHubAuth: [] }],
163
+ responses: {
164
+ '200': {
165
+ description: 'Success',
166
+ content: {
167
+ 'application/json': {
168
+ schema: {
169
+ type: 'array',
170
+ items: {
171
+ type: 'object',
172
+ properties: {
173
+ name: { type: 'string' },
174
+ },
175
+ },
176
+ },
177
+ },
178
+ },
179
+ },
180
+ },
181
+ },
182
+ },
183
+ '/slack/messages': {
184
+ post: {
185
+ operationId: 'slack_postMessage',
186
+ summary: 'Post Slack message',
187
+ security: [{ SlackAuth: [] }],
188
+ requestBody: {
189
+ required: true,
190
+ content: {
191
+ 'application/json': {
192
+ schema: {
193
+ type: 'object',
194
+ properties: {
195
+ channel: { type: 'string' },
196
+ text: { type: 'string' },
197
+ },
198
+ required: ['channel', 'text'],
199
+ },
200
+ },
201
+ },
202
+ },
203
+ responses: {
204
+ '200': {
205
+ description: 'Success',
206
+ },
207
+ },
208
+ },
209
+ },
210
+ '/admin/settings': {
211
+ get: {
212
+ operationId: 'admin_getSettings',
213
+ summary: 'Get admin settings',
214
+ security: [{ ApiKeyAuth: [] }],
215
+ responses: {
216
+ '200': {
217
+ description: 'Success',
218
+ },
219
+ },
220
+ },
221
+ },
222
+ },
223
+ };
224
+ /**
225
+ * Mock AuthInfo for testing
226
+ */
227
+ exports.mockAuthInfo = {
228
+ token: 'mock-jwt-token',
229
+ user: {
230
+ id: 'user-123',
231
+ email: 'test@example.com',
232
+ githubToken: 'github-token-123',
233
+ slackToken: 'slack-token-456',
234
+ apiKey: 'api-key-789',
235
+ },
236
+ };
237
+ /**
238
+ * Mock context for tool execution
239
+ */
240
+ exports.mockContext = {
241
+ authInfo: exports.mockAuthInfo,
242
+ };
243
+ /**
244
+ * Mock fetch responses
245
+ */
246
+ const mockFetchSuccess = (data) => {
247
+ return Promise.resolve({
248
+ ok: true,
249
+ status: 200,
250
+ statusText: 'OK',
251
+ headers: new Headers({ 'content-type': 'application/json' }),
252
+ text: () => Promise.resolve(JSON.stringify(data)),
253
+ json: () => Promise.resolve(data),
254
+ });
255
+ };
256
+ exports.mockFetchSuccess = mockFetchSuccess;
257
+ const mockFetchError = (status, message) => {
258
+ return Promise.resolve({
259
+ ok: false,
260
+ status,
261
+ statusText: message,
262
+ headers: new Headers({ 'content-type': 'text/plain' }),
263
+ text: () => Promise.resolve(message),
264
+ });
265
+ };
266
+ exports.mockFetchError = mockFetchError;
267
+ /**
268
+ * Spy on console methods for testing logs
269
+ */
270
+ const spyOnConsole = () => {
271
+ const consoleSpy = {
272
+ log: jest.spyOn(console, 'log').mockImplementation(),
273
+ error: jest.spyOn(console, 'error').mockImplementation(),
274
+ warn: jest.spyOn(console, 'warn').mockImplementation(),
275
+ };
276
+ return {
277
+ ...consoleSpy,
278
+ restore: () => {
279
+ consoleSpy.log.mockRestore();
280
+ consoleSpy.error.mockRestore();
281
+ consoleSpy.warn.mockRestore();
282
+ },
283
+ };
284
+ };
285
+ exports.spyOnConsole = spyOnConsole;
286
+ //# sourceMappingURL=fixtures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../../../src/openapi/__tests__/fixtures.ts"],"names":[],"mappings":";AAAA,8BAA8B;AAC9B;;GAEG;;;AAGH;;GAEG;AACU,QAAA,gBAAgB,GAAuB;IAClD,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,OAAO;KACjB;IACD,KAAK,EAAE;QACL,aAAa,EAAE;YACb,GAAG,EAAE;gBACH,WAAW,EAAE,SAAS;gBACtB,OAAO,EAAE,gBAAgB;gBACzB,UAAU,EAAE;oBACV;wBACE,IAAI,EAAE,IAAI;wBACV,EAAE,EAAE,MAAM;wBACV,QAAQ,EAAE,IAAI;wBACd,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;qBAC3B;iBACF;gBACD,SAAS,EAAE;oBACT,KAAK,EAAE;wBACL,WAAW,EAAE,SAAS;wBACtB,OAAO,EAAE;4BACP,kBAAkB,EAAE;gCAClB,MAAM,EAAE;oCACN,IAAI,EAAE,QAAQ;oCACd,UAAU,EAAE;wCACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wCACtB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;qCACzB;iCACF;6BACF;yBACF;qBACF;iBACF;aACF;YACD,IAAI,EAAE;gBACJ,WAAW,EAAE,YAAY;gBACzB,OAAO,EAAE,mBAAmB;gBAC5B,WAAW,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE;wBACP,kBAAkB,EAAE;4BAClB,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,UAAU,EAAE;oCACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oCACxB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iCAC1B;gCACD,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;6BAC5B;yBACF;qBACF;iBACF;gBACD,SAAS,EAAE;oBACT,KAAK,EAAE;wBACL,WAAW,EAAE,SAAS;wBACtB,OAAO,EAAE;4BACP,kBAAkB,EAAE;gCAClB,MAAM,EAAE;oCACN,IAAI,EAAE,QAAQ;oCACd,UAAU,EAAE;wCACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wCACtB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wCACxB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;qCAC1B;iCACF;6BACF;yBACF;qBACF;iBACF;aACF;SACF;KACF;CACF,CAAC;AAEF;;GAEG;AACU,QAAA,cAAc,GAAuB;IAChD,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,mBAAmB;QAC1B,OAAO,EAAE,OAAO;KACjB;IACD,UAAU,EAAE;QACV,eAAe,EAAE;YACf,UAAU,EAAE;gBACV,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,QAAQ;gBAChB,YAAY,EAAE,KAAK;aACpB;SACF;KACF;IACD,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC9B,KAAK,EAAE;QACL,YAAY,EAAE;YACZ,GAAG,EAAE;gBACH,WAAW,EAAE,cAAc;gBAC3B,OAAO,EAAE,wBAAwB;gBACjC,SAAS,EAAE;oBACT,KAAK,EAAE;wBACL,WAAW,EAAE,SAAS;wBACtB,OAAO,EAAE;4BACP,kBAAkB,EAAE;gCAClB,MAAM,EAAE;oCACN,IAAI,EAAE,QAAQ;oCACd,UAAU,EAAE;wCACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;qCAC5B;iCACF;6BACF;yBACF;qBACF;iBACF;aACF;SACF;KACF;CACF,CAAC;AAEF;;GAEG;AACU,QAAA,aAAa,GAAuB;IAC/C,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,gBAAgB;QACvB,OAAO,EAAE,OAAO;KACjB;IACD,UAAU,EAAE;QACV,eAAe,EAAE;YACf,UAAU,EAAE;gBACV,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,QAAQ;gBAChB,WAAW,EAAE,oBAAoB;aAClC;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,QAAQ;gBAChB,WAAW,EAAE,mBAAmB;aACjC;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,EAAE,EAAE,QAAQ;gBACZ,IAAI,EAAE,WAAW;aAClB;SACF;KACF;IACD,KAAK,EAAE;QACL,eAAe,EAAE;YACf,GAAG,EAAE;gBACH,WAAW,EAAE,iBAAiB;gBAC9B,OAAO,EAAE,kBAAkB;gBAC3B,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;gBAC9B,SAAS,EAAE;oBACT,KAAK,EAAE;wBACL,WAAW,EAAE,SAAS;wBACtB,OAAO,EAAE;4BACP,kBAAkB,EAAE;gCAClB,MAAM,EAAE;oCACN,IAAI,EAAE,OAAO;oCACb,KAAK,EAAE;wCACL,IAAI,EAAE,QAAQ;wCACd,UAAU,EAAE;4CACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;yCACzB;qCACF;iCACF;6BACF;yBACF;qBACF;iBACF;aACF;SACF;QACD,iBAAiB,EAAE;YACjB,IAAI,EAAE;gBACJ,WAAW,EAAE,mBAAmB;gBAChC,OAAO,EAAE,oBAAoB;gBAC7B,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;gBAC7B,WAAW,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE;wBACP,kBAAkB,EAAE;4BAClB,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,UAAU,EAAE;oCACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oCAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iCACzB;gCACD,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;6BAC9B;yBACF;qBACF;iBACF;gBACD,SAAS,EAAE;oBACT,KAAK,EAAE;wBACL,WAAW,EAAE,SAAS;qBACvB;iBACF;aACF;SACF;QACD,iBAAiB,EAAE;YACjB,GAAG,EAAE;gBACH,WAAW,EAAE,mBAAmB;gBAChC,OAAO,EAAE,oBAAoB;gBAC7B,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;gBAC9B,SAAS,EAAE;oBACT,KAAK,EAAE;wBACL,WAAW,EAAE,SAAS;qBACvB;iBACF;aACF;SACF;KACF;CACF,CAAC;AAEF;;GAEG;AACU,QAAA,YAAY,GAAG;IAC1B,KAAK,EAAE,gBAAgB;IACvB,IAAI,EAAE;QACJ,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE,kBAAkB;QAC/B,UAAU,EAAE,iBAAiB;QAC7B,MAAM,EAAE,aAAa;KACtB;CACF,CAAC;AAEF;;GAEG;AACU,QAAA,WAAW,GAAG;IACzB,QAAQ,EAAE,oBAAY;CACvB,CAAC;AAEF;;GAEG;AACI,MAAM,gBAAgB,GAAG,CAAC,IAAa,EAAE,EAAE;IAChD,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,EAAE,EAAE,IAAI;QACR,MAAM,EAAE,GAAG;QACX,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,IAAI,OAAO,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QAC5D,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;KACtB,CAAC,CAAC;AACjB,CAAC,CAAC;AATW,QAAA,gBAAgB,oBAS3B;AAEK,MAAM,cAAc,GAAG,CAAC,MAAc,EAAE,OAAe,EAAE,EAAE;IAChE,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,EAAE,EAAE,KAAK;QACT,MAAM;QACN,UAAU,EAAE,OAAO;QACnB,OAAO,EAAE,IAAI,OAAO,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;QACtD,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;KACzB,CAAC,CAAC;AACjB,CAAC,CAAC;AARW,QAAA,cAAc,kBAQzB;AAEF;;GAEG;AACI,MAAM,YAAY,GAAG,GAAG,EAAE;IAC/B,MAAM,UAAU,GAAG;QACjB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,EAAE;QACpD,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,EAAE;QACxD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,kBAAkB,EAAE;KACvD,CAAC;IAEF,OAAO;QACL,GAAG,UAAU;QACb,OAAO,EAAE,GAAG,EAAE;YACZ,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YAC7B,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAC/B,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAChC,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAfW,QAAA,YAAY,gBAevB","sourcesContent":["/// <reference types=\"jest\" />\n/**\n * Test fixtures and mocks for OpenAPI adapter tests\n */\n\nimport type { OpenAPIV3 } from 'openapi-types';\n/**\n * Basic OpenAPI spec without security\n */\nexport const basicOpenApiSpec: OpenAPIV3.Document = {\n openapi: '3.0.0',\n info: {\n title: 'Test API',\n version: '1.0.0',\n },\n paths: {\n '/users/{id}': {\n get: {\n operationId: 'getUser',\n summary: 'Get user by ID',\n parameters: [\n {\n name: 'id',\n in: 'path',\n required: true,\n schema: { type: 'string' },\n },\n ],\n responses: {\n '200': {\n description: 'Success',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n name: { type: 'string' },\n },\n },\n },\n },\n },\n },\n },\n post: {\n operationId: 'createUser',\n summary: 'Create a new user',\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n email: { type: 'string' },\n },\n required: ['name', 'email'],\n },\n },\n },\n },\n responses: {\n '201': {\n description: 'Created',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n name: { type: 'string' },\n email: { type: 'string' },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n};\n\n/**\n * OpenAPI spec with Bearer authentication\n */\nexport const bearerAuthSpec: OpenAPIV3.Document = {\n openapi: '3.0.0',\n info: {\n title: 'Authenticated API',\n version: '1.0.0',\n },\n components: {\n securitySchemes: {\n BearerAuth: {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n },\n },\n },\n security: [{ BearerAuth: [] }],\n paths: {\n '/protected': {\n get: {\n operationId: 'getProtected',\n summary: 'Get protected resource',\n responses: {\n '200': {\n description: 'Success',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n message: { type: 'string' },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n};\n\n/**\n * OpenAPI spec with multiple security schemes\n */\nexport const multiAuthSpec: OpenAPIV3.Document = {\n openapi: '3.0.0',\n info: {\n title: 'Multi-Auth API',\n version: '1.0.0',\n },\n components: {\n securitySchemes: {\n GitHubAuth: {\n type: 'http',\n scheme: 'bearer',\n description: 'GitHub OAuth token',\n },\n SlackAuth: {\n type: 'http',\n scheme: 'bearer',\n description: 'Slack OAuth token',\n },\n ApiKeyAuth: {\n type: 'apiKey',\n in: 'header',\n name: 'X-API-Key',\n },\n },\n },\n paths: {\n '/github/repos': {\n get: {\n operationId: 'github_getRepos',\n summary: 'Get GitHub repos',\n security: [{ GitHubAuth: [] }],\n responses: {\n '200': {\n description: 'Success',\n content: {\n 'application/json': {\n schema: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n '/slack/messages': {\n post: {\n operationId: 'slack_postMessage',\n summary: 'Post Slack message',\n security: [{ SlackAuth: [] }],\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n channel: { type: 'string' },\n text: { type: 'string' },\n },\n required: ['channel', 'text'],\n },\n },\n },\n },\n responses: {\n '200': {\n description: 'Success',\n },\n },\n },\n },\n '/admin/settings': {\n get: {\n operationId: 'admin_getSettings',\n summary: 'Get admin settings',\n security: [{ ApiKeyAuth: [] }],\n responses: {\n '200': {\n description: 'Success',\n },\n },\n },\n },\n },\n};\n\n/**\n * Mock AuthInfo for testing\n */\nexport const mockAuthInfo = {\n token: 'mock-jwt-token',\n user: {\n id: 'user-123',\n email: 'test@example.com',\n githubToken: 'github-token-123',\n slackToken: 'slack-token-456',\n apiKey: 'api-key-789',\n },\n};\n\n/**\n * Mock context for tool execution\n */\nexport const mockContext = {\n authInfo: mockAuthInfo,\n};\n\n/**\n * Mock fetch responses\n */\nexport const mockFetchSuccess = (data: unknown) => {\n return Promise.resolve({\n ok: true,\n status: 200,\n statusText: 'OK',\n headers: new Headers({ 'content-type': 'application/json' }),\n text: () => Promise.resolve(JSON.stringify(data)),\n json: () => Promise.resolve(data),\n } as Response);\n};\n\nexport const mockFetchError = (status: number, message: string) => {\n return Promise.resolve({\n ok: false,\n status,\n statusText: message,\n headers: new Headers({ 'content-type': 'text/plain' }),\n text: () => Promise.resolve(message),\n } as Response);\n};\n\n/**\n * Spy on console methods for testing logs\n */\nexport const spyOnConsole = () => {\n const consoleSpy = {\n log: jest.spyOn(console, 'log').mockImplementation(),\n error: jest.spyOn(console, 'error').mockImplementation(),\n warn: jest.spyOn(console, 'warn').mockImplementation(),\n };\n\n return {\n ...consoleSpy,\n restore: () => {\n consoleSpy.log.mockRestore();\n consoleSpy.error.mockRestore();\n consoleSpy.warn.mockRestore();\n },\n };\n};\n"]}
@@ -1,8 +1,13 @@
1
1
  import { DynamicAdapter, FrontMcpAdapterResponse } from '@frontmcp/sdk';
2
2
  import { OpenApiAdapterOptions } from './openapi.types';
3
3
  export default class OpenapiAdapter extends DynamicAdapter<OpenApiAdapterOptions> {
4
+ private generator?;
4
5
  options: OpenApiAdapterOptions;
5
6
  constructor(options: OpenApiAdapterOptions);
6
7
  fetch(): Promise<FrontMcpAdapterResponse>;
7
- private parseTools;
8
+ /**
9
+ * Initialize the OpenAPI tool generator from URL or spec
10
+ * @private
11
+ */
12
+ private initializeGenerator;
8
13
  }
@@ -2,46 +2,97 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const sdk_1 = require("@frontmcp/sdk");
5
- const openapi_mcp_generator_1 = require("openapi-mcp-generator");
5
+ const mcp_from_openapi_1 = require("mcp-from-openapi");
6
6
  const openapi_tool_1 = require("./openapi.tool");
7
+ const openapi_security_1 = require("./openapi.security");
7
8
  let OpenapiAdapter = class OpenapiAdapter extends sdk_1.DynamicAdapter {
8
9
  constructor(options) {
9
10
  super();
10
11
  this.options = options;
11
12
  }
12
13
  async fetch() {
13
- let urlOrSpec = '';
14
+ // Lazy load: Initialize generator on first fetch if not already initialized
15
+ if (!this.generator) {
16
+ this.generator = await this.initializeGenerator();
17
+ }
18
+ // Generate tools from OpenAPI spec
19
+ const openapiTools = await this.generator.generateTools({
20
+ includeOperations: this.options.generateOptions?.includeOperations,
21
+ excludeOperations: this.options.generateOptions?.excludeOperations,
22
+ filterFn: this.options.generateOptions?.filterFn,
23
+ namingStrategy: this.options.generateOptions?.namingStrategy,
24
+ preferredStatusCodes: this.options.generateOptions?.preferredStatusCodes ?? [200, 201, 202, 204],
25
+ includeDeprecated: this.options.generateOptions?.includeDeprecated ?? false,
26
+ includeAllResponses: this.options.generateOptions?.includeAllResponses ?? true,
27
+ includeSecurityInInput: this.options.generateOptions?.includeSecurityInInput ?? false,
28
+ maxSchemaDepth: this.options.generateOptions?.maxSchemaDepth,
29
+ includeExamples: this.options.generateOptions?.includeExamples,
30
+ });
31
+ // Validate security configuration
32
+ const validation = (0, openapi_security_1.validateSecurityConfiguration)(openapiTools, this.options);
33
+ // Log security information
34
+ console.log(`\n[OpenAPI Adapter: ${this.options.name}] Security Analysis:`);
35
+ console.log(` Security Risk Score: ${validation.securityRiskScore.toUpperCase()}`);
36
+ console.log(` Valid Configuration: ${validation.valid ? 'YES' : 'NO'}`);
37
+ if (validation.warnings.length > 0) {
38
+ console.log('\n Messages:');
39
+ validation.warnings.forEach((warning) => {
40
+ console.log(` - ${warning}`);
41
+ });
42
+ }
43
+ // Fail if configuration is invalid and security is required
44
+ if (!validation.valid) {
45
+ throw new Error(`[OpenAPI Adapter: ${this.options.name}] Invalid security configuration.\n` +
46
+ `Missing auth provider mappings for security schemes: ${validation.missingMappings.join(', ')}\n\n` +
47
+ `Your OpenAPI spec requires these security schemes, but no auth configuration was provided.\n\n` +
48
+ `Add one of the following to your adapter configuration:\n\n` +
49
+ `1. authProviderMapper (recommended):\n` +
50
+ ` authProviderMapper: {\n` +
51
+ validation.missingMappings.map((s) => ` '${s}': (authInfo) => authInfo.user?.${s.toLowerCase()}Token,`).join('\n') +
52
+ `\n }\n\n` +
53
+ `2. securityResolver:\n` +
54
+ ` securityResolver: (tool, authInfo) => ({ jwt: authInfo.token })\n\n` +
55
+ `3. staticAuth:\n` +
56
+ ` staticAuth: { jwt: process.env.API_TOKEN }\n\n` +
57
+ `4. Include security in input (NOT recommended for production):\n` +
58
+ ` generateOptions: { includeSecurityInInput: true }`);
59
+ }
60
+ console.log(''); // Empty line for readability
61
+ // Convert OpenAPI tools to FrontMCP tools
62
+ const tools = openapiTools.map((openapiTool) => (0, openapi_tool_1.createOpenApiTool)(openapiTool, this.options));
63
+ return { tools };
64
+ }
65
+ /**
66
+ * Initialize the OpenAPI tool generator from URL or spec
67
+ * @private
68
+ */
69
+ async initializeGenerator() {
14
70
  if ('url' in this.options) {
15
- urlOrSpec = this.options.url;
71
+ return await mcp_from_openapi_1.OpenAPIToolGenerator.fromURL(this.options.url, {
72
+ baseUrl: this.options.baseUrl,
73
+ validate: this.options.loadOptions?.validate ?? true,
74
+ dereference: this.options.loadOptions?.dereference ?? true,
75
+ headers: this.options.loadOptions?.headers,
76
+ timeout: this.options.loadOptions?.timeout,
77
+ followRedirects: this.options.loadOptions?.followRedirects,
78
+ });
16
79
  }
17
80
  else if ('spec' in this.options) {
18
- urlOrSpec = this.options.spec;
81
+ return await mcp_from_openapi_1.OpenAPIToolGenerator.fromJSON(this.options.spec, {
82
+ baseUrl: this.options.baseUrl,
83
+ validate: this.options.loadOptions?.validate ?? true,
84
+ dereference: this.options.loadOptions?.dereference ?? true,
85
+ });
19
86
  }
20
87
  else {
21
- throw new Error('Either url or spec must be provided');
88
+ throw new Error('Either url or spec must be provided in OpenApiAdapterOptions');
22
89
  }
23
- const { baseUrl, filterFn, defaultInclude, excludeOperationIds } = this.options;
24
- const openApiTools = await (0, openapi_mcp_generator_1.getToolsFromOpenApi)(urlOrSpec, {
25
- baseUrl,
26
- filterFn,
27
- defaultInclude,
28
- excludeOperationIds,
29
- dereference: false,
30
- });
31
- return {
32
- tools: this.parseTools(openApiTools),
33
- };
34
- }
35
- parseTools(openApiTools) {
36
- return openApiTools.map(tool => {
37
- return (0, openapi_tool_1.createOpenApiTool)(tool, this.options);
38
- });
39
90
  }
40
91
  };
41
92
  OpenapiAdapter = tslib_1.__decorate([
42
93
  (0, sdk_1.Adapter)({
43
94
  name: 'openapi',
44
- description: 'OpenAPI adapter that plugin for expense-mcp',
95
+ description: 'OpenAPI adapter for FrontMCP - Automatically generates MCP tools from OpenAPI specifications',
45
96
  }),
46
97
  tslib_1.__metadata("design:paramtypes", [Object])
47
98
  ], OpenapiAdapter);
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.adapter.js","sourceRoot":"","sources":["../../../src/openapi/openapi.adapter.ts"],"names":[],"mappings":";;;AAAA,uCAIuB;AAEvB,iEAA6E;AAC7E,iDAAiD;AAOlC,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,oBAAqC;IAG/E,YAAY,OAA8B;QACxC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAGD,KAAK,CAAC,KAAK;QACT,IAAI,SAAS,GAAgC,EAAE,CAAA;QAC/C,IAAI,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1B,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;QAC/B,CAAC;aAAM,IAAI,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,EAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,mBAAmB,EAAC,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9E,MAAM,YAAY,GAAG,MAAM,IAAA,2CAAmB,EAAC,SAAS,EAAE;YACxD,OAAO;YACP,QAAQ;YACR,cAAc;YACd,mBAAmB;YACnB,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QAEH,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;SACrC,CAAC;IACJ,CAAC;IAEO,UAAU,CAAC,YAAiC;QAClD,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YAC7B,OAAO,IAAA,gCAAiB,EAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AArCoB,cAAc;IAJlC,IAAA,aAAO,EAAC;QACP,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,8CAA8C;KAC5D,CAAC;;GACmB,cAAc,CAqClC;kBArCoB,cAAc","sourcesContent":["import {\n Adapter,\n DynamicAdapter,\n FrontMcpAdapterResponse,\n} from '@frontmcp/sdk';\nimport {OpenApiAdapterOptions} from './openapi.types';\nimport {getToolsFromOpenApi, McpToolDefinition} from 'openapi-mcp-generator';\nimport {createOpenApiTool} from \"./openapi.tool\";\nimport {OpenAPIV3} from \"openapi-types\";\n\n@Adapter({\n name: 'openapi',\n description: 'OpenAPI adapter that plugin for expense-mcp',\n})\nexport default class OpenapiAdapter extends DynamicAdapter<OpenApiAdapterOptions> {\n options: OpenApiAdapterOptions;\n\n constructor(options: OpenApiAdapterOptions) {\n super();\n this.options = options;\n }\n\n\n async fetch(): Promise<FrontMcpAdapterResponse> {\n let urlOrSpec: string | OpenAPIV3.Document = ''\n if ('url' in this.options) {\n urlOrSpec = this.options.url;\n } else if ('spec' in this.options) {\n urlOrSpec = this.options.spec;\n } else {\n throw new Error('Either url or spec must be provided');\n }\n const {baseUrl, filterFn, defaultInclude, excludeOperationIds} = this.options;\n const openApiTools = await getToolsFromOpenApi(urlOrSpec, {\n baseUrl,\n filterFn,\n defaultInclude,\n excludeOperationIds,\n dereference: false,\n });\n\n return {\n tools: this.parseTools(openApiTools),\n };\n }\n\n private parseTools(openApiTools: McpToolDefinition[]) {\n return openApiTools.map(tool => {\n return createOpenApiTool(tool, this.options);\n });\n }\n}"]}
1
+ {"version":3,"file":"openapi.adapter.js","sourceRoot":"","sources":["../../../src/openapi/openapi.adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { Adapter, DynamicAdapter, FrontMcpAdapterResponse } from '@frontmcp/sdk';\nimport { OpenApiAdapterOptions } from './openapi.types';\nimport { OpenAPIToolGenerator } from 'mcp-from-openapi';\nimport { createOpenApiTool } from './openapi.tool';\nimport { validateSecurityConfiguration } from './openapi.security';\n\n@Adapter({\n name: 'openapi',\n description: 'OpenAPI adapter for FrontMCP - Automatically generates MCP tools from OpenAPI specifications',\n})\nexport default class OpenapiAdapter extends DynamicAdapter<OpenApiAdapterOptions> {\n private generator?: OpenAPIToolGenerator;\n public options: OpenApiAdapterOptions;\n\n constructor(options: OpenApiAdapterOptions) {\n super();\n this.options = options;\n }\n\n async fetch(): Promise<FrontMcpAdapterResponse> {\n // Lazy load: Initialize generator on first fetch if not already initialized\n if (!this.generator) {\n this.generator = await this.initializeGenerator();\n }\n\n // Generate tools from OpenAPI spec\n const openapiTools = await this.generator.generateTools({\n includeOperations: this.options.generateOptions?.includeOperations,\n excludeOperations: this.options.generateOptions?.excludeOperations,\n filterFn: this.options.generateOptions?.filterFn,\n namingStrategy: this.options.generateOptions?.namingStrategy,\n preferredStatusCodes: this.options.generateOptions?.preferredStatusCodes ?? [200, 201, 202, 204],\n includeDeprecated: this.options.generateOptions?.includeDeprecated ?? false,\n includeAllResponses: this.options.generateOptions?.includeAllResponses ?? true,\n includeSecurityInInput: this.options.generateOptions?.includeSecurityInInput ?? false,\n maxSchemaDepth: this.options.generateOptions?.maxSchemaDepth,\n includeExamples: this.options.generateOptions?.includeExamples,\n });\n\n // Validate security configuration\n const validation = validateSecurityConfiguration(openapiTools, this.options);\n\n // Log security information\n console.log(`\\n[OpenAPI Adapter: ${this.options.name}] Security Analysis:`);\n console.log(` Security Risk Score: ${validation.securityRiskScore.toUpperCase()}`);\n console.log(` Valid Configuration: ${validation.valid ? 'YES' : 'NO'}`);\n\n if (validation.warnings.length > 0) {\n console.log('\\n Messages:');\n validation.warnings.forEach((warning) => {\n console.log(` - ${warning}`);\n });\n }\n\n // Fail if configuration is invalid and security is required\n if (!validation.valid) {\n throw new Error(\n `[OpenAPI Adapter: ${this.options.name}] Invalid security configuration.\\n` +\n `Missing auth provider mappings for security schemes: ${validation.missingMappings.join(', ')}\\n\\n` +\n `Your OpenAPI spec requires these security schemes, but no auth configuration was provided.\\n\\n` +\n `Add one of the following to your adapter configuration:\\n\\n` +\n `1. authProviderMapper (recommended):\\n` +\n ` authProviderMapper: {\\n` +\n validation.missingMappings.map((s) => ` '${s}': (authInfo) => authInfo.user?.${s.toLowerCase()}Token,`).join('\\n') +\n `\\n }\\n\\n` +\n `2. securityResolver:\\n` +\n ` securityResolver: (tool, authInfo) => ({ jwt: authInfo.token })\\n\\n` +\n `3. staticAuth:\\n` +\n ` staticAuth: { jwt: process.env.API_TOKEN }\\n\\n` +\n `4. Include security in input (NOT recommended for production):\\n` +\n ` generateOptions: { includeSecurityInInput: true }`\n );\n }\n\n console.log(''); // Empty line for readability\n\n // Convert OpenAPI tools to FrontMCP tools\n const tools = openapiTools.map((openapiTool) =>\n createOpenApiTool(openapiTool, this.options)\n );\n\n return { tools };\n }\n\n /**\n * Initialize the OpenAPI tool generator from URL or spec\n * @private\n */\n private async initializeGenerator(): Promise<OpenAPIToolGenerator> {\n if ('url' in this.options) {\n return await OpenAPIToolGenerator.fromURL(this.options.url, {\n baseUrl: this.options.baseUrl,\n validate: this.options.loadOptions?.validate ?? true,\n dereference: this.options.loadOptions?.dereference ?? true,\n headers: this.options.loadOptions?.headers,\n timeout: this.options.loadOptions?.timeout,\n followRedirects: this.options.loadOptions?.followRedirects,\n });\n } else if ('spec' in this.options) {\n return await OpenAPIToolGenerator.fromJSON(this.options.spec, {\n baseUrl: this.options.baseUrl,\n validate: this.options.loadOptions?.validate ?? true,\n dereference: this.options.loadOptions?.dereference ?? true,\n });\n } else {\n throw new Error('Either url or spec must be provided in OpenApiAdapterOptions');\n }\n }\n}\n"]}
@@ -0,0 +1,56 @@
1
+ import { type McpOpenAPITool, type SecurityContext } from 'mcp-from-openapi';
2
+ import type { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
3
+ import type { OpenApiAdapterOptions } from './openapi.types';
4
+ /**
5
+ * Security scheme information extracted from OpenAPI spec
6
+ */
7
+ export interface SecuritySchemeInfo {
8
+ name: string;
9
+ type: string;
10
+ scheme?: string;
11
+ in?: string;
12
+ description?: string;
13
+ }
14
+ /**
15
+ * Security validation result
16
+ */
17
+ export interface SecurityValidationResult {
18
+ valid: boolean;
19
+ missingMappings: string[];
20
+ warnings: string[];
21
+ securityRiskScore: 'low' | 'medium' | 'high';
22
+ }
23
+ /**
24
+ * Resolve security context from FrontMCP auth info with support for multiple auth providers
25
+ *
26
+ * @param tool - OpenAPI tool to resolve security for
27
+ * @param authInfo - FrontMCP authentication info
28
+ * @param options - Adapter options with auth configuration
29
+ * @returns Security context for resolver
30
+ */
31
+ export declare function createSecurityContextFromAuth(tool: McpOpenAPITool, authInfo: AuthInfo, options: Pick<OpenApiAdapterOptions, 'securityResolver' | 'authProviderMapper' | 'staticAuth'>): Promise<SecurityContext>;
32
+ /**
33
+ * Extract all security schemes used by a set of tools
34
+ *
35
+ * @param tools - OpenAPI tools
36
+ * @returns Set of security scheme names
37
+ */
38
+ export declare function extractSecuritySchemes(tools: McpOpenAPITool[]): Set<string>;
39
+ /**
40
+ * Validate security configuration against OpenAPI security requirements
41
+ *
42
+ * @param tools - OpenAPI tools
43
+ * @param options - Adapter options
44
+ * @returns Validation result with errors and warnings
45
+ */
46
+ export declare function validateSecurityConfiguration(tools: McpOpenAPITool[], options: Pick<OpenApiAdapterOptions, 'securityResolver' | 'authProviderMapper' | 'staticAuth' | 'generateOptions'>): SecurityValidationResult;
47
+ /**
48
+ * Resolve security for an OpenAPI tool with validation
49
+ *
50
+ * @param tool - OpenAPI tool with mapper
51
+ * @param authInfo - FrontMCP authentication info
52
+ * @param options - Adapter options with auth configuration
53
+ * @returns Resolved security (headers, query params, etc.)
54
+ * @throws Error if security cannot be resolved
55
+ */
56
+ export declare function resolveToolSecurity(tool: McpOpenAPITool, authInfo: AuthInfo, options: Pick<OpenApiAdapterOptions, 'securityResolver' | 'authProviderMapper' | 'staticAuth'>): Promise<import("mcp-from-openapi").ResolvedSecurity>;