- 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.
2220 lines
98 KiB
TypeScript
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();
|
|
}
|
|
}
|