Skip to main content

Chapter 22: Interacting with the Host Database

TL;DR

  1. Define your schema: Create a sql/ directory in your pack's root. Add .sql files with CREATE TABLE statements (e.g., 001_my_table.sql). The files are executed alphabetically on install.
  2. No direct database access: Packs do not connect to the host DB directly. All access is via the worka/db virtual pack.
  3. Query from your backend: Use the in‑process MCP client to call execute_query on worka/db.
  4. Use execute_query: Provide sql and params; the host runs it against your private schema and returns rows.

Many packs need to store their own data—user settings, created items, session information, etc. Worka provides a robust, secure, and isolated persistence model for every pack using the central PostgreSQL database managed by the Host.

Step 1: Defining Your Pack's Schema

To create your own private tables, you start by creating a sql/ directory in the root of your pack.

Inside this directory, you place standard .sql files containing your CREATE TABLE statements and any other DDL (Data Definition Language) commands.

There is a critical convention you must follow: the Host executes these files alphabetically during pack installation. Therefore, you must name your files with a numeric prefix to control their execution order.

Example Structure:

my-pack/
└── sql/
├── 001_create_authors_table.sql
├── 002_create_posts_table.sql
└── 003_add_indexes.sql

When your pack is installed, Worka will automatically create a private schema for your pack in the database and then execute these files in order, setting up your tables.

Step 2: The worka/db Virtual Pack

For security, packs never connect to the host database directly. All access is brokered through worka/db, which enforces schema isolation. This prevents a compromised pack from accessing data outside its own schema.

The interface for this brokered access is the worka/db virtual pack.

Step 3: Querying from Your Backend

To run a query from your pack’s backend, call worka/db using the in‑process MCP client.

let client = McpClient::inproc();
let response = client.call(
"worka/db",
"execute_query",
json!({
"sql": "SELECT id, title, content FROM my_posts WHERE id = $1",
"params": [123]
})
).await?;

This secure flow ensures that your pack can only ever run queries against its own, isolated schema, providing a powerful yet safe persistence model for all packs in the ecosystem.