Agent skill · software engineering · aiskillstore
extension-oql
Make a canister's data queryable by the Caffeine Data Intelligence agent. Use whenever an app stores structured data (Maps/Lists/arrays of records) that should be answerable in natural language — "top customers", "revenue by region", "active projects". Adds a discoverable `schema()` and a JSON `execute()` query endpoint via the `caffeineai-oql` mops package's `Expose` mixin.
Why this skill is useful
Adds a specific implementation for making structured data queryable via the Caffeine Data Intelligence agent, which includes unique entity definitions and query methods not commonly found in public documentation.
What it needs
Requires mops installed locally. About 9k tokens when loaded. Last updated 2026-08-07. 405 stars on the source repository.
What this skill does
OQL — Object Query Layer Go over the actor's fields (non-transient) and, for each collection worth querying, consider how its data maps to a table in a database (an entity). You only declare one entity per table — the Expose mixin makes them queryable. Backend Each entity carries an authorization level; the default .controllerOnly() is safe (private to users, still readable by the Data Intelligence agent). Model your entities first, then pick a level per entity — see ## Auth. Setup Run mops add caffeineai-oql@0.4.0 in the same write batch as your first mo:caffeineai-oql/... import. Auto-derivation requires moc >= 1.11 (the generated-app template already satisfies this). Declare entities and install .toEntity(name, typeName, primaryKey) turns a collection of records into a queryable entity; the compiler auto-derives the fields. Each entity sets its own authorization level (see ## Auth); the example below shows one table per level. Expose adds only the OQL query methods (schema / execute) — your existing state, types, and shared methods are untouched. Auth Authorization is per entity — each builder declares a level, and schema() and execute() both run the check against the live caller. No app-wide config, no tokens. The default when none is set is #controllerOnly. Builder call Who reads Rows returned --- --- --- .public() anyone (incl. anonymous) all .controllerOnly() (default) controllers only all .scopedPerUser() any signed-in caller only the caller's own .controllerOrScoped() controllers + signed-in callers controller: all; user: own Choosing a level Pick per entity by who should read its rows — when in doubt, keep the default. .controllerOnly() (default) — private app data the agent should answer over, but no end user reads directly (orders, metrics, audit logs, config). The agent calls as the controller, so it reads everything while the data stays private to users. …
How to use it
Reference it in AdaL, Claude Code, Cursor or any coding agent — nothing to install:
@skills aiskillstore/extension-oql