Skip to main content
Glama
spelling.ts6.71 kB
/** * Spelling and character access tools */ import { createIndexedList } from '../utils/visualization.js'; // ============================================================================ // spell_word - Break a word into individual characters // ============================================================================ export interface SpellWordInput { text: string; include_indices: boolean; } export interface SpellWordOutput { text: string; length: number; characters: string[]; indexed_characters: Array<{ index: number; char: string }>; spelled_out: string; } export function spellWord(input: SpellWordInput): SpellWordOutput { const { text, include_indices } = input; const characters = [...text]; const indexed_characters = createIndexedList(text); const spelled_out = include_indices ? indexed_characters.map(ic => `${ic.index}:'${ic.char}'`).join(', ') : characters.map(c => `'${c}'`).join(', '); return { text, length: characters.length, characters, indexed_characters, spelled_out, }; } // ============================================================================ // char_at - Get character at a specific index // ============================================================================ export interface CharAtInput { text: string; index: number; } export interface CharAtOutput { text: string; index: number; character: string | null; valid: boolean; text_length: number; error?: string; } export function charAt(input: CharAtInput): CharAtOutput { const { text, index } = input; const characters = [...text]; // Handle negative indices (Python-style) const normalizedIndex = index < 0 ? characters.length + index : index; if (normalizedIndex < 0 || normalizedIndex >= characters.length) { return { text, index, character: null, valid: false, text_length: characters.length, error: `Index ${index} is out of bounds. Valid range: 0 to ${characters.length - 1} (or -${characters.length} to -1 for negative indices).`, }; } return { text, index, character: characters[normalizedIndex], valid: true, text_length: characters.length, }; } // ============================================================================ // nth_character - Get the nth character (1-indexed, human-friendly) // ============================================================================ export interface NthCharacterInput { text: string; position: number; from_end: boolean; } export interface NthCharacterOutput { text: string; position: number; from_end: boolean; character: string | null; valid: boolean; text_length: number; description: string; error?: string; } export function nthCharacter(input: NthCharacterInput): NthCharacterOutput { const { text, position, from_end } = input; const characters = [...text]; if (position < 1) { return { text, position, from_end, character: null, valid: false, text_length: characters.length, description: '', error: `Position must be at least 1. Use position=1 for the ${from_end ? 'last' : 'first'} character.`, }; } const index = from_end ? characters.length - position : position - 1; if (index < 0 || index >= characters.length) { return { text, position, from_end, character: null, valid: false, text_length: characters.length, description: '', error: `Position ${position} is out of bounds. The text only has ${characters.length} characters.`, }; } const ordinal = getOrdinal(position); const description = from_end ? `The ${ordinal} character from the end of "${text}" is '${characters[index]}'.` : `The ${ordinal} character of "${text}" is '${characters[index]}'.`; return { text, position, from_end, character: characters[index], valid: true, text_length: characters.length, description, }; } function getOrdinal(n: number): string { const s = ['th', 'st', 'nd', 'rd']; const v = n % 100; return n + (s[(v - 20) % 10] || s[v] || s[0]); } // ============================================================================ // word_length - Get the exact length of text // ============================================================================ export interface WordLengthInput { text: string; count_spaces: boolean; } export interface WordLengthOutput { text: string; length: number; length_without_spaces: number; space_count: number; word_count: number; description: string; } export function wordLength(input: WordLengthInput): WordLengthOutput { const { text, count_spaces } = input; const characters = [...text]; const spaceCount = characters.filter(c => c === ' ').length; const words = text.split(/\s+/).filter(w => w.length > 0); const length = count_spaces ? characters.length : characters.length - spaceCount; return { text, length, length_without_spaces: characters.length - spaceCount, space_count: spaceCount, word_count: words.length, description: `"${text}" has ${characters.length} total characters (${characters.length - spaceCount} letters, ${spaceCount} spaces).`, }; } // ============================================================================ // reverse_text - Reverse text character by character // ============================================================================ export interface ReverseTextInput { text: string; reverse_words_only: boolean; } export interface ReverseTextOutput { original: string; reversed: string; reverse_words_only: boolean; is_palindrome: boolean; description: string; } export function reverseText(input: ReverseTextInput): ReverseTextOutput { const { text, reverse_words_only } = input; let reversed: string; if (reverse_words_only) { // Reverse order of words but keep each word's characters in order reversed = text.split(/(\s+)/).reverse().join(''); } else { // Reverse all characters reversed = [...text].reverse().join(''); } const normalizedOriginal = text.toLowerCase().replace(/[^a-z0-9]/g, ''); const normalizedReversed = [...normalizedOriginal].reverse().join(''); const is_palindrome = normalizedOriginal === normalizedReversed && normalizedOriginal.length > 0; const description = reverse_words_only ? `Words reversed: "${text}" → "${reversed}"` : `Characters reversed: "${text}" → "${reversed}"${is_palindrome ? ' (This is a palindrome!)' : ''}`; return { original: text, reversed, reverse_words_only, is_palindrome, description, }; }

Implementation Reference

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/Aaryan-Kapoor/mcp-character-tools'

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