anytype_update_object
Update existing objects in Anytype by modifying their name, content, icon, or properties. Supports Markdown and ensures flexibility in managing object details within your space.
Instructions
Actualiza un objeto existente - Esta es la funcionalidad clave que faltaba en el MCP oficial
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | Nuevo contenido del objeto (soporta Markdown) | |
| icon | No | Nuevo icono del objeto | |
| name | No | Nuevo nombre del objeto | |
| object_id | Yes | ID del objeto a actualizar | |
| properties | No | Propiedades actualizadas del objeto | |
| space_id | Yes | ID del espacio |
Implementation Reference
- src/handlers/objects.ts:167-274 (handler)Main handler function for anytype_update_object. Implements replacement strategy for content (body/markdown) updates by creating new object and deleting old one, with fallback to PATCH. Handles properties including tag validation.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 for parameters like space_id, object_id, name, body/markdown, icon, and properties.{ 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)Registration/dispatch of the tool handler in the main switch statement in index.ts.case 'anytype_update_object': return await handleUpdateObject(args);
- src/handlers/objects.ts:9-49 (helper)Helper function to validate and process properties, especially multi_select (tags) and select properties before updating objects.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; }
- src/utils.ts:37-64 (helper)Helper function to build data for new replacement object, preserving name, type, icon, properties (filtered), and applying new content.export function buildNewObjectData(updateData: any, currentObject: any, contentField: string): any { const newObjectData: any = { name: updateData.name || currentObject.object.name, type_key: currentObject.object.type?.key || 'page', body: contentField }; // Only add icon if it exists and is not empty if (updateData.icon || (currentObject.object.icon && currentObject.object.icon !== null)) { newObjectData.icon = updateData.icon || currentObject.object.icon; } // Handle properties with improved tag support if (updateData.properties) { // Use new properties from updateData (already processed by validateAndProcessTags) newObjectData.properties = updateData.properties; console.log(`Using updated properties: ${updateData.properties.length} properties`); } else if (currentObject.object.properties) { // Use existing properties, filtered to remove system properties const filteredProperties = filterSystemProperties(currentObject.object.properties); if (filteredProperties.length > 0) { newObjectData.properties = filteredProperties; console.log(`Using existing properties: ${filteredProperties.length} properties`); } } return newObjectData; }