SQL to
Kotlin.
Turn a CREATE TABLE script into Kotlin data class models. One file per table, camelCase field names, nullable columns as Type? = null, and SQL enum types as @Serializable enum class. No ORM wiring, no annotations you did not ask for.
CREATE TYPE payment_method AS ENUM ('card', 'bank', 'wallet');
CREATE TABLE payments (
id UUID PRIMARY KEY,
amount DECIMAL(12, 2) NOT NULL,
currency VARCHAR(3),
method payment_method NOT NULL,
created_at TIMESTAMP NOT NULL
);// Payments.kt
package com.example.payments
import kotlinx.serialization.Serializable
import java.util.UUID
import java.math.BigDecimal
import java.time.LocalDateTime
import kotlinx.serialization.Contextual
@Serializable
data class Payments(
val id: @Contextual UUID,
val amount: @Contextual BigDecimal,
val currency: String? = null,
val method: PaymentMethod,
val createdAt: @Contextual LocalDateTime
)Kotlin data classes. Nothing more.
Below: a small payments schema with an enum type, rendered to Kotlin. Each table becomes a @Serializable data class; each SQL ENUM becomes a @Serializable enum class. The output is model types — no table mapper, no query DSL, no entity manager.
// PaymentMethod.kt — enum type, one file
package com.example.payments
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
@Serializable
enum class PaymentMethod {
@SerialName("card")
CARD,
@SerialName("bank")
BANK,
@SerialName("wallet")
WALLET
}
// Payments.kt — table, one file
package com.example.payments
import kotlinx.serialization.Serializable
import java.util.UUID
import java.math.BigDecimal
import java.time.LocalDateTime
import kotlinx.serialization.Contextual
@Serializable
data class Payments(
val id: @Contextual UUID,
val amount: @Contextual BigDecimal,
val currency: String? = null,
val method: PaymentMethod,
val createdAt: @Contextual LocalDateTime
)Grounded in how the DDL reads.
Each claim here is something you can verify by pasting your own schema into the converter. Click a card to see the DDL fragment that triggered it and the Kotlin that came out.
CREATE TABLE employees (
id INT PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(150) UNIQUE NOT NULL,
hire_date DATE NOT NULL,
salary DECIMAL(10, 2),
department_id INT NOT NULL
);// Employees.kt
package com.example.models
import kotlinx.serialization.Serializable
import java.time.LocalDate
import java.math.BigDecimal
import kotlinx.serialization.Contextual
@Serializable
data class Employees(
val id: Int,
val firstName: String,
val lastName: String,
val email: String,
val hireDate: LocalDate,
val salary: @Contextual BigDecimal? = null,
val departmentId: Int
)Data classes, ready to drop in.
One Kotlin data class per CREATE TABLE, inside a package you choose. No JPA annotations, no Exposed tables, no runtime you did not already have. The types are annotated for kotlinx.serialization; wire them to whatever DB layer your project already uses.
// Departments.kt
package com.example.models
import kotlinx.serialization.Serializable
@Serializable
data class Departments(val id: Int, val name: String, val location: String? = null)
// Employees.kt
package com.example.models
import kotlinx.serialization.Serializable
import java.time.LocalDate
import java.math.BigDecimal
import kotlinx.serialization.Contextual
@Serializable
data class Employees(
val id: Int,
val firstName: String,
val lastName: String,
val email: String,
val hireDate: LocalDate,
val salary: @Contextual BigDecimal? = null,
val departmentId: Int
)Or ask Claude to do it.
The same generator ships as a Model Context Protocol server. It calls the same web API this converter uses, so the output is identical. Point Claude Desktop, Cursor, or any MCP-aware agent at a <code>.sql</code> file and it produces the Kotlin models as a diff — free, no token, no leaving the chat.
// claude-desktop config · .mcp.json
{
"mcpServers": {
"metaengine": {
"command": "npx",
"args": ["-y", "@metaengine/mcp-server"]
}
}
}
// Then in Claude:
// "Load db/schema.sql and generate Kotlin
// models in package com.acme.domain."Things people ask.
The niche between "hand-writing model classes" and "pulling in an ORM" is thinly covered. Most of these answer what you actually get.
CREATE TABLE and one per CREATE TYPE ... AS ENUM, under a package you provide. The output is model types only — no query DSL, no table mappers, no repository layer. You get the data classes; you pick the data layer.Try it on your own schema.
The converter runs in the browser. Your DDL never leaves the page.