leshan-mcp-server
Version:
A standards-compliant MCP server for Leshan LwM2M, exposing Leshan as Model Context Protocol tools.
101 lines (88 loc) • 3.11 kB
JavaScript
import { get } from "../utils/leshanClient.js";
import { deviceIdSchema } from "../utils/validation.js";
import logger from "../utils/loggerConfig.js";
/**
* Get detailed information about a specific LwM2M device
* @param {Object} params - Parameters
* @param {string} params.deviceId - Device endpoint
* @returns {Promise<Object>} MCP tool response
*/
export async function getDeviceInfo({ deviceId }) {
const operationId = `get-device-info-${Date.now()}`;
try {
logger.info("Get device info operation started", { operationId, deviceId });
const validatedDeviceId = deviceIdSchema.parse(deviceId);
const endpoint = `/clients/${encodeURIComponent(validatedDeviceId)}`;
logger.debug("Fetching device information", { operationId, endpoint });
const deviceInfo = await get(endpoint);
if (!deviceInfo) {
throw new Error(`Device '${validatedDeviceId}' not found`);
}
// Enrich device info with additional details
const enrichedInfo = {
basic: {
endpoint: deviceInfo.endpoint,
registrationId: deviceInfo.registrationId,
registrationDate: new Date(deviceInfo.registrationDate).toISOString(),
lastUpdate: new Date(deviceInfo.lastUpdate).toISOString(),
address: deviceInfo.address,
port: deviceInfo.port,
lifetime: deviceInfo.lifetime,
bindingMode: deviceInfo.bindingMode,
lwM2mVersion: deviceInfo.lwM2mVersion
},
objects: Object.keys(deviceInfo.availableInstances || {}).map(objId => ({
objectId: parseInt(objId),
instances: deviceInfo.availableInstances[objId] || []
})),
objectCount: Object.keys(deviceInfo.availableInstances || {}).length,
totalInstances: Object.values(deviceInfo.availableInstances || {})
.reduce((sum, instances) => sum + instances.length, 0)
};
logger.info("Device info retrieved successfully", {
operationId,
deviceId: validatedDeviceId,
objectCount: enrichedInfo.objectCount,
totalInstances: enrichedInfo.totalInstances
});
return {
content: [{
type: "text",
text: JSON.stringify({
success: true,
operation: "getDeviceInfo",
operationId,
timestamp: new Date().toISOString(),
device: enrichedInfo,
rawData: deviceInfo
}, null, 2)
}]
};
} catch (error) {
logger.error("Get device info operation failed", {
operationId,
deviceId,
error: error.message,
errorType: error.constructor.name
});
return {
content: [{
type: "text",
text: JSON.stringify({
success: false,
operation: "getDeviceInfo",
operationId,
timestamp: new Date().toISOString(),
error: {
message: error.message,
type: error.constructor.name,
...(error.statusCode && { statusCode: error.statusCode })
},
request: { deviceId }
}, null, 2)
}],
isError: true
};
}
}
export default getDeviceInfo;