SQL·Kotlin·Free

SQL to
Kotlin.

Turn a CREATE TABLE script into Kotlin model classes. One file per table, camelCase field names, nullable columns as Type?, and SQL enum types as real Kotlin enum class. No ORM wiring, no annotations you did not ask for.

DDL·Kotlin·JVM·Package·MIT
payments.sqlInput
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
);
compile
Payments.kt tsc cleanOutput
// Payments.kt
package com.example.payments

import java.util.UUID
import java.math.BigDecimal
import java.time.OffsetDateTime
import kotlinx.serialization.Contextual

class Payments {
    val id: UUID
    val amount: BigDecimal
    val currency: String?
    val method: PaymentMethod
    val createdAt: @Contextual OffsetDateTime
}
What gets generated

Plain Kotlin classes. Nothing more.

Below: a small payments schema with an enum type, rendered to Kotlin. Each table becomes a 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 java.util.UUID
import java.math.BigDecimal
import java.time.OffsetDateTime
import kotlinx.serialization.Contextual

class Payments {
    val id: UUID
    val amount: BigDecimal
    val currency: String?
    val method: PaymentMethod
    val createdAt: @Contextual OffsetDateTime
}
Three things we get right

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.

01Proofsnake_case columns become camelCase fields.Spec · InCode · Out
schema.sql fragment
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
);
emitted Employees.kt
// Employees.kt
package com.example.models

import java.time.OffsetDateTime
import java.math.BigDecimal
import kotlinx.serialization.Contextual

class Employees {
    val id: Int
    val firstName: String
    val lastName: String
    val email: String
    val hireDate: @Contextual OffsetDateTime
    val salary: BigDecimal?
    val departmentId: Int
}
Plain Kotlin

Model classes, ready to drop in.

One Kotlin class per CREATE TABLE, inside a package you choose. No JPA annotations, no Exposed tables, no runtime you did not already have. Wire them to whatever DB layer your project already uses.

src/main/kotlin/com/example/models/ generated
// Departments.kt
package com.example.models

class Departments {
    val id: Int
    val name: String
    val location: String?
}

// Employees.kt
package com.example.models

import java.time.OffsetDateTime
import java.math.BigDecimal
import kotlinx.serialization.Contextual

class Employees {
    val id: Int
    val firstName: String
    val lastName: String
    val email: String
    val hireDate: @Contextual OffsetDateTime
    val salary: BigDecimal?
    val departmentId: Int
}
Also available via MCP

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."
See the MCP page
Questions

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.

One Kotlin file per CREATE TABLE and one per CREATE TYPE ... AS ENUM, under a package you provide. The output is model classes only — no query DSL, no table mappers, no repository layer. You get the types; you pick the data layer.

Try it on your own schema.

The converter runs in the browser. Your DDL never leaves the page.

Open the converter