get-attributes
Retrieve attribute data for CRM resources including companies, people, lists, records, tasks, deals, and notes by specifying resource type, record ID, categories, or specific fields.
Instructions
Get attributes for any resource type (companies, people, lists, records, tasks, deals, notes)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| categories | No | Attribute categories | |
| fields | No | Specific attribute field names | |
| record_id | No | Record ID to get attributes for (optional) | |
| resource_type | Yes | Type of resource to operate on (companies, people, lists, records, tasks) |
Implementation Reference
- src/config/tool-aliases.ts:31-36 (registration)Tool alias registration: 'get-attributes' maps to canonical 'records_get_attributes''get-attributes': { target: 'records_get_attributes', reason: 'Phase 1 search tool rename (#776)', since: SINCE_PHASE_1, removal: 'v1.x (TBD)', },
- Input schema definition for get-attributes tool (records_get_attributes)export const getAttributesSchema = { type: 'object' as const, properties: { resource_type: resourceTypeProperty, record_id: { type: 'string' as const, description: 'Record ID to get attributes for (optional)', }, categories: { type: 'array' as const, items: { type: 'string' as const }, description: 'Attribute categories', }, fields: { type: 'array' as const, items: { type: 'string' as const }, description: 'Specific attribute field names', }, }, required: ['resource_type' as const], additionalProperties: false, examples: [ { resource_type: 'companies', categories: ['standard'], }, ], };
- Tool handler configuration: validates params and delegates to UniversalMetadataService via shared handlerexport const getAttributesConfig: UniversalToolConfig< UniversalAttributesParams, Record<string, unknown> | { error: string; success: boolean } > = { name: 'records_get_attributes', handler: async ( params: UniversalAttributesParams ): Promise<Record<string, unknown> | { error: string; success: boolean }> => { try { const sanitizedParams = validateUniversalToolParams( 'records_get_attributes', params ); return await handleUniversalGetAttributes(sanitizedParams); } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error); return { error: errorMessage, success: false }; } }, formatResult: ( attributes: Record<string, unknown>, ...args: unknown[] ): string => { const resourceType = args[0] as UniversalResourceType | undefined; if (!attributes) { return 'No attributes found'; } const resourceTypeName = resourceType ? getSingularResourceType(resourceType) : 'record'; if (Array.isArray(attributes)) { return `${resourceTypeName.charAt(0).toUpperCase() + resourceTypeName.slice(1)} attributes (${attributes.length}):\n${attributes .map((attr: Record<string, unknown>, index: number) => { const name = attr.title || attr.api_slug || attr.name || attr.slug || 'Unnamed'; const type = attr.type || 'unknown'; return `${index + 1}. ${name} (${type})`; }) .join('\n')}`; } if (typeof attributes === 'object' && attributes !== null) { if (attributes.all && Array.isArray(attributes.all)) { return `Available ${resourceTypeName} attributes (${(attributes.all as []).length}):\n${( attributes.all as Record<string, unknown>[] ) .map((attr: Record<string, unknown>, index: number) => { const name = attr.title || attr.api_slug || attr.name || attr.slug || 'Unnamed'; const type = attr.type || 'unknown'; return `${index + 1}. ${name} (${type})`; }) .join('\n')}`; } if (attributes.attributes && Array.isArray(attributes.attributes)) { return `Available ${resourceTypeName} attributes (${(attributes.attributes as []).length}):\n${( attributes.attributes as Record<string, unknown>[] ) .map((attr: Record<string, unknown>, index: number) => { const name = attr.name || attr.api_slug || attr.slug || 'Unnamed'; const type = attr.type || 'unknown'; return `${index + 1}. ${name} (${type})`; }) .join('\n')}`; } const keys = Object.keys(attributes); if (keys.length > 0) { return `${resourceTypeName.charAt(0).toUpperCase() + resourceTypeName.slice(1)} attributes (${keys.length}):\n${keys .map((key, index) => { const value = attributes[key]; if (typeof value === 'string') { return `${index + 1}. ${key}: "${value}"`; } return `${index + 1}. ${key}`; }) .join('\n')}`; } } return `${resourceTypeName.charAt(0).toUpperCase() + resourceTypeName.slice(1)} attributes available`; }, };
- Shared handler delegate: routes to UniversalMetadataService.getAttributesexport async function handleUniversalGetAttributes( params: UniversalAttributesParams ): Promise<JsonObject> { return UniversalMetadataService.getAttributes(params); }
- Core implementation: Routes to resource-specific metadata getters based on resource_type, applies category filteringasync getAttributes(params: UniversalAttributesParams): Promise<JsonObject> { const { resource_type, record_id, categories } = params; let result: JsonObject; switch (resource_type) { case UniversalResourceType.COMPANIES: { if (record_id) { result = await getCompanyAttributes(record_id); } else { result = await discoverCompanyAttributes(); } break; } case UniversalResourceType.PEOPLE: { if (record_id) { result = await this.recordService.getAttributesForRecord( resource_type, record_id ); } else { result = await this.discoverAttributesForResourceType(resource_type, { categories, }); } break; } case UniversalResourceType.LISTS: { result = await getListAttributes(); break; } case UniversalResourceType.RECORDS: { if (record_id) { result = await this.recordService.getAttributesForRecord( resource_type, record_id ); } else { result = await this.discoverAttributesForResourceType(resource_type, { categories, }); } break; } case UniversalResourceType.DEALS: { if (record_id) { result = await this.recordService.getAttributesForRecord( resource_type, record_id ); } else { result = await this.discoverAttributesForResourceType(resource_type, { categories, }); } break; } case UniversalResourceType.TASKS: { if (record_id) { result = await this.recordService.getAttributesForRecord( resource_type, record_id ); } else { result = await this.discoverAttributesForResourceType(resource_type, { categories, }); } break; } default: throw new Error( `Unsupported resource type for get attributes: ${resource_type}` ); } const filtered = this.transformService.filterByCategory(result, categories); return filtered as JsonObject; }