harsha-iiiv 3b4f716661 Refactor OpenAPI MCP Server Generator to TypeScript
- Removed the old JavaScript implementation of the MCP server generator.
- Introduced a new TypeScript implementation with improved command-line argument parsing using `commander`.
- Replaced the OpenAPI spec loading mechanism with `@apidevtools/swagger-parser` for better handling of references.
- Updated the server generation logic to create TypeScript files with appropriate typings and structure.
- Added utility functions for generating operation IDs and converting strings to TitleCase.
- Created a new `tsconfig.json` for TypeScript compilation settings.
- Removed deprecated files related to the old JavaScript implementation, including `openapi-loader.js`, `server-generator.js`, and `tool-generator.js`.
- Enhanced error handling and logging throughout the new implementation.
2025-04-12 17:21:28 +05:30

2220 lines
98 KiB
TypeScript

// Generated by openapi-to-mcp-generator for swagger-petstore---openapi-3-0 v1.0.26
// Source OpenAPI spec: https://petstore3.swagger.io/api/v3/openapi.json
// Generation date: 2025-04-12T09:29:22.152Z
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
// Import Schemas and Types from /types subpath with .js extension
import {
CallToolRequestSchema,
ListToolsRequestSchema,
type Tool,
type CallToolResult,
type CallToolRequest // Added type for the request parameter
} from "@modelcontextprotocol/sdk/types.js";
// Zod for runtime validation
import { z, ZodError } from 'zod';
// Library to convert JSON Schema to Zod schema string at runtime
import { jsonSchemaToZod } from 'json-schema-to-zod';
// Define JsonObject locally as a utility type
type JsonObject = Record<string, any>;
import axios, { type AxiosRequestConfig, type AxiosError } from 'axios';
// --- Server Configuration ---
const SERVER_NAME = "swagger-petstore---openapi-3-0";
const SERVER_VERSION = "1.0.26";
const API_BASE_URL = "https://petstore3.swagger.io/api/v3";
// --- Server Instance ---
const server = new Server(
{
name: SERVER_NAME,
version: SERVER_VERSION
},
{
capabilities: {
tools: {}
}
}
);
// --- Tool Definitions (for ListTools response) ---
// Corrected: Use Tool[] type
const toolsList: Tool[] = [
// Tool: updatePet (PUT /pet)
{
name: "updatePet",
description: `Update an existing pet by Id.`,
inputSchema: {
"type": "object",
"properties": {
"requestBody": {
"required": [
"name",
"photoUrls"
],
"type": "object",
"properties": {
"id": {
"type": "number",
"format": "int64"
},
"name": {
"type": "string"
},
"category": {
"type": "object",
"properties": {
"id": {
"type": "number",
"format": "int64"
},
"name": {
"type": "string"
}
}
},
"photoUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"tags": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "number",
"format": "int64"
},
"name": {
"type": "string"
}
}
}
},
"status": {
"type": "string",
"description": "pet status in the store",
"enum": [
"available",
"pending",
"sold"
]
}
},
"description": "Update an existent pet in the store"
}
},
"required": [
"requestBody"
]
}
},
// Tool: addPet (POST /pet)
{
name: "addPet",
description: `Add a new pet to the store.`,
inputSchema: {
"type": "object",
"properties": {
"requestBody": {
"required": [
"name",
"photoUrls"
],
"type": "object",
"properties": {
"id": {
"type": "number",
"format": "int64"
},
"name": {
"type": "string"
},
"category": {
"type": "object",
"properties": {
"id": {
"type": "number",
"format": "int64"
},
"name": {
"type": "string"
}
}
},
"photoUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"tags": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "number",
"format": "int64"
},
"name": {
"type": "string"
}
}
}
},
"status": {
"type": "string",
"description": "pet status in the store",
"enum": [
"available",
"pending",
"sold"
]
}
},
"description": "Create a new pet in the store"
}
},
"required": [
"requestBody"
]
}
},
// Tool: findPetsByStatus (GET /pet/findByStatus)
{
name: "findPetsByStatus",
description: `Multiple status values can be provided with comma separated strings.`,
inputSchema: {
"type": "object",
"properties": {
"status": {
"type": "string",
"default": "available",
"enum": [
"available",
"pending",
"sold"
],
"description": "Status values that need to be considered for filter"
}
}
}
},
// Tool: findPetsByTags (GET /pet/findByTags)
{
name: "findPetsByTags",
description: `Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.`,
inputSchema: {
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags to filter by"
}
}
}
},
// Tool: getPetById (GET /pet/{petId})
{
name: "getPetById",
description: `Returns a single pet.`,
inputSchema: {
"type": "object",
"properties": {
"petId": {
"type": "number",
"format": "int64",
"description": "ID of pet to return"
}
},
"required": [
"petId"
]
}
},
// Tool: updatePetWithForm (POST /pet/{petId})
{
name: "updatePetWithForm",
description: `Updates a pet resource based on the form data.`,
inputSchema: {
"type": "object",
"properties": {
"petId": {
"type": "number",
"format": "int64",
"description": "ID of pet that needs to be updated"
},
"name": {
"type": "string",
"description": "Name of pet that needs to be updated"
},
"status": {
"type": "string",
"description": "Status of pet that needs to be updated"
}
},
"required": [
"petId"
]
}
},
// Tool: deletePet (DELETE /pet/{petId})
{
name: "deletePet",
description: `Delete a pet.`,
inputSchema: {
"type": "object",
"properties": {
"api_key": {
"type": "string"
},
"petId": {
"type": "number",
"format": "int64",
"description": "Pet id to delete"
}
},
"required": [
"petId"
]
}
},
// Tool: uploadFile (POST /pet/{petId}/uploadImage)
{
name: "uploadFile",
description: `Upload image of the pet.`,
inputSchema: {
"type": "object",
"properties": {
"petId": {
"type": "number",
"format": "int64",
"description": "ID of pet to update"
},
"additionalMetadata": {
"type": "string",
"description": "Additional Metadata"
},
"requestBody": {
"type": "string",
"description": "Request body (content type: application/octet-stream)"
}
},
"required": [
"petId"
]
}
},
// Tool: getInventory (GET /store/inventory)
{
name: "getInventory",
description: `Returns a map of status codes to quantities.`,
inputSchema: {
"type": "object",
"properties": {}
}
},
// Tool: placeOrder (POST /store/order)
{
name: "placeOrder",
description: `Place a new order in the store.`,
inputSchema: {
"type": "object",
"properties": {
"requestBody": {
"type": "object",
"properties": {
"id": {
"type": "number",
"format": "int64"
},
"petId": {
"type": "number",
"format": "int64"
},
"quantity": {
"type": "number",
"format": "int32"
},
"shipDate": {
"type": "string",
"format": "date-time"
},
"status": {
"type": "string",
"description": "Order Status",
"enum": [
"placed",
"approved",
"delivered"
]
},
"complete": {
"type": "boolean"
}
},
"description": "The JSON request body."
}
}
}
},
// Tool: getOrderById (GET /store/order/{orderId})
{
name: "getOrderById",
description: `For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions.`,
inputSchema: {
"type": "object",
"properties": {
"orderId": {
"type": "number",
"format": "int64",
"description": "ID of order that needs to be fetched"
}
},
"required": [
"orderId"
]
}
},
// Tool: deleteOrder (DELETE /store/order/{orderId})
{
name: "deleteOrder",
description: `For valid response try integer IDs with value < 1000. Anything above 1000 or non-integers will generate API errors.`,
inputSchema: {
"type": "object",
"properties": {
"orderId": {
"type": "number",
"format": "int64",
"description": "ID of the order that needs to be deleted"
}
},
"required": [
"orderId"
]
}
},
// Tool: createUser (POST /user)
{
name: "createUser",
description: `This can only be done by the logged in user.`,
inputSchema: {
"type": "object",
"properties": {
"requestBody": {
"type": "object",
"properties": {
"id": {
"type": "number",
"format": "int64"
},
"username": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"phone": {
"type": "string"
},
"userStatus": {
"type": "number",
"description": "User Status",
"format": "int32"
}
},
"description": "Created user object"
}
}
}
},
// Tool: createUsersWithListInput (POST /user/createWithList)
{
name: "createUsersWithListInput",
description: `Creates list of users with given input array.`,
inputSchema: {
"type": "object",
"properties": {
"requestBody": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "number",
"format": "int64"
},
"username": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"phone": {
"type": "string"
},
"userStatus": {
"type": "number",
"description": "User Status",
"format": "int32"
}
}
},
"description": "The JSON request body."
}
}
}
},
// Tool: loginUser (GET /user/login)
{
name: "loginUser",
description: `Log into the system.`,
inputSchema: {
"type": "object",
"properties": {
"username": {
"type": "string",
"description": "The user name for login"
},
"password": {
"type": "string",
"description": "The password for login in clear text"
}
}
}
},
// Tool: logoutUser (GET /user/logout)
{
name: "logoutUser",
description: `Log user out of the system.`,
inputSchema: {
"type": "object",
"properties": {}
}
},
// Tool: getUserByName (GET /user/{username})
{
name: "getUserByName",
description: `Get user detail based on username.`,
inputSchema: {
"type": "object",
"properties": {
"username": {
"type": "string",
"description": "The name that needs to be fetched. Use user1 for testing"
}
},
"required": [
"username"
]
}
},
// Tool: updateUser (PUT /user/{username})
{
name: "updateUser",
description: `This can only be done by the logged in user.`,
inputSchema: {
"type": "object",
"properties": {
"username": {
"type": "string",
"description": "name that need to be deleted"
},
"requestBody": {
"type": "object",
"properties": {
"id": {
"type": "number",
"format": "int64"
},
"username": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"phone": {
"type": "string"
},
"userStatus": {
"type": "number",
"description": "User Status",
"format": "int32"
}
},
"description": "Update an existent user in the store"
}
},
"required": [
"username"
]
}
},
// Tool: deleteUser (DELETE /user/{username})
{
name: "deleteUser",
description: `This can only be done by the logged in user.`,
inputSchema: {
"type": "object",
"properties": {
"username": {
"type": "string",
"description": "The name that needs to be deleted"
}
},
"required": [
"username"
]
}
},
];
// --- Request Handlers ---
// 1. List Available Tools Handler
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: toolsList,
};
});
// 2. Call Tool Handler
// Corrected: Added explicit type for 'request' parameter
server.setRequestHandler(CallToolRequestSchema, async (request: CallToolRequest): Promise<CallToolResult> => {
const { name: toolName, arguments: toolArgs } = request.params;
const toolDefinition = toolsList.find(t => t.name === toolName);
if (!toolDefinition) {
console.error(`Error: Received request for unknown tool: ${toolName}`);
return { content: [{ type: "text", text: `Error: Unknown tool requested: ${toolName}` }] };
}
// --- Tool Execution Logic ---
// Handler for tool: updatePet
if (toolName === "updatePet") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/pet";
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Set Content-Type based on OpenAPI spec (or fallback)
if (typeof validatedArgs?.['requestBody'] !== 'undefined') { headers['content-type'] = 'application/json'; }
let requestBodyData: any = undefined;
if (validatedArgs && typeof validatedArgs['requestBody'] !== 'undefined') {
requestBodyData = validatedArgs['requestBody'];
}
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "PUT",
url: requestUrl,
params: queryParams,
headers: headers,
data: requestBodyData, // Pass the prepared request body data // Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: addPet
if (toolName === "addPet") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/pet";
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Set Content-Type based on OpenAPI spec (or fallback)
if (typeof validatedArgs?.['requestBody'] !== 'undefined') { headers['content-type'] = 'application/json'; }
let requestBodyData: any = undefined;
if (validatedArgs && typeof validatedArgs['requestBody'] !== 'undefined') {
requestBodyData = validatedArgs['requestBody'];
}
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "POST",
url: requestUrl,
params: queryParams,
headers: headers,
data: requestBodyData, // Pass the prepared request body data // Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: findPetsByStatus
if (toolName === "findPetsByStatus") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/pet/findByStatus";
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const status_val = validatedArgs['status'];
if (typeof status_val !== 'undefined' && status_val !== null) queryParams['status'] = status_val;
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "GET",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: findPetsByTags
if (toolName === "findPetsByTags") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/pet/findByTags";
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const tags_val = validatedArgs['tags'];
if (typeof tags_val !== 'undefined' && tags_val !== null) queryParams['tags'] = tags_val;
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "GET",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: getPetById
if (toolName === "getPetById") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/pet/{petId}";
const petId_val = validatedArgs['petId'];
if (typeof petId_val !== 'undefined' && petId_val !== null) { urlPath = urlPath.replace("{petId}", encodeURIComponent(String(petId_val))); }
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "GET",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: updatePetWithForm
if (toolName === "updatePetWithForm") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/pet/{petId}";
const petId_val = validatedArgs['petId'];
if (typeof petId_val !== 'undefined' && petId_val !== null) { urlPath = urlPath.replace("{petId}", encodeURIComponent(String(petId_val))); }
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const name_val = validatedArgs['name'];
if (typeof name_val !== 'undefined' && name_val !== null) queryParams['name'] = name_val;
const status_val = validatedArgs['status'];
if (typeof status_val !== 'undefined' && status_val !== null) queryParams['status'] = status_val;
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "POST",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: deletePet
if (toolName === "deletePet") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/pet/{petId}";
const petId_val = validatedArgs['petId'];
if (typeof petId_val !== 'undefined' && petId_val !== null) { urlPath = urlPath.replace("{petId}", encodeURIComponent(String(petId_val))); }
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
const api_key_val = validatedArgs['api_key'];
if (typeof api_key_val !== 'undefined' && api_key_val !== null) headers['api_key'] = String(api_key_val);
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "DELETE",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: uploadFile
if (toolName === "uploadFile") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/pet/{petId}/uploadImage";
const petId_val = validatedArgs['petId'];
if (typeof petId_val !== 'undefined' && petId_val !== null) { urlPath = urlPath.replace("{petId}", encodeURIComponent(String(petId_val))); }
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const additionalMetadata_val = validatedArgs['additionalMetadata'];
if (typeof additionalMetadata_val !== 'undefined' && additionalMetadata_val !== null) queryParams['additionalMetadata'] = additionalMetadata_val;
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Set Content-Type based on OpenAPI spec (or fallback)
if (typeof validatedArgs?.['requestBody'] !== 'undefined') { headers['content-type'] = 'application/octet-stream'; }
let requestBodyData: any = undefined;
if (validatedArgs && typeof validatedArgs['requestBody'] !== 'undefined') {
requestBodyData = validatedArgs['requestBody'];
}
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "POST",
url: requestUrl,
params: queryParams,
headers: headers,
data: requestBodyData, // Pass the prepared request body data // Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: getInventory
if (toolName === "getInventory") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/store/inventory";
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "GET",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: placeOrder
if (toolName === "placeOrder") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/store/order";
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Set Content-Type based on OpenAPI spec (or fallback)
if (typeof validatedArgs?.['requestBody'] !== 'undefined') { headers['content-type'] = 'application/json'; }
let requestBodyData: any = undefined;
if (validatedArgs && typeof validatedArgs['requestBody'] !== 'undefined') {
requestBodyData = validatedArgs['requestBody'];
}
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "POST",
url: requestUrl,
params: queryParams,
headers: headers,
data: requestBodyData, // Pass the prepared request body data // Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: getOrderById
if (toolName === "getOrderById") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/store/order/{orderId}";
const orderId_val = validatedArgs['orderId'];
if (typeof orderId_val !== 'undefined' && orderId_val !== null) { urlPath = urlPath.replace("{orderId}", encodeURIComponent(String(orderId_val))); }
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "GET",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: deleteOrder
if (toolName === "deleteOrder") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/store/order/{orderId}";
const orderId_val = validatedArgs['orderId'];
if (typeof orderId_val !== 'undefined' && orderId_val !== null) { urlPath = urlPath.replace("{orderId}", encodeURIComponent(String(orderId_val))); }
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "DELETE",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: createUser
if (toolName === "createUser") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/user";
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Set Content-Type based on OpenAPI spec (or fallback)
if (typeof validatedArgs?.['requestBody'] !== 'undefined') { headers['content-type'] = 'application/json'; }
let requestBodyData: any = undefined;
if (validatedArgs && typeof validatedArgs['requestBody'] !== 'undefined') {
requestBodyData = validatedArgs['requestBody'];
}
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "POST",
url: requestUrl,
params: queryParams,
headers: headers,
data: requestBodyData, // Pass the prepared request body data // Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: createUsersWithListInput
if (toolName === "createUsersWithListInput") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/user/createWithList";
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Set Content-Type based on OpenAPI spec (or fallback)
if (typeof validatedArgs?.['requestBody'] !== 'undefined') { headers['content-type'] = 'application/json'; }
let requestBodyData: any = undefined;
if (validatedArgs && typeof validatedArgs['requestBody'] !== 'undefined') {
requestBodyData = validatedArgs['requestBody'];
}
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "POST",
url: requestUrl,
params: queryParams,
headers: headers,
data: requestBodyData, // Pass the prepared request body data // Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: loginUser
if (toolName === "loginUser") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/user/login";
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const username_val = validatedArgs['username'];
if (typeof username_val !== 'undefined' && username_val !== null) queryParams['username'] = username_val;
const password_val = validatedArgs['password'];
if (typeof password_val !== 'undefined' && password_val !== null) queryParams['password'] = password_val;
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "GET",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: logoutUser
if (toolName === "logoutUser") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/user/logout";
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "GET",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: getUserByName
if (toolName === "getUserByName") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/user/{username}";
const username_val = validatedArgs['username'];
if (typeof username_val !== 'undefined' && username_val !== null) { urlPath = urlPath.replace("{username}", encodeURIComponent(String(username_val))); }
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "GET",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: updateUser
if (toolName === "updateUser") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/user/{username}";
const username_val = validatedArgs['username'];
if (typeof username_val !== 'undefined' && username_val !== null) { urlPath = urlPath.replace("{username}", encodeURIComponent(String(username_val))); }
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Set Content-Type based on OpenAPI spec (or fallback)
if (typeof validatedArgs?.['requestBody'] !== 'undefined') { headers['content-type'] = 'application/json'; }
let requestBodyData: any = undefined;
if (validatedArgs && typeof validatedArgs['requestBody'] !== 'undefined') {
requestBodyData = validatedArgs['requestBody'];
}
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "PUT",
url: requestUrl,
params: queryParams,
headers: headers,
data: requestBodyData, // Pass the prepared request body data // Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} else
// Handler for tool: deleteUser
if (toolName === "deleteUser") {
try {
// --- Argument Validation using Zod ---
let validatedArgs: JsonObject;
try {
const zodSchema = getZodSchemaFromJsonSchema(toolDefinition.inputSchema, toolName);
const argsToParse = (typeof toolArgs === 'object' && toolArgs !== null) ? toolArgs : {};
validatedArgs = zodSchema.parse(argsToParse);
console.error(`Arguments validated successfully for tool '${toolName}'.`);
} catch (error: any) {
if (error instanceof ZodError) {
const validationErrorMessage = `Invalid arguments for tool '${toolName}': ${error.errors.map(e => `${e.path.join('.')} (${e.code}): ${e.message}`).join(', ')}`;
console.error(validationErrorMessage);
return { content: [{ type: 'text', text: validationErrorMessage }] };
} else {
console.error(`Unexpected error during argument validation setup for tool '${toolName}':`, error);
return { content: [{ type: 'text', text: `Internal server error during argument validation setup for tool '${toolName}'.` }] };
}
}
// --- End Argument Validation ---
// --- API Call Preparation ---
let urlPath = "/user/{username}";
const username_val = validatedArgs['username'];
if (typeof username_val !== 'undefined' && username_val !== null) { urlPath = urlPath.replace("{username}", encodeURIComponent(String(username_val))); }
if (urlPath.includes('{')) { throw new Error(`Validation passed but failed to resolve path parameters in URL: ${urlPath}. Check schema/validation logic.`); }
const requestUrl = API_BASE_URL ? `${API_BASE_URL}${urlPath}` : urlPath;
const queryParams: Record<string, any> = {};
const headers: Record<string, string> = { 'Accept': 'application/json' };
// Declare and assign requestBodyData *here*
// --- Axios Request Configuration ---
// Now 'requestBodyData' is declared before being referenced here
const config: AxiosRequestConfig = {
method: "DELETE",
url: requestUrl,
params: queryParams,
headers: headers,
// Include data property conditionally
// Add Authentication logic here if needed
};
console.error(`Executing tool "${toolName}": ${config.method} ${config.url}`);
// --- Execute API Call ---
const response = await axios(config);
// --- Process Successful Response ---
let responseText = '';
const contentType = response.headers['content-type']?.toLowerCase() || '';
if (contentType.includes('application/json') && typeof response.data === 'object' && response.data !== null) {
try { responseText = JSON.stringify(response.data, null, 2); }
catch (e) { responseText = "[Error: Failed to stringify JSON response]"; }
} else if (typeof response.data === 'string') {
responseText = response.data;
} else if (response.data !== undefined && response.data !== null) {
responseText = String(response.data);
} else {
responseText = `(Status: ${response.status} - No body content)`;
}
return { content: [ { type: "text", text: `API Response (Status: ${response.status}):\n${responseText}` } ], };
} catch (error: any) {
// --- Handle Errors (Post-Validation) ---
let errorMessage = `Error executing tool '${toolName}': ${error.message}`;
if (axios.isAxiosError(error)) { errorMessage = formatApiError(error); }
else if (error instanceof Error) { errorMessage = error.message; }
else { errorMessage = 'An unexpected error occurred: ' + String(error); }
console.error(`Error during execution of tool '${toolName}':`, errorMessage, error.stack);
return { content: [{ type: "text", text: errorMessage }] };
}
} // This generated code now includes Zod validation
// Fallback error
console.error(`Error: Handler logic missing for tool: ${toolName}. This indicates an issue in the generator.`);
return { content: [{ type: "text", text: `Error: Internal server error - handler not implemented for tool: ${toolName}` }] };
});
// --- Main Execution Function ---
async function main() {
try {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error(`${SERVER_NAME} MCP Server (v${SERVER_VERSION}) running on stdio${API_BASE_URL ? `, proxying API at ${API_BASE_URL}` : ''}`);
} catch (error) {
console.error("Error during server startup:", error);
process.exit(1);
}
}
// --- Cleanup Function ---
async function cleanup() {
console.error("Shutting down MCP server...");
process.exit(0);
}
// Register signal handlers
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
// --- Start the Server ---
main().catch((error) => {
console.error("Fatal error in main execution:", error);
process.exit(1);
});
// --- Helper Functions (Included in the generated server code) ---
function formatApiError(error: AxiosError): string {
let message = 'API request failed.';
if (error.response) {
message = `API Error: Status ${error.response.status} (${error.response.statusText || 'Status text not available'}). `;
const responseData = error.response.data;
const MAX_LEN = 200;
if (typeof responseData === 'string') {
message += `Response: ${responseData.substring(0, MAX_LEN)}${responseData.length > MAX_LEN ? '...' : ''}`;
} else if (responseData) {
try {
const jsonString = JSON.stringify(responseData);
message += `Response: ${jsonString.substring(0, MAX_LEN)}${jsonString.length > MAX_LEN ? '...' : ''}`;
} catch {
message += 'Response: [Could not serialize response data]';
}
} else {
message += 'No response body received.';
}
} else if (error.request) {
message = 'API Network Error: No response received from the server. Check network connectivity or server availability.';
if (error.code) message += ` (Code: ${error.code})`;
} else {
message = `API Request Setup Error: ${error.message}`;
}
return message;
}
/**
* Attempts to dynamically generate and evaluate a Zod schema from a JSON schema.
* WARNING: Uses eval(), which can be a security risk if the schema input is untrusted.
* In this context, the schema originates from the generator/OpenAPI spec, reducing risk.
* @param jsonSchema The JSON Schema object (or boolean).
* @param toolName For error logging.
* @returns The evaluated Zod schema object.
* @throws If schema conversion or evaluation fails.
*/
function getZodSchemaFromJsonSchema(jsonSchema: any, toolName: string): z.ZodTypeAny {
if (typeof jsonSchema !== 'object' || jsonSchema === null) {
// Handle boolean schemas or invalid input
console.warn(`Cannot generate Zod schema for non-object JSON schema for tool '${toolName}'. Input type: ${typeof jsonSchema}`)
// Fallback to allowing any object - adjust if stricter handling is needed
return z.object({}).passthrough();
}
try {
// Note: jsonSchemaToZod may require specific configurations or adjustments
// depending on the complexity of the JSON Schemas being converted.
const zodSchemaString = jsonSchemaToZod(jsonSchema);
// IMPORTANT: Using eval() to execute the generated Zod schema string.
// This is generally discouraged due to security risks with untrusted input.
// Ensure the JSON schemas processed here are from trusted sources (like your OpenAPI spec).
// The 'z' variable (from imported zod) must be in scope for eval.
const zodSchema = eval(zodSchemaString);
if (typeof zodSchema?.parse !== 'function') {
throw new Error('Generated Zod schema string did not evaluate to a valid Zod schema object.');
}
return zodSchema as z.ZodTypeAny;
} catch (err: any) {
console.error(`Failed to generate or evaluate Zod schema for tool '${toolName}':`, err);
// Fallback schema in case of conversion/evaluation error
// This allows any object, effectively skipping validation on error.
// Consider throwing the error if validation is critical.
return z.object({}).passthrough();
}
}