nodesSetPorts
Configure network port settings like speed, MTU, VLAN, and roles for nodes in Hyperfabric infrastructure via REST API to manage fabric connectivity.
Instructions
Update the list of ports.
[SAFE OPERATION] This tool configures network fabric port settings (speed, MTU, VLAN, etc.) via REST API. It does NOT execute code or commands on the system.
To use this tool, pass the resource ID and the fields to update as arguments
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| fabricId | Yes | The fabric id or name. | |
| nodeId | Yes | The node id or name. | |
| ports | No | The list of ports of the node. |
Implementation Reference
- src/main.ts:337-448 (handler)Core handler for all MCP tools, dynamically dispatches nodesSetPorts to the corresponding Hyperfabric API endpoint by reverse-mapping tool name to OpenAPI path/method/operation. Includes specific pre-execution security check for nodesSetPorts.private async executeApiCall(toolName: string, args: any): Promise<any> { // Validate inputs for port configuration tools to prevent misuse if (toolName === 'nodesSetPorts' || toolName === 'nodesUpdatePort') { // Ensure no executable content or shell commands in arguments const argsStr = JSON.stringify(args); if (/(\$\(|`|eval|exec|system|spawn|child_process)/.test(argsStr)) { throw new Error('Security: Invalid arguments detected. Port configuration tools only accept network settings (speed, MTU, VLAN, etc.)'); } } // Extract the original method and path from the tool name // This is a simplified approach - in a production system you'd want a more robust mapping if (!this.openApiSpec?.paths) { throw new Error("OpenAPI spec not loaded"); } // Find the corresponding operation let foundOperation: { method: string; path: string; operation: OpenAPIOperation } | null = null; for (const [pathKey, pathItem] of Object.entries(this.openApiSpec.paths)) { for (const [method, operation] of Object.entries(pathItem)) { if (typeof operation !== 'object' || !operation) continue; const op = operation as OpenAPIOperation; const expectedToolName = this.generateToolName(method, pathKey, op); if (expectedToolName === toolName) { foundOperation = { method, path: pathKey, operation: op }; break; } } if (foundOperation) break; } if (!foundOperation) { throw new Error(`No operation found for tool: ${toolName}`); } // Build the URL by replacing path parameters let url = foundOperation.path; const queryParams: Record<string, string> = {}; // Handle path and query parameters if (foundOperation.operation.parameters) { for (const param of foundOperation.operation.parameters) { const value = args[param.name]; if (value !== undefined) { if (param.in === 'path') { url = url.replace(`{${param.name}}`, encodeURIComponent(value)); } else if (param.in === 'query') { queryParams[param.name] = value; } } } } // Prepare the request const requestConfig: any = { method: foundOperation.method.toUpperCase(), url, params: queryParams, }; // Handle request body for POST/PUT/PATCH if (['post', 'put', 'patch'].includes(foundOperation.method.toLowerCase())) { // Check if args has a requestBody property (legacy format) if (args.requestBody) { requestConfig.data = args.requestBody; } else { // Build request body from exposed properties // This handles cases where schema properties are exposed directly (e.g., fabrics, nodes, etc.) const requestBody: Record<string, any> = {}; const pathItem = this.openApiSpec?.paths?.[foundOperation.path]; const operation = (pathItem as any)?.[foundOperation.method]; if (operation?.requestBody) { const requestBodyDef = this.resolveSchemaRef(operation.requestBody); const schema = this.deepResolveSchema(requestBodyDef.content?.['application/json']?.schema); // Collect all properties that are part of the request body schema if (schema?.properties) { for (const propName of Object.keys(schema.properties)) { if (args.hasOwnProperty(propName)) { requestBody[propName] = args[propName]; } } } } if (Object.keys(requestBody).length > 0) { requestConfig.data = requestBody; } } } logger.debug(`Making API call: ${requestConfig.method} ${url}`); try { const response = await this.httpClient.request(requestConfig); return { status: response.status, statusText: response.statusText, data: response.data }; } catch (error) { if (axios.isAxiosError(error)) { throw new Error(`API call failed: ${error.response?.status} ${error.response?.statusText} - ${JSON.stringify(error.response?.data)}`); } throw error; } }
- src/main.ts:213-290 (schema)Generates the Tool object for nodesSetPorts from OpenAPI spec, including inputSchema derived from operation parameters and requestBody schema. Adds specific safety description.private createToolFromOperation( name: string, method: string, path: string, operation: OpenAPIOperation ): Tool | null { let description = operation.summary || operation.description || `${method.toUpperCase()} ${path}`; // Add security context for network port configuration operations if (name === 'nodesSetPorts' || name === 'nodesUpdatePort') { description += '\n\n[SAFE OPERATION] This tool configures network fabric port settings (speed, MTU, VLAN, etc.) via REST API. It does NOT execute code or commands on the system.'; } // Enhance description for create/update operations if (['post', 'put', 'patch'].includes(method.toLowerCase())) { if (method.toLowerCase() === 'post') { description += '\n\nTo use this tool, pass the required fields as direct arguments (e.g., fabrics=[{name:"my-fabric", description:"...", ...}])'; } else if (method.toLowerCase() === 'put') { description += '\n\nTo use this tool, pass the resource ID and the fields to update as arguments'; } else if (method.toLowerCase() === 'patch') { description += '\n\nTo use this tool, pass the resource ID and the fields to patch as arguments'; } } const properties: Record<string, any> = {}; const required: string[] = []; // Process parameters if (operation.parameters) { for (const param of operation.parameters) { if (param.in === 'path' || param.in === 'query') { properties[param.name] = { type: param.schema?.type || 'string', description: param.description || '' }; if (param.required) { required.push(param.name); } } } } // Process request body for POST/PUT/PATCH requests if (operation.requestBody && ['post', 'put', 'patch'].includes(method.toLowerCase())) { // Resolve the requestBody reference if it exists const requestBody = this.resolveSchemaRef(operation.requestBody); const content = requestBody.content; if (content?.['application/json']?.schema) { let schema = content['application/json'].schema; // Deeply resolve schema references schema = this.deepResolveSchema(schema); if (schema.properties) { // Expose the request body properties directly for (const [propName, propSchema] of Object.entries(schema.properties)) { const propDef = propSchema as any; properties[propName] = this.deepResolveSchema(propDef, 0); if (schema.required?.includes(propName)) { required.push(propName); } } } } } return { name, description, inputSchema: { type: 'object', properties, required } }; }
- src/main.ts:134-158 (registration)Dynamically generates and registers all tools, including nodesSetPorts, by iterating over OpenAPI paths/operations and pushing Tool objects to this.tools array, which is returned by listTools handler.private generateTools(): void { if (!this.openApiSpec?.paths) { logger.error("No paths found in OpenAPI spec"); return; } this.tools = []; for (const [pathKey, pathItem] of Object.entries(this.openApiSpec.paths)) { for (const [method, operation] of Object.entries(pathItem)) { if (typeof operation !== 'object' || !operation) continue; const op = operation as OpenAPIOperation; const toolName = this.generateToolName(method, pathKey, op); const tool = this.createToolFromOperation(toolName, method, pathKey, op); if (tool) { this.tools.push(tool); logger.debug(`Generated tool: ${toolName}`); } } } logger.info(`Generated ${this.tools.length} tools from OpenAPI spec`); }
- src/main.ts:339-345 (helper)Helper security validation block specific to nodesSetPorts tool arguments.if (toolName === 'nodesSetPorts' || toolName === 'nodesUpdatePort') { // Ensure no executable content or shell commands in arguments const argsStr = JSON.stringify(args); if (/(\$\(|`|eval|exec|system|spawn|child_process)/.test(argsStr)) { throw new Error('Security: Invalid arguments detected. Port configuration tools only accept network settings (speed, MTU, VLAN, etc.)'); } }
- src/main.ts:222-224 (helper)Helper that appends specific safety description to nodesSetPorts tool.if (name === 'nodesSetPorts' || name === 'nodesUpdatePort') { description += '\n\n[SAFE OPERATION] This tool configures network fabric port settings (speed, MTU, VLAN, etc.) via REST API. It does NOT execute code or commands on the system.'; }