extract_data
Extract embedded data like i18n translations from source code into a structured JSON file, replacing the original file with a migration warning to track moved data.
Instructions
Extract data content (e.g. i18n translations) from source code to a JSON file. IMPORTANT: When encountering files with data such as i18n content embedded in code, use this tool directly instead of reading the file content first. This tool will programmatically extract all translations into a structured JSON file, preserving nested objects, arrays, template variables, and formatting. This helps keep translations as configuration and prevents filling up the AI context window with translation content. By default, the source file will be replaced with "MIGRATED TO " and a warning message after successful extraction, making it easy to track where the data was moved to. This behaviour can be disabled by setting the DISABLE_SOURCE_REPLACEMENT environment variable to 'true'. The warning message can be customized by setting the WARNING_MESSAGE environment variable.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| sourcePath | Yes | Path to the source file containing data inside code | |
| targetPath | Yes | Path where the resulting JSON file should be written |
Implementation Reference
- src/index.ts:297-353 (handler)The `extractDataContent` method is the core handler that parses source code using Babel, traverses the AST looking for export default declarations that are object expressions, processes nested objects/arrays, and extracts string literal or template literal values into a flat key-value record (e.g., 'key.subkey' format).
private async extractDataContent(sourceCode: string): Promise<Record<string, string | string[] | Array<Record<string, string | string[]>>>> { const ast = parser.parse(sourceCode, { sourceType: 'module', plugins: ['typescript', 'jsx'], }); const result: Record<string, any> = {}; const processValue = (value: t.Node, currentPath: string[]): void => { if (t.isStringLiteral(value) || t.isTemplateLiteral(value)) { const extractedValue = this.extractStringValue(value); if (extractedValue !== null && extractedValue.trim() !== '') { result[this.buildKey(currentPath)] = extractedValue; } } else if (t.isArrayExpression(value)) { value.elements.forEach((element, index) => { if (!element) return; if (t.isStringLiteral(element) || t.isTemplateLiteral(element)) { const extractedValue = this.extractStringValue(element); if (extractedValue !== null && extractedValue.trim() !== '') { result[`${this.buildKey(currentPath)}.${index}`] = extractedValue; } } else if (t.isObjectExpression(element)) { processObject(element, [...currentPath, index.toString()]); } }); } else if (t.isObjectExpression(value)) { processObject(value, currentPath); } }; const processObject = (obj: t.ObjectExpression, parentPath: string[] = []): void => { obj.properties.forEach(prop => { if (!t.isObjectProperty(prop)) return; const key = t.isIdentifier(prop.key) ? prop.key.name : t.isStringLiteral(prop.key) ? prop.key.value : null; if (!key) return; const currentPath = [...parentPath, key]; processValue(prop.value, currentPath); }); }; traverse(ast, { ExportDefaultDeclaration(path: NodePath<t.ExportDefaultDeclaration>) { const declaration = path.node.declaration; if (t.isObjectExpression(declaration)) { processObject(declaration); } } }); return result; } - src/index.ts:111-144 (handler)The `CallToolRequestSchema` handler for 'extract_data': reads the source file, calls `extractDataContent`, writes the result as a JSON file, and optionally replaces the source file with a migration notice.
if (request.params.name === 'extract_data') { const { targetPath } = request.params.arguments as { targetPath: string }; const dataContent = await this.extractDataContent(sourceCode); // Create target directory if it doesn't exist await fs.mkdir(path.dirname(targetPath), { recursive: true }); // Write extracted content to JSON file await fs.writeFile( targetPath, JSON.stringify(dataContent, null, 2), 'utf-8' ); // Replace source file content with migration message if not disabled if (!DISABLE_SOURCE_REPLACEMENT) { const absoluteTargetPath = path.resolve(targetPath); await fs.writeFile( sourcePath, `MIGRATED TO ${absoluteTargetPath}${WARNING_MESSAGE}`, 'utf-8' ); } return { content: [ { type: 'text', text: `Successfully extracted ${Object.keys(dataContent).length} data entries to ${path.resolve(targetPath)}${ !DISABLE_SOURCE_REPLACEMENT ? `. Source file replaced with "MIGRATED TO ${path.resolve(targetPath)}"` : '' }`, }, ], }; - src/index.ts:62-79 (registration)Tool registration for 'extract_data' in the `ListToolsRequestSchema` handler: defines the tool name, description, and input schema (sourcePath and targetPath required strings).
{ name: 'extract_data', description: 'Extract data content (e.g. i18n translations) from source code to a JSON file. IMPORTANT: When encountering files with data such as i18n content embedded in code, use this tool directly instead of reading the file content first. This tool will programmatically extract all translations into a structured JSON file, preserving nested objects, arrays, template variables, and formatting. This helps keep translations as configuration and prevents filling up the AI context window with translation content. By default, the source file will be replaced with "MIGRATED TO <target absolute path>" and a warning message after successful extraction, making it easy to track where the data was moved to. This behaviour can be disabled by setting the DISABLE_SOURCE_REPLACEMENT environment variable to \'true\'. The warning message can be customized by setting the WARNING_MESSAGE environment variable.', inputSchema: { type: 'object', properties: { sourcePath: { type: 'string', description: 'Path to the source file containing data inside code', }, targetPath: { type: 'string', description: 'Path where the resulting JSON file should be written', }, }, required: ['sourcePath', 'targetPath'], }, }, - src/index.ts:23-26 (schema)The `DataExtraction` interface defining the shape of extracted data entries (key and value strings).
interface DataExtraction { key: string; value: string; } - src/index.ts:198-200 (helper)The `buildKey` helper method that joins path parts with dots (e.g., ['key', 'subkey'] -> 'key.subkey').
private buildKey(parts: string[]): string { return parts.join('.'); }