get_switch_info
Retrieve detailed information about a specific switch in Sakura Cloud by providing its ID and zone. Enables infrastructure management and configuration insights.
Instructions
Get detailed information about a specific switch
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| switchId | Yes | The ID of the switch to retrieve | |
| zone | No | The zone to use (e.g., "tk1v", "is1a", "tk1a"). Defaults to "tk1v" if not specified. |
Implementation Reference
- src/server.ts:1489-1512 (handler)The execution handler for the get_switch_info tool within the CallToolRequestSchema handler. It validates credentials, extracts switchId and optional zone, calls fetchFromSakuraCloud to get switch details from /switch/{switchId}, and returns JSON stringified response.} else if (request.params.name === 'get_switch_info') { try { validateCredentials(); const switchId = request.params.arguments?.switchId as string; if (!switchId) { throw new Error('Switch ID is required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const switchInfo = await fetchFromSakuraCloud(`/switch/${switchId}`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(switchInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; }
- src/server.ts:787-802 (schema)The schema definition and registration of the get_switch_info tool in the ListToolsRequestSchema response, including input schema with required switchId and optional zone.name: 'get_switch_info', description: 'Get detailed information about a specific switch', inputSchema: { type: 'object', properties: { switchId: { type: 'string', description: 'The ID of the switch to retrieve' }, zone: { type: 'string', description: 'The zone to use (e.g., "tk1v", "is1a", "tk1a"). Defaults to "tk1v" if not specified.' } }, required: ['switchId'] }
- src/server.ts:20-72 (helper)Core helper function fetchFromSakuraCloud used by get_switch_info to perform authenticated HTTPS GET requests to Sakura Cloud API endpoints, constructing the path with zone and handling JSON responses.async function fetchFromSakuraCloud(path: string, isPublicAPI: boolean = false, zone: string = DEFAULT_ZONE, method: string = 'GET', bodyData?: any): Promise<any> { return new Promise((resolve, reject) => { const basePath = isPublicAPI ? '/cloud/api/cloud/1.1' : `/cloud/zone/${zone}/api/cloud/1.1`; const options = { hostname: 'secure.sakura.ad.jp', port: 443, path: `${basePath}${path}`, method: method, headers: { 'Accept': 'application/json', 'Authorization': '', 'Content-Type': 'application/json' } }; // Add authorization for non-public APIs if (!isPublicAPI) { options.headers['Authorization'] = `Basic ${Buffer.from(`${SACLOUD_API_TOKEN}:${SACLOUD_API_SECRET}`).toString('base64')}`; } const req = https.request(options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { try { if (data) { const parsedData = JSON.parse(data); resolve(parsedData); } else { resolve({}); } } catch (err) { reject(new Error(`Failed to parse response: ${err}`)); } }); }); req.on('error', (error) => { reject(error); }); if (bodyData && (method === 'POST' || method === 'PUT')) { req.write(JSON.stringify(bodyData)); } req.end(); }); }
- src/server.ts:125-129 (helper)Helper function validateCredentials called by get_switch_info handler to ensure environment variables SACLOUD_API_TOKEN and SACLOUD_API_SECRET are set.function validateCredentials(): void { if (!SACLOUD_API_TOKEN || !SACLOUD_API_SECRET) { throw new Error('Missing API credentials. Set SACLOUD_API_TOKEN and SACLOUD_API_SECRET environment variables.'); } }
- src/server.ts:1426-2469 (registration)The overall registration of the CallToolRequestSchema handler which dispatches to the specific get_switch_info implementation via name matching.server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === 'get_server_info') { try { validateCredentials(); const serverId = request.params.arguments?.serverId as string; if (!serverId) { throw new Error('Server ID is required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const serverInfo = await fetchFromSakuraCloud(`/server/${serverId}`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(serverInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_server_list') { try { validateCredentials(); const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const serverList = await fetchFromSakuraCloud(`/server`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(serverList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_switch_list') { try { validateCredentials(); const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const switchList = await fetchFromSakuraCloud(`/switch`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(switchList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_switch_info') { try { validateCredentials(); const switchId = request.params.arguments?.switchId as string; if (!switchId) { throw new Error('Switch ID is required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const switchInfo = await fetchFromSakuraCloud(`/switch/${switchId}`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(switchInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_appliance_list') { try { validateCredentials(); const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const applianceList = await fetchFromSakuraCloud(`/appliance`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(applianceList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_appliance_info') { try { validateCredentials(); const applianceId = request.params.arguments?.applianceId as string; if (!applianceId) { throw new Error('Appliance ID is required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const applianceInfo = await fetchFromSakuraCloud(`/appliance/${applianceId}`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(applianceInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_disk_list') { try { validateCredentials(); const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const diskList = await fetchFromSakuraCloud(`/disk`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(diskList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_disk_info') { try { validateCredentials(); const diskId = request.params.arguments?.diskId as string; if (!diskId) { throw new Error('Disk ID is required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const diskInfo = await fetchFromSakuraCloud(`/disk/${diskId}`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(diskInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_archive_list') { try { validateCredentials(); const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const archiveList = await fetchFromSakuraCloud(`/archive`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(archiveList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_archive_info') { try { validateCredentials(); const archiveId = request.params.arguments?.archiveId as string; if (!archiveId) { throw new Error('Archive ID is required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const archiveInfo = await fetchFromSakuraCloud(`/archive/${archiveId}`, false, zone); return { content: [ { type: 'text', text: JSON.stringify(archiveInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_cdrom_list') { try { validateCredentials(); const cdromList = await fetchFromSakuraCloud(`/cdrom`); return { content: [ { type: 'text', text: JSON.stringify(cdromList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_cdrom_info') { try { validateCredentials(); const cdromId = request.params.arguments?.cdromId as string; if (!cdromId) { throw new Error('ISO Image ID is required'); } const cdromInfo = await fetchFromSakuraCloud(`/cdrom/${cdromId}`); return { content: [ { type: 'text', text: JSON.stringify(cdromInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_bridge_list') { try { validateCredentials(); const bridgeList = await fetchFromSakuraCloud(`/bridge`); return { content: [ { type: 'text', text: JSON.stringify(bridgeList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_bridge_info') { try { validateCredentials(); const bridgeId = request.params.arguments?.bridgeId as string; if (!bridgeId) { throw new Error('Bridge ID is required'); } const bridgeInfo = await fetchFromSakuraCloud(`/bridge/${bridgeId}`); return { content: [ { type: 'text', text: JSON.stringify(bridgeInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_router_list') { try { validateCredentials(); const routerList = await fetchFromSakuraCloud(`/internet`); return { content: [ { type: 'text', text: JSON.stringify(routerList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_router_info') { try { validateCredentials(); const routerId = request.params.arguments?.routerId as string; if (!routerId) { throw new Error('Router ID is required'); } const routerInfo = await fetchFromSakuraCloud(`/internet/${routerId}`); return { content: [ { type: 'text', text: JSON.stringify(routerInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_interface_list') { try { validateCredentials(); const interfaceList = await fetchFromSakuraCloud(`/interface`); return { content: [ { type: 'text', text: JSON.stringify(interfaceList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_interface_info') { try { validateCredentials(); const interfaceId = request.params.arguments?.interfaceId as string; if (!interfaceId) { throw new Error('Interface ID is required'); } const interfaceInfo = await fetchFromSakuraCloud(`/interface/${interfaceId}`); return { content: [ { type: 'text', text: JSON.stringify(interfaceInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_icon_list') { try { validateCredentials(); const iconList = await fetchFromSakuraCloud(`/icon`); return { content: [ { type: 'text', text: JSON.stringify(iconList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_icon_info') { try { validateCredentials(); const iconId = request.params.arguments?.iconId as string; if (!iconId) { throw new Error('Icon ID is required'); } const iconInfo = await fetchFromSakuraCloud(`/icon/${iconId}`); return { content: [ { type: 'text', text: JSON.stringify(iconInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_note_list') { try { validateCredentials(); const noteList = await fetchFromSakuraCloud(`/note`); return { content: [ { type: 'text', text: JSON.stringify(noteList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_note_info') { try { validateCredentials(); const noteId = request.params.arguments?.noteId as string; if (!noteId) { throw new Error('Note ID is required'); } const noteInfo = await fetchFromSakuraCloud(`/note/${noteId}`); return { content: [ { type: 'text', text: JSON.stringify(noteInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_sshkey_list') { try { validateCredentials(); const sshkeyList = await fetchFromSakuraCloud(`/sshkey`); return { content: [ { type: 'text', text: JSON.stringify(sshkeyList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_sshkey_info') { try { validateCredentials(); const sshkeyId = request.params.arguments?.sshkeyId as string; if (!sshkeyId) { throw new Error('SSH Key ID is required'); } const sshkeyInfo = await fetchFromSakuraCloud(`/sshkey/${sshkeyId}`); return { content: [ { type: 'text', text: JSON.stringify(sshkeyInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_region_list') { try { validateCredentials(); const regionList = await fetchFromSakuraCloud(`/region`); return { content: [ { type: 'text', text: JSON.stringify(regionList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_region_info') { try { validateCredentials(); const regionId = request.params.arguments?.regionId as string; if (!regionId) { throw new Error('Region ID is required'); } const regionInfo = await fetchFromSakuraCloud(`/region/${regionId}`); return { content: [ { type: 'text', text: JSON.stringify(regionInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_zone_list') { try { validateCredentials(); const zoneList = await fetchFromSakuraCloud(`/zone`); return { content: [ { type: 'text', text: JSON.stringify(zoneList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_zone_info') { try { validateCredentials(); const zoneId = request.params.arguments?.zoneId as string; if (!zoneId) { throw new Error('Zone ID is required'); } const zoneInfo = await fetchFromSakuraCloud(`/zone/${zoneId}`); return { content: [ { type: 'text', text: JSON.stringify(zoneInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_product_info') { try { validateCredentials(); const productType = request.params.arguments?.productType as string; if (!productType) { throw new Error('Product type is required'); } // Validate product type if (!['server', 'disk', 'internet', 'license'].includes(productType)) { throw new Error('Invalid product type. Must be one of: server, disk, internet, license'); } const productInfo = await fetchFromSakuraCloud(`/product/${productType}`); return { content: [ { type: 'text', text: JSON.stringify(productInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_commonserviceitem_list') { try { validateCredentials(); const commonServiceItemList = await fetchFromSakuraCloud(`/commonserviceitem`); return { content: [ { type: 'text', text: JSON.stringify(commonServiceItemList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_commonserviceitem_info') { try { validateCredentials(); const itemId = request.params.arguments?.itemId as string; if (!itemId) { throw new Error('Common Service Item ID is required'); } const itemInfo = await fetchFromSakuraCloud(`/commonserviceitem/${itemId}`); return { content: [ { type: 'text', text: JSON.stringify(itemInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_license_list') { try { validateCredentials(); const licenseList = await fetchFromSakuraCloud(`/license`); return { content: [ { type: 'text', text: JSON.stringify(licenseList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_license_info') { try { validateCredentials(); const licenseId = request.params.arguments?.licenseId as string; if (!licenseId) { throw new Error('License ID is required'); } const licenseInfo = await fetchFromSakuraCloud(`/license/${licenseId}`); return { content: [ { type: 'text', text: JSON.stringify(licenseInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_bill_info') { try { validateCredentials(); const year = request.params.arguments?.year as string; const month = request.params.arguments?.month as string; if (!year || !month) { throw new Error('Year and month are required for billing information'); } const billInfo = await fetchFromSakuraCloud(`/bill/${year}${month}`); return { content: [ { type: 'text', text: JSON.stringify(billInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_bill_detail') { try { validateCredentials(); const year = request.params.arguments?.year as string; const month = request.params.arguments?.month as string; if (!year || !month) { throw new Error('Year and month are required for billing details'); } const billDetailInfo = await fetchFromSakuraCloud(`/bill/${year}${month}/detail`); return { content: [ { type: 'text', text: JSON.stringify(billDetailInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_coupon_info') { try { validateCredentials(); const couponId = request.params.arguments?.couponId as string; if (!couponId) { throw new Error('Coupon ID is required'); } const couponInfo = await fetchFromSakuraCloud(`/coupon/${couponId}`); return { content: [ { type: 'text', text: JSON.stringify(couponInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_privatehost_info') { try { validateCredentials(); const privateHostId = request.params.arguments?.privateHostId as string; if (!privateHostId) { throw new Error('Private Host ID is required'); } const privateHostInfo = await fetchFromSakuraCloud(`/privatehost/${privateHostId}`); return { content: [ { type: 'text', text: JSON.stringify(privateHostInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_public_price') { try { // No authentication needed for public price API const priceData = await fetchFromSakuraCloud('/public/price', true); return { content: [ { type: 'text', text: JSON.stringify(priceData, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_apprun_list') { try { validateCredentials(); const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const appRunList = await fetchFromAppRunAPI('/applications'); return { content: [ { type: 'text', text: JSON.stringify(appRunList, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_apprun_info') { try { validateCredentials(); const appId = request.params.arguments?.appId as string; if (!appId) { throw new Error('AppRun application ID is required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const appRunInfo = await fetchFromAppRunAPI(`/applications/${appId}`); return { content: [ { type: 'text', text: JSON.stringify(appRunInfo, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'create_apprun') { try { validateCredentials(); const name = request.params.arguments?.name as string; const description = request.params.arguments?.description as string || ''; const dockerImage = request.params.arguments?.dockerImage as string; const planId = request.params.arguments?.planId as string; const environment = request.params.arguments?.environment as Array<{key: string, value: string}> || []; if (!name || !dockerImage || !planId) { throw new Error('Name, Docker image, and plan ID are required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const createBody = { name: name, description: description, planId: planId, image: dockerImage, environment: environment.map(env => ({ key: env.key, value: env.value })), }; const createResult = await fetchFromAppRunAPI('/applications', 'POST', createBody); return { content: [ { type: 'text', text: JSON.stringify(createResult, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'delete_apprun') { try { validateCredentials(); const appId = request.params.arguments?.appId as string; if (!appId) { throw new Error('AppRun application ID is required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const deleteResult = await fetchFromAppRunAPI(`/applications/${appId}`, 'DELETE'); return { content: [ { type: 'text', text: JSON.stringify(deleteResult, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'start_apprun') { try { validateCredentials(); const appId = request.params.arguments?.appId as string; if (!appId) { throw new Error('AppRun application ID is required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const startResult = await fetchFromAppRunAPI(`/applications/${appId}/start`, 'POST'); return { content: [ { type: 'text', text: JSON.stringify(startResult, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'stop_apprun') { try { validateCredentials(); const appId = request.params.arguments?.appId as string; if (!appId) { throw new Error('AppRun application ID is required'); } const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const stopResult = await fetchFromAppRunAPI(`/applications/${appId}/stop`, 'POST'); return { content: [ { type: 'text', text: JSON.stringify(stopResult, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'update_apprun') { try { validateCredentials(); const appId = request.params.arguments?.appId as string; if (!appId) { throw new Error('AppRun application ID is required'); } // Get current application data first const currentApp = await fetchFromAppRunAPI(`/applications/${appId}`); // Extract current values const currentName = currentApp.name || ''; const currentDescription = currentApp.description || ''; const currentPlanId = currentApp.planId || ''; const currentDockerImage = currentApp.image || ''; const currentEnvironment = currentApp.environment || []; // Get update values from request or use current values const name = request.params.arguments?.name as string || currentName; const description = request.params.arguments?.description as string || currentDescription; const planId = request.params.arguments?.planId as string || currentPlanId; const dockerImage = request.params.arguments?.dockerImage as string || currentDockerImage; const environment = request.params.arguments?.environment as Array<{key: string, value: string}> || currentEnvironment.map((env: {Key: string, Value: string}) => ({ key: env.Key, value: env.Value })); const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const updateBody = { name: name, description: description, planId: planId, image: dockerImage, environment: environment.map(env => ({ key: env.key, value: env.value })), }; const updateResult = await fetchFromAppRunAPI(`/applications/${appId}`, 'PUT', updateBody); return { content: [ { type: 'text', text: JSON.stringify(updateResult, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } else if (request.params.name === 'get_apprun_logs') { try { validateCredentials(); const appId = request.params.arguments?.appId as string; if (!appId) { throw new Error('AppRun application ID is required'); } const offset = request.params.arguments?.offset as number || 0; const limit = request.params.arguments?.limit as number || 100; const zone = request.params.arguments?.zone as string || DEFAULT_ZONE; const logsQuery = `/applications/${appId}/logs?offset=${offset}&limit=${limit}`; const logs = await fetchFromAppRunAPI(logsQuery); return { content: [ { type: 'text', text: JSON.stringify(logs, null, 2) } ] }; } catch (error) { console.error('Error calling tool:', error); throw error; } } throw new Error(`Tool not found: ${request.params.name}`); });