Skip to main content
Glama

move_list_item

Move items between sections in structured memory documents to reorganize information and maintain context for better project management.

Instructions

Move an item from one section to another

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
memory_idYesThe ID of the memory document to update
from_sectionYesThe source section containing the item
to_sectionYesThe destination section for the item
item_identifierYesIdentifier for the item to move (e.g., company name)
reasonNoOptional reason for the move (stored as metadata)

Implementation Reference

  • The main handler function `moveListItemTool` that implements the core logic for moving a list item between sections in a memory document.
    export async function moveListItemTool(
      storageManager: StorageManager,
      args: any
    ): Promise<any> {
      const params = args as MoveListItemParams;
      
      if (!params.memory_id || !params.from_section || !params.to_section || !params.item_identifier) {
        throw new Error('memory_id, from_section, to_section, and item_identifier are required');
      }
    
      // Read the memory document
      const memory = await storageManager.readMemory(params.memory_id);
      if (!memory) {
        throw new Error(`Memory document '${params.memory_id}' not found`);
      }
    
      // Find both sections
      const fromSection = storageManager.findSection(memory.content, params.from_section);
      if (!fromSection) {
        throw new Error(`Source section '${params.from_section}' not found in memory document '${params.memory_id}'`);
      }
    
      const toSection = storageManager.findSection(memory.content, params.to_section);
      const toSectionExists = toSection !== null;
    
      // Parse the from section to find and extract the item
      const fromLines = fromSection.content.split('\n');
      const boundaries = findItemBoundaries(fromLines, params.item_identifier);
      
      if (!boundaries) {
        throw new Error(`Item '${params.item_identifier}' not found in section '${params.from_section}'`);
      }
      
      // Extract the item
      let extractedItem = extractItemLines(fromLines, boundaries);
      
      // Add reason as metadata if provided
      if (params.reason) {
        extractedItem = addReasonToItem(extractedItem, params.reason, params.from_section);
      }
      
      // Remove item from source section
      const remainingFromLines = removeItemFromLines(fromLines, boundaries);
      const newFromContent = remainingFromLines.join('\n');
      
      // Add item to destination section
      const existingToContent = toSectionExists && toSection ? toSection.content : null;
      const newToContent = prepareDestinationContent(extractedItem, existingToContent);
      
      // Update both sections
      await storageManager.updateSection(params.memory_id, params.from_section, newFromContent, 'replace');
      await storageManager.updateSection(params.memory_id, params.to_section, newToContent, 'replace');
      
      return {
        content: [{
          type: 'text',
          text: `Successfully moved item '${params.item_identifier}' from '${params.from_section}' to '${params.to_section}' in memory document '${params.memory_id}':
    
    **Item**: ${params.item_identifier}
    **From**: ${params.from_section}
    **To**: ${params.to_section}${params.reason ? `\n**Reason**: ${params.reason}` : ''}
    **Destination Section**: ${toSectionExists ? 'Updated existing section' : 'Created new section'}
    
    The item has been moved successfully. You can view both sections using the get_section tool.`
        }]
      };
    }
  • src/index.ts:198-233 (registration)
    Tool registration in the list of available tools, defining name, description, and input schema for MCP protocol.
    {
      name: "move_list_item",
      description: "Move an item from one section to another",
      inputSchema: {
        type: "object",
        properties: {
          memory_id: {
            type: "string",
            description: "The ID of the memory document to update",
          },
          from_section: {
            type: "string",
            description: "The source section containing the item",
          },
          to_section: {
            type: "string",
            description: "The destination section for the item",
          },
          item_identifier: {
            type: "string",
            description:
              "Identifier for the item to move (e.g., company name)",
          },
          reason: {
            type: "string",
            description: "Optional reason for the move (stored as metadata)",
          },
        },
        required: [
          "memory_id",
          "from_section",
          "to_section",
          "item_identifier",
        ],
      },
    },
  • TypeScript interface defining the parameters for the move_list_item tool.
    export interface MoveListItemParams {
      memory_id: string;
      from_section: string;
      to_section: string;
      item_identifier: string;
      reason?: string;
    }
  • Supporting helper functions for identifying, extracting, removing, and inserting list items.
    // Helper functions for moveListItem tool
    
    export interface ItemBoundaries {
      startIndex: number;
      endIndex: number;
    }
    
    export interface ExtractedItem {
      lines: string[];
      boundaries: ItemBoundaries;
    }
    
    /**
     * Finds the boundaries of an item in a section by identifier
     */
    export function findItemBoundaries(lines: string[], identifier: string): ItemBoundaries | null {
      for (let i = 0; i < lines.length; i++) {
        const line = lines[i].trim();
        
        if (line.toLowerCase().includes(identifier.toLowerCase())) {
          const startIndex = i;
          let endIndex = i;
          
          // Find the end of this item by looking for the next heading or end of content
          for (let j = i + 1; j < lines.length; j++) {
            const nextLine = lines[j].trim();
            
            // If we hit another heading (### ), this item ends at the previous line
            if (nextLine.startsWith('### ')) {
              endIndex = j - 1;
              break;
            }
            
            // If we hit an empty line followed by a heading, the item ends at the empty line
            if (nextLine === '' && lines[j + 1]?.trim().startsWith('### ')) {
              endIndex = j - 1;
              break;
            }
            
            // Otherwise, this line is part of the item
            endIndex = j;
          }
          
          return { startIndex, endIndex };
        }
      }
      
      return null;
    }
    
    /**
     * Extracts an item from lines based on boundaries
     */
    export function extractItemLines(lines: string[], boundaries: ItemBoundaries): string[] {
      return lines.slice(boundaries.startIndex, boundaries.endIndex + 1);
    }
    
    /**
     * Removes an item from lines based on boundaries
     */
    export function removeItemFromLines(lines: string[], boundaries: ItemBoundaries): string[] {
      return [
        ...lines.slice(0, boundaries.startIndex),
        ...lines.slice(boundaries.endIndex + 1)
      ];
    }
    
    /**
     * Adds reason metadata to extracted item lines
     */
    export function addReasonToItem(itemLines: string[], reason: string, fromSection: string): string[] {
      const reasonLine = `  <!-- Moved from ${fromSection}: ${reason} -->`;
      return [...itemLines, reasonLine];
    }
    
    /**
     * Prepares content for destination section (new or existing)
     */
    export function prepareDestinationContent(
      itemLines: string[], 
      existingContent: string | null
    ): string {
      if (existingContent !== null) {
        // Append to existing section
        const existingLines = existingContent.split('\n');
        const combinedLines = [...existingLines, '', ...itemLines];
        return combinedLines.join('\n');
      } else {
        // Create new section with the item
        return itemLines.join('\n');
      }
    }
    
    /**
     * Validates that an item identifier exists in the given lines
     */
    export function validateItemExists(lines: string[], identifier: string): boolean {
      return lines.some(line => 
        line.trim().toLowerCase().includes(identifier.toLowerCase())
      );
    }
    
    /**
     * Counts remaining items in section after removal
     */
    export function countRemainingItems(lines: string[]): number {
      return lines.filter(line => line.trim().startsWith('### ')).length;
    }
  • src/index.ts:283-284 (registration)
    Dispatch handler in the switch statement for calling the moveListItemTool.
    case "move_list_item":
      return await moveListItemTool(storageManager, args);
