Skip to main content
Glama

extract_svg

Extract SVG components from React/TypeScript/JavaScript files into individual SVG files, preserving structure while removing React-specific code.

Instructions

Extract SVG components from React/TypeScript/JavaScript files into individual .svg files. This tool will preserve the SVG structure and attributes while removing React-specific code. 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 SVGs were 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

TableJSON Schema
NameRequiredDescriptionDefault
sourcePathYesPath to the source file containing SVG components
targetDirYesDirectory where the SVG files should be written

Implementation Reference

  • Executes the extract_svg tool: extracts SVGs using extractSvgs, writes individual SVG files to targetDir, optionally replaces source file with migration notice.
    } else if (request.params.name === 'extract_svg') {
      const { targetDir } = request.params.arguments as { targetDir: string };
      const svgs = await this.extractSvgs(sourceCode);
    
      // Create target directory if it doesn't exist
      await fs.mkdir(targetDir, { recursive: true });
    
      // Write each SVG to a separate file
      for (const svg of svgs) {
        const filePath = path.join(targetDir, `${svg.name}.svg`);
        await fs.writeFile(filePath, svg.content, 'utf-8');
      }
    
      // Replace source file content with migration message if not disabled
      if (!DISABLE_SOURCE_REPLACEMENT) {
        const absoluteTargetDir = path.resolve(targetDir);
        await fs.writeFile(
          sourcePath,
          `MIGRATED TO ${absoluteTargetDir}${WARNING_MESSAGE}`,
          'utf-8'
        );
      }
    
      return {
        content: [
          {
            type: 'text',
            text: `Successfully extracted ${svgs.length} SVG components to ${path.resolve(targetDir)}${
              !DISABLE_SOURCE_REPLACEMENT ? `. Source file replaced with "MIGRATED TO ${path.resolve(targetDir)}"` : ''
            }`,
          },
        ],
      };
  • Input schema definition for extract_svg tool requiring sourcePath and targetDir.
    inputSchema: {
      type: 'object',
      properties: {
        sourcePath: {
          type: 'string',
          description: 'Path to the source file containing SVG components',
        },
        targetDir: {
          type: 'string',
          description: 'Directory where the SVG files should be written',
        },
      },
      required: ['sourcePath', 'targetDir'],
    },
  • src/index.ts:80-97 (registration)
    Registers the extract_svg tool in the tools list with name, description, and input schema.
    {
      name: 'extract_svg',
      description: 'Extract SVG components from React/TypeScript/JavaScript files into individual .svg files. This tool will preserve the SVG structure and attributes while removing React-specific code. 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 SVGs were 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 SVG components',
          },
          targetDir: {
            type: 'string',
            description: 'Directory where the SVG files should be written',
          },
        },
        required: ['sourcePath', 'targetDir'],
      },
    },
  • Core extraction logic: parses source with Babel, traverses AST for SVG JSX in arrow function declarations, extracts using extractSvgContent.
    private async extractSvgs(sourceCode: string): Promise<SvgExtraction[]> {
      const ast = parser.parse(sourceCode, {
        sourceType: 'module',
        plugins: ['typescript', 'jsx'],
      });
    
      const svgs: SvgExtraction[] = [];
    
      traverse(ast, {
        VariableDeclaration(path: NodePath<t.VariableDeclaration>) {
          const declaration = path.node.declarations[0];
          if (t.isVariableDeclarator(declaration) &&
              t.isIdentifier(declaration.id) &&
              t.isArrowFunctionExpression(declaration.init)) {
    
            // Look for JSX in the arrow function body
            const body = declaration.init.body;
            if (t.isJSXElement(body)) {
              const svgContent = this.extractSvgContent(body);
              if (svgContent) {
                svgs.push({
                  name: declaration.id.name,
                  content: svgContent
                });
              }
            }
          }
        }
      });
    
      return svgs;
    }
  • Helper to convert JSX SVG element to plain SVG string, handling attributes, nested elements, and text content.
    private extractSvgContent(jsxElement: t.JSXElement): string | null {
      // Check if this is an SVG element
      if (t.isJSXIdentifier(jsxElement.openingElement.name) &&
          jsxElement.openingElement.name.name.toLowerCase() === 'svg') {
    
        // Convert JSX attributes to string
        const attributes = jsxElement.openingElement.attributes
          .map(attr => {
            if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name)) {
              const name = attr.name.name;
              if (t.isStringLiteral(attr.value)) {
                return `${name}="${attr.value.value}"`;
              } else if (t.isJSXExpressionContainer(attr.value) &&
                        t.isStringLiteral(attr.value.expression)) {
                return `${name}="${attr.value.expression.value}"`;
              }
            }
            return '';
          })
          .filter(Boolean)
          .join(' ');
    
        // Convert children to string
        const children = jsxElement.children
          .map(child => {
            if (t.isJSXElement(child)) {
              const elementName = (child.openingElement.name as t.JSXIdentifier).name;
              const childAttributes = child.openingElement.attributes
                .map(attr => {
                  if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name)) {
                    const name = attr.name.name;
                    if (t.isStringLiteral(attr.value)) {
                      return `${name}="${attr.value.value}"`;
                    }
                  }
                  return '';
                })
                .filter(Boolean)
                .join(' ');
    
              return `<${elementName} ${childAttributes}>${child.children
                .map(c => t.isJSXText(c) ? c.value : '')
                .join('')}</${elementName}>`;
            }
            return '';
          })
          .join('\n    ');
    
        return `<svg ${attributes}>\n    ${children}\n</svg>`;
      }
      return null;
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does well by disclosing key behavioral traits: it describes the default behavior of replacing the source file with a migration message, the ability to disable this via an environment variable, and customization of the warning message. However, it lacks details on error handling, performance, or side effects beyond file replacement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded, starting with the core purpose and key behavior. However, the second sentence could be more concise, and some details about environment variables might be better structured, but overall it avoids unnecessary repetition and stays focused.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (file processing with environment variable customization) and no annotations or output schema, the description is fairly complete: it covers the purpose, behavior, and customization options. However, it lacks information on output format (e.g., what the extracted SVG files look like) and error cases, which would enhance completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, so the schema already documents the two parameters (sourcePath and targetDir) adequately. The description does not add specific meaning or usage examples for these parameters beyond what the schema provides, such as file format expectations or directory requirements.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('extract SVG components'), the source format ('React/TypeScript/JavaScript files'), the output format ('individual .svg files'), and the transformation ('preserve SVG structure and attributes while removing React-specific code'). It distinguishes from the sibling tool 'extract_data' by specifying SVG extraction rather than generic data extraction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for migrating SVG components from React/TypeScript/JavaScript files to standalone SVG files, but it does not explicitly state when to use this tool versus alternatives or provide exclusions. No guidance is given on prerequisites or comparison with the sibling tool 'extract_data'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/sammcj/mcp-data-extractor'

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