anytype_update_object
Update existing Anytype objects by modifying names, icons, properties, or content using a replacement strategy for Markdown updates to ensure proper functionality.
Instructions
Actualiza un objeto existente. IMPORTANTE: Para actualizaciones de contenido (body/markdown), utiliza una estrategia de reemplazo que crea un nuevo objeto con el contenido actualizado y elimina el original, ya que la API de Anytype no actualiza correctamente el contenido markdown con el método tradicional.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| space_id | Yes | ID del espacio | |
| object_id | Yes | ID del objeto | |
| name | No | Nuevo nombre del objeto | |
| body | No | Nuevo contenido (Markdown) - Se aplicará estrategia de reemplazo | |
| markdown | No | Nuevo contenido (Markdown) - alias para body - Se aplicará estrategia de reemplazo | |
| icon | No | Icono | |
| properties | No | Propiedades del objeto |
Implementation Reference
- src/handlers/objects.ts:167-274 (handler)The primary handler function executing the tool's logic: handles updates via replacement strategy for content (fetch old, create new with updates, delete old) or direct PATCH, processes properties/tags, with fallback handling.export async function handleUpdateObject(args: any) { const { space_id, object_id, body, markdown, properties, ...updateData } = args; // Handle markdown alias const contentField = markdown || body; // Process and validate tags if properties are provided let processedProperties = []; if (properties && Array.isArray(properties)) { processedProperties = await validateAndProcessTags(space_id, properties); console.log(`Processed ${processedProperties.length} properties for object update`); } // Prepare final update data const finalUpdateData = { ...updateData, ...(processedProperties.length > 0 && { properties: processedProperties }) }; // If there's content to update, use replacement strategy if (contentField) { try { // Get current object const currentObject = await makeRequest(`/v1/spaces/${space_id}/objects/${object_id}`); // Build new object data with processed properties const newObjectData = buildNewObjectData(finalUpdateData, currentObject, contentField); // Create new object const newObjectResponse = await makeRequest(`/v1/spaces/${space_id}/objects`, { method: 'POST', body: JSON.stringify(newObjectData), }); // Delete old object await makeRequest(`/v1/spaces/${space_id}/objects/${object_id}`, { method: 'DELETE', }); return { content: [{ type: 'text', text: JSON.stringify({ message: 'Object updated successfully using replacement strategy', old_object_id: object_id, new_object: newObjectResponse, strategy: 'replacement', processed_properties: processedProperties.length, tag_assignments: processedProperties.filter(p => p.multi_select || p.select).length }, null, 2) }] }; } catch (replacementError) { console.error('Replacement strategy failed, trying traditional update:', replacementError); // Fallback to traditional PATCH method try { const patchData = { body: contentField, ...finalUpdateData }; const response = await makeRequest(`/v1/spaces/${space_id}/objects/${object_id}`, { method: 'PATCH', body: JSON.stringify(patchData), }); return { content: [{ type: 'text', text: JSON.stringify({ message: 'Object updated using traditional method (replacement failed)', object: response, strategy: 'traditional', processed_properties: processedProperties.length, tag_assignments: processedProperties.filter(p => p.multi_select || p.select).length, replacement_error: replacementError instanceof Error ? replacementError.message : 'Unknown error' }, null, 2) }] }; } catch (traditionalError) { throw new AnytypeApiError( `Both replacement and traditional update methods failed. Replacement error: ${replacementError instanceof Error ? replacementError.message : 'Unknown'}. Traditional error: ${traditionalError instanceof Error ? traditionalError.message : 'Unknown'}`, 500, { replacementError, traditionalError } ); } } } else { // No content update, use traditional PATCH const response = await makeRequest(`/v1/spaces/${space_id}/objects/${object_id}`, { method: 'PATCH', body: JSON.stringify(finalUpdateData), }); return { content: [{ type: 'text', text: JSON.stringify({ message: 'Object updated successfully', object: response, processed_properties: processedProperties.length, tag_assignments: processedProperties.filter(p => p.multi_select || p.select).length }, null, 2) }] }; } }
- src/tools/objects.ts:63-79 (schema)Tool schema definition including input validation, properties, required fields, and description noting the replacement strategy.{ name: 'anytype_update_object', description: 'Actualiza un objeto existente. IMPORTANTE: Para actualizaciones de contenido (body/markdown), utiliza una estrategia de reemplazo que crea un nuevo objeto con el contenido actualizado y elimina el original, ya que la API de Anytype no actualiza correctamente el contenido markdown con el método tradicional.', inputSchema: { type: 'object', properties: { space_id: { type: 'string', description: 'ID del espacio' }, object_id: { type: 'string', description: 'ID del objeto' }, name: { type: 'string', description: 'Nuevo nombre del objeto' }, body: { type: 'string', description: 'Nuevo contenido (Markdown) - Se aplicará estrategia de reemplazo' }, markdown: { type: 'string', description: 'Nuevo contenido (Markdown) - alias para body - Se aplicará estrategia de reemplazo' }, icon: iconSchema, properties: objectPropertiesSchema, }, required: ['space_id', 'object_id'], }, },
- src/index.ts:130-131 (registration)Switch case registration dispatching to the handleUpdateObject handler.case 'anytype_update_object': return await handleUpdateObject(args);
- src/index.ts:85-93 (registration)Tool list registration including objectTools which contains the anytype_update_object definition.const tools = [ ...spaceTools, ...objectTools, ...propertyTools, ...typeTools, ...tagTools, ...templateTools, ...listTools, ];
- src/handlers/objects.ts:9-49 (helper)Helper function to validate and process tag assignments in properties for object updates.async function validateAndProcessTags(spaceId: string, properties: any[]): Promise<any[]> { if (!properties || !Array.isArray(properties)) { return []; } const processedProperties = []; for (const prop of properties) { const processedProp = { ...prop }; // Handle multi_select properties (tags) if (prop.multi_select && Array.isArray(prop.multi_select)) { try { // Validate that all tag IDs exist // Note: We can't easily validate individual tags without knowing the property_id // This is a limitation of the current API structure console.log(`Processing multi_select property "${prop.key}" with ${prop.multi_select.length} tags`); processedProp.multi_select = prop.multi_select; } catch (error) { console.warn(`Warning: Could not validate tags for property "${prop.key}":`, error); // Keep the tags anyway, let the API handle validation processedProp.multi_select = prop.multi_select; } } // Handle single select properties if (prop.select) { try { console.log(`Processing select property "${prop.key}" with tag: ${prop.select}`); processedProp.select = prop.select; } catch (error) { console.warn(`Warning: Could not validate tag for property "${prop.key}":`, error); processedProp.select = prop.select; } } processedProperties.push(processedProp); } return processedProperties; }