mcp4openapi 0.1.0 → 0.2.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.
Files changed (152) hide show
  1. package/README.md +137 -95
  2. package/dist/scripts/validate-profile.js +3 -3
  3. package/dist/scripts/validate-profile.js.map +1 -1
  4. package/dist/src/composite-executor.d.ts +3 -1
  5. package/dist/src/composite-executor.d.ts.map +1 -1
  6. package/dist/src/composite-executor.js +16 -5
  7. package/dist/src/composite-executor.js.map +1 -1
  8. package/dist/src/constants.d.ts +49 -0
  9. package/dist/src/constants.d.ts.map +1 -1
  10. package/dist/src/constants.js +49 -0
  11. package/dist/src/constants.js.map +1 -1
  12. package/dist/src/errors.d.ts +6 -0
  13. package/dist/src/errors.d.ts.map +1 -1
  14. package/dist/src/errors.js +13 -0
  15. package/dist/src/errors.js.map +1 -1
  16. package/dist/src/generated-schemas.d.ts +832 -52
  17. package/dist/src/generated-schemas.d.ts.map +1 -1
  18. package/dist/src/generated-schemas.js +31 -8
  19. package/dist/src/generated-schemas.js.map +1 -1
  20. package/dist/src/http-client-factory.d.ts.map +1 -1
  21. package/dist/src/http-client-factory.js +14 -3
  22. package/dist/src/http-client-factory.js.map +1 -1
  23. package/dist/src/http-transport.d.ts +65 -0
  24. package/dist/src/http-transport.d.ts.map +1 -1
  25. package/dist/src/http-transport.js +921 -77
  26. package/dist/src/http-transport.js.map +1 -1
  27. package/dist/src/index.js +108 -8
  28. package/dist/src/index.js.map +1 -1
  29. package/dist/src/interceptors.d.ts +3 -0
  30. package/dist/src/interceptors.d.ts.map +1 -1
  31. package/dist/src/interceptors.js +76 -8
  32. package/dist/src/interceptors.js.map +1 -1
  33. package/dist/src/logger.d.ts +1 -1
  34. package/dist/src/logger.js +3 -3
  35. package/dist/src/logger.js.map +1 -1
  36. package/dist/src/mcp-server.d.ts +33 -0
  37. package/dist/src/mcp-server.d.ts.map +1 -1
  38. package/dist/src/mcp-server.js +263 -54
  39. package/dist/src/mcp-server.js.map +1 -1
  40. package/dist/src/oauth-provider.d.ts +92 -0
  41. package/dist/src/oauth-provider.d.ts.map +1 -0
  42. package/dist/src/oauth-provider.js +588 -0
  43. package/dist/src/oauth-provider.js.map +1 -0
  44. package/dist/src/openapi-parser.d.ts +16 -0
  45. package/dist/src/openapi-parser.d.ts.map +1 -1
  46. package/dist/src/openapi-parser.js +141 -6
  47. package/dist/src/openapi-parser.js.map +1 -1
  48. package/dist/src/profile-loader.d.ts +2 -2
  49. package/dist/src/profile-loader.d.ts.map +1 -1
  50. package/dist/src/profile-loader.js +45 -24
  51. package/dist/src/profile-loader.js.map +1 -1
  52. package/dist/src/testing/fixtures.d.ts +189 -0
  53. package/dist/src/testing/fixtures.d.ts.map +1 -1
  54. package/dist/src/testing/fixtures.js +144 -0
  55. package/dist/src/testing/fixtures.js.map +1 -1
  56. package/dist/src/testing/mock-gitlab-server.d.ts +26 -17
  57. package/dist/src/testing/mock-gitlab-server.d.ts.map +1 -1
  58. package/dist/src/testing/mock-gitlab-server.js +567 -304
  59. package/dist/src/testing/mock-gitlab-server.js.map +1 -1
  60. package/dist/src/types/http-transport.d.ts +16 -0
  61. package/dist/src/types/http-transport.d.ts.map +1 -1
  62. package/dist/src/types/openapi.d.ts +5 -0
  63. package/dist/src/types/openapi.d.ts.map +1 -1
  64. package/dist/src/types/profile.d.ts +112 -3
  65. package/dist/src/types/profile.d.ts.map +1 -1
  66. package/dist/src/validation-utils.d.ts +12 -0
  67. package/dist/src/validation-utils.d.ts.map +1 -1
  68. package/dist/src/validation-utils.js +17 -0
  69. package/dist/src/validation-utils.js.map +1 -1
  70. package/package.json +12 -3
  71. package/profile-schema.json +169 -7
  72. package/dist/composite-executor.d.ts +0 -65
  73. package/dist/composite-executor.d.ts.map +0 -1
  74. package/dist/composite-executor.js +0 -147
  75. package/dist/composite-executor.js.map +0 -1
  76. package/dist/constants.d.ts +0 -36
  77. package/dist/constants.d.ts.map +0 -1
  78. package/dist/constants.js +0 -36
  79. package/dist/constants.js.map +0 -1
  80. package/dist/http-transport.d.ts +0 -195
  81. package/dist/http-transport.d.ts.map +0 -1
  82. package/dist/http-transport.js +0 -760
  83. package/dist/http-transport.js.map +0 -1
  84. package/dist/interceptors.d.ts +0 -74
  85. package/dist/interceptors.d.ts.map +0 -1
  86. package/dist/interceptors.js +0 -220
  87. package/dist/interceptors.js.map +0 -1
  88. package/dist/logger.d.ts +0 -81
  89. package/dist/logger.d.ts.map +0 -1
  90. package/dist/logger.js +0 -264
  91. package/dist/logger.js.map +0 -1
  92. package/dist/mcp-server.d.ts +0 -110
  93. package/dist/mcp-server.d.ts.map +0 -1
  94. package/dist/mcp-server.js +0 -568
  95. package/dist/mcp-server.js.map +0 -1
  96. package/dist/metrics.d.ts +0 -86
  97. package/dist/metrics.d.ts.map +0 -1
  98. package/dist/metrics.js +0 -229
  99. package/dist/metrics.js.map +0 -1
  100. package/dist/openapi-parser.d.ts +0 -35
  101. package/dist/openapi-parser.d.ts.map +0 -1
  102. package/dist/openapi-parser.js +0 -160
  103. package/dist/openapi-parser.js.map +0 -1
  104. package/dist/profile-loader.d.ts +0 -25
  105. package/dist/profile-loader.d.ts.map +0 -1
  106. package/dist/profile-loader.js +0 -134
  107. package/dist/profile-loader.js.map +0 -1
  108. package/dist/schema-validator.d.ts +0 -32
  109. package/dist/schema-validator.d.ts.map +0 -1
  110. package/dist/schema-validator.js +0 -126
  111. package/dist/schema-validator.js.map +0 -1
  112. package/dist/testing/fixtures.d.ts +0 -186
  113. package/dist/testing/fixtures.d.ts.map +0 -1
  114. package/dist/testing/fixtures.js +0 -135
  115. package/dist/testing/fixtures.js.map +0 -1
  116. package/dist/testing/http-integration.test.d.ts +0 -7
  117. package/dist/testing/http-integration.test.d.ts.map +0 -1
  118. package/dist/testing/http-integration.test.js +0 -383
  119. package/dist/testing/http-integration.test.js.map +0 -1
  120. package/dist/testing/http-multiuser.test.d.ts +0 -10
  121. package/dist/testing/http-multiuser.test.d.ts.map +0 -1
  122. package/dist/testing/http-multiuser.test.js +0 -255
  123. package/dist/testing/http-multiuser.test.js.map +0 -1
  124. package/dist/testing/integration.test.d.ts +0 -8
  125. package/dist/testing/integration.test.d.ts.map +0 -1
  126. package/dist/testing/integration.test.js +0 -247
  127. package/dist/testing/integration.test.js.map +0 -1
  128. package/dist/testing/mock-gitlab-server.d.ts +0 -34
  129. package/dist/testing/mock-gitlab-server.d.ts.map +0 -1
  130. package/dist/testing/mock-gitlab-server.js +0 -224
  131. package/dist/testing/mock-gitlab-server.js.map +0 -1
  132. package/dist/testing/test-types.d.ts +0 -59
  133. package/dist/testing/test-types.d.ts.map +0 -1
  134. package/dist/testing/test-types.js +0 -7
  135. package/dist/testing/test-types.js.map +0 -1
  136. package/dist/tool-generator.d.ts +0 -43
  137. package/dist/tool-generator.d.ts.map +0 -1
  138. package/dist/tool-generator.js +0 -123
  139. package/dist/tool-generator.js.map +0 -1
  140. package/dist/tsconfig.tsbuildinfo +0 -1
  141. package/dist/types/http-transport.d.ts +0 -39
  142. package/dist/types/http-transport.d.ts.map +0 -1
  143. package/dist/types/http-transport.js +0 -8
  144. package/dist/types/http-transport.js.map +0 -1
  145. package/dist/types/openapi.d.ts +0 -50
  146. package/dist/types/openapi.d.ts.map +0 -1
  147. package/dist/types/openapi.js +0 -9
  148. package/dist/types/openapi.js.map +0 -1
  149. package/dist/types/profile.d.ts +0 -76
  150. package/dist/types/profile.d.ts.map +0 -1
  151. package/dist/types/profile.js +0 -9
  152. package/dist/types/profile.js.map +0 -1
