leshan-mcp-server
Version:
A standards-compliant MCP server for Leshan LwM2M, exposing Leshan as Model Context Protocol tools.
106 lines (93 loc) • 3.2 kB
JavaScript
import { put } from "../utils/leshanClient.js";
import { validateLwM2MPath, validateResourceValue } from "../utils/validation.js";
import logger from "../utils/loggerConfig.js";
/**
* Write a value to a LwM2M device resource
* @param {Object} params - Parameters
* @param {string} params.deviceId - Device endpoint
* @param {string} params.objectId - Object ID
* @param {string} params.instanceId - Instance ID
* @param {string} params.resourceId - Resource ID
* @param {any} params.value - Value to write
* @returns {Promise<Object>} MCP tool response
*/
export async function writeResource({ deviceId, objectId, instanceId, resourceId, value }) {
const operationId = `write-resource-${Date.now()}`;
try {
logger.info("Write resource operation started", {
operationId,
deviceId,
path: `${objectId}/${instanceId}/${resourceId}`,
valueType: typeof value
});
// Validate path parameters
const validatedParams = validateLwM2MPath(deviceId, objectId, instanceId, resourceId);
// Validate resource value
const validatedValue = validateResourceValue(value);
const endpoint = `/clients/${encodeURIComponent(validatedParams.deviceId)}/${validatedParams.objectId}/${validatedParams.instanceId}/${validatedParams.resourceId}`;
logger.debug("Making write request", {
operationId,
endpoint,
value: validatedValue
});
const result = await put(endpoint, { value: validatedValue });
logger.info("Resource written successfully", {
operationId,
deviceId: validatedParams.deviceId,
path: `${validatedParams.objectId}/${validatedParams.instanceId}/${validatedParams.resourceId}`,
writtenValue: validatedValue
});
return {
content: [{
type: "text",
text: JSON.stringify({
success: true,
operation: "writeResource",
operationId,
timestamp: new Date().toISOString(),
device: {
endpoint: validatedParams.deviceId,
path: `${validatedParams.objectId}/${validatedParams.instanceId}/${validatedParams.resourceId}`
},
request: {
value: validatedValue,
originalValue: value
},
result
}, null, 2)
}]
};
} catch (error) {
logger.error("Write resource operation failed", {
operationId,
deviceId,
path: `${objectId}/${instanceId}/${resourceId}`,
value,
error: error.message,
errorType: error.constructor.name
});
return {
content: [{
type: "text",
text: JSON.stringify({
success: false,
operation: "writeResource",
operationId,
timestamp: new Date().toISOString(),
error: {
message: error.message,
type: error.constructor.name,
...(error.statusCode && { statusCode: error.statusCode })
},
request: {
deviceId,
path: `${objectId}/${instanceId}/${resourceId}`,
value
}
}, null, 2)
}],
isError: true
};
}
}
export default writeResource;