Behavior2/5

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

No annotations are provided, so the description carries full burden. It states the action is a 'move' which implies mutation, but doesn't disclose behavioral traits like whether this requires specific permissions, if it's destructive (e.g., removes from source), what happens if sections don't exist, or any rate limits. The description is minimal and lacks important operational context.

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 extremely concise at just 7 words, front-loaded with the core action. Every word earns its place - 'move' specifies the action, 'item' specifies what's being moved, and 'from one section to another' specifies the scope. No wasted words or unnecessary elaboration.

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?

For a mutation tool with no annotations and no output schema, the description is inadequate. It doesn't explain what happens during the move operation, what the expected outcome is, whether there are side effects, or what format the response takes. The 100% schema coverage helps with parameters, but the overall operational context is missing.

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 5 parameters thoroughly. The description doesn't add any meaningful semantic context beyond what's in the schema - it doesn't explain relationships between parameters, provide examples, or clarify edge cases. 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.

Purpose4/5

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

The description clearly states the action ('move') and resource ('item from one section to another'), providing a specific verb+resource combination. However, it doesn't differentiate this tool from sibling tools like 'update_list_item' or 'update_section', which might have overlapping functionality for list/section modifications.

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 versus alternatives. With siblings like 'update_list_item' and 'update_section' that might handle similar operations, there's no indication of when this specific move operation is appropriate versus other modification tools.

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/nmeierpolys/mcp-structured-memory'

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