create_field_node
Add custom fields to existing Tana nodes to organize and enrich data with structured attributes like text, dates, URLs, files, and references.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| targetNodeId | No | ||
| attributeId | Yes | ||
| children | No |
Implementation Reference
- src/server/tana-mcp-server.ts:357-388 (handler)Handler function that constructs a field node with type 'field', attributeId, and optional children, then calls tanaClient.createNode to execute the tool logic.async ({ targetNodeId, attributeId, children }) => { try { // Properly type the field node according to TanaFieldNode interface const fieldNode = { type: 'field' as const, // Use 'as const' to ensure type is "field" attributeId, children }; // Cast to TanaNode to satisfy the type system const result = await this.tanaClient.createNode(targetNodeId, fieldNode as any); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ], isError: false }; } catch (error) { return { content: [ { type: 'text', text: `Error creating field node: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; }
- Zod input schema for the create_field_node tool parameters.{ targetNodeId: z.string().optional(), attributeId: z.string(), children: z.array(NodeSchema).optional() },
- src/server/tana-mcp-server.ts:27-44 (schema)Recursive Zod schema definition for Tana nodes, referenced in create_field_node input schema for children.const NodeSchema = z.lazy(() => z.object({ name: z.string().optional(), description: z.string().optional(), supertags: z.array(SupertagSchema).optional(), children: z.array(z.any()).optional(), // Will be validated by implementation // Fields for specific node types dataType: z.enum(['plain', 'reference', 'date', 'url', 'boolean', 'file']).optional(), id: z.string().optional(), // For reference nodes value: z.boolean().optional(), // For boolean nodes file: z.string().optional(), // For file nodes (base64) filename: z.string().optional(), // For file nodes contentType: z.string().optional(), // For file nodes // Field node properties type: z.literal('field').optional(), attributeId: z.string().optional() }) );
- src/server/tana-mcp-server.ts:350-390 (registration)Registration of the create_field_node tool on the McpServer instance.this.server.tool( 'create_field_node', { targetNodeId: z.string().optional(), attributeId: z.string(), children: z.array(NodeSchema).optional() }, async ({ targetNodeId, attributeId, children }) => { try { // Properly type the field node according to TanaFieldNode interface const fieldNode = { type: 'field' as const, // Use 'as const' to ensure type is "field" attributeId, children }; // Cast to TanaNode to satisfy the type system const result = await this.tanaClient.createNode(targetNodeId, fieldNode as any); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ], isError: false }; } catch (error) { return { content: [ { type: 'text', text: `Error creating field node: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } );