UNPKG

leshan-mcp-server

Version:

A standards-compliant MCP server for Leshan LwM2M, exposing Leshan as Model Context Protocol tools.

103 lines (90 loc) 3.13 kB
import { post } from "../utils/leshanClient.js"; import { validateLwM2MPath } from "../utils/validation.js"; import logger from "../utils/loggerConfig.js"; /** * Execute a resource on a LwM2M device * @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.arguments - Optional execution arguments * @returns {Promise<Object>} MCP tool response */ export async function executeResource({ deviceId, objectId, instanceId, resourceId, arguments: execArgs }) { const operationId = `execute-resource-${Date.now()}`; try { logger.info("Execute resource operation started", { operationId, deviceId, path: `${objectId}/${instanceId}/${resourceId}`, hasArguments: !!execArgs }); // Validate path parameters const validatedParams = validateLwM2MPath(deviceId, objectId, instanceId, resourceId); const endpoint = `/clients/${encodeURIComponent(validatedParams.deviceId)}/${validatedParams.objectId}/${validatedParams.instanceId}/${validatedParams.resourceId}`; const requestBody = execArgs ? { arguments: execArgs } : {}; logger.debug("Making execute request", { operationId, endpoint, requestBody }); const result = await post(endpoint, requestBody); logger.info("Resource executed successfully", { operationId, deviceId: validatedParams.deviceId, path: `${validatedParams.objectId}/${validatedParams.instanceId}/${validatedParams.resourceId}` }); return { content: [{ type: "text", text: JSON.stringify({ success: true, operation: "executeResource", operationId, timestamp: new Date().toISOString(), device: { endpoint: validatedParams.deviceId, path: `${validatedParams.objectId}/${validatedParams.instanceId}/${validatedParams.resourceId}` }, request: { arguments: execArgs }, result }, null, 2) }] }; } catch (error) { logger.error("Execute resource operation failed", { operationId, deviceId, path: `${objectId}/${instanceId}/${resourceId}`, arguments: execArgs, error: error.message, errorType: error.constructor.name }); return { content: [{ type: "text", text: JSON.stringify({ success: false, operation: "executeResource", operationId, timestamp: new Date().toISOString(), error: { message: error.message, type: error.constructor.name, ...(error.statusCode && { statusCode: error.statusCode }) }, request: { deviceId, path: `${objectId}/${instanceId}/${resourceId}`, arguments: execArgs } }, null, 2) }], isError: true }; } } export default executeResource;