text_transform
Transform text with operations including case changes, Base64 encoding, slug generation, word count, and duplicate removal.
Instructions
Transform text using various operations.
Supported operations:
"uppercase": Convert to UPPERCASE
"lowercase": Convert to lowercase
"titlecase": Convert to Title Case
"camelcase": Convert to camelCase
"snakecase": Convert to snake_case
"kebabcase": Convert to kebab-case
"reverse": Reverse the text
"trim": Remove leading/trailing whitespace
"slug": URL-safe slug (lowercase, hyphens, no special chars)
"base64_encode": Encode to Base64
"base64_decode": Decode from Base64
"word_count": Count words, characters, sentences, and paragraphs
"remove_duplicates": Remove duplicate lines
"sort_lines": Sort lines alphabetically
"extract_emails": Extract all email addresses from text
"extract_urls": Extract all URLs from text
"hash": Simple hash summary (character frequency)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The input text to transform. | |
| operation | Yes | The transformation operation to apply (see list above). |
Implementation Reference
- src/tools/text-transform.ts:39-228 (handler)The main tool handler function that performs text transformations. It accepts 'text' and 'operation' parameters and uses a switch statement to handle 17 different operations: uppercase, lowercase, titlecase, camelcase, snakecase, kebabcase, reverse, trim, slug, base64_encode, base64_decode, word_count, remove_duplicates, sort_lines, extract_emails, extract_urls, hash. Returns JSON response with operation metadata and result.
async ({ text, operation }) => { try { let result: string; switch (operation) { case "uppercase": result = text.toUpperCase(); break; case "lowercase": result = text.toLowerCase(); break; case "titlecase": result = text.replace( /\w\S*/g, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase() ); break; case "camelcase": result = toCamelCase(text); break; case "snakecase": result = toSnakeCase(text); break; case "kebabcase": result = toSnakeCase(text).replace(/_/g, "-"); break; case "reverse": result = [...text].reverse().join(""); break; case "trim": result = text.trim(); break; case "slug": result = text .toLowerCase() .trim() .replace(/[^\w\s-]/g, "") .replace(/[\s_]+/g, "-") .replace(/-+/g, "-") .replace(/^-|-$/g, ""); break; case "base64_encode": result = Buffer.from(text, "utf-8").toString("base64"); break; case "base64_decode": result = Buffer.from(text, "base64").toString("utf-8"); break; case "word_count": { const words = text.trim().split(/\s+/).filter(Boolean).length; const chars = text.length; const charsNoSpaces = text.replace(/\s/g, "").length; const sentences = text.split(/[.!?]+/).filter(Boolean).length; const paragraphs = text .split(/\n\s*\n/) .filter((p) => p.trim().length > 0).length; const lines = text.split("\n").length; return { content: [ { type: "text" as const, text: JSON.stringify( { words, characters: chars, charactersNoSpaces: charsNoSpaces, sentences, paragraphs, lines, averageWordLength: chars > 0 ? (charsNoSpaces / words).toFixed(1) : 0, }, null, 2 ), }, ], }; } case "remove_duplicates": { const lines = text.split("\n"); const seen = new Set<string>(); const unique: string[] = []; for (const line of lines) { if (!seen.has(line)) { seen.add(line); unique.push(line); } } result = unique.join("\n"); break; } case "sort_lines": result = text .split("\n") .sort((a, b) => a.localeCompare(b)) .join("\n"); break; case "extract_emails": { const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g; const emails = [...new Set(text.match(emailRegex) || [])]; return { content: [ { type: "text" as const, text: JSON.stringify( { count: emails.length, emails }, null, 2 ), }, ], }; } case "extract_urls": { const urlRegex = /https?:\/\/[^\s<>"{}|\\^`\]]+/g; const urls = [...new Set(text.match(urlRegex) || [])]; return { content: [ { type: "text" as const, text: JSON.stringify( { count: urls.length, urls }, null, 2 ), }, ], }; } default: return { content: [ { type: "text" as const, text: `Error: Unknown operation '${operation}'. Valid operations: uppercase, lowercase, titlecase, camelcase, snakecase, kebabcase, reverse, trim, slug, base64_encode, base64_decode, word_count, remove_duplicates, sort_lines, extract_emails, extract_urls, hash`, }, ], isError: true, }; } return { content: [ { type: "text" as const, text: JSON.stringify( { operation, inputLength: text.length, outputLength: result.length, result, }, null, 2 ), }, ], }; } catch (err: any) { return { content: [ { type: "text" as const, text: `Text Transform Error: ${err.message}`, }, ], isError: true, }; } } ); } - src/tools/text-transform.ts:33-38 (schema)Input schema for the text_transform tool. Defines 'text' (string) and 'operation' (string) parameters using Zod validation.
{ text: z.string().describe("The input text to transform."), operation: z .string() .describe("The transformation operation to apply (see list above)."), }, - src/tools/text-transform.ts:10-228 (registration)Registration function (registerTextTransformTool) that calls server.tool(...) with name 'text_transform', description, schema, and handler.
export function registerTextTransformTool(server: McpServer): void { server.tool( "text_transform", `Transform text using various operations. Supported operations: - "uppercase": Convert to UPPERCASE - "lowercase": Convert to lowercase - "titlecase": Convert to Title Case - "camelcase": Convert to camelCase - "snakecase": Convert to snake_case - "kebabcase": Convert to kebab-case - "reverse": Reverse the text - "trim": Remove leading/trailing whitespace - "slug": URL-safe slug (lowercase, hyphens, no special chars) - "base64_encode": Encode to Base64 - "base64_decode": Decode from Base64 - "word_count": Count words, characters, sentences, and paragraphs - "remove_duplicates": Remove duplicate lines - "sort_lines": Sort lines alphabetically - "extract_emails": Extract all email addresses from text - "extract_urls": Extract all URLs from text - "hash": Simple hash summary (character frequency)`, { text: z.string().describe("The input text to transform."), operation: z .string() .describe("The transformation operation to apply (see list above)."), }, async ({ text, operation }) => { try { let result: string; switch (operation) { case "uppercase": result = text.toUpperCase(); break; case "lowercase": result = text.toLowerCase(); break; case "titlecase": result = text.replace( /\w\S*/g, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase() ); break; case "camelcase": result = toCamelCase(text); break; case "snakecase": result = toSnakeCase(text); break; case "kebabcase": result = toSnakeCase(text).replace(/_/g, "-"); break; case "reverse": result = [...text].reverse().join(""); break; case "trim": result = text.trim(); break; case "slug": result = text .toLowerCase() .trim() .replace(/[^\w\s-]/g, "") .replace(/[\s_]+/g, "-") .replace(/-+/g, "-") .replace(/^-|-$/g, ""); break; case "base64_encode": result = Buffer.from(text, "utf-8").toString("base64"); break; case "base64_decode": result = Buffer.from(text, "base64").toString("utf-8"); break; case "word_count": { const words = text.trim().split(/\s+/).filter(Boolean).length; const chars = text.length; const charsNoSpaces = text.replace(/\s/g, "").length; const sentences = text.split(/[.!?]+/).filter(Boolean).length; const paragraphs = text .split(/\n\s*\n/) .filter((p) => p.trim().length > 0).length; const lines = text.split("\n").length; return { content: [ { type: "text" as const, text: JSON.stringify( { words, characters: chars, charactersNoSpaces: charsNoSpaces, sentences, paragraphs, lines, averageWordLength: chars > 0 ? (charsNoSpaces / words).toFixed(1) : 0, }, null, 2 ), }, ], }; } case "remove_duplicates": { const lines = text.split("\n"); const seen = new Set<string>(); const unique: string[] = []; for (const line of lines) { if (!seen.has(line)) { seen.add(line); unique.push(line); } } result = unique.join("\n"); break; } case "sort_lines": result = text .split("\n") .sort((a, b) => a.localeCompare(b)) .join("\n"); break; case "extract_emails": { const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g; const emails = [...new Set(text.match(emailRegex) || [])]; return { content: [ { type: "text" as const, text: JSON.stringify( { count: emails.length, emails }, null, 2 ), }, ], }; } case "extract_urls": { const urlRegex = /https?:\/\/[^\s<>"{}|\\^`\]]+/g; const urls = [...new Set(text.match(urlRegex) || [])]; return { content: [ { type: "text" as const, text: JSON.stringify( { count: urls.length, urls }, null, 2 ), }, ], }; } default: return { content: [ { type: "text" as const, text: `Error: Unknown operation '${operation}'. Valid operations: uppercase, lowercase, titlecase, camelcase, snakecase, kebabcase, reverse, trim, slug, base64_encode, base64_decode, word_count, remove_duplicates, sort_lines, extract_emails, extract_urls, hash`, }, ], isError: true, }; } return { content: [ { type: "text" as const, text: JSON.stringify( { operation, inputLength: text.length, outputLength: result.length, result, }, null, 2 ), }, ], }; } catch (err: any) { return { content: [ { type: "text" as const, text: `Text Transform Error: ${err.message}`, }, ], isError: true, }; } } ); } - src/index.ts:55-57 (registration)Where registerTextTransformTool is called in the McpToolkitServer class to register the tool on the MCP server.
registerTextTransformTool(this.server); registerEnvironmentTool(this.server); } - src/tools/text-transform.ts:233-244 (helper)Helper function toCamelCase - converts a string to camelCase by splitting on spaces, underscores, and hyphens.
export function toCamelCase(str: string): string { return str .replace(/[^a-zA-Z0-9\s_-]/g, "") .split(/[\s_-]+/) .filter(Boolean) .map((word, index) => index === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() ) .join(""); } - src/tools/text-transform.ts:249-256 (helper)Helper function toSnakeCase - converts a string to snake_case by splitting on spaces and hyphens.
export function toSnakeCase(str: string): string { return str .replace(/[^a-zA-Z0-9\s_-]/g, "") .split(/[\s-]+/) .filter(Boolean) .map((word) => word.toLowerCase()) .join("_"); }