@@ -1,383 +0,0 @@
1
- /**
2
- * Integration tests for HTTP transport with mocked message handler
3
- *
4
- * Tests HTTP protocol compliance without full MCPServer complexity
5
- */
6
- import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';
7
- import request from 'supertest';
8
- import { HttpTransport } from '../http-transport.js';
9
- import { ConsoleLogger } from '../logger.js';
10
- describe('HTTP Transport Integration', () => {
11
- let transport;
12
- let app;
13
- let sessionId;
14
- const mockTools = [
15
- {
16
- name: 'test_tool',
17
- description: 'Test tool',
18
- inputSchema: {
19
- type: 'object',
20
- properties: {
21
- message: { type: 'string' },
22
- },
23
- },
24
- },
25
- ];
26
- beforeAll(async () => {
27
- const config = {
28
- host: '127.0.0.1',
29
- port: 0,
30
- sessionTimeoutMs: 1800000,
31
- heartbeatEnabled: false,
32
- heartbeatIntervalMs: 30000,
33
- metricsEnabled: false,
34
- metricsPath: '/metrics',
35
- };
36
- const logger = new ConsoleLogger();
37
- transport = new HttpTransport(config, logger);
38
- app = transport.app;
39
- // Set up mock message handler
40
- transport.setMessageHandler(async (message) => {
41
- const msg = message;
42
- if (msg.method === 'initialize') {
43
- return {
44
- jsonrpc: '2.0',
45
- id: msg.id,
46
- result: {
47
- protocolVersion: '2025-03-26',
48
- serverInfo: {
49
- name: 'test-server',
50
- version: '1.0.0',
51
- },
52
- capabilities: {
53
- tools: {},
54
- },
55
- },
56
- };
57
- }
58
- if (msg.method === 'tools/list') {
59
- return {
60
- jsonrpc: '2.0',
61
- id: msg.id,
62
- result: {
63
- tools: mockTools,
64
- },
65
- };
66
- }
67
- if (msg.method === 'tools/call') {
68
- return {
69
- jsonrpc: '2.0',
70
- id: msg.id,
71
- result: {
72
- content: [
73
- {
74
- type: 'text',
75
- text: JSON.stringify({ success: true, message: 'Tool executed' }),
76
- },
77
- ],
78
- },
79
- };
80
- }
81
- // Batch request
82
- if (Array.isArray(msg)) {
83
- return msg.map((m) => {
84
- if (m.method === 'tools/list') {
85
- return {
86
- jsonrpc: '2.0',
87
- id: m.id,
88
- result: { tools: mockTools },
89
- };
90
- }
91
- return {
92
- jsonrpc: '2.0',
93
- id: m.id,
94
- result: { success: true },
95
- };
96
- });
97
- }
98
- return {
99
- jsonrpc: '2.0',
100
- id: msg.id,
101
- error: {
102
- code: -32601,
103
- message: 'Method not found',
104
- },
105
- };
106
- });
107
- });
108
- afterAll(async () => {
109
- await transport.stop();
110
- });
111
- beforeEach(() => {
112
- // Reset session ID for each test
113
- sessionId = '';
114
- });
115
- describe('Initialization', () => {
116
- it('should initialize and create session', async () => {
117
- const response = await request(app)
118
- .post('/mcp')
119
- .set('Accept', 'application/json')
120
- .send({
121
- jsonrpc: '2.0',
122
- id: 1,
123
- method: 'initialize',
124
- params: {
125
- protocolVersion: '2025-03-26',
126
- clientInfo: {
127
- name: 'test-client',
128
- version: '1.0.0',
129
- },
130
- },
131
- });
132
- expect(response.status).toBe(200);
133
- expect(response.headers['mcp-session-id']).toBeDefined();
134
- expect(response.body).toHaveProperty('jsonrpc', '2.0');
135
- expect(response.body).toHaveProperty('result');
136
- expect(response.body.result).toHaveProperty('protocolVersion', '2025-03-26');
137
- expect(response.body.result).toHaveProperty('serverInfo');
138
- // Save session ID for subsequent tests
139
- sessionId = response.headers['mcp-session-id'];
140
- });
141
- });
142
- describe('Tools List', () => {
143
- it('should list available tools', async () => {
144
- // Initialize first
145
- const initResponse = await request(app)
146
- .post('/mcp')
147
- .set('Accept', 'application/json')
148
- .send({
149
- jsonrpc: '2.0',
150
- id: 1,
151
- method: 'initialize',
152
- params: {},
153
- });
154
- sessionId = initResponse.headers['mcp-session-id'];
155
- const response = await request(app)
156
- .post('/mcp')
157
- .set('Accept', 'application/json')
158
- .set('Mcp-Session-Id', sessionId)
159
- .send({
160
- jsonrpc: '2.0',
161
- id: 2,
162
- method: 'tools/list',
163
- params: {},
164
- });
165
- expect(response.status).toBe(200);
166
- expect(response.body).toHaveProperty('result');
167
- expect(response.body.result).toHaveProperty('tools');
168
- expect(Array.isArray(response.body.result.tools)).toBe(true);
169
- expect(response.body.result.tools.length).toBeGreaterThan(0);
170
- // Check tool structure
171
- const tool = response.body.result.tools[0];
172
- expect(tool).toHaveProperty('name');
173
- expect(tool).toHaveProperty('description');
174
- expect(tool).toHaveProperty('inputSchema');
175
- });
176
- });
177
- describe('Tool Execution', () => {
178
- beforeEach(async () => {
179
- // Initialize for each test
180
- const initResponse = await request(app)
181
- .post('/mcp')
182
- .set('Accept', 'application/json')
183
- .send({
184
- jsonrpc: '2.0',
185
- id: 1,
186
- method: 'initialize',
187
- params: {},
188
- });
189
- sessionId = initResponse.headers['mcp-session-id'];
190
- });
191
- it('should execute tool call', async () => {
192
- const response = await request(app)
193
- .post('/mcp')
194
- .set('Accept', 'application/json')
195
- .set('Mcp-Session-Id', sessionId)
196
- .send({
197
- jsonrpc: '2.0',
198
- id: 3,
199
- method: 'tools/call',
200
- params: {
201
- name: 'test_tool',
202
- arguments: {
203
- message: 'Hello',
204
- },
205
- },
206
- });
207
- expect(response.status).toBe(200);
208
- expect(response.body).toHaveProperty('result');
209
- expect(response.body.result).toHaveProperty('content');
210
- expect(Array.isArray(response.body.result.content)).toBe(true);
211
- const content = response.body.result.content[0];
212
- expect(content.type).toBe('text');
213
- const result = JSON.parse(content.text);
214
- expect(result).toHaveProperty('success', true);
215
- });
216
- it('should handle unknown method', async () => {
217
- const response = await request(app)
218
- .post('/mcp')
219
- .set('Accept', 'application/json')
220
- .set('Mcp-Session-Id', sessionId)
221
- .send({
222
- jsonrpc: '2.0',
223
- id: 5,
224
- method: 'unknown/method',
225
- params: {},
226
- });
227
- expect(response.status).toBe(200);
228
- expect(response.body).toHaveProperty('error');
229
- expect(response.body.error).toHaveProperty('code', -32601);
230
- expect(response.body.error.message).toContain('Method not found');
231
- });
232
- });
233
- describe('SSE Streaming', () => {
234
- it('should support SSE response for requests', async () => {
235
- // Initialize first
236
- const initResponse = await request(app)
237
- .post('/mcp')
238
- .set('Accept', 'application/json')
239
- .send({
240
- jsonrpc: '2.0',
241
- id: 1,
242
- method: 'initialize',
243
- params: {},
244
- });
245
- sessionId = initResponse.headers['mcp-session-id'];
246
- const response = await request(app)
247
- .post('/mcp')
248
- .set('Accept', 'text/event-stream')
249
- .set('Mcp-Session-Id', sessionId)
250
- .send({
251
- jsonrpc: '2.0',
252
- id: 6,
253
- method: 'tools/list',
254
- params: {},
255
- });
256
- expect(response.status).toBe(200);
257
- expect(response.headers['content-type']).toContain('text/event-stream');
258
- expect(response.text).toContain('id:');
259
- expect(response.text).toContain('data:');
260
- // Parse SSE data
261
- const lines = response.text.split('\n');
262
- const dataLine = lines.find(l => l.startsWith('data:'));
263
- expect(dataLine).toBeDefined();
264
- const data = JSON.parse(dataLine.substring(5).trim());
265
- expect(data.result).toHaveProperty('tools');
266
- });
267
- });
268
- describe('Session Management', () => {
269
- it('should reject requests with invalid session', async () => {
270
- const response = await request(app)
271
- .post('/mcp')
272
- .set('Accept', 'application/json')
273
- .set('Mcp-Session-Id', 'invalid-session-id')
274
- .send({
275
- jsonrpc: '2.0',
276
- id: 7,
277
- method: 'tools/list',
278
- params: {},
279
- });
280
- expect(response.status).toBe(404);
281
- expect(response.body).toHaveProperty('error');
282
- expect(response.body.message).toContain('Session not found');
283
- });
284
- it('should allow explicit session termination', async () => {
285
- // Create new session
286
- const initResponse = await request(app)
287
- .post('/mcp')
288
- .set('Accept', 'application/json')
289
- .send({
290
- jsonrpc: '2.0',
291
- id: 8,
292
- method: 'initialize',
293
- params: {},
294
- });
295
- const tempSessionId = initResponse.headers['mcp-session-id'];
296
- expect(tempSessionId).toBeDefined();
297
- // Verify session works
298
- const listResponse = await request(app)
299
- .post('/mcp')
300
- .set('Accept', 'application/json')
301
- .set('Mcp-Session-Id', tempSessionId)
302
- .send({
303
- jsonrpc: '2.0',
304
- id: 9,
305
- method: 'tools/list',
306
- params: {},
307
- });
308
- expect(listResponse.status).toBe(200);
309
- // Terminate session
310
- const deleteResponse = await request(app)
311
- .delete('/mcp')
312
- .set('Mcp-Session-Id', tempSessionId);
313
- expect(deleteResponse.status).toBe(204);
314
- // Verify session is gone
315
- const afterDeleteResponse = await request(app)
316
- .post('/mcp')
317
- .set('Accept', 'application/json')
318
- .set('Mcp-Session-Id', tempSessionId)
319
- .send({
320
- jsonrpc: '2.0',
321
- id: 10,
322
- method: 'tools/list',
323
- params: {},
324
- });
325
- expect(afterDeleteResponse.status).toBe(404);
326
- });
327
- });
328
- describe('Batch Requests', () => {
329
- it('should handle batch of requests', async () => {
330
- // Initialize first
331
- const initResponse = await request(app)
332
- .post('/mcp')
333
- .set('Accept', 'application/json')
334
- .send({
335
- jsonrpc: '2.0',
336
- id: 1,
337
- method: 'initialize',
338
- params: {},
339
- });
340
- sessionId = initResponse.headers['mcp-session-id'];
341
- const response = await request(app)
342
- .post('/mcp')
343
- .set('Accept', 'application/json')
344
- .set('Mcp-Session-Id', sessionId)
345
- .send([
346
- {
347
- jsonrpc: '2.0',
348
- id: 11,
349
- method: 'tools/list',
350
- params: {},
351
- },
352
- {
353
- jsonrpc: '2.0',
354
- id: 12,
355
- method: 'tools/call',
356
- params: {
357
- name: 'test_tool',
358
- arguments: { message: 'test' },
359
- },
360
- },
361
- ]);
362
- expect(response.status).toBe(200);
363
- expect(Array.isArray(response.body)).toBe(true);
364
- expect(response.body).toHaveLength(2);
365
- // Check each response
366
- expect(response.body[0]).toHaveProperty('id', 11);
367
- expect(response.body[0]).toHaveProperty('result');
368
- expect(response.body[1]).toHaveProperty('id', 12);
369
- expect(response.body[1]).toHaveProperty('result');
370
- });
371
- });
372
- describe('Health Check', () => {
373
- it('should return health status', async () => {
374
- const response = await request(app)
375
- .get('/health');
376
- expect(response.status).toBe(200);
377
- expect(response.body).toHaveProperty('status', 'ok');
378
- expect(response.body).toHaveProperty('sessions');
379
- expect(typeof response.body.sessions).toBe('number');
380
- });
381
- });
382
- });
383
- //# sourceMappingURL=http-integration.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"http-integration.test.js","sourceRoot":"","sources":["../../src/testing/http-integration.test.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- /**
2
- * Integration test for HTTP transport in multi-user mode (no API_TOKEN in env)
3
- *
4
- * Tests that:
5
- * 1. Server can start without API_TOKEN env var
6
- * 2. Clients can send tokens in Authorization header
7
- * 3. Each session uses its own token
8
- */
9
- export {};
10
- //# sourceMappingURL=http-multiuser.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"http-multiuser.test.d.ts","sourceRoot":"","sources":["../../src/testing/http-multiuser.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -1,255 +0,0 @@
1
- /**
2
- * Integration test for HTTP transport in multi-user mode (no API_TOKEN in env)
3
- *
4
- * Tests that:
5
- * 1. Server can start without API_TOKEN env var
6
- * 2. Clients can send tokens in Authorization header
7
- * 3. Each session uses its own token
8
- */
9
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
10
- import { HttpTransport } from '../http-transport.js';
11
- import { ConsoleLogger } from '../logger.js';
12
- import request from 'supertest';
13
- describe('HTTP Multi-User Mode (No API_TOKEN)', () => {
14
- let httpTransport;
15
- let app;
16
- // Save original env
17
- const originalApiToken = process.env.API_TOKEN;
18
- beforeAll(() => {
19
- // IMPORTANT: Remove API_TOKEN from env to test multi-user mode
20
- delete process.env.API_TOKEN;
21
- const logger = new ConsoleLogger('error'); // Quiet during tests
22
- const config = {
23
- host: '127.0.0.1',
24
- port: 0, // Port 0 for supertest - doesn't actually listen
25
- sessionTimeoutMs: 1800000,
26
- heartbeatEnabled: false,
27
- heartbeatIntervalMs: 30000,
28
- metricsEnabled: false,
29
- metricsPath: '/metrics',
30
- };
31
- httpTransport = new HttpTransport(config, logger);
32
- app = httpTransport.app;
33
- // Set up simple mock message handler
34
- httpTransport.setMessageHandler(async (message, sessionId) => {
35
- const msg = message;
36
- if (msg.method === 'initialize') {
37
- return {
38
- jsonrpc: '2.0',
39
- id: msg.id,
40
- result: {
41
- protocolVersion: '2025-03-26',
42
- serverInfo: {
43
- name: 'test-server',
44
- version: '1.0.0',
45
- },
46
- capabilities: {
47
- tools: {},
48
- },
49
- },
50
- };
51
- }
52
- if (msg.method === 'tools/list') {
53
- return {
54
- jsonrpc: '2.0',
55
- id: msg.id,
56
- result: {
57
- tools: [
58
- {
59
- name: 'test_tool',
60
- description: 'Test',
61
- inputSchema: { type: 'object', properties: {} }
62
- }
63
- ],
64
- },
65
- };
66
- }
67
- return {
68
- jsonrpc: '2.0',
69
- id: msg.id,
70
- error: {
71
- code: -32601,
72
- message: 'Method not found',
73
- },
74
- };
75
- });
76
- });
77
- afterAll(() => {
78
- // Restore original env
79
- if (originalApiToken) {
80
- process.env.API_TOKEN = originalApiToken;
81
- }
82
- else {
83
- delete process.env.API_TOKEN;
84
- }
85
- });
86
- describe('Server Initialization', () => {
87
- it('should start successfully without API_TOKEN env var', async () => {
88
- expect(process.env.API_TOKEN).toBeUndefined();
89
- expect(app).toBeDefined();
90
- // Health check should work
91
- const response = await request(app).get('/health');
92
- expect(response.status).toBe(200);
93
- expect(response.body.status).toBe('ok');
94
- });
95
- });
96
- describe('Client Authentication', () => {
97
- it('should accept initialization with Authorization header', async () => {
98
- const response = await request(app)
99
- .post('/mcp')
100
- .set('Content-Type', 'application/json')
101
- .set('Accept', 'application/json')
102
- .set('Authorization', 'Bearer glpat-test-token-123')
103
- .send({
104
- jsonrpc: '2.0',
105
- id: 1,
106
- method: 'initialize',
107
- params: {
108
- protocolVersion: '2025-03-26',
109
- clientInfo: {
110
- name: 'test-client',
111
- version: '1.0.0'
112
- }
113
- }
114
- });
115
- expect(response.status).toBe(200);
116
- expect(response.body.result).toBeDefined();
117
- expect(response.body.result.protocolVersion).toBe('2025-03-26');
118
- expect(response.headers['mcp-session-id']).toBeDefined();
119
- });
120
- it('should accept initialization with X-API-Token header', async () => {
121
- const response = await request(app)
122
- .post('/mcp')
123
- .set('Content-Type', 'application/json')
124
- .set('Accept', 'application/json')
125
- .set('X-API-Token', 'glpat-test-token-456')
126
- .send({
127
- jsonrpc: '2.0',
128
- id: 2,
129
- method: 'initialize',
130
- params: {
131
- protocolVersion: '2025-03-26',
132
- clientInfo: {
133
- name: 'test-client-2',
134
- version: '1.0.0'
135
- }
136
- }
137
- });
138
- expect(response.status).toBe(200);
139
- expect(response.headers['mcp-session-id']).toBeDefined();
140
- });
141
- it('should create separate sessions for different tokens', async () => {
142
- // Client 1
143
- const response1 = await request(app)
144
- .post('/mcp')
145
- .set('Content-Type', 'application/json')
146
- .set('Accept', 'application/json')
147
- .set('Authorization', 'Bearer token-user-1')
148
- .send({
149
- jsonrpc: '2.0',
150
- id: 3,
151
- method: 'initialize',
152
- params: {
153
- protocolVersion: '2025-03-26',
154
- clientInfo: { name: 'client-1', version: '1.0.0' }
155
- }
156
- });
157
- const sessionId1 = response1.headers['mcp-session-id'];
158
- expect(sessionId1).toBeDefined();
159
- // Client 2
160
- const response2 = await request(app)
161
- .post('/mcp')
162
- .set('Content-Type', 'application/json')
163
- .set('Accept', 'application/json')
164
- .set('Authorization', 'Bearer token-user-2')
165
- .send({
166
- jsonrpc: '2.0',
167
- id: 4,
168
- method: 'initialize',
169
- params: {
170
- protocolVersion: '2025-03-26',
171
- clientInfo: { name: 'client-2', version: '1.0.0' }
172
- }
173
- });
174
- const sessionId2 = response2.headers['mcp-session-id'];
175
- expect(sessionId2).toBeDefined();
176
- // Sessions should be different
177
- expect(sessionId1).not.toBe(sessionId2);
178
- });
179
- });
180
- describe('Security', () => {
181
- it('should reject malformed Authorization header', async () => {
182
- const response = await request(app)
183
- .post('/mcp')
184
- .set('Content-Type', 'application/json')
185
- .set('Accept', 'application/json')
186
- .set('Authorization', 'InvalidFormat token')
187
- .send({
188
- jsonrpc: '2.0',
189
- id: 5,
190
- method: 'initialize',
191
- params: {
192
- protocolVersion: '2025-03-26',
193
- clientInfo: { name: 'test', version: '1.0.0' }
194
- }
195
- });
196
- // P0#2 fix: Now properly rejects invalid format
197
- expect(response.status).toBe(500);
198
- expect(response.body.error).toBe('Internal Server Error');
199
- expect(response.body.message).toContain('Invalid Authorization header format');
200
- });
201
- it('should handle initialization without any token gracefully', async () => {
202
- const response = await request(app)
203
- .post('/mcp')
204
- .set('Content-Type', 'application/json')
205
- .set('Accept', 'application/json')
206
- .send({
207
- jsonrpc: '2.0',
208
- id: 6,
209
- method: 'initialize',
210
- params: {
211
- protocolVersion: '2025-03-26',
212
- clientInfo: { name: 'test', version: '1.0.0' }
213
- }
214
- });
215
- // Should create session, token will be checked on first tool call
216
- expect(response.status).toBe(200);
217
- });
218
- });
219
- describe('Token Storage', () => {
220
- it('should store token in session and use it for subsequent requests', async () => {
221
- // Initialize with token
222
- const initResponse = await request(app)
223
- .post('/mcp')
224
- .set('Content-Type', 'application/json')
225
- .set('Accept', 'application/json')
226
- .set('Authorization', 'Bearer session-token-test')
227
- .send({
228
- jsonrpc: '2.0',
229
- id: 7,
230
- method: 'initialize',
231
- params: {
232
- protocolVersion: '2025-03-26',
233
- clientInfo: { name: 'test', version: '1.0.0' }
234
- }
235
- });
236
- const sessionId = initResponse.headers['mcp-session-id'];
237
- expect(sessionId).toBeDefined();
238
- // List tools without token in header (should use session token)
239
- const toolsResponse = await request(app)
240
- .post('/mcp')
241
- .set('Content-Type', 'application/json')
242
- .set('Accept', 'application/json')
243
- .set('Mcp-Session-Id', sessionId)
244
- .send({
245
- jsonrpc: '2.0',
246
- id: 8,
247
- method: 'tools/list',
248
- params: {}
249
- });
250
- expect(toolsResponse.status).toBe(200);
251
- expect(toolsResponse.body.result).toBeDefined();
252
- });
253
- });
254
- });
255
- //# sourceMappingURL=http-multiuser.test.js.map