leshan-mcp-server
Version:
A standards-compliant MCP server for Leshan LwM2M, exposing Leshan as Model Context Protocol tools.
94 lines (82 loc) • 2.94 kB
JavaScript
import { del } from "../utils/leshanClient.js";
import { validateLwM2MPath } from "../utils/validation.js";
import logger from "../utils/loggerConfig.js";
/**
* Cancel an active observation on a LwM2M 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
* @returns {Promise<Object>} MCP tool response
*/
export async function cancelObservation({ deviceId, objectId, instanceId, resourceId }) {
const operationId = `cancel-observation-${Date.now()}`;
try {
logger.info("Cancel observation operation started", {
operationId,
deviceId,
path: `${objectId}/${instanceId}/${resourceId}`
});
// Validate path parameters
const validatedParams = validateLwM2MPath(deviceId, objectId, instanceId, resourceId);
const endpoint = `/clients/${encodeURIComponent(validatedParams.deviceId)}/${validatedParams.objectId}/${validatedParams.instanceId}/${validatedParams.resourceId}/observe`;
logger.debug("Making cancel observation request", { operationId, endpoint });
const result = await del(endpoint);
logger.info("Resource observation cancelled successfully", {
operationId,
deviceId: validatedParams.deviceId,
path: `${validatedParams.objectId}/${validatedParams.instanceId}/${validatedParams.resourceId}`
});
return {
content: [{
type: "text",
text: JSON.stringify({
success: true,
operation: "cancelObservation",
operationId,
timestamp: new Date().toISOString(),
device: {
endpoint: validatedParams.deviceId,
path: `${validatedParams.objectId}/${validatedParams.instanceId}/${validatedParams.resourceId}`
},
observation: {
status: "cancelled",
cancelTime: new Date().toISOString()
},
result
}, null, 2)
}]
};
} catch (error) {
logger.error("Cancel observation operation failed", {
operationId,
deviceId,
path: `${objectId}/${instanceId}/${resourceId}`,
error: error.message,
errorType: error.constructor.name
});
return {
content: [{
type: "text",
text: JSON.stringify({
success: false,
operation: "cancelObservation",
operationId,
timestamp: new Date().toISOString(),
error: {
message: error.message,
type: error.constructor.name,
...(error.statusCode && { statusCode: error.statusCode })
},
request: {
deviceId,
path: `${objectId}/${instanceId}/${resourceId}`
}
}, null, 2)
}],
isError: true
};
}
}
export default cancelObservation;