nth_character
Extract a specific character from text using 1-based indexing, counting from start or end as needed for precise character-level analysis.
Instructions
Get the nth character (1-based, human-friendly numbering).
"What's the 3rd letter?" uses position=3.
Args:
text (string): The text to examine
position (number): Which character (1 = first, 2 = second, etc.)
from_end (boolean): Count from end instead (default: false)
Returns: The character and a human-readable description.
Example: nth_character("hello", 2) → 'e' (the 2nd character)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The text to examine | |
| position | Yes | Which character (1-based) | |
| from_end | No | Count from end instead |
Implementation Reference
- src/tools/spelling.ts:108-154 (handler)The core handler function implementing the nth_character tool. Takes input with text, position (1-indexed), and from_end option. Computes the character, handles bounds checking, generates ordinal description using getOrdinal helper, and returns structured output.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, }; }
- src/tools/spelling.ts:91-106 (schema)TypeScript interfaces defining the input schema (text, position, from_end) and output schema (including character, valid flag, description, optional error) for the nth_character tool.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; }
- src/index.ts:277-308 (registration)MCP server registration of the 'nth_character' tool, including title, description, Zod input schema validation, annotations, and async wrapper that calls the nthCharacter handler and formats response."nth_character", { title: "Nth Character", description: `Get the nth character (1-based, human-friendly numbering). "What's the 3rd letter?" uses position=3. Args: - text (string): The text to examine - position (number): Which character (1 = first, 2 = second, etc.) - from_end (boolean): Count from end instead (default: false) Returns: The character and a human-readable description. Example: nth_character("hello", 2) → 'e' (the 2nd character)`, inputSchema: z.object({ text: z.string().min(1).describe("The text to examine"), position: z.number().int().min(1).describe("Which character (1-based)"), from_end: z.boolean().default(false).describe("Count from end instead"), }).strict(), annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, }, async (params) => { const result = nthCharacter({ text: params.text, position: params.position, from_end: params.from_end, }); return { content: [{ type: "text" as const, text: result.valid ? result.description : result.error || "Invalid position" }], }; }
- src/tools/spelling.ts:156-160 (helper)Helper function getOrdinal used by nthCharacter to generate human-readable ordinal suffixes (1st, 2nd, 3rd, etc.) for descriptions.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]); }