| 271 | ) |
| 272 | |
| 273 | function validateToolArguments(tool: McpTool, args: Record<string, unknown>): string | null { |
| 274 | if (!tool.inputSchema) { |
| 275 | return null |
| 276 | } |
| 277 | |
| 278 | const schema = tool.inputSchema |
| 279 | |
| 280 | if (schema.required && Array.isArray(schema.required)) { |
| 281 | for (const requiredProp of schema.required) { |
| 282 | if (!(requiredProp in (args || {}))) { |
| 283 | return `Missing required property: ${requiredProp}` |
| 284 | } |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | if (schema.properties && args) { |
| 289 | for (const [propName, propSchema] of Object.entries(schema.properties)) { |
| 290 | const propValue = args[propName] |
| 291 | if (propValue !== undefined && hasType(propSchema)) { |
| 292 | const expectedType = propSchema.type |
| 293 | const actualType = typeof propValue |
| 294 | |
| 295 | if (expectedType === 'string' && actualType !== 'string') { |
| 296 | return `Property ${propName} must be a string` |
| 297 | } |
| 298 | if (expectedType === 'number' && actualType !== 'number') { |
| 299 | return `Property ${propName} must be a number` |
| 300 | } |
| 301 | if ( |
| 302 | expectedType === 'integer' && |
| 303 | (actualType !== 'number' || !Number.isInteger(propValue)) |
| 304 | ) { |
| 305 | return `Property ${propName} must be an integer` |
| 306 | } |
| 307 | if (expectedType === 'boolean' && actualType !== 'boolean') { |
| 308 | return `Property ${propName} must be a boolean` |
| 309 | } |
| 310 | if ( |
| 311 | expectedType === 'object' && |
| 312 | (actualType !== 'object' || propValue === null || Array.isArray(propValue)) |
| 313 | ) { |
| 314 | return `Property ${propName} must be an object` |
| 315 | } |
| 316 | if (expectedType === 'array' && !Array.isArray(propValue)) { |
| 317 | return `Property ${propName} must be an array` |
| 318 | } |
| 319 | } |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | return null |
| 324 | } |
| 325 | |
| 326 | function transformToolResult(result: McpToolResult): ToolExecutionResult { |
| 327 | if (result.isError) { |