Skip to main content
Glama
lin2000wl

Serena MCP Server

by lin2000wl

insert_after_symbol

Inserts code after a specified symbol's definition in files. Use to add new classes, functions, methods, fields, or variable assignments by providing the symbol's name path, file location, and content to insert.

Instructions

Inserts the given body/content after the end of the definition of the given symbol (via the symbol's location). A typical use case is to insert a new class, function, method, field or variable assignment.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
name_pathYesName path of the symbol after which to insert content (definitions in the `find_symbol` tool apply).
relative_pathYesThe relative path to the file containing the symbol.
bodyYesThe body/content to be inserted. The inserted code shall begin with the next line after the symbol.

Implementation Reference

  • Main handler method for insert_after_symbol tool, finds the symbol by name and delegates to insert_after_symbol_at_location.
    def insert_after_symbol(self, name_path: str, relative_file_path: str, body: str, *, use_same_indentation: bool = True) -> None:
        """
        Inserts content after the symbol with the given name in the given file.
        """
        symbol_candidates = self.find_by_name(name_path, within_relative_path=relative_file_path)
        if len(symbol_candidates) == 0:
            raise ValueError(f"No symbol with name {name_path} found in file {relative_file_path}")
        if len(symbol_candidates) > 1:
            raise ValueError(
                f"Found multiple {len(symbol_candidates)} symbols with name {name_path} in file {relative_file_path}. "
                f"May be an overwritten variable, in which case you can ignore this error. Proceeding with the last one. "
                f"Found symbols at locations: \n" + json.dumps([s.location.to_dict() for s in symbol_candidates], indent=2)
            )
        symbol = symbol_candidates[-1]
        return self.insert_after_symbol_at_location(symbol.location, body, use_same_indentation=use_same_indentation)
  • Core implementation logic for inserting code after a symbol's body end position, handling indentation, newlines, and file editing.
    def insert_after_symbol_at_location(self, location: SymbolLocation, body: str, *, use_same_indentation: bool = True) -> None:
        """
        Appends content after the given symbol
    
        :param location: the location of the symbol after which to add new lines
        :param body: the body of the entity to append
        """
        # make sure body always ends with at least one newline
        if not body.endswith("\n"):
            body += "\n"
    
        assert location.relative_path is not None
    
        # Find the symbol to get its end position
        symbol = self.find_by_location(location)
        if symbol is None:
            raise ValueError("Symbol not found/has no defined location within a file")
    
        pos = symbol.body_end_position
        if pos is None:
            raise ValueError(f"Symbol at {location} does not have a defined end position.")
    
        # start at the beginning of the next line
        col = 0
        line = pos["line"] + 1
        # make sure a suitable number of leading empty lines is used (at least 0/1 depending on the symbol type,
        # otherwise as many as the caller wanted to insert)
        original_leading_newlines = self._count_leading_newlines(body)
        body = body.lstrip("\r\n")
        min_empty_lines = 0
        if symbol.is_neighbouring_definition_separated_by_empty_line():
            min_empty_lines = 1
        num_leading_empty_lines = max(min_empty_lines, original_leading_newlines)
        if num_leading_empty_lines:
            body = ("\n" * num_leading_empty_lines) + body
        # make sure the one line break succeeding the original symbol, which we repurposed as prefix via
        # `line += 1`, is replaced
        body = body.rstrip("\r\n") + "\n"
    
        if use_same_indentation:
            symbol_start_pos = symbol.body_start_position
            assert symbol_start_pos is not None, f"Symbol at {location=} does not have a defined start position."
            symbol_identifier_col = symbol_start_pos["character"]
            indent = " " * (symbol_identifier_col)
            body = "\n".join(indent + line for line in body.splitlines())
            # IMPORTANT: without this, the insertion does the wrong thing. See implementation of insert_text_at_position in TextUtils,
            # it is somewhat counterintuitive (never inserts whitespace)
            # I am not 100% sure whether col=0 is always the best choice here.
            #
            # Without col=0, inserting after dataclass_instance in variables.py:
            # > dataclass_instance = VariableDataclass(id=1, name="Test")
            # > test test
            # > dataclass_instancetest test
            # > second line
            # > .status = "active"  # Reassign dataclass field
            #
            # With col=0:
            # > dataclass_instance = VariableDataclass(id=1, name="Test")
            # > test test
            # > second line
            # > dataclass_instance.status = "active"  # Reassign dataclass field
    
        with self._edited_symbol_location(location):
            self._lang_server.insert_text_at_position(location.relative_path, line=line, column=col, text_to_be_inserted=body)
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It discloses that the tool inserts content after a symbol's definition and that the inserted code begins on the next line, adding useful behavioral context. However, it does not cover permissions, error handling, or side effects, leaving gaps for a mutation tool with no annotation coverage.

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

Conciseness5/5

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

The description is front-loaded with the core purpose in the first sentence, followed by a concise typical use case. Both sentences earn their place by clarifying intent and context without any wasted words, making it efficiently structured and easy to parse.

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

Completeness3/5

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

Given no annotations and no output schema, the description provides adequate purpose and usage context but lacks details on behavioral traits like error handling or side effects. For a mutation tool with 3 parameters and 100% schema coverage, it is minimally viable but has clear gaps in completeness, especially around operational transparency.

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?

Schema description coverage is 100%, so the schema already documents all three parameters. The description adds minimal value by implying that 'name_path' refers to a symbol's location and 'body' is the content to insert, but it does not provide additional syntax or format details beyond what the schema provides. Baseline 3 is appropriate when schema does the heavy lifting.

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 verb 'inserts' and specifies the resource 'body/content' after the definition of a given symbol via its location. It distinguishes from sibling tools like 'insert_before_symbol' by specifying 'after' and from 'insert_at_line' by focusing on symbol-based positioning. The typical use cases (class, function, method, field, variable assignment) further clarify the purpose.

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

Usage Guidelines4/5

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

The description provides clear context for when to use this tool: for inserting content after a symbol's definition, with typical use cases listed. It implicitly distinguishes from 'insert_before_symbol' by specifying 'after' and from 'insert_at_line' by using symbol-based positioning. However, it does not explicitly state when not to use it or name alternatives, missing full explicit guidance.

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/lin2000wl/Serena-cursor-mcp'

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