Building Your First Cereal Automation Script: A Step-by-Step Guide

TL;DR: Clone the Script-Template repo, update
manifest.jsonand the package name, define aScriptConfigurationinterface, implement your script class withonStart/execute/onFinish, and run the test via JUnit. That’s the full loop — from zero to a working, locally-tested Cereal script.
This guide walks through building your first Cereal automation script from scratch. By the end, you’ll have a working script you can run and test locally — and a clear picture of how Cereal’s SDK fits together. Users install and run scripts through the Cereal desktop app, which is free for macOS, Windows, and Linux.
Prerequisites
Before you start, make sure you have the following installed:
- Java Development Kit (JDK) 17 or higher
- IntelliJ IDEA (Community or Ultimate edition)
- Git for version control
Step 1: Set Up the Project
The fastest way to start is the official Cereal Script Template, which comes pre-configured with the right dependencies and build scripts.
- Use the template: Go to the Script-Template repository on GitHub.
- Create your repository: Click Use this template to create a new repository under your account. Name it something like
my-first-cereal-script. - Clone the repository:
git clone https://github.com/YourUsername/my-first-cereal-script.git - Open in IntelliJ: Select Open and navigate to the cloned folder.
Step 2: Configure the Project
Once the project is open, update a few metadata files to identify your script.
Update Build Settings
Open settings.gradle.kts and change rootProject.name to match your script:
rootProject.name = "MyFirstScript"Configure the Manifest
The manifest.json file tells Cereal about your script. Open src/main/resources/manifest.json and update the fields:
{
"package_name": "com.yourname.script.first",
"name": "My First Script",
"version_code": 1,
"script": "com.yourname.script.first.MyFirstScript"
}- package_name: Must be unique. Use reverse domain notation (e.g.,
com.yourname.script.first). - name: The display name shown in the Cereal client.
- version_code: An integer that must be incremented for each release.
- script: The fully qualified class name of your main script class.
Rename the Package
In the Project view, expand src/main/kotlin. Right-click com.cereal.script.sample, choose Refactor > Rename, and rename it to match your package_name.
Step 3: Define the Script Configuration
Scripts take user input through a ScriptConfiguration interface. Locate SampleConfiguration.kt in your package, rename it to MyScriptConfiguration.kt, and replace the content:
package com.yourname.script.first
import com.cereal.api.script.configuration.ScriptConfiguration
import com.cereal.api.script.configuration.ScriptConfigurationItem
interface MyScriptConfiguration : ScriptConfiguration {
@ScriptConfigurationItem(
keyName = "greeting_message",
name = "Greeting Message",
description = "The message to display in the logs.",
defaultValue = "Hello, Cereal World!"
)
fun greetingMessage(): String
}This creates a single configurable field. The Cereal client automatically generates a UI for it — no frontend code needed.
Step 4: Implement the Script Logic
Locate SampleScript.kt, rename it to MyFirstScript.kt, and replace the content:
package com.yourname.script.first
import com.cereal.api.script.Script
import com.cereal.api.script.ScriptComponentProvider
import com.cereal.api.script.execution.ExecutionResult
import kotlinx.coroutines.delay
class MyFirstScript : Script<MyScriptConfiguration> {
override suspend fun onStart(configuration: MyScriptConfiguration, provider: ScriptComponentProvider): Boolean {
provider.logger().info("Starting My First Script...")
return true
}
override suspend fun execute(
configuration: MyScriptConfiguration,
provider: ScriptComponentProvider,
statusUpdate: (String) -> Unit
): ExecutionResult {
val message = configuration.greetingMessage()
provider.logger().info("User says: $message")
statusUpdate("Processing greeting...")
delay(1000)
return ExecutionResult.Success("Script completed successfully!")
}
override suspend fun onFinish(configuration: MyScriptConfiguration, provider: ScriptComponentProvider) {
provider.logger().info("Cleaning up...")
}
}What Each Method Does
onStart: Runs once at initialization. Use it for validation or setup. Returningfalseaborts the script.execute: The main loop. Returns anExecutionResultthat determines whether the script should loop (Loop), finish cleanly (Success), or fail (Error).onFinish: Runs when the script stops, useful for cleanup.
Step 5: Test Locally
You don’t need to upload the script to Cereal to test it. Open src/test/kotlin/com/yourname/script/first/TestSampleScript.kt, rename it to TestMyFirstScript.kt, and update it:
package com.yourname.script.first
import com.cereal.api.script.test.TestScriptRunner
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test
class TestMyFirstScript {
@Test
fun testScript() = runBlocking {
val script = MyFirstScript()
TestScriptRunner.run(script)
}
}Click the green play icon next to testScript. In the Run console, you should see:
[INFO] Starting My First Script...
[INFO] User says: Hello, Cereal World!
[INFO] Cleaning up...Next Steps
You’ve built and tested your first Cereal script. From here:
- Publish your script to the Cereal Marketplace
- Explore available components like notifications and user interaction
- Read about advanced configuration
- See how to build and sell automation scripts on the marketplace