Module Reference
46+ built-in modules, zero dependencies. Use assay context <query> for LLM-ready docs on any module.
assay modules # list all modules
assay context "grafana health" # get detailed docs for LLM
Rust Builtins
Available globally in all .lua scripts — no require needed.
HTTP & Networking
| Module |
Key Functions |
Description |
http |
http.get/post/put/patch/delete/serve |
HTTP client, server, and SSE streaming |
ws |
ws.connect/send/recv/close |
WebSocket client |
SSE Streaming Example
http.serve(8080, {
GET = {
["/events"] = function(req)
return {
sse = function(send)
send({ data = "connected" })
sleep(1)
send({ event = "update", data = json.encode({count = 1}), id = "1" })
-- stream closes when function returns
end
}
end
}
})
The send callback accepts event, data, id,
and retry fields. SSE headers (text/event-stream, no-cache,
keep-alive) are set automatically.
Serialization
| Module |
Key Functions |
Description |
json |
json.parse/encode |
JSON parse and encode |
yaml |
yaml.parse/encode |
YAML parse and encode |
toml |
toml.parse/encode |
TOML parse and encode |
base64 |
base64.encode/decode |
Base64 encoding |
System
| Module |
Key Functions |
Description |
fs |
fs.read/write |
Filesystem operations |
env |
env.get |
Environment variables |
sleep |
sleep(n) |
Pause execution |
time |
time() |
Unix timestamp |
Cryptography
| Module |
Key Functions |
Description |
crypto |
crypto.jwt_sign/hash/hmac/random |
JWT, hashing, HMAC |
regex |
regex.match/find/replace |
Regular expressions |
Database
| Module |
Key Functions |
Description |
db |
db.connect/query/execute/close |
SQL — Postgres, MySQL, SQLite |
Templates & Async
| Module |
Key Functions |
Description |
template |
template.render/render_string |
Jinja2-compatible templates |
async |
async.spawn/spawn_interval |
Async task execution |
Testing & Logging
| Module |
Key Functions |
Description |
assert |
assert.eq/ne/gt/lt/contains/not_nil/matches |
Assertions |
log |
log.info/warn/error |
Structured logging |
Stdlib Modules
29 embedded Lua modules loaded via require("assay.<name>").
All follow the client pattern: M.client(url, opts) → client object → c:method().
Monitoring & Observability
| Module |
require() |
Description |
Client Pattern |
assay.prometheus |
require("assay.prometheus") |
PromQL queries, alerts, targets |
prom.query(url, expr) |
assay.alertmanager |
require("assay.alertmanager") |
Alert management, silences |
am.client(url) |
assay.loki |
require("assay.loki") |
Log push, query, labels |
loki.client(url) |
assay.grafana |
require("assay.grafana") |
Health, dashboards, datasources |
gf.client(url, opts) |
Kubernetes & GitOps
| Module |
require() |
Description |
Client Pattern |
assay.k8s |
require("assay.k8s") |
30+ K8s resource types, CRDs |
k8s.client(url, opts) |
assay.argocd |
require("assay.argocd") |
Apps, sync, health, projects |
argo.client(url, opts) |
assay.kargo |
require("assay.kargo") |
Stages, freight, promotions |
kargo.client(url, opts) |
assay.flux |
require("assay.flux") |
GitRepositories, Kustomizations |
flux.client(url, opts) |
assay.traefik |
require("assay.traefik") |
Routers, services, middlewares |
traefik.client(url) |
Security & Identity
| Module |
require() |
Description |
Client Pattern |
assay.vault |
require("assay.vault") |
KV secrets, transit, PKI |
vault.client(url, opts) |
assay.openbao |
require("assay.openbao") |
OpenBao (Vault API-compatible) |
bao.client(url, opts) |
assay.certmanager |
require("assay.certmanager") |
Certificates, issuers, ACME |
cm.client(url, opts) |
assay.eso |
require("assay.eso") |
ExternalSecrets, SecretStores |
eso.client(url, opts) |
assay.dex |
require("assay.dex") |
OIDC discovery, JWKS, health |
dex.client(url) |
assay.zitadel |
require("assay.zitadel") |
OIDC identity, JWT machine auth |
zitadel.client(url, opts) |
Infrastructure
| Module |
require() |
Description |
Client Pattern |
assay.crossplane |
require("assay.crossplane") |
Providers, XRDs, compositions |
xp.client(url, opts) |
assay.velero |
require("assay.velero") |
Backups, restores, schedules |
velero.client(url, opts) |
assay.temporal |
require("assay.temporal") |
Workflows, task queues |
temporal.client(url, opts) |
assay.harbor |
require("assay.harbor") |
Projects, repos, vulnerability scanning |
harbor.client(url, opts) |
Data & Storage
| Module |
require() |
Description |
Client Pattern |
assay.postgres |
require("assay.postgres") |
PostgreSQL user/db management |
pg.client(url, opts) |
assay.s3 |
require("assay.s3") |
S3-compatible storage, Sig V4 |
s3.client(url, opts) |
Utilities
| Module |
require() |
Description |
Client Pattern |
assay.healthcheck |
require("assay.healthcheck") |
HTTP checks, JSON path, latency |
hc.check(url, opts) |
assay.unleash |
require("assay.unleash") |
Feature flags, environments |
unleash.client(url, opts) |
AI Agent & Workflow
Integrate with AI agent platforms, GitHub, Gmail, and Google Calendar — all via native HTTP, zero shell dependencies.
assay.openclaw
OpenClaw AI agent platform integration. Invoke tools, send messages, manage state, spawn sub-agents, approval gates, LLM tasks.
local openclaw = require("assay.openclaw")
local c = openclaw.client() -- auto-discovers $OPENCLAW_URL + $OPENCLAW_TOKEN
-- Invoke any OpenClaw tool
local result = c:invoke("message", "send", { target = "#general", message = "Hello!" })
-- Shorthand: send message
c:send("discord", "#alerts", "Service is down!")
c:notify("ops-team", "Deployment complete")
-- Persistent state
c:state_set("last-deploy", { version = "1.2.3", time = time() })
local prev = c:state_get("last-deploy")
-- Diff detection
local diff = c:diff("pr-state", new_snapshot)
if diff.changed then log.info("State changed!") end
-- LLM task
local answer = c:llm_task("Summarize this PR", { model = "claude-sonnet" })
-- Cron jobs
c:cron_add({ schedule = "0 9 * * *", task = "daily-report" })
-- Sub-agents
c:spawn("Fix the login bug", { model = "gpt-4o" })
assay.github
GitHub REST API client. PRs, issues, actions, repositories, GraphQL. No gh CLI dependency.
local github = require("assay.github")
local c = github.client() -- uses $GITHUB_TOKEN
-- Pull requests
local pr = c:pr_view("owner/repo", 123)
local prs = c:pr_list("owner/repo", { state = "open" })
local reviews = c:pr_reviews("owner/repo", 123)
c:pr_merge("owner/repo", 123, { merge_method = "squash" })
-- Issues
local issues = c:issue_list("owner/repo", { labels = "bug", state = "open" })
local issue = c:issue_get("owner/repo", 42)
c:issue_create("owner/repo", "Bug title", "Description", { labels = {"bug"} })
c:issue_comment("owner/repo", 42, "Fixed in PR #123")
-- Actions
local runs = c:runs_list("owner/repo", { status = "completed" })
local run = c:run_get("owner/repo", 12345)
-- GraphQL
local data = c:graphql("query { viewer { login } }")
assay.gmail
Gmail REST API with OAuth2 token auto-refresh. Search, read, reply, send emails.
local gmail = require("assay.gmail")
local c = gmail.client({
credentials_file = "/path/to/credentials.json",
token_file = "/path/to/token.json",
})
-- Search emails
local emails = c:search("newer_than:1d is:unread", { max = 20 })
-- Read a message
local msg = c:get("message-id-here")
-- Reply to an email
c:reply("message-id", { body = "Thanks for the update!" })
-- Send new email
c:send("user@example.com", "Subject", "Email body")
-- List labels
local labels = c:labels()
assay.gcal
Google Calendar REST API with OAuth2 token auto-refresh. Events CRUD, calendar list.
local gcal = require("assay.gcal")
local c = gcal.client({
credentials_file = "/path/to/credentials.json",
token_file = "/path/to/token.json",
})
-- List upcoming events
local events = c:events({ timeMin = "2026-04-05T00:00:00Z", maxResults = 10 })
-- Get specific event
local event = c:event_get("event-id")
-- Create event
c:event_create({
summary = "Team standup",
start = { dateTime = "2026-04-06T09:00:00Z" },
["end"] = { dateTime = "2026-04-06T09:30:00Z" },
})
-- Update / delete
c:event_update("event-id", updated_event)
c:event_delete("event-id")
-- List all calendars
local calendars = c:calendars()
assay.oauth2
Google OAuth2 token management. File-based credentials loading, automatic access token refresh, token persistence.
local oauth2 = require("assay.oauth2")
-- Load credentials and token from default paths
-- (~/.config/gog/credentials.json and ~/.config/gog/token.json)
local auth = oauth2.from_file()
-- Or specify custom paths
local auth = oauth2.from_file("/path/to/credentials.json", "/path/to/token.json")
-- Refresh access token
auth:refresh()
-- Persist updated token back to file
auth:save()
-- Get auth headers for API calls
local headers = auth:headers()
-- Returns: {Authorization = "Bearer ...", ["Content-Type"] = "application/json"}
-- Use with http builtins
local resp = http.get("https://www.googleapis.com/calendar/v3/calendars/primary/events", {
headers = auth:headers()
})
assay.email_triage
Email classification and triage. Deterministic rule-based categorization or OpenClaw LLM-assisted classification into action, reply, and FYI buckets.
local email_triage = require("assay.email_triage")
local gmail = require("assay.gmail")
local gc = gmail.client({
credentials_file = "/path/to/credentials.json",
token_file = "/path/to/token.json",
})
-- Fetch recent emails
local emails = gc:search("newer_than:1d", { max = 50 })
-- Deterministic categorization (no LLM needed)
local buckets = email_triage.categorize(emails)
log.info("Needs reply: " .. #buckets.needs_reply)
log.info("Needs action: " .. #buckets.needs_action)
log.info("FYI: " .. #buckets.fyi)
-- LLM-assisted triage via OpenClaw (smarter classification)
local openclaw = require("assay.openclaw")
local oc = openclaw.client()
local smart_buckets = email_triage.categorize_llm(emails, oc)
| Module |
require() |
Description |
Client Pattern |
assay.openclaw |
require("assay.openclaw") |
AI agent tools, state, approve, LLM |
openclaw.client(url?, opts?) |
assay.github |
require("assay.github") |
PRs, issues, actions, GraphQL |
github.client(opts?) |
assay.gmail |
require("assay.gmail") |
Email search, read, reply, send |
gmail.client(opts) |
assay.gcal |
require("assay.gcal") |
Calendar events CRUD |
gcal.client(opts) |
assay.oauth2 |
require("assay.oauth2") |
OAuth2 token management, auto-refresh |
oauth2.from_file(creds?, token?) |
assay.email_triage |
require("assay.email_triage") |
Email classification, triage buckets |
email_triage.categorize(emails) |
Custom Modules
Place .lua files in ./modules/ (project-local) or ~/.assay/modules/ (global).
Or set ASSAY_MODULES_PATH to override the global directory.
They are auto-discovered and appear in assay modules output.
./modules/
myapi.lua # require("assay.myapi")
~/.assay/modules/
company.lua # require("assay.company")
For LLM agents: llms.txt · llms-full.txt