Skip to main content
Glama

move_list_item

Relocate an item within a structured memory document by specifying source and destination sections, ensuring organized knowledge management for project contexts.

Instructions

Move an item from one section to another

Input Schema

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

Input Schema (JSON Schema)

{ "properties": { "from_section": { "description": "The source section containing the item", "type": "string" }, "item_identifier": { "description": "Identifier for the item to move (e.g., company name)", "type": "string" }, "memory_id": { "description": "The ID of the memory document to update", "type": "string" }, "reason": { "description": "Optional reason for the move (stored as metadata)", "type": "string" }, "to_section": { "description": "The destination section for the item", "type": "string" } }, "required": [ "memory_id", "from_section", "to_section", "item_identifier" ], "type": "object" }

Implementation Reference

  • Main handler function for the 'move_list_item' tool. Validates parameters, reads memory, locates sections, finds and extracts the item using helpers, removes from source, adds to destination, updates storage, and returns success message.
    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.` }] }; }
  • TypeScript interface defining the input parameters for the moveListItemTool, used for type validation in the handler.
    export interface MoveListItemParams { memory_id: string; from_section: string; to_section: string; item_identifier: string; reason?: string; }
  • src/index.ts:198-233 (registration)
    Tool registration in the ListTools response, including name 'move_list_item', description, and inputSchema matching the MoveListItemParams interface.
    { 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", ], }, },
  • src/index.ts:283-284 (registration)
    Dispatch handler in the CallToolRequest switch statement that routes 'move_list_item' calls to the moveListItemTool function.
    case "move_list_item": return await moveListItemTool(storageManager, args);
  • Key helper functions used by the handler: finding item boundaries, extracting, removing, adding reason, and preparing destination content.
    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'); } }

Other Tools

Related 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