Skip to main content
Glama
GongRzhe

Terminal Controller for MCP

by GongRzhe

insert_file_content

Insert content at specific row(s) in a file using path and content parameters, with optional row or rows arguments for precise placement.

Instructions

Insert content at specific row(s) in a file

Args:
    path: Path to the file
    content: Content to insert (string or JSON object)
    row: Row number to insert at (0-based, optional)
    rows: List of row numbers to insert at (0-based, optional)

Returns:
    Operation result information

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYes
contentYes
rowNo
rowsNo

Implementation Reference

  • The main handler for the 'insert_file_content' tool. This async function accepts path, content, and optional row/rows parameters. It handles inserting content at specific row(s) in a file, creating the file if it doesn't exist, and appending content if neither row nor rows is specified. Decorated with @mcp.tool() which registers it as an MCP tool.
    @mcp.tool()
    async def insert_file_content(path: str, content: str, row: int = None, rows: list = None) -> str:
        """
        Insert content at specific row(s) in a file
        
        Args:
            path: Path to the file
            content: Content to insert (string or JSON object)
            row: Row number to insert at (0-based, optional)
            rows: List of row numbers to insert at (0-based, optional)
        
        Returns:
            Operation result information
        """
        try:
            # Handle different content types
            if not isinstance(content, str):
                try:
                    import json
                    content = json.dumps(content, indent=4, sort_keys=False, ensure_ascii=False, default=str)
                except Exception as e:
                    return f"Error: Unable to convert content to JSON string: {str(e)}"
                
            # Ensure content ends with a newline if it doesn't already
            if content and not content.endswith('\n'):
                content += '\n'
                
            # Create file if it doesn't exist
            directory = os.path.dirname(os.path.abspath(path))
            if not os.path.exists(directory):
                os.makedirs(directory, exist_ok=True)
                
            if not os.path.exists(path):
                with open(path, 'w', encoding='utf-8') as file:
                    pass
                
            with open(path, 'r', encoding='utf-8', errors='replace') as file:
                lines = file.readlines()
            
            # Ensure all existing lines end with newlines
            for i in range(len(lines)):
                if lines[i] and not lines[i].endswith('\n'):
                    lines[i] += '\n'
            
            # Prepare lines for insertion
            content_lines = content.splitlines(True)  # Keep line endings
            
            # Handle inserting at specific rows
            if rows is not None:
                if not isinstance(rows, list):
                    return "Error: 'rows' parameter must be a list of integers."
                    
                # Sort rows in descending order to avoid changing indices during insertion
                rows = sorted(rows, reverse=True)
                
                for r in rows:
                    if not isinstance(r, int) or r < 0:
                        return "Error: Row numbers must be non-negative integers."
                        
                    if r > len(lines):
                        # If row is beyond the file, append necessary empty lines
                        lines.extend(['\n'] * (r - len(lines)))
                        lines.extend(content_lines)
                    else:
                        # Insert content at each specified row
                        for line in reversed(content_lines):
                            lines.insert(r, line)
                
                # Write back to the file
                with open(path, 'w', encoding='utf-8') as file:
                    file.writelines(lines)
                    
                return f"Successfully inserted content at rows {rows} in '{path}'."
                
            # Handle inserting at a single row
            elif row is not None:
                if not isinstance(row, int) or row < 0:
                    return "Error: Row number must be a non-negative integer."
                    
                if row > len(lines):
                    # If row is beyond the file, append necessary empty lines
                    lines.extend(['\n'] * (row - len(lines)))
                    lines.extend(content_lines)
                else:
                    # Insert content at the specified row
                    for line in reversed(content_lines):
                        lines.insert(row, line)
                
                # Write back to the file
                with open(path, 'w', encoding='utf-8') as file:
                    file.writelines(lines)
                    
                return f"Successfully inserted content at row {row} in '{path}'."
            
            # If neither row nor rows specified, append to the end
            else:
                with open(path, 'a', encoding='utf-8') as file:
                    file.write(content)
                return f"Successfully appended content to '{path}'."
                
        except PermissionError:
            return f"Error: No permission to modify file '{path}'."
        except Exception as e:
            return f"Error inserting content: {str(e)}"
  • The tool is registered via the @mcp.tool() decorator on line 400. The 'mcp' object is a FastMCP instance created on line 11 with name 'terminal-controller'.
    @mcp.tool()

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

B3.3/5.0
Behavior2/5

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

No annotations are present. The description omits behavioral details such as what happens if the file does not exist, if the row index is out of range, or whether the operation can be reversed. The return value is vaguely described as 'Operation result information'.

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 short and begins with the main purpose, then lists parameters in a clear format. However, the docstring-style repetition of parameter info could be more streamlined.

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

Completeness2/5

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

Given the lack of annotations and output schema, the description should provide more context about return values, error behavior, and edge cases. It only covers basic parameter semantics, leaving gaps in understanding how the tool behaves in practice.

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

Parameters4/5

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

With 0% schema description coverage, the description compensates by explaining each parameter's purpose, including that 'row' and 'rows' are 0-based. It also notes that 'content' can be a string or JSON object, adding value beyond the schema's type string.

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 action ('Insert content') and the resource ('at specific row(s) in a file'). This is distinct from sibling tools like 'write_file' (overwrite) or 'update_file_content' (modify existing content).

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool over alternatives such as 'write_file' or 'update_file_content'. It does not mention prerequisites or scenarios where insertion is appropriate.

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