Skip to main content
Glama

update_note_type

Modify existing note types by updating instructions, descriptions, or metadata fields to adapt note structures for AI collaboration in Flint Note.

Instructions

Update one or more fields of an existing note type

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
type_nameYesName of the note type to update
instructionsNoNew agent instructions for the note type
descriptionNoNew description for the note type
metadata_schemaNoArray of metadata field definitions
content_hashYesContent hash of the current note type definition to prevent conflicts
vault_idNoOptional vault ID to operate on. If not provided, uses the current active vault.

Implementation Reference

  • The primary handler function that implements the 'update_note_type' tool. Validates inputs, checks content hash for concurrency control, updates note type description/instructions/metadata schema, validates schema fields, writes updated _description.md file, and returns success/error response.
    handleUpdateNoteType = async (args: UpdateNoteTypeArgs) => { // Validate arguments validateToolArgs('update_note_type', args); const { noteTypeManager, workspace } = await this.resolveVaultContext(args.vault_id); try { if (!args.content_hash) { throw new Error('content_hash is required for all note type update operations'); } // Validate that at least one field is provided if ( args.instructions === undefined && args.description === undefined && args.metadata_schema === undefined ) { throw new Error( 'At least one field must be provided: instructions, description, or metadata_schema' ); } // Get current note type info const currentInfo = await noteTypeManager.getNoteTypeDescription(args.type_name); // Validate content hash to prevent conflicts const currentHashableContent = createNoteTypeHashableContent({ description: currentInfo.description, agent_instructions: currentInfo.parsed.agentInstructions.join('\n'), metadata_schema: currentInfo.metadataSchema }); const currentHash = generateContentHash(currentHashableContent); if (currentHash !== args.content_hash) { const error = new Error( 'Note type definition has been modified since last read. Please fetch the latest version.' ) as Error & { code: string; current_hash: string; provided_hash: string; }; error.code = 'content_hash_mismatch'; error.current_hash = currentHash; error.provided_hash = args.content_hash; throw error; } // Start with current description let updatedDescription = currentInfo.description; const fieldsUpdated: string[] = []; // Update instructions if provided if (args.instructions) { // Parse instructions from value (can be newline-separated or bullet points) const instructions = args.instructions .split('\n') .map(line => line.trim()) .filter(line => line.length > 0) .map(line => (line.startsWith('-') ? line.substring(1).trim() : line)) .map(line => `- ${line}`) .join('\n'); // Use the current description and replace the agent instructions section updatedDescription = updatedDescription.replace( /## Agent Instructions\n[\s\S]*?(?=\n## |$)/, `## Agent Instructions\n${instructions}\n` ); fieldsUpdated.push('instructions'); } // Update description if provided if (args.description) { updatedDescription = noteTypeManager.formatNoteTypeDescription( args.type_name, args.description ); fieldsUpdated.push('description'); } // Update metadata schema if provided if (args.metadata_schema) { const fields = args.metadata_schema; // Validate each field definition for (let i = 0; i < fields.length; i++) { const field = fields[i]; if (!field || typeof field !== 'object') { throw new Error(`Field at index ${i} must be an object`); } if (!field.name || typeof field.name !== 'string') { throw new Error(`Field at index ${i} must have a valid "name" string`); } if (!field.type || typeof field.type !== 'string') { throw new Error(`Field at index ${i} must have a valid "type" string`); } // Check for protected fields const protectedFields = new Set(['title', 'filename', 'created', 'updated']); if (protectedFields.has(field.name)) { throw new Error( `Cannot define protected field "${field.name}" in metadata schema. ` + `These fields are automatically managed by the system and cannot be redefined.` ); } const validTypes = ['string', 'number', 'boolean', 'date', 'array', 'select']; if (!validTypes.includes(field.type)) { throw new Error( `Field "${field.name}" has invalid type "${field.type}". Valid types: ${validTypes.join(', ')}` ); } // Validate constraints if present if (field.constraints) { if (typeof field.constraints !== 'object') { throw new Error(`Field "${field.name}" constraints must be an object`); } // Validate select field options if (field.type === 'select') { if ( !field.constraints.options || !Array.isArray(field.constraints.options) ) { throw new Error( `Select field "${field.name}" must have constraints.options array` ); } if (field.constraints.options.length === 0) { throw new Error( `Select field "${field.name}" must have at least one option` ); } } // Validate numeric constraints if ( field.constraints.min !== undefined && typeof field.constraints.min !== 'number' ) { throw new Error(`Field "${field.name}" min constraint must be a number`); } if ( field.constraints.max !== undefined && typeof field.constraints.max !== 'number' ) { throw new Error(`Field "${field.name}" max constraint must be a number`); } if ( field.constraints.min !== undefined && field.constraints.max !== undefined && field.constraints.min > field.constraints.max ) { throw new Error( `Field "${field.name}" min constraint cannot be greater than max` ); } // Validate pattern constraint if (field.constraints.pattern !== undefined) { if (typeof field.constraints.pattern !== 'string') { throw new Error( `Field "${field.name}" pattern constraint must be a string` ); } try { new RegExp(field.constraints.pattern); } catch (regexError) { throw new Error( `Field "${field.name}" pattern constraint is not a valid regex: ${regexError instanceof Error ? regexError.message : 'Unknown regex error'}` ); } } } // Validate default values if present if (field.default !== undefined) { const validationError = this.validateDefaultValue( field.name, field.default, field ); if (validationError) { throw new Error(validationError); } } } // Check for duplicate field names const fieldNames = fields.map(f => f.name); const duplicates = fieldNames.filter( (name, index) => fieldNames.indexOf(name) !== index ); if (duplicates.length > 0) { throw new Error(`Duplicate field names found: ${duplicates.join(', ')}`); } // Create MetadataSchema object and generate the schema section const parsedSchema = { fields }; const schemaSection = MetadataSchemaParser.generateSchemaSection(parsedSchema); updatedDescription = updatedDescription.replace( /## Metadata Schema\n[\s\S]*$/, schemaSection ); fieldsUpdated.push('metadata_schema'); } // Write the updated description to the file in note type directory const descriptionPath = path.join( workspace.getNoteTypePath(args.type_name), '_description.md' ); await fs.writeFile(descriptionPath, updatedDescription, 'utf-8'); // Get the updated note type info const result = await noteTypeManager.getNoteTypeDescription(args.type_name); return { content: [ { type: 'text', text: JSON.stringify( { success: true, type_name: args.type_name, fields_updated: fieldsUpdated, updated_info: { name: result.name, purpose: result.parsed.purpose, agent_instructions: result.parsed.agentInstructions } }, null, 2 ) } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` } ], isError: true }; } };
  • JSON Schema definition for the 'update_note_type' tool, specifying input parameters including type_name (required), optional updates to description/instructions/schema, required content_hash for safety, and optional vault_id.
    name: 'update_note_type', description: 'Update an existing note type', inputSchema: { type: 'object', properties: { type_name: { type: 'string', description: 'Name of the note type to update' }, description: { type: 'string', description: 'New description for the note type' }, agent_instructions: { type: 'array', items: { type: 'string' }, description: 'New agent instructions for this note type' }, metadata_schema: { type: 'object', properties: { fields: { type: 'array', items: { type: 'object', properties: { name: { type: 'string', description: 'Name of the metadata field' }, type: { type: 'string', enum: ['string', 'number', 'boolean', 'date', 'array', 'select'], description: 'Type of the metadata field' }, description: { type: 'string', description: 'Optional description of the field' }, required: { type: 'boolean', description: 'Whether this field is required' }, constraints: { type: 'object', description: 'Optional field constraints (min, max, options, etc.)' }, default: { description: 'Optional default value for the field' } }, required: ['name', 'type'] } }, version: { type: 'string', description: 'Optional schema version' } }, required: ['fields'], description: 'New metadata schema definition for this note type' }, content_hash: { type: 'string', description: 'Content hash of the note type being updated (for concurrent update protection)' }, vault_id: { type: 'string', description: 'Optional vault ID to operate on. If not provided, uses the current active vault.' } }, required: ['type_name'] } },
  • Tool dispatch/registration in the MCP CallToolRequestSchema handler switch statement, routing 'update_note_type' calls to the NoteTypeHandlers.handleUpdateNoteType method.
    case 'update_note_type': return await this.noteTypeHandlers.handleUpdateNoteType( args as unknown as UpdateNoteTypeArgs );
  • TypeScript interface defining the expected arguments for the update_note_type handler.
    export interface UpdateNoteTypeArgs { type_name: string; instructions?: string; description?: string; metadata_schema?: MetadataFieldDefinition[]; content_hash: string; vault_id?: string; }
  • Runtime validation rules for update_note_type tool arguments, ensuring required fields, types, and custom validations are met before handler execution.
    update_note_type: [ { field: 'type_name', required: true, type: 'string', allowEmpty: false }, { field: 'instructions', required: false, type: 'string', allowEmpty: true }, { field: 'description', required: false, type: 'string', allowEmpty: false }, { field: 'metadata_schema', required: false, type: 'array', allowEmpty: true }, { field: 'content_hash', required: true, type: 'string', allowEmpty: false }, { field: 'vault_id', required: false, type: 'string', allowEmpty: false } ],

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/disnet/flint-note'

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