Welcome to the Hangar Open Beta. Please report any issue you encounter on GitHub!
Avatar for oKidd

Skript addon for executing asynchronous SQL queries against Supabase/Postgres from Minecraft scripts

Report skupabase?

Skupabase

Skupabase is a Skript addon for running SQL queries against Supabase/Postgres directly from Minecraft. (Java 21)

Optional dependency

If you want to convert JSON query results into Skript lists, install JSkon:

JSkon on SpigotMC

Installation

  • Copy skupabase.jar into your server's plugins/ folder.

  • Install Skript.

  • Start the server once.

  • Configure:

plugins/Skupabase/config.yml
  • Restart the server.

Supabase setup

Step 1: Get the database connection details Click the green Connect button in your Supabase project.

Open the connection sheet and select:

  • Direct: Connection String

  • Connection Method: Session pooler

  • Type: JDBC

https://i.imgur.com/8I18Oxc.gif

Copy the following values into config.yml:

  • Host

  • Port

  • Database

  • User

Step 2: Get or reset the database password If you do not know your database password, click Reset password, generate a new password, copy it, and save it somewhere secure.

https://i.imgur.com/3I2zae9.gif

Step 3: Get the Supabase API credentials Open the Connect sheet again and select:

  • Server: Build APIs

Copy the following values into config.yml:

  • SUPABASE_URL

  • SUPABASE_SECRET_KEY

https://i.imgur.com/fYn5XMx.gif

Step 4: Configure Skupabase Fill in:

plugins/Skupabase/config.yml

Example:

host: "aws-1-sa-east-1.pooler.supabase.com"
port: "5432"
database: "postgres"
user: "postgres.jftqytycpvjjcjacojyd"
password: "your_password"

SUPABASE_URL: "https://jftqytycpvjjcjacojyd.supabase.co"
SUPABASE_SECRET_KEY: "sb_secret_..."

connect-timeout-seconds: 10
query-timeout-seconds: 30
max-result-rows: 500

For SQL queries, Skupabase builds the JDBC URL using:

  • host

  • port

  • database

  • user

  • password

Usage

Run a query

set {_id} to supabase query "select * from public.players"

The returned value is the query ID.

You can use this ID to wait for the query, check its status, or read its result.

Wait for the last query

await last supabase query:
send "Last query finished"
send "%supabase query status {_id}%"
send "%supabase query result {_id}%"

Wait for a specific query

await {_id} supabase query:
send "Query finished"
send "%supabase query status {_id}%"
send "%supabase query result {_id}%"

Check the query status

send "%supabase query status {_id}%"

Read the query result

send "%supabase query result {_id}%"

Read a single row

send "%supabase single query result {_id}%"

If the query returns exactly one row, this variant returns the row as a JSON object instead of a JSON array.

Run a query without keeping the ID

run supabase query "update public.players set coins = coins + 10 where uuid = '...'"

Use this syntax when you do not need to wait for the query or read its result.

Realtime subscriptions

Realtime subscriptions are optional.

Configure these values in plugins/Skupabase/config.yml only if you want to listen for database changes:

SUPABASE_URL: "https://jftqytycpvjjcjacojyd.supabase.co"
SUPABASE_SECRET_KEY: "sb_secret_..."

realtime-log-level: "info"
realtime-heartbeat-seconds: 25

If Realtime events are not firing, check the server console for messages such as:

Supabase Realtime websocket open
Sending realtime join
Realtime subscription ready

Supabase Realtime does not log every WebSocket connection by default.

Setting:

realtime-log-level: "info"

helps show the connection, join, and subscription flow in the server logs.

Subscribe to database changes

Subscriptions should normally be created inside on load: or another startup section.

on load:
set {sub} to subscribe to postgres changes in table "public.skupabase_test" with event "*"

The * event listens for all supported database changes.

Unsubscribe when the script unloads

Use on unload: to remove the subscription when the script is reloaded, disabled, or unloaded.

on unload:
if {sub} is set:
unsubscribe postgres subscription {sub}

Handle Realtime payloads

Use the following event to receive Postgres changes:

on supabase postgres change:
broadcast "&7Change received!"
broadcast "&7Table: %supabase change table%"
broadcast "&7Type: %supabase change type%"
broadcast "&7Payload: %supabase change payload%"

Conditional checks

Check the table

on supabase postgres change:
if supabase change table is "skupabase_test":
broadcast "&aChange in skupabase_test"

Check the schema and table

on supabase postgres change:
if supabase change schema is "public":
if supabase change table is "skupabase_test":
broadcast "&7Received change for public.skupabase_test"

Check the event type

on supabase postgres change:
if supabase change type is "INSERT":
broadcast "&aNew row inserted"

Possible event types include:

INSERT
UPDATE
DELETE

Mini tutorial

The following example creates a table and adds commands for inserting, selecting, updating, and deleting rows.

Create the table

command /create_table:
trigger:
set {_id} to supabase query "create table if not exists public.skupabase_test (id bigint generated by default as identity primary key, player_uuid text not null, player_name text not null, created_at timestamptz not null default now())"

   await {_id} supabase query:
       send "%supabase query status {_id}%"
       send "%supabase query result {_id}%"

Insert a row

command /insert:
trigger:
set {_id} to supabase query "insert into public.skupabase_test (player_uuid, player_name) values ('%uuid of player%', '%player%')"

   await {_id} supabase query:
       send "%supabase query status {_id}%"
       send "%supabase query result {_id}%"

Select a row

command /select:
trigger:
set {_id} to supabase query "select * from public.skupabase_test where player_uuid = '%uuid of player%' order by id desc limit 1"

   await {_id} supabase query:
       send "%supabase query status {_id}%"
       send "%supabase query result {_id}%"

Update a row

command /update:
trigger:
set {_id} to supabase query "update public.skupabase_test set player_name = '%player%_edited' where player_uuid = '%uuid of player%'"

   await {_id} supabase query:
       send "%supabase query status {_id}%"
       send "%supabase query result {_id}%"

Delete a row

command /delete:
trigger:
set {_id} to supabase query "delete from public.skupabase_test where player_uuid = '%uuid of player%'"

   await {_id} supabase query:
       send "%supabase query status {_id}%"
       send "%supabase query result {_id}%"

Notes

  • Queries run asynchronously.

  • Use await when you need to wait for a query to finish.

  • Query results are limited by max-result-rows.

  • Invalid queries return an error through the query status or result.

  • Realtime subscriptions require SUPABASE_URL and SUPABASE_SECRET_KEY.

  • Remember to unsubscribe from Realtime subscriptions inside on unload:.

  • Never share your database password or SUPABASE_SECRET_KEY publicly.

Information

CategoryDeveloper Tools
Published onJuly 14, 2026
LicenseUnspecified
Downloads0
Stars0
Watchers0

Pinned Versions

Members

Avatar for oKidd

oKidd

Owner