create_template_version
Create new email template versions with HTML content and subject lines to update and manage your email campaigns in SendGrid.
Instructions
Create a new version of a template with HTML content and settings
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| active | No | Set as active version (1 = active, 0 = inactive) | |
| generate_plain_content | No | Auto-generate plain text from HTML | |
| html_content | Yes | HTML content of the email template (supports Handlebars) | |
| name | Yes | Name for this version | |
| plain_content | No | Plain text version (optional) | |
| subject | Yes | Email subject line (supports Handlebars) | |
| template_id | Yes | ID of the template to add version to | |
| test_data | No | JSON string of test data for Handlebars variables |
Implementation Reference
- src/tools/templates.ts:124-179 (handler)The main handler function that executes the tool: checks read-only mode, prepares version data, parses test_data if provided, makes POST request to SendGrid API to create template version, and returns success message with details.handler: async ({ template_id, name, subject, html_content, plain_content, active, generate_plain_content, test_data }: { template_id: string; name: string; subject: string; html_content: string; plain_content?: string; active?: number; generate_plain_content?: boolean; test_data?: string; }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const versionData: any = { name, subject, html_content, active: active ?? 1, generate_plain_content: generate_plain_content ?? true, }; if (plain_content) { versionData.plain_content = plain_content; } if (test_data) { try { versionData.test_data = JSON.parse(test_data); } catch (error) { return { content: [{ type: "text", text: "Error: test_data must be valid JSON" }] }; } } const result = await makeRequest(`https://api.sendgrid.com/v3/templates/${template_id}/versions`, { method: "POST", body: JSON.stringify(versionData), }); return { content: [{ type: "text", text: `Template version created successfully!\n\n${JSON.stringify(result, null, 2)}\n\nYou can now use this template with the Mail API using template_id: ${template_id}` }] }; },
- src/tools/templates.ts:113-122 (schema)Zod input schema defining all parameters for the create_template_version tool, including descriptions and defaults.inputSchema: { template_id: z.string().describe("ID of the template to add version to"), name: z.string().describe("Name for this version"), subject: z.string().describe("Email subject line (supports Handlebars)"), html_content: z.string().describe("HTML content of the email template (supports Handlebars)"), plain_content: z.string().optional().describe("Plain text version (optional)"), active: z.number().optional().default(1).describe("Set as active version (1 = active, 0 = inactive)"), generate_plain_content: z.boolean().optional().default(true).describe("Auto-generate plain text from HTML"), test_data: z.string().optional().describe("JSON string of test data for Handlebars variables"), },
- src/index.ts:21-23 (registration)MCP server registration loop that registers all tools from allTools object, including 'create_template_version' by name.for (const [name, tool] of Object.entries(allTools)) { server.registerTool(name, tool.config as any, tool.handler as any); }
- src/tools/index.ts:9-16 (registration)Assembles allTools by spreading templateTools (containing create_template_version) along with other tool sets for export to main index.tsexport const allTools = { ...automationTools, ...campaignTools, ...contactTools, ...mailTools, ...miscTools, ...statsTools, ...templateTools,
- src/tools/templates.ts:109-180 (helper)Complete tool definition object for create_template_version, combining config/schema and handler.create_template_version: { config: { title: "Create Template Version", description: "Create a new version of a template with HTML content and settings", inputSchema: { template_id: z.string().describe("ID of the template to add version to"), name: z.string().describe("Name for this version"), subject: z.string().describe("Email subject line (supports Handlebars)"), html_content: z.string().describe("HTML content of the email template (supports Handlebars)"), plain_content: z.string().optional().describe("Plain text version (optional)"), active: z.number().optional().default(1).describe("Set as active version (1 = active, 0 = inactive)"), generate_plain_content: z.boolean().optional().default(true).describe("Auto-generate plain text from HTML"), test_data: z.string().optional().describe("JSON string of test data for Handlebars variables"), }, }, handler: async ({ template_id, name, subject, html_content, plain_content, active, generate_plain_content, test_data }: { template_id: string; name: string; subject: string; html_content: string; plain_content?: string; active?: number; generate_plain_content?: boolean; test_data?: string; }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const versionData: any = { name, subject, html_content, active: active ?? 1, generate_plain_content: generate_plain_content ?? true, }; if (plain_content) { versionData.plain_content = plain_content; } if (test_data) { try { versionData.test_data = JSON.parse(test_data); } catch (error) { return { content: [{ type: "text", text: "Error: test_data must be valid JSON" }] }; } } const result = await makeRequest(`https://api.sendgrid.com/v3/templates/${template_id}/versions`, { method: "POST", body: JSON.stringify(versionData), }); return { content: [{ type: "text", text: `Template version created successfully!\n\n${JSON.stringify(result, null, 2)}\n\nYou can now use this template with the Mail API using template_id: ${template_id}` }] }; }, },