lokalise-mcp
Version:
The Lokalise MCP Server brings Lokalise's localization power to Claude and AI assistants—manage projects, keys, and translations by chat.
271 lines (270 loc) • 11.9 kB
JavaScript
import { config } from "../../shared/utils/config.util.js";
import { buildErrorContext, handleControllerError, } from "../../shared/utils/error-handler.util.js";
import { Logger } from "../../shared/utils/logger.util.js";
import { formatBulkDeleteKeysResult, formatBulkUpdateKeysResult, formatCreateKeysResult, formatDeleteKeyResult, formatKeyDetails, formatKeysList, formatUpdateKeyResult, } from "./keys.formatter.js";
import * as keysService from "./keys.service.js";
/**
* @namespace KeysController
* @description Controller responsible for handling Lokalise Keys API operations.
* It orchestrates calls to the keys service, applies defaults,
* maps options, and formats the response using the formatter.
*/
/**
* @function listKeys
* @description Fetches a list of keys from a Lokalise project with optional filtering and pagination.
* @memberof KeysController
* @param {ListKeysToolArgsType} args - Arguments containing project ID, filters, and pagination options
* @returns {Promise<ControllerResponse>} A promise that resolves to the standard controller response containing the formatted keys list in Markdown.
* @throws {McpError} Throws an McpError (handled by `handleControllerError`) if the service call fails or returns an error.
*/
async function listKeys(args) {
const methodLogger = Logger.forContext("controllers/keys.controller.ts", "listKeys");
try {
methodLogger.debug("Starting listKeys operation", {
projectId: args.projectId,
limit: args.limit,
page: args.page,
includeTranslations: args.includeTranslations,
});
// Map arguments to service parameters
const serviceParams = {
project_id: args.projectId,
limit: args.limit || 100,
page: args.page || 1,
include_translations: args.includeTranslations,
filter_keys: args.filterKeys,
filter_platforms: args.filterPlatforms,
pagination: "cursor", // Use cursor pagination for better performance
};
const result = await keysService.getKeys(serviceParams);
methodLogger.debug("Keys service call successful", {
projectId: args.projectId,
keysCount: result.items?.length || 0,
hasNextCursor: !!result.nextCursor,
});
const formatted = formatKeysList(result, args.projectId);
return { content: formatted };
}
catch (error) {
throw handleControllerError(error, buildErrorContext("Lokalise Key", "listKeys", "controllers/keys.controller.ts@listKeys", args.projectId, { args }));
}
}
/**
* @function createKeys
* @description Creates multiple keys in a Lokalise project
* @memberof KeysController
* @param {CreateKeysToolArgsType} args - Arguments containing project ID and keys data
* @returns {Promise<ControllerResponse>} A promise that resolves to the standard controller response containing the creation results.
*/
async function createKeys(args) {
const methodLogger = Logger.forContext("controllers/keys.controller.ts", "createKeys");
try {
methodLogger.debug("Starting createKeys operation", {
projectId: args.projectId,
keysCount: args.keys.length,
});
// Map arguments to service parameters
const serviceParams = {
project_id: args.projectId,
keys: args.keys.map((key) => ({
key_name: key.key_name,
description: key.description,
platforms: key.platforms,
translations: key.translations,
tags: key.tags,
})),
};
const result = await keysService.createKeys(serviceParams);
methodLogger.debug("Keys creation successful", {
projectId: args.projectId,
createdCount: result.items?.length || 0,
errorsCount: result.errors?.length || 0,
});
const formatted = formatCreateKeysResult(result, args.projectId);
return { content: formatted };
}
catch (error) {
throw handleControllerError(error, buildErrorContext("Lokalise Key", "createKeys", "controllers/keys.controller.ts@createKeys", args.projectId, { args, keysCount: args.keys.length }));
}
}
/**
* @function getKey
* @description Fetches a single key from a Lokalise project
* @memberof KeysController
* @param {GetKeyToolArgsType} args - Arguments containing project ID and key ID
* @returns {Promise<ControllerResponse>} A promise that resolves to the standard controller response containing the key details.
*/
async function getKey(args) {
const methodLogger = Logger.forContext("controllers/keys.controller.ts", "getKey");
try {
methodLogger.debug("Starting getKey operation", {
projectId: args.projectId,
keyId: args.keyId,
});
// Map arguments to service parameters
const serviceParams = {
project_id: args.projectId,
key_id: args.keyId,
};
const result = await keysService.getKey(serviceParams);
methodLogger.debug("Key retrieval successful", {
projectId: args.projectId,
keyId: args.keyId,
keyName: result.key_name,
});
const formatted = formatKeyDetails(result, args.projectId);
return { content: formatted };
}
catch (error) {
throw handleControllerError(error, buildErrorContext("Lokalise Key", "getKey", "controllers/keys.controller.ts@getKey", `${args.projectId}:${args.keyId}`, { args }));
}
}
/**
* @function updateKey
* @description Updates a single key in a Lokalise project
* @memberof KeysController
* @param {UpdateKeyToolArgsType} args - Arguments containing project ID, key ID and update data
* @returns {Promise<ControllerResponse>} A promise that resolves to the standard controller response containing the updated key details.
*/
async function updateKey(args) {
const methodLogger = Logger.forContext("controllers/keys.controller.ts", "updateKey");
try {
methodLogger.debug("Starting updateKey operation", {
projectId: args.projectId,
keyId: args.keyId,
});
// Map arguments to service parameters
const serviceParams = {
project_id: args.projectId,
key_id: args.keyId,
description: args.keyData.description,
platforms: args.keyData.platforms, // Type conversion for platforms
tags: args.keyData.tags,
};
const result = await keysService.updateKey(serviceParams);
methodLogger.debug("Key update successful", {
projectId: args.projectId,
keyId: args.keyId,
keyName: result.key_name,
});
const formatted = formatUpdateKeyResult(result, args.projectId);
return { content: formatted };
}
catch (error) {
throw handleControllerError(error, buildErrorContext("Lokalise Key", "updateKey", "controllers/keys.controller.ts@updateKey", `${args.projectId}:${args.keyId}`, { args }));
}
}
/**
* @function deleteKey
* @description Deletes a single key from a Lokalise project
* @memberof KeysController
* @param {DeleteKeyToolArgsType} args - Arguments containing project ID and key ID
* @returns {Promise<ControllerResponse>} A promise that resolves to the standard controller response containing the deletion confirmation.
*/
async function deleteKey(args) {
const methodLogger = Logger.forContext("controllers/keys.controller.ts", "deleteKey");
try {
methodLogger.debug("Starting deleteKey operation", {
projectId: args.projectId,
keyId: args.keyId,
});
// Map arguments to service parameters
const serviceParams = {
project_id: args.projectId,
key_id: args.keyId,
};
const result = await keysService.deleteKey(serviceParams);
methodLogger.debug("Key deletion successful", {
projectId: args.projectId,
keyId: args.keyId,
});
const formatted = formatDeleteKeyResult(result, args.projectId, args.keyId);
return { content: formatted };
}
catch (error) {
throw handleControllerError(error, buildErrorContext("Lokalise Key", "deleteKey", "controllers/keys.controller.ts@deleteKey", `${args.projectId}:${args.keyId}`, { args }));
}
}
/**
* @function bulkUpdateKeys
* @description Updates multiple keys in a Lokalise project
* @memberof KeysController
* @param {BulkUpdateKeysToolArgsType} args - Arguments containing project ID and keys update data
* @returns {Promise<ControllerResponse>} A promise that resolves to the standard controller response containing the bulk update results.
*/
async function bulkUpdateKeys(args) {
const methodLogger = Logger.forContext("controllers/keys.controller.ts", "bulkUpdateKeys");
try {
methodLogger.debug("Starting bulkUpdateKeys operation", {
projectId: args.projectId,
keysCount: args.keys.length,
});
config.load();
// Map arguments to service parameters
const serviceParams = {
project_id: args.projectId,
keys: args.keys.map((key) => ({
key_id: key.keyId,
description: key.description,
platforms: key.platforms, // Type conversion for platforms
tags: key.tags,
})),
};
const result = await keysService.bulkUpdateKeys(serviceParams);
methodLogger.debug("Bulk keys update successful", {
projectId: args.projectId,
updatedCount: result.items?.length || 0,
errorsCount: result.errors?.length || 0,
});
const formatted = formatBulkUpdateKeysResult(result, args.projectId);
return { content: formatted };
}
catch (error) {
throw handleControllerError(error, buildErrorContext("Lokalise Key", "bulkUpdateKeys", "controllers/keys.controller.ts@bulkUpdateKeys", args.projectId, { args, keysCount: args.keys.length }));
}
}
/**
* @function bulkDeleteKeys
* @description Deletes multiple keys from a Lokalise project
* @memberof KeysController
* @param {BulkDeleteKeysToolArgsType} args - Arguments containing project ID and key IDs
* @returns {Promise<ControllerResponse>} A promise that resolves to the standard controller response containing the bulk deletion results.
*/
async function bulkDeleteKeys(args) {
const methodLogger = Logger.forContext("controllers/keys.controller.ts", "bulkDeleteKeys");
try {
methodLogger.debug("Starting bulkDeleteKeys operation", {
projectId: args.projectId,
keysCount: args.keyIds.length,
});
config.load();
// Map arguments to service parameters
const serviceParams = {
project_id: args.projectId,
key_ids: args.keyIds,
};
const result = await keysService.bulkDeleteKeys(serviceParams);
methodLogger.debug("Bulk keys deletion successful", {
projectId: args.projectId,
deletedCount: args.keyIds.length,
});
const formatted = formatBulkDeleteKeysResult(result, args.projectId, args.keyIds.length);
return { content: formatted };
}
catch (error) {
throw handleControllerError(error, buildErrorContext("Lokalise Key", "bulkDeleteKeys", "controllers/keys.controller.ts@bulkDeleteKeys", args.projectId, { args, keysCount: args.keyIds.length }));
}
}
/**
* Export the controller functions
*/
const keysController = {
listKeys,
createKeys,
getKey,
updateKey,
deleteKey,
bulkUpdateKeys,
bulkDeleteKeys,
};
export default keysController;