add-table
Create a new table in Xano database with custom schema, including field types, validation rules, and foreign key relationships.
Instructions
Add a new table to the Xano database
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name of the table | |
| description | No | Description of the table | |
| schema | No | Schema configuration for the table. For foreign key relationships, use type 'int' with tableref_id. Example: { "name": "contact_id", "type": "int", "description": "Reference to contact table", "nullable": false, "required": false, "access": "public", "style": "single", "default": "0", "tableref_id": "100" // ID of the table to reference } |
Implementation Reference
- src/index.ts:302-369 (handler)The handler function for the 'add-table' tool. It creates a new table in Xano using POST /workspace/{XANO_WORKSPACE}/table, then optionally processes and applies the provided schema via PUT /table/{tableId}/schema, handling foreign key validation for fields with tableref_id.async ({ name, description, schema }) => { console.error(`[Tool] Executing add-table for table: ${name}`); try { // Step 1: Create the table const createTableResponse = await makeXanoRequest<{ id: string }>( `/workspace/${XANO_WORKSPACE}/table`, 'POST', { name, description } ); const tableId = createTableResponse.id; console.error(`[Tool] Table created with ID: ${tableId}`); // Step 2: If schema is provided, process and add it to the table if (schema && schema.length > 0) { try { // Process schema fields to handle relationships const processedSchema = schema.map(field => { // Validate relationship fields if (field.tableref_id && field.type !== "int") { throw new Error(`Field "${field.name}" has tableref_id but type is not "int". Foreign key fields must be of type "int".`); } return field; }); // Update the schema with processed fields await makeXanoRequest( `/workspace/${XANO_WORKSPACE}/table/${tableId}/schema`, 'PUT', { schema: processedSchema } ); console.error(`[Tool] Schema successfully added to table ID: ${tableId}`); } catch (schemaError) { console.error(`[Error] Failed to add schema: ${schemaError instanceof Error ? schemaError.message : String(schemaError)}`); return { content: [ { type: "text", text: `Table created with ID ${tableId}, but failed to add schema: ${schemaError instanceof Error ? schemaError.message : String(schemaError)}` } ], isError: true }; } } return { content: [ { type: "text", text: `Successfully created table "${name}" with ID: ${tableId}${schema ? ' and added the specified schema.' : '.'}` } ] }; } catch (error) { console.error(`[Error] Failed to create table: ${error instanceof Error ? error.message : String(error)}`); return { content: [ { type: "text", text: `Error creating table: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } }
- src/index.ts:257-301 (schema)Zod schema defining the input parameters for the 'add-table' tool: table name, optional description, and optional array of schema fields with comprehensive type, validation, and relationship support.{ name: z.string().describe("Name of the table"), description: z.string().optional().describe("Description of the table"), schema: z.array(z.object({ name: z.string().describe("Name of the schema element"), type: z.enum([ "attachment", "audio", "bool", "date", "decimal", "email", "enum", "geo_linestring", "geo_multilinestring", "geo_multipoint", "geo_multipolygon", "geo_point", "geo_polygon", "image", "int", "json", "object", "password", "tablerefuuid", "text", "timestamp", "uuid", "vector", "video" ]).describe("Type of the schema element"), description: z.string().optional().describe("Description of the schema element"), nullable: z.boolean().optional().default(false).describe("Whether the field can be null"), required: z.boolean().optional().default(false).describe("Whether the field is required"), access: z.enum(["public", "private", "internal"]).optional().default("public").describe("Access level for the field"), style: z.enum(["single", "list"]).optional().default("single").describe("Whether the field is a single value or a list"), default: z.string().optional().describe("Default value for the field"), config: z.record(z.any()).optional().describe("Additional configuration for specific field types"), validators: z.object({ lower: z.boolean().optional(), max: z.number().optional(), maxLength: z.number().optional(), min: z.number().optional(), minLength: z.number().optional(), pattern: z.string().optional(), precision: z.number().optional(), scale: z.number().optional(), trim: z.boolean().optional() }).optional().describe("Validation rules for the field"), children: z.array(z.any()).optional().describe("Nested fields for object types"), tableref_id: z.string().optional().describe("ID of the referenced table (only valid when type is 'int')"), values: z.array(z.string()).optional().describe("Array of allowed values (only for enum type)") })).optional().describe(`Schema configuration for the table. For foreign key relationships, use type 'int' with tableref_id. Example: { "name": "contact_id", "type": "int", "description": "Reference to contact table", "nullable": false, "required": false, "access": "public", "style": "single", "default": "0", "tableref_id": "100" // ID of the table to reference }`) },
- src/index.ts:255-370 (registration)The server.tool registration call that defines and registers the 'add-table' tool with its description, input schema, and handler function."add-table", "Add a new table to the Xano database", { name: z.string().describe("Name of the table"), description: z.string().optional().describe("Description of the table"), schema: z.array(z.object({ name: z.string().describe("Name of the schema element"), type: z.enum([ "attachment", "audio", "bool", "date", "decimal", "email", "enum", "geo_linestring", "geo_multilinestring", "geo_multipoint", "geo_multipolygon", "geo_point", "geo_polygon", "image", "int", "json", "object", "password", "tablerefuuid", "text", "timestamp", "uuid", "vector", "video" ]).describe("Type of the schema element"), description: z.string().optional().describe("Description of the schema element"), nullable: z.boolean().optional().default(false).describe("Whether the field can be null"), required: z.boolean().optional().default(false).describe("Whether the field is required"), access: z.enum(["public", "private", "internal"]).optional().default("public").describe("Access level for the field"), style: z.enum(["single", "list"]).optional().default("single").describe("Whether the field is a single value or a list"), default: z.string().optional().describe("Default value for the field"), config: z.record(z.any()).optional().describe("Additional configuration for specific field types"), validators: z.object({ lower: z.boolean().optional(), max: z.number().optional(), maxLength: z.number().optional(), min: z.number().optional(), minLength: z.number().optional(), pattern: z.string().optional(), precision: z.number().optional(), scale: z.number().optional(), trim: z.boolean().optional() }).optional().describe("Validation rules for the field"), children: z.array(z.any()).optional().describe("Nested fields for object types"), tableref_id: z.string().optional().describe("ID of the referenced table (only valid when type is 'int')"), values: z.array(z.string()).optional().describe("Array of allowed values (only for enum type)") })).optional().describe(`Schema configuration for the table. For foreign key relationships, use type 'int' with tableref_id. Example: { "name": "contact_id", "type": "int", "description": "Reference to contact table", "nullable": false, "required": false, "access": "public", "style": "single", "default": "0", "tableref_id": "100" // ID of the table to reference }`) }, async ({ name, description, schema }) => { console.error(`[Tool] Executing add-table for table: ${name}`); try { // Step 1: Create the table const createTableResponse = await makeXanoRequest<{ id: string }>( `/workspace/${XANO_WORKSPACE}/table`, 'POST', { name, description } ); const tableId = createTableResponse.id; console.error(`[Tool] Table created with ID: ${tableId}`); // Step 2: If schema is provided, process and add it to the table if (schema && schema.length > 0) { try { // Process schema fields to handle relationships const processedSchema = schema.map(field => { // Validate relationship fields if (field.tableref_id && field.type !== "int") { throw new Error(`Field "${field.name}" has tableref_id but type is not "int". Foreign key fields must be of type "int".`); } return field; }); // Update the schema with processed fields await makeXanoRequest( `/workspace/${XANO_WORKSPACE}/table/${tableId}/schema`, 'PUT', { schema: processedSchema } ); console.error(`[Tool] Schema successfully added to table ID: ${tableId}`); } catch (schemaError) { console.error(`[Error] Failed to add schema: ${schemaError instanceof Error ? schemaError.message : String(schemaError)}`); return { content: [ { type: "text", text: `Table created with ID ${tableId}, but failed to add schema: ${schemaError instanceof Error ? schemaError.message : String(schemaError)}` } ], isError: true }; } } return { content: [ { type: "text", text: `Successfully created table "${name}" with ID: ${tableId}${schema ? ' and added the specified schema.' : '.'}` } ] }; } catch (error) { console.error(`[Error] Failed to create table: ${error instanceof Error ? error.message : String(error)}`); return { content: [ { type: "text", text: `Error creating table: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } );