Skip to main content
Glama

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
NameRequiredDescriptionDefault
space_idYesID del espacio
object_idYesID del objeto
nameNoNuevo nombre del objeto
bodyNoNuevo contenido (Markdown) - Se aplicará estrategia de reemplazo
markdownNoNuevo contenido (Markdown) - alias para body - Se aplicará estrategia de reemplazo
iconNoIcono
propertiesNoPropiedades del objeto

Implementation Reference

  • 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) 
          }] 
        };
      }
    }
  • 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,
    ];
  • 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;
    }
Behavior5/5

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

With no annotations provided, the description carries full burden and delivers crucial behavioral information. It discloses the non-standard 'replacement strategy' behavior where content updates create a new object and delete the original, explaining this is due to API limitations with markdown. This goes beyond basic 'update' semantics to reveal important implementation details an agent needs to know.

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 perfectly concise with two sentences that each earn their place. The first states the core purpose, the second provides critical behavioral guidance with the 'IMPORTANTE' flag front-loading the most crucial information. There's zero wasted text or redundancy.

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

Completeness4/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 does an excellent job covering the most critical behavioral aspects (the replacement strategy). However, it doesn't address other important context like permission requirements, error conditions, or what the tool returns. Given the complexity of the input schema (7 parameters with nested objects), some additional guidance about the update operation's scope would be beneficial.

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 parameters are well-documented in the schema itself. The description adds minimal parameter-specific information beyond noting the replacement strategy applies to body/markdown parameters. It doesn't explain parameter interactions or provide additional context about the complex 'properties' array structure, so it meets but doesn't exceed the baseline expectation.

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 verb ('Actualiza' - updates) and resource ('un objeto existente' - an existing object), making the purpose evident. It distinguishes from creation tools like 'anytype_create_object' by specifying it's for existing objects. However, it doesn't explicitly differentiate from other update tools like 'anytype_update_property' or 'anytype_update_space' beyond the object focus.

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

Usage Guidelines5/5

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

The description provides explicit usage guidance with the 'IMPORTANTE' section that specifies when to use this tool for content updates (body/markdown) versus when not to use traditional update methods. It clearly states the replacement strategy is required for markdown content due to API limitations, giving specific context for when this tool is appropriate.

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/cryptonahue/mcp-anytype'

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