vrfsGetFabricStaticRoute
Retrieve a specific static route configuration from a VRF in Hyperfabric network infrastructure by providing fabric, VRF, and route identifiers.
Instructions
Get a specific static route.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| fabricId | Yes | The fabric id or name. | |
| vrfId | Yes | The vrf id or name. | |
| routeId | Yes | The route id or name. | |
| candidate | No | The candidate configuration name. If not set the default candidate configuration values are returned. | |
| includeMetadata | No | Include object metadata in the response. |
Implementation Reference
- src/main.ts:337-448 (handler)This function implements the core logic for executing the 'vrfsGetFabricStaticRoute' tool (and all others) by dynamically mapping the tool name to the corresponding OpenAPI operation, constructing the HTTP request with path/query/body parameters, and calling the Hyperfabric API.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:134-158 (registration)Dynamically generates and registers all MCP tools, including 'vrfsGetFabricStaticRoute', by iterating over OpenAPI spec paths and operations, using operationId or generating from method/path.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:213-290 (schema)Generates the input schema, description, and Tool object for 'vrfsGetFabricStaticRoute' (and others) by processing OpenAPI operation parameters, query params, and requestBody schema.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:293-296 (registration)Registers the MCP ListTools handler that returns the list of available tools including 'vrfsGetFabricStaticRoute'.this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: this.tools }; });
- src/main.ts:297-335 (handler)MCP CallTool request handler that dispatches to executeApiCall for the specific tool 'vrfsGetFabricStaticRoute'.this.server.setRequestHandler(CallToolRequestSchema, async (request: any) => { const { name, arguments: args } = request.params; logger.info(`Calling tool: ${name}`); logger.debug(`Tool arguments: ${JSON.stringify(args, null, 2)}`); try { // Find the tool definition const tool = this.tools.find(t => t.name === name); if (!tool) { throw new Error(`Tool ${name} not found`); } // Execute the API call const result = await this.executeApiCall(name, args); return { content: [ { type: "text", text: JSON.stringify(result, null, 2) } ] }; } catch (error) { logger.error(`Error executing tool ${name}:`, error); return { content: [ { type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } }); }