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 {{domainName}}Controller from "./{{domainName}}.controller.js";
import type {
{{#if:list}}
List{{domainNamePascal}}ToolArgsType,
{{/if:list}}
{{#if:get}}
Get{{domainNamePascal}}ToolArgsType,
{{/if:get}}
{{#if:create}}
Add{{domainNamePascal}}ToolArgsType,
{{/if:create}}
{{#if:update}}
Update{{domainNamePascal}}ToolArgsType,
{{/if:update}}
{{#if:delete}}
Remove{{domainNamePascal}}ToolArgsType,
{{/if:delete}}
} from "./{{domainName}}.types.js";
import {
{{#if:list}}
List{{domainNamePascal}}ToolArgs,
{{/if:list}}
{{#if:get}}
Get{{domainNamePascal}}ToolArgs,
{{/if:get}}
{{#if:create}}
Add{{domainNamePascal}}ToolArgs,
{{/if:create}}
{{#if:update}}
Update{{domainNamePascal}}ToolArgs,
{{/if:update}}
{{#if:delete}}
Remove{{domainNamePascal}}ToolArgs,
{{/if:delete}}
} from "./{{domainName}}.types.js";
{{#if:list}}
/**
* @function handleList{{domainNamePascal}}
* @description MCP Tool handler to retrieve a list of {{domainName}} from a Lokalise project.
* It calls the {{domainName}}Controller to fetch the data and formats the response for the MCP.
*
* @param {List{{domainNamePascal}}sToolArgsType} 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 handleList{{domainNamePascal}}(args: List{{domainNamePascal}}ToolArgsType) {
const methodLogger = Logger.forContext(
"{{domainName}}.tool.ts",
"handleList{{domainNamePascal}}",
);
methodLogger.debug(
`Getting Lokalise {{domainName}} list (limit: ${args.limit || "default"}, page: ${args.page || "1"})...`,
args,
);
try {
const result = await {{domainName}}Controller.list{{domainNamePascal}}(args);
methodLogger.debug("Got the response from the controller", result);
return {
content: [
{
type: "text" as const,
text: result.content,
},
],
};
} catch (error) {
methodLogger.error("Tool failed", {
error: (error as Error).message,
args,
});
return formatErrorForMcpTool(error);
}
}
{{/if:list}}
{{#if:get}}
/**
* @function handleGet{{domainNamePascal}}
* @description MCP Tool handler to retrieve details of a specific {{domainName}}.
*
* @param {Get{{domainNamePascal}}ToolArgsType} 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 handleGet{{domainNamePascal}}(args: Get{{domainNamePascal}}ToolArgsType) {
const methodLogger = Logger.forContext(
"{{domainName}}.tool.ts",
"handleGet{{domainNamePascal}}",
);
methodLogger.debug("Getting {{domainName}} details...", args);
try {
const result = await {{domainName}}Controller.get{{domainNamePascal}}(args);
methodLogger.debug("Got the response from the controller", result);
return {
content: [
{
type: "text" as const,
text: result.content,
},
],
};
} catch (error) {
methodLogger.error("Tool failed", {
error: (error as Error).message,
args,
});
return formatErrorForMcpTool(error);
}
}
{{/if:get}}
{{#if:create}}
/**
* @function handleAdd{{domainNamePascal}}
* @description MCP Tool handler to add new {{domainName}} to a project.
*
* @param {Add{{domainNamePascal}}sToolArgsType} 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 handleAdd{{domainNamePascal}}(args: Add{{domainNamePascal}}ToolArgsType) {
const methodLogger = Logger.forContext(
"{{domainName}}.tool.ts",
"handleAdd{{domainNamePascal}}",
);
methodLogger.debug("Adding {{domainName}}...", args);
try {
const result = await {{domainName}}Controller.add{{domainNamePascal}}(args);
methodLogger.debug("Got the response from the controller", result);
return {
content: [
{
type: "text" as const,
text: result.content,
},
],
};
} catch (error) {
methodLogger.error("Tool failed", {
error: (error as Error).message,
args,
});
return formatErrorForMcpTool(error);
}
}
{{/if:create}}
{{#if:update}}
/**
* @function handleUpdate{{domainNamePascal}}
* @description MCP Tool handler to update a {{domainName}}'s properties.
*
* @param {Update{{domainNamePascal}}ToolArgsType} 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 handleUpdate{{domainNamePascal}}(args: Update{{domainNamePascal}}ToolArgsType) {
const methodLogger = Logger.forContext(
"{{domainName}}.tool.ts",
"handleUpdate{{domainNamePascal}}",
);
methodLogger.debug("Updating {{domainName}}...", args);
try {
const result = await {{domainName}}Controller.update{{domainNamePascal}}(args);
methodLogger.debug("Got the response from the controller", result);
return {
content: [
{
type: "text" as const,
text: result.content,
},
],
};
} catch (error) {
methodLogger.error("Tool failed", {
error: (error as Error).message,
args,
});
return formatErrorForMcpTool(error);
}
}
{{/if:update}}
{{#if:delete}}
/**
* @function handleRemove{{domainNamePascal}}
* @description MCP Tool handler to remove a {{domainName}} from a project.
*
* @param {Remove{{domainNamePascal}}ToolArgsType} 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 handleRemove{{domainNamePascal}}(args: Remove{{domainNamePascal}}ToolArgsType) {
const methodLogger = Logger.forContext(
"{{domainName}}.tool.ts",
"handleRemove{{domainNamePascal}}",
);
methodLogger.debug("Removing {{domainName}}...", args);
try {
const result = await {{domainName}}Controller.remove{{domainNamePascal}}(args);
methodLogger.debug("Got the response from the controller", result);
return {
content: [
{
type: "text" as const,
text: result.content,
},
],
};
} catch (error) {
methodLogger.error("Tool failed", {
error: (error as Error).message,
args,
});
return formatErrorForMcpTool(error);
}
}
{{/if:delete}}
/**
* @function registerTools
* @description Registers all {{domainName}}-related tools with the MCP server.
* This function binds the tool names to their handler functions and schemas.
*
* @param {McpServer} server - The MCP server instance where tools will be registered.
*/
function registerTools(server: McpServer) {
const methodLogger = Logger.forContext(
"{{domainName}}.tool.ts",
"registerTools",
);
methodLogger.info("Registering {{domainName}} MCP tools");
{{#if:list}}
server.tool(
"lokalise_list_{{domainNameKebab}}",
"Lists all {{domainName}} in a Lokalise project with filtering and pagination support",
List{{domainNamePascal}}ToolArgs.shape,
handleList{{domainNamePascal}},
);
{{/if:list}}
{{#if:get}}
server.tool(
"lokalise_get_{{domainNameKebab}}",
"Gets detailed information about a specific {{domainName}} in a project",
Get{{domainNamePascal}}ToolArgs.shape,
handleGet{{domainNamePascal}},
);
{{/if:get}}
{{#if:create}}
server.tool(
"lokalise_add_{{domainNameKebab}}",
"Adds one or more {{domainName}} to a Lokalise project",
Add{{domainNamePascal}}ToolArgs.shape,
handleAdd{{domainNamePascal}},
);
{{/if:create}}
{{#if:update}}
server.tool(
"lokalise_update_{{domainNameKebab}}",
"Updates a {{domainName}}'s properties in a project",
Update{{domainNamePascal}}ToolArgs.shape,
handleUpdate{{domainNamePascal}},
);
{{/if:update}}
{{#if:delete}}
server.tool(
"lokalise_delete_{{domainNameKebab}}",
"Removes a {{domainName}} from a Lokalise project",
Remove{{domainNamePascal}}ToolArgs.shape,
handleRemove{{domainNamePascal}},
);
{{/if:delete}}
methodLogger.info("{{domainNamePascal}} MCP tools registered successfully");
}
// Export the domain tool implementation
const {{domainName}}Tool: DomainTool = {
registerTools,
getMeta(): DomainMeta {
return {
name: "{{domainName}}",
description: "{{domainDescription}}",
version: "1.0.0",
toolsCount: {{toolsCount}},
};
},
};
export default {{domainName}}Tool;