Skip to main content
Glama
projects.tool.ts10.8 kB
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { DomainMeta, DomainTool, } from "../../shared/types/domain.types.js"; import { formatErrorForMcpTool } from "../../shared/utils/error.util.js"; import { Logger } from "../../shared/utils/logger.util.js"; import projectsController from "./projects.controller.js"; import type { CreateProjectToolArgsType, DeleteProjectToolArgsType, EmptyProjectToolArgsType, GetProjectDetailsToolArgsType, ListProjectsToolArgsType, UpdateProjectToolArgsType, } from "./projects.types.js"; import { CreateProjectToolArgs, DeleteProjectToolArgs, EmptyProjectToolArgs, GetProjectDetailsToolArgs, ListProjectsToolArgs, UpdateProjectToolArgs, } from "./projects.types.js"; /** * @function handleListProjects * @description MCP Tool handler to retrieve a list of Lokalise projects. * It calls the projectsController to fetch the data and formats the response for the MCP. * * @param {ListProjectsToolArgsType} args - Arguments provided to the tool. * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP. * @throws {McpError} Formatted error if the controller or service layer encounters an issue. */ async function handleListProjects(args: ListProjectsToolArgsType) { const methodLogger = Logger.forContext( "tools/projects.tool.ts", "handleListProjects", ); methodLogger.debug( `Getting Lokalise projects list (limit: ${args.limit || "default"}, page: ${args.page || "1"})...`, args, ); try { // Pass args directly to the controller const result = await projectsController.listProjects(args); methodLogger.debug("Got the response from the controller", result); // Format the response for the MCP tool return { content: [ { type: "text" as const, text: result.content, }, ], }; } catch (error) { methodLogger.error("Error getting Lokalise projects list", error); return formatErrorForMcpTool(error); } } /** * @function handleGetProjectDetails * @description MCP Tool handler to retrieve detailed information about a specific Lokalise project. * It calls the projectsController to fetch the data and formats the response for the MCP. * * @param {GetProjectDetailsToolArgsType} args - Arguments provided to the tool. * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP. * @throws {McpError} Formatted error if the controller or service layer encounters an issue. */ async function handleGetProjectDetails(args: GetProjectDetailsToolArgsType) { const methodLogger = Logger.forContext( "tools/projects.tool.ts", "handleGetProjectDetails", ); methodLogger.debug( `Getting Lokalise project details for project ${args.projectId}...`, args, ); try { // Pass args directly to the controller const result = await projectsController.getProjectDetails(args); methodLogger.debug("Got the response from the controller", result); // Format the response for the MCP tool return { content: [ { type: "text" as const, text: result.content, }, ], }; } catch (error) { methodLogger.error( `Error getting details for project: ${args.projectId}`, error, ); return formatErrorForMcpTool(error); } } /** * @function handleCreateProject * @description MCP Tool handler to create a new Lokalise project. * * @param {CreateProjectToolArgsType} args - Arguments provided to the tool. * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP. * @throws {McpError} Formatted error if the controller or service layer encounters an issue. */ async function handleCreateProject(args: CreateProjectToolArgsType) { const methodLogger = Logger.forContext( "tools/projects.tool.ts", "handleCreateProject", ); methodLogger.debug(`Creating new Lokalise project: ${args.name}...`, args); try { const result = await projectsController.createProject(args); methodLogger.debug("Got the response from the controller", result); return { content: [ { type: "text" as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error creating project: ${args.name}`, error); return formatErrorForMcpTool(error); } } /** * @function handleUpdateProject * @description MCP Tool handler to update an existing Lokalise project. * * @param {UpdateProjectToolArgsType} args - Arguments provided to the tool. * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP. * @throws {McpError} Formatted error if the controller or service layer encounters an issue. */ async function handleUpdateProject(args: UpdateProjectToolArgsType) { const methodLogger = Logger.forContext( "tools/projects.tool.ts", "handleUpdateProject", ); methodLogger.debug(`Updating Lokalise project: ${args.projectId}...`, args); try { const result = await projectsController.updateProject(args); methodLogger.debug("Got the response from the controller", result); return { content: [ { type: "text" as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error updating project: ${args.projectId}`, error); return formatErrorForMcpTool(error); } } /** * @function handleDeleteProject * @description MCP Tool handler to delete a Lokalise project. * * @param {DeleteProjectToolArgsType} args - Arguments provided to the tool. * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP. * @throws {McpError} Formatted error if the controller or service layer encounters an issue. */ async function handleDeleteProject(args: DeleteProjectToolArgsType) { const methodLogger = Logger.forContext( "tools/projects.tool.ts", "handleDeleteProject", ); methodLogger.debug(`Deleting Lokalise project: ${args.projectId}...`, args); try { const result = await projectsController.deleteProject(args); methodLogger.debug("Got the response from the controller", result); return { content: [ { type: "text" as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error deleting project: ${args.projectId}`, error); return formatErrorForMcpTool(error); } } /** * @function handleEmptyProject * @description MCP Tool handler to empty a Lokalise project (remove all keys and translations). * * @param {EmptyProjectToolArgsType} args - Arguments provided to the tool. * @returns {Promise<{ content: Array<{ type: 'text', text: string }> }>} Formatted response for the MCP. * @throws {McpError} Formatted error if the controller or service layer encounters an issue. */ async function handleEmptyProject(args: EmptyProjectToolArgsType) { const methodLogger = Logger.forContext( "tools/projects.tool.ts", "handleEmptyProject", ); methodLogger.debug(`Emptying Lokalise project: ${args.projectId}...`, args); try { const result = await projectsController.emptyProject(args); methodLogger.debug("Got the response from the controller", result); return { content: [ { type: "text" as const, text: result.content, }, ], }; } catch (error) { methodLogger.error(`Error emptying project: ${args.projectId}`, error); return formatErrorForMcpTool(error); } } /** * @function registerTools * @description Registers all Projects tools with the MCP server. * * @param {McpServer} server - The MCP server instance. */ function registerTools(server: McpServer) { const methodLogger = Logger.forContext( "tools/projects.tool.ts", "registerTools", ); methodLogger.debug("Registering Projects tools..."); // Register project listing tool server.tool( "lokalise_list_projects", "Portfolio overview showing all accessible localization projects. Optional: limit (100), page, includeStats (adds progress/QA data). Use as entry point to discover projects, assess translation health, or find specific project IDs. Returns: Projects with names, IDs, base language, stats. Start here before diving into specific projects.", ListProjectsToolArgs.shape, handleListProjects, ); // Register project details tool server.tool( "lokalise_get_project", "Deep analysis of a single project's health and configuration. Required: projectId. Optional: includeLanguages (completion rates), includeKeysSummary (content stats). Use for project audits, progress reports, or understanding structure. Returns: Complete project metadata, team info, language progress, key statistics. Essential for project status assessment.", GetProjectDetailsToolArgs.shape, handleGetProjectDetails, ); // Register project creation tool server.tool( "lokalise_create_project", "Initializes a new localization project for an app or service. Required: name. Optional: description, base_lang_iso (default 'en'). Use when starting localization for new products or creating test environments. Returns: Project ID and access details. Next steps: Add languages, upload keys, invite team members.", CreateProjectToolArgs.shape, handleCreateProject, ); // Register project update tool server.tool( "lokalise_update_project", "Modifies project settings and metadata. Required: projectId, projectData object. Optional in data: name, description. Use to rename projects, update descriptions, or fix project information. Returns: Updated project details. Note: Only changes metadata - use other tools for content/language changes.", UpdateProjectToolArgs.shape, handleUpdateProject, ); // Register project deletion tool server.tool( "lokalise_delete_project", "Permanently destroys a project and ALL its data. Required: projectId. Use for removing test projects or discontinued products. Returns: Deletion confirmation. CRITICAL WARNING: Irreversible - deletes all keys, translations, history, and team assignments. Export data first if needed. Consider emptying instead.", DeleteProjectToolArgs.shape, handleDeleteProject, ); // Register project empty tool server.tool( "lokalise_empty_project", "Resets project content while preserving settings and team. Required: projectId. Use for major refactoring, starting fresh, or clearing test data. Returns: Operation confirmation. Effect: Removes all keys and translations but keeps languages, team, and project configuration. Safer alternative to deletion.", EmptyProjectToolArgs.shape, handleEmptyProject, ); methodLogger.debug("Successfully registered all Projects tools."); } const projectsTools: DomainTool = { registerTools, getMeta(): DomainMeta { return { name: "projects", description: "Projects management domain", version: "1.0.0", toolsCount: 6, }; }, }; export default projectsTools;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AbdallahAHO/lokalise-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server