api2ai 1.0.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,493 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * petstore-api - MCP Server
5
+ *
6
+ * Auto-generated from OpenAPI specification using mcp-use framework.
7
+ *
8
+ * Features:
9
+ * - 19 API tools available
10
+ * - Built-in Inspector at http://localhost:3000/inspector
11
+ * - Streamable HTTP transport
12
+ */
13
+
14
+ import 'dotenv/config';
15
+ import { MCPServer } from 'mcp-use/server';
16
+ import { z } from 'zod';
17
+ import { executeRequest } from './http-client.js';
18
+ import { toolConfigMap } from './tools-config.js';
19
+
20
+ // ============================================================================
21
+ // Configuration
22
+ // ============================================================================
23
+
24
+ const PORT = parseInt(process.env.PORT || '3000');
25
+ const isDev = process.env.NODE_ENV !== 'production';
26
+
27
+ // API configuration
28
+ const apiConfig = {
29
+ baseUrl: process.env.API_BASE_URL || '/api/v3',
30
+ headers: {},
31
+ };
32
+
33
+ // Set up authentication headers
34
+ if (process.env.API_KEY) {
35
+ apiConfig.headers['Authorization'] = `Bearer ${process.env.API_KEY}`;
36
+ }
37
+
38
+ if (process.env.API_AUTH_HEADER) {
39
+ const [key, ...valueParts] = process.env.API_AUTH_HEADER.split(':');
40
+ const value = valueParts.join(':'); // Handle values with colons
41
+ if (key && value) {
42
+ apiConfig.headers[key.trim()] = value.trim();
43
+ }
44
+ }
45
+
46
+ // ============================================================================
47
+ // Server Setup
48
+ // ============================================================================
49
+
50
+ const server = new MCPServer({
51
+ name: 'petstore-api',
52
+ version: '1.0.0',
53
+ description: 'MCP server generated from OpenAPI specification',
54
+ baseUrl: process.env.MCP_URL || `http://localhost:${PORT}`,
55
+ allowedOrigins: isDev
56
+ ? undefined // Development: allow all origins
57
+ : process.env.ALLOWED_ORIGINS?.split(',').map(s => s.trim()) || [],
58
+ });
59
+
60
+ // ============================================================================
61
+ // Tool Registrations
62
+ // ============================================================================
63
+
64
+ // Add a new pet to the store.
65
+ server.tool('addPet', {
66
+ description: 'Add a new pet to the store.',
67
+ parameters: z.object({
68
+ requestBody: z.unknown().describe('Create a new pet in the store')
69
+ }),
70
+ execute: async (params) => {
71
+ const toolConfig = toolConfigMap.get('addPet');
72
+ const result = await executeRequest(toolConfig, params, apiConfig);
73
+
74
+ if (result.ok) {
75
+ return typeof result.data === 'string'
76
+ ? result.data
77
+ : JSON.stringify(result.data, null, 2);
78
+ } else {
79
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
80
+ }`);
81
+ }
82
+ },
83
+ });
84
+
85
+ // Update an existing pet.
86
+ server.tool('updatePet', {
87
+ description: 'Update an existing pet.',
88
+ parameters: z.object({
89
+ requestBody: z.unknown().describe('Update an existent pet in the store')
90
+ }),
91
+ execute: async (params) => {
92
+ const toolConfig = toolConfigMap.get('updatePet');
93
+ const result = await executeRequest(toolConfig, params, apiConfig);
94
+
95
+ if (result.ok) {
96
+ return typeof result.data === 'string'
97
+ ? result.data
98
+ : JSON.stringify(result.data, null, 2);
99
+ } else {
100
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
101
+ }`);
102
+ }
103
+ },
104
+ });
105
+
106
+ // Finds Pets by status.
107
+ server.tool('findPetsByStatus', {
108
+ description: 'Finds Pets by status.',
109
+ parameters: z.object({
110
+ status: z.enum(['available', 'pending', 'sold']).describe('Status values that need to be considered for filter')
111
+ }),
112
+ execute: async (params) => {
113
+ const toolConfig = toolConfigMap.get('findPetsByStatus');
114
+ const result = await executeRequest(toolConfig, params, apiConfig);
115
+
116
+ if (result.ok) {
117
+ return typeof result.data === 'string'
118
+ ? result.data
119
+ : JSON.stringify(result.data, null, 2);
120
+ } else {
121
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
122
+ }`);
123
+ }
124
+ },
125
+ });
126
+
127
+ // Finds Pets by tags.
128
+ server.tool('findPetsByTags', {
129
+ description: 'Finds Pets by tags.',
130
+ parameters: z.object({
131
+ tags: z.array(z.string()).describe('Tags to filter by')
132
+ }),
133
+ execute: async (params) => {
134
+ const toolConfig = toolConfigMap.get('findPetsByTags');
135
+ const result = await executeRequest(toolConfig, params, apiConfig);
136
+
137
+ if (result.ok) {
138
+ return typeof result.data === 'string'
139
+ ? result.data
140
+ : JSON.stringify(result.data, null, 2);
141
+ } else {
142
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
143
+ }`);
144
+ }
145
+ },
146
+ });
147
+
148
+ // Find pet by ID.
149
+ server.tool('getPetById', {
150
+ description: 'Find pet by ID.',
151
+ parameters: z.object({
152
+ petId: z.number().int().describe('ID of pet to return')
153
+ }),
154
+ execute: async (params) => {
155
+ const toolConfig = toolConfigMap.get('getPetById');
156
+ const result = await executeRequest(toolConfig, params, apiConfig);
157
+
158
+ if (result.ok) {
159
+ return typeof result.data === 'string'
160
+ ? result.data
161
+ : JSON.stringify(result.data, null, 2);
162
+ } else {
163
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
164
+ }`);
165
+ }
166
+ },
167
+ });
168
+
169
+ // Updates a pet in the store with form data.
170
+ server.tool('updatePetWithForm', {
171
+ description: 'Updates a pet in the store with form data.',
172
+ parameters: z.object({
173
+ petId: z.number().int().describe('ID of pet that needs to be updated'),
174
+ name: z.string().optional().describe('Name of pet that needs to be updated'),
175
+ status: z.string().optional().describe('Status of pet that needs to be updated')
176
+ }),
177
+ execute: async (params) => {
178
+ const toolConfig = toolConfigMap.get('updatePetWithForm');
179
+ const result = await executeRequest(toolConfig, params, apiConfig);
180
+
181
+ if (result.ok) {
182
+ return typeof result.data === 'string'
183
+ ? result.data
184
+ : JSON.stringify(result.data, null, 2);
185
+ } else {
186
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
187
+ }`);
188
+ }
189
+ },
190
+ });
191
+
192
+ // Deletes a pet.
193
+ server.tool('deletePet', {
194
+ description: 'Deletes a pet.',
195
+ parameters: z.object({
196
+ api_key: z.string().optional(),
197
+ petId: z.number().int().describe('Pet id to delete')
198
+ }),
199
+ execute: async (params) => {
200
+ const toolConfig = toolConfigMap.get('deletePet');
201
+ const result = await executeRequest(toolConfig, params, apiConfig);
202
+
203
+ if (result.ok) {
204
+ return typeof result.data === 'string'
205
+ ? result.data
206
+ : JSON.stringify(result.data, null, 2);
207
+ } else {
208
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
209
+ }`);
210
+ }
211
+ },
212
+ });
213
+
214
+ // Uploads an image.
215
+ server.tool('uploadFile', {
216
+ description: 'Uploads an image.',
217
+ parameters: z.object({
218
+ petId: z.number().int().describe('ID of pet to update'),
219
+ additionalMetadata: z.string().optional().describe('Additional Metadata'),
220
+ requestBody: z.string().optional().describe('Request body')
221
+ }),
222
+ execute: async (params) => {
223
+ const toolConfig = toolConfigMap.get('uploadFile');
224
+ const result = await executeRequest(toolConfig, params, apiConfig);
225
+
226
+ if (result.ok) {
227
+ return typeof result.data === 'string'
228
+ ? result.data
229
+ : JSON.stringify(result.data, null, 2);
230
+ } else {
231
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
232
+ }`);
233
+ }
234
+ },
235
+ });
236
+
237
+ // Returns pet inventories by status.
238
+ server.tool('getInventory', {
239
+ description: 'Returns pet inventories by status.',
240
+ parameters: z.object({}),
241
+ execute: async (params) => {
242
+ const toolConfig = toolConfigMap.get('getInventory');
243
+ const result = await executeRequest(toolConfig, params, apiConfig);
244
+
245
+ if (result.ok) {
246
+ return typeof result.data === 'string'
247
+ ? result.data
248
+ : JSON.stringify(result.data, null, 2);
249
+ } else {
250
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
251
+ }`);
252
+ }
253
+ },
254
+ });
255
+
256
+ // Place an order for a pet.
257
+ server.tool('placeOrder', {
258
+ description: 'Place an order for a pet.',
259
+ parameters: z.object({
260
+ requestBody: z.unknown().optional().describe('Request body')
261
+ }),
262
+ execute: async (params) => {
263
+ const toolConfig = toolConfigMap.get('placeOrder');
264
+ const result = await executeRequest(toolConfig, params, apiConfig);
265
+
266
+ if (result.ok) {
267
+ return typeof result.data === 'string'
268
+ ? result.data
269
+ : JSON.stringify(result.data, null, 2);
270
+ } else {
271
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
272
+ }`);
273
+ }
274
+ },
275
+ });
276
+
277
+ // Find purchase order by ID.
278
+ server.tool('getOrderById', {
279
+ description: 'Find purchase order by ID.',
280
+ parameters: z.object({
281
+ orderId: z.number().int().describe('ID of order that needs to be fetched')
282
+ }),
283
+ execute: async (params) => {
284
+ const toolConfig = toolConfigMap.get('getOrderById');
285
+ const result = await executeRequest(toolConfig, params, apiConfig);
286
+
287
+ if (result.ok) {
288
+ return typeof result.data === 'string'
289
+ ? result.data
290
+ : JSON.stringify(result.data, null, 2);
291
+ } else {
292
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
293
+ }`);
294
+ }
295
+ },
296
+ });
297
+
298
+ // Delete purchase order by identifier.
299
+ server.tool('deleteOrder', {
300
+ description: 'Delete purchase order by identifier.',
301
+ parameters: z.object({
302
+ orderId: z.number().int().describe('ID of the order that needs to be deleted')
303
+ }),
304
+ execute: async (params) => {
305
+ const toolConfig = toolConfigMap.get('deleteOrder');
306
+ const result = await executeRequest(toolConfig, params, apiConfig);
307
+
308
+ if (result.ok) {
309
+ return typeof result.data === 'string'
310
+ ? result.data
311
+ : JSON.stringify(result.data, null, 2);
312
+ } else {
313
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
314
+ }`);
315
+ }
316
+ },
317
+ });
318
+
319
+ // Create user.
320
+ server.tool('createUser', {
321
+ description: 'Create user.',
322
+ parameters: z.object({
323
+ requestBody: z.unknown().optional().describe('Created user object')
324
+ }),
325
+ execute: async (params) => {
326
+ const toolConfig = toolConfigMap.get('createUser');
327
+ const result = await executeRequest(toolConfig, params, apiConfig);
328
+
329
+ if (result.ok) {
330
+ return typeof result.data === 'string'
331
+ ? result.data
332
+ : JSON.stringify(result.data, null, 2);
333
+ } else {
334
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
335
+ }`);
336
+ }
337
+ },
338
+ });
339
+
340
+ // Creates list of users with given input array.
341
+ server.tool('createUsersWithListInput', {
342
+ description: 'Creates list of users with given input array.',
343
+ parameters: z.object({
344
+ requestBody: z.array(z.unknown()).optional().describe('Request body')
345
+ }),
346
+ execute: async (params) => {
347
+ const toolConfig = toolConfigMap.get('createUsersWithListInput');
348
+ const result = await executeRequest(toolConfig, params, apiConfig);
349
+
350
+ if (result.ok) {
351
+ return typeof result.data === 'string'
352
+ ? result.data
353
+ : JSON.stringify(result.data, null, 2);
354
+ } else {
355
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
356
+ }`);
357
+ }
358
+ },
359
+ });
360
+
361
+ // Logs user into the system.
362
+ server.tool('loginUser', {
363
+ description: 'Logs user into the system.',
364
+ parameters: z.object({
365
+ username: z.string().optional().describe('The user name for login'),
366
+ password: z.string().optional().describe('The password for login in clear text')
367
+ }),
368
+ execute: async (params) => {
369
+ const toolConfig = toolConfigMap.get('loginUser');
370
+ const result = await executeRequest(toolConfig, params, apiConfig);
371
+
372
+ if (result.ok) {
373
+ return typeof result.data === 'string'
374
+ ? result.data
375
+ : JSON.stringify(result.data, null, 2);
376
+ } else {
377
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
378
+ }`);
379
+ }
380
+ },
381
+ });
382
+
383
+ // Logs out current logged in user session.
384
+ server.tool('logoutUser', {
385
+ description: 'Logs out current logged in user session.',
386
+ parameters: z.object({}),
387
+ execute: async (params) => {
388
+ const toolConfig = toolConfigMap.get('logoutUser');
389
+ const result = await executeRequest(toolConfig, params, apiConfig);
390
+
391
+ if (result.ok) {
392
+ return typeof result.data === 'string'
393
+ ? result.data
394
+ : JSON.stringify(result.data, null, 2);
395
+ } else {
396
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
397
+ }`);
398
+ }
399
+ },
400
+ });
401
+
402
+ // Get user by user name.
403
+ server.tool('getUserByName', {
404
+ description: 'Get user by user name.',
405
+ parameters: z.object({
406
+ username: z.string().describe('The name that needs to be fetched. Use user1 for testing')
407
+ }),
408
+ execute: async (params) => {
409
+ const toolConfig = toolConfigMap.get('getUserByName');
410
+ const result = await executeRequest(toolConfig, params, apiConfig);
411
+
412
+ if (result.ok) {
413
+ return typeof result.data === 'string'
414
+ ? result.data
415
+ : JSON.stringify(result.data, null, 2);
416
+ } else {
417
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
418
+ }`);
419
+ }
420
+ },
421
+ });
422
+
423
+ // Update user resource.
424
+ server.tool('updateUser', {
425
+ description: 'Update user resource.',
426
+ parameters: z.object({
427
+ username: z.string().describe('name that need to be deleted'),
428
+ requestBody: z.unknown().optional().describe('Update an existent user in the store')
429
+ }),
430
+ execute: async (params) => {
431
+ const toolConfig = toolConfigMap.get('updateUser');
432
+ const result = await executeRequest(toolConfig, params, apiConfig);
433
+
434
+ if (result.ok) {
435
+ return typeof result.data === 'string'
436
+ ? result.data
437
+ : JSON.stringify(result.data, null, 2);
438
+ } else {
439
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
440
+ }`);
441
+ }
442
+ },
443
+ });
444
+
445
+ // Delete user resource.
446
+ server.tool('deleteUser', {
447
+ description: 'Delete user resource.',
448
+ parameters: z.object({
449
+ username: z.string().describe('The name that needs to be deleted')
450
+ }),
451
+ execute: async (params) => {
452
+ const toolConfig = toolConfigMap.get('deleteUser');
453
+ const result = await executeRequest(toolConfig, params, apiConfig);
454
+
455
+ if (result.ok) {
456
+ return typeof result.data === 'string'
457
+ ? result.data
458
+ : JSON.stringify(result.data, null, 2);
459
+ } else {
460
+ throw new Error(`API Error (${result.status}): ${typeof result.data === 'string' ? result.data : JSON.stringify(result.data)
461
+ }`);
462
+ }
463
+ },
464
+ });
465
+
466
+ // ============================================================================
467
+ // Start Server
468
+ // ============================================================================
469
+
470
+ server.listen(PORT);
471
+
472
+ console.log(`
473
+ 🚀 petstore-api MCP Server Started!
474
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
475
+
476
+ 📍 Server: http://localMCP Server Starthost:${PORT}
477
+ 🔍 Inspector: http://localhost:${PORT}/inspector
478
+ 📡 MCP: http://localhost:${PORT}/mcp
479
+ 🔄 SSE: http://localhost:${PORT}/sse
480
+
481
+ 🛠️ Tools Available: 19
482
+ • addPet
483
+ • updatePet
484
+ • findPetsByStatus
485
+ • findPetsByTags
486
+ • getPetById
487
+ ... and 14 more
488
+
489
+ Environment: ${isDev ? 'Development' : 'Production'}
490
+ API Base: ${apiConfig.baseUrl || 'Not configured'}
491
+
492
+ Press Ctrl+C to stop the server.
493
+ `);