Skip to main content
Glama
qckfx

Tree-Hugger-JS MCP Server

by qckfx

transform_code

Apply multiple code transformations in a single operation to refactor JavaScript/TypeScript, including renaming, replacing patterns, inserting code, and removing unused imports.

Instructions

Apply multiple transformations in a single operation. Most powerful tool for complex refactoring workflows.

Examples: • API refactor: [{type: 'rename', parameters: {oldName: 'getData', newName: 'fetchData'}}, {type: 'removeUnusedImports'}] • Environment update: [{type: 'replaceIn', parameters: {nodeType: 'string', pattern: /localhost/g, replacement: 'api.production.com'}}, {type: 'removeUnusedImports'}] • Add logging: [{type: 'insertAfter', parameters: {pattern: 'function_declaration', text: 'console.log("Function called");'}}, {type: 'removeUnusedImports'}] • Bulk rename: [{type: 'rename', parameters: {oldName: 'user', newName: 'customer'}}, {type: 'rename', parameters: {oldName: 'id', newName: 'customerId'}}] • Legacy migration: [{type: 'replaceIn', parameters: {nodeType: 'call_expression', pattern: /XMLHttpRequest/g, replacement: 'fetch'}}, {type: 'removeUnusedImports'}]

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationsYesArray of transformation operations applied in sequence. Use preview:true first!
previewNoReturn preview only without applying changes (default: false). ALWAYS preview complex transformations first.

Implementation Reference

  • The main handler function for the 'transform_code' tool. It applies a sequence of transformation operations (rename, removeUnusedImports, replaceIn, insertBefore, insertAfter) to the current AST using tree-hugger-js transformer, optionally in preview mode, and updates the AST state if not preview.
    private async transformCode(args: { operations: TransformOperation[]; preview?: boolean }) {
      if (!this.currentAST) {
        return {
          content: [{
            type: "text",
            text: "No AST loaded. Please use parse_code first.",
          }],
          isError: true,
        };
      }
    
      try {
        let transformer = this.currentAST.tree.transform();
        
        for (const op of args.operations) {
          switch (op.type) {
            case "rename":
              if (!op.parameters.oldName || !op.parameters.newName) {
                throw new Error("Rename operation requires oldName and newName parameters");
              }
              transformer = transformer.rename(op.parameters.oldName, op.parameters.newName);
              break;
            case "removeUnusedImports":
              transformer = transformer.removeUnusedImports();
              break;
            case "replaceIn":
              if (!op.parameters.nodeType || !op.parameters.pattern || !op.parameters.replacement) {
                throw new Error("ReplaceIn operation requires nodeType, pattern, and replacement parameters");
              }
              transformer = transformer.replaceIn(op.parameters.nodeType, op.parameters.pattern, op.parameters.replacement);
              break;
            case "insertBefore":
              if (!op.parameters.pattern || !op.parameters.text) {
                throw new Error("InsertBefore operation requires pattern and text parameters");
              }
              transformer = transformer.insertBefore(String(op.parameters.pattern), op.parameters.text);
              break;
            case "insertAfter":
              if (!op.parameters.pattern || !op.parameters.text) {
                throw new Error("InsertAfter operation requires pattern and text parameters");
              }
              transformer = transformer.insertAfter(String(op.parameters.pattern), op.parameters.text);
              break;
            default:
              throw new Error(`Unknown operation type: ${op.type}`);
          }
        }
    
        const result = transformer.toString();
        
        if (!args.preview) {
          this.currentAST.sourceCode = result;
          this.currentAST.tree = parse(result);
          this.currentAST.timestamp = new Date();
        }
    
        const transformResult: TransformResult = {
          operation: "transform_code",
          parameters: {}, // TransformOperation parameters don't include operations array
          preview: result.slice(0, 500) + (result.length > 500 ? '...' : ''),
          timestamp: new Date(),
        };
        
        this.transformHistory.push(transformResult);
    
        return {
          content: [{
            type: "text",
            text: `${args.preview ? 'Preview: ' : ''}Applied ${args.operations.length} transformations\n\n${args.preview ? 'Preview:\n' : 'Result:\n'}${result}`,
          }],
        };
      } catch (error) {
        return {
          content: [{
            type: "text",
            text: `Error transforming code: ${error instanceof Error ? error.message : String(error)}`,
          }],
          isError: true,
        };
      }
    }
  • The input schema definition for the 'transform_code' tool, defining the expected parameters: operations array (with type and parameters) and optional preview boolean.
    {
      name: "transform_code",
      description: "Apply multiple transformations in a single operation. Most powerful tool for complex refactoring workflows.\n\nExamples:\n• API refactor: [{type: 'rename', parameters: {oldName: 'getData', newName: 'fetchData'}}, {type: 'removeUnusedImports'}]\n• Environment update: [{type: 'replaceIn', parameters: {nodeType: 'string', pattern: /localhost/g, replacement: 'api.production.com'}}, {type: 'removeUnusedImports'}]\n• Add logging: [{type: 'insertAfter', parameters: {pattern: 'function_declaration', text: 'console.log(\"Function called\");'}}, {type: 'removeUnusedImports'}]\n• Bulk rename: [{type: 'rename', parameters: {oldName: 'user', newName: 'customer'}}, {type: 'rename', parameters: {oldName: 'id', newName: 'customerId'}}]\n• Legacy migration: [{type: 'replaceIn', parameters: {nodeType: 'call_expression', pattern: /XMLHttpRequest/g, replacement: 'fetch'}}, {type: 'removeUnusedImports'}]",
      inputSchema: {
        type: "object",
        properties: {
          operations: {
            type: "array",
            items: {
              type: "object",
              properties: {
                type: {
                  type: "string",
                  enum: ["rename", "removeUnusedImports", "replaceIn", "insertBefore", "insertAfter"]
                },
                parameters: {
                  type: "object",
                  description: "Parameters: rename{oldName,newName}, replaceIn{nodeType,pattern,replacement}, insert{pattern,text}"
                }
              },
              required: ["type"]
            },
            description: "Array of transformation operations applied in sequence. Use preview:true first!"
          },
          preview: {
            type: "boolean",
            description: "Return preview only without applying changes (default: false). ALWAYS preview complex transformations first."
          }
        },
        required: ["operations"],
      },
    },
  • src/index.ts:437-438 (registration)
    The switch case registration in the CallToolRequestHandler that dispatches calls to the transformCode handler function.
    case "transform_code":
      return await this.transformCode(args as { operations: TransformOperation[]; preview?: boolean });

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/qckfx/tree-hugger-js-mcp'

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