Data & Storage
## g.store.* — Persistent Storage
Section titled “## g.store.* — Persistent Storage”Workspace-scoped document storage backed by LiteDB. Requires an open workspace.
| Method | Signature | Async | Description |
|---|---|---|---|
put | (collection, key, data) | No | Store a document |
get | (collection, key) → StoreDoc | null | No | Retrieve a document |
list | (collection, options?) → StoreDoc[] | No | List documents in a collection |
search | (collection, query, options?) → StoreDoc[] | No | Text search within a collection |
delete | (collection, key) → boolean | No | Delete a document |
count | (collection) → number | No | Count documents |
clear | (collection) | No | Delete all documents in a collection |
collections | () → string[] | No | List all collection names |
StoreDoc:
{ key: string data: any createdAt: string // ISO 8601 updatedAt: string // ISO 8601}StoreListOptions:
{ limit?: number // default: 100 offset?: number // default: 0 sort?: string // "key", "createdAt", "updatedAt" (default) order?: string // "asc" or "desc" (default)}Example
Section titled “Example”async function main() { // Store data g.store.put("products", "item-1", { name: "Widget", price: 9.99, inStock: true });
// Retrieve it const doc = g.store.get("products", "item-1"); if (doc) g.log("Found: " + doc.data.name);
// Search const results = g.store.search("products", "Widget"); g.log("Matches: " + results.length);}## g.queue.* — Work Queue
Section titled “## g.queue.* — Work Queue”Workspace-scoped persistent queue with priority levels and dead-letter support. Requires an open workspace.
| Method | Signature | Async | Description |
|---|---|---|---|
enqueue | (name, data, options?) | No | Add an item to a queue |
dequeue | (name) → QueueItem | null | No | Check out the next item |
commit | (checkoutId) | No | Mark a dequeued item as completed |
abort | (checkoutId, error?) → boolean | No | Return an item to the queue (or dead-letter if max retries) |
peek | (name) → QueueItem | null | No | View the next item without checking it out |
count | (name) → number | No | Count pending items |
clear | (name) | No | Delete all items in a queue |
list | (name, options?) → QueueItem[] | No | List pending items |
queues | () → string[] | No | List all queue names |
deadLetter | (name, options?) → DeadLetterItem[] | No | List dead-letter items |
retry | (name, deadLetterId) | No | Re-enqueue a dead-letter item |
waitForItem | (name, options?) → Promise<QueueItem | null> | Yes | Block until an item is available |
QueueEnqueueOptions:
{ priority?: number // 0=low, 1=normal (default), 2=high maxRetries?: number // default: 3}QueueItem:
{ id: number data: any priority: number attempts: number maxRetries: number enqueuedAt: string lastAttemptAt?: string lastError?: string}Example
Section titled “Example”async function main() { // Enqueue work items g.queue.enqueue("urls", { url: "https://example.com/page1" }); g.queue.enqueue("urls", { url: "https://example.com/page2" }, { priority: 2 });
// Process items const item = g.queue.dequeue("urls"); if (!item) return g.log("Queue empty");
await g.nav.navigateToUrl(item.data.url); const html = await g.page.getDom();
// Mark complete g.queue.commit(item.id);}## g.search.* — Full-Text Search
Section titled “## g.search.* — Full-Text Search”Workspace-scoped Lucene.NET search index. Supports boolean operators, wildcards, fuzzy matching, and field-specific queries. Requires an open workspace.
| Method | Signature | Async | Description |
|---|---|---|---|
index | (fields) | No | Index a document (must include _key and _collection) |
query | (queryString, options?) → SearchResult[] | No | Search the index with Lucene query syntax |
delete | (collection, key) | No | Remove a document from the index |
deleteByCollection | (collection) → number | No | Remove all documents in a collection |
count | (collection?) → number | No | Count indexed documents |
clear | () | No | Clear the entire index |
SearchResult:
{ key: string collection: string score: number // Lucene relevance score fields: Record<string, string>}Example
Section titled “Example”async function main() { // Index documents g.search.index({ _key: "article-1", _collection: "articles", title: "Getting Started with Guida", body: "Guida is a scriptable browser..." });
// Query with Lucene syntax const results = g.search.query("scriptable browser", { collection: "articles" }); for (const r of results) { g.log(r.fields.title + " (score: " + r.score + ")"); }}## g.s3.* — S3-Compatible Object Storage
Section titled “## g.s3.* — S3-Compatible Object Storage”S3-compatible storage via MinIO SDK. Works with AWS S3, MinIO, and any S3-compatible service. The conn parameter is a secret name containing the connection string. Blocked for MCP-origin scripts.
| Method | Signature | Async | Description |
|---|---|---|---|
listBuckets | (conn) → Promise<S3BucketInfo[]> | Yes | List all accessible buckets |
bucketExists | (conn, bucket) → Promise<boolean> | Yes | Check if a bucket exists |
listObjects | (conn, bucket, options?) → Promise<S3ObjectInfo[]> | Yes | List objects in a bucket |
getObjectText | (conn, bucket, key) → Promise<string> | Yes | Download object as UTF-8 text |
getObject | (conn, bucket, key, localPath) → Promise | Yes | Download object to a local file |
putObjectText | (conn, bucket, key, content, contentType?) → Promise | Yes | Upload text as an object |
putObject | (conn, bucket, key, localPath, contentType?) → Promise | Yes | Upload a local file as an object |
deleteObject | (conn, bucket, key) → Promise | Yes | Delete an object |
objectExists | (conn, bucket, key) → Promise<boolean> | Yes | Check if an object exists |
createBucket | (conn, bucket, region?) → Promise | Yes | Create a new bucket |
copyObject | (conn, srcBucket, srcKey, dstBucket, dstKey) → Promise | Yes | Server-side copy (no data through client) |
getPresignedUrl | (conn, bucket, key, options?) → Promise<string> | Yes | Generate a time-limited presigned URL |
S3ListOptions:
{ prefix?: string // filter objects by key prefix maxKeys?: number // max objects to return (default: 1000)}S3BucketInfo:
{ name: string creationDate: string // ISO 8601}S3ObjectInfo:
{ key: string // object key (path) size: number // size in bytes lastModified: string // ISO 8601 etag: string // entity tag (hash)}S3PresignedUrlOptions:
{ method?: string // "GET" (download, default) or "PUT" (upload) expiry?: number // URL expiry in seconds (default: 3600)}Example
Section titled “Example”async function main() { // List CSV files in a bucket const files = await g.s3.listObjects("my-s3", "data-bucket", { prefix: "exports/" }); g.log("Found " + files.length + " objects");
// Upload scraped data await g.s3.putObjectText( "my-s3", "data-bucket", "exports/results.json", JSON.stringify({ items: [1, 2, 3] }), "application/json" );
// Generate a shareable link const url = await g.s3.getPresignedUrl("my-s3", "data-bucket", "exports/results.json", { expiry: 86400 // 24 hours }); g.log("Download link: " + url);}## g.mongodb.* — MongoDB
Section titled “## g.mongodb.* — MongoDB”MongoDB operations via MongoDB.Driver. The conn parameter is a secret name containing the connection string. Uses automatic connection pooling. Blocked for MCP-origin scripts.
| Method | Signature | Async | Description |
|---|---|---|---|
find | (conn, db, collection, filter?, options?) → Promise<object[]> | Yes | Find documents matching a filter |
findOne | (conn, db, collection, filter?) → Promise<object | null> | Yes | Find first matching document |
insertOne | (conn, db, collection, document) → Promise<MongoInsertResult> | Yes | Insert a single document |
insertMany | (conn, db, collection, documents) → Promise<MongoInsertManyResult> | Yes | Insert multiple documents |
updateOne | (conn, db, collection, filter, update) → Promise<MongoUpdateResult> | Yes | Update first matching document |
updateMany | (conn, db, collection, filter, update) → Promise<MongoUpdateResult> | Yes | Update all matching documents |
deleteOne | (conn, db, collection, filter) → Promise<MongoDeleteResult> | Yes | Delete first matching document |
deleteMany | (conn, db, collection, filter) → Promise<MongoDeleteResult> | Yes | Delete all matching documents |
replaceOne | (conn, db, collection, filter, replacement) → Promise<MongoUpdateResult> | Yes | Replace first matching document |
countDocuments | (conn, db, collection, filter?) → Promise<number> | Yes | Count matching documents |
listDatabases | (conn) → Promise<string[]> | Yes | List all database names |
listCollections | (conn, db) → Promise<string[]> | Yes | List collection names in a database |
aggregate | (conn, db, collection, pipeline) → Promise<object[]> | Yes | Run an aggregation pipeline |
createIndex | (conn, db, collection, keys, options?) → Promise<string> | Yes | Create an index, returns index name |
dropCollection | (conn, db, collection) → Promise | Yes | Drop a collection |
distinct | (conn, db, collection, fieldName, filter?) → Promise<any[]> | Yes | Get distinct values for a field |
bulkWrite | (conn, db, collection, operations) → Promise<MongoBulkWriteResult> | Yes | Execute multiple write operations in a batch |
MongoFindOptions:
{ sort?: object // e.g., { name: 1, age: -1 } limit?: number skip?: number projection?: object // e.g., { name: 1, _id: 0 }}MongoInsertResult:
{ insertedId: string // the _id of the inserted document}MongoInsertManyResult:
{ insertedCount: number insertedIds: string[]}MongoUpdateResult:
{ matchedCount: number modifiedCount: number}MongoDeleteResult:
{ deletedCount: number}MongoIndexOptions:
{ unique?: boolean // enforce uniqueness name?: string // custom index name}MongoBulkOperation:
{ type: string // "insertOne", "updateOne", "updateMany", // "deleteOne", "deleteMany", "replaceOne" filter?: object // for update/delete/replace document?: object // for insertOne update?: object // for updateOne/updateMany replacement?: object // for replaceOne}MongoBulkWriteResult:
{ insertedCount: number matchedCount: number modifiedCount: number deletedCount: number}Example
Section titled “Example”async function main() { const conn = "my-mongo"; // secret name with connection string
// Insert a document const result = await g.mongodb.insertOne(conn, "scraping", "products", { name: "Widget", price: 9.99, category: "tools" }); g.log("Inserted: " + result.insertedId);
// Find with filter and sort const docs = await g.mongodb.find(conn, "scraping", "products", { price: { $lt: 20 } }, { sort: { price: 1 }, limit: 10 } ); g.log("Found " + docs.length + " cheap products");
// Aggregation pipeline const stats = await g.mongodb.aggregate(conn, "scraping", "products", [ { $group: { _id: "$category", avgPrice: { $avg: "$price" }, count: { $sum: 1 } } }, { $sort: { count: -1 } } ]); for (const s of stats) { g.log(s._id + ": " + s.count + " items, avg $" + s.avgPrice.toFixed(2)); }}## g.postgres.* — PostgreSQL
Section titled “## g.postgres.* — PostgreSQL”PostgreSQL operations via Npgsql. Uses $1, $2, ... positional parameters — never interpolate values into SQL strings. The conn parameter is a secret name containing the connection string. Uses automatic connection pooling. Blocked for MCP-origin scripts.
| Method | Signature | Async | Description |
|---|---|---|---|
query | (conn, sql, params?) → Promise<object[]> | Yes | SELECT returning all rows |
queryOne | (conn, sql, params?) → Promise<object | null> | Yes | SELECT returning first row |
execute | (conn, sql, params?) → Promise<PgExecuteResult> | Yes | INSERT/UPDATE/DELETE |
scalar | (conn, sql, params?) → Promise<any> | Yes | Return first column of first row |
transaction | (conn, callback) → Promise<any> | Yes | Execute callback in a transaction (JS only) |
executeBatch | (conn, statements) → Promise<PgBatchResult> | Yes | Multiple statements in a single transaction |
copyFrom | (conn, table, rows, options?) → Promise<PgCopyResult> | Yes | Bulk insert via COPY protocol |
copyTo | (conn, query, options?) → Promise<string[][]> | Yes | Bulk export via COPY protocol |
listDatabases | (conn) → Promise<string[]> | Yes | List non-template database names |
listSchemas | (conn, options?) → Promise<string[]> | Yes | List schema names |
listTables | (conn, schema?) → Promise<PgTableInfo[]> | Yes | List tables and views with row counts |
describeTable | (conn, table, schema?) → Promise<PgColumnInfo[]> | Yes | Column metadata (types, nullability, defaults, PKs) |
listIndexes | (conn, table, schema?) → Promise<PgIndexInfo[]> | Yes | Index metadata with definitions |
listConstraints | (conn, table, schema?) → Promise<PgConstraintInfo[]> | Yes | Constraint metadata (PK, FK, UNIQUE, CHECK) |
PgExecuteResult:
{ rowsAffected: number}PgTableInfo:
{ name: string schema: string type: string // "table" or "view" estimatedRows: number // from pg_class.reltuples}PgColumnInfo:
{ name: string type: string // e.g., "integer", "character varying", "timestamp with time zone" nullable: boolean defaultValue: string | null isPrimaryKey: boolean maxLength: number | null // for string types}PgIndexInfo:
{ name: string columns: string[] isUnique: boolean isPrimary: boolean definition: string // full CREATE INDEX statement}PgConstraintInfo:
{ name: string type: string // "PRIMARY KEY", "FOREIGN KEY", "UNIQUE", "CHECK" columns: string // comma-separated column names definition: string // constraint definition}PgBatchStatement:
{ sql: string // SQL with $1, $2, ... positional parameters params?: any[] // parameter values}PgBatchResult:
{ results: PgExecuteResult[] // per-statement rowsAffected counts}PgTransactionProxy — passed to the transaction callback:
{ query: (sql, params?) => Promise<object[]> queryOne: (sql, params?) => Promise<object | null> execute: (sql, params?) => Promise<PgExecuteResult> scalar: (sql, params?) => Promise<any>}PgCopyFromOptions:
{ columns?: string[] // column names to map row values to (in order) schema?: string // default: "public"}PgCopyToOptions:
{ schema?: string // default: "public" (only for table names, not SQL queries)}PgCopyResult:
{ rowsCopied: number}PgSchemaOptions:
{ includeSystem?: boolean // include pg_* and information_schema (default: false)}Example
Section titled “Example”async function main() { const conn = "my-postgres"; // secret name with connection string
try { // Query with parameters const rows = await g.postgres.query(conn, "SELECT id, name, price FROM products WHERE price < $1 ORDER BY price", [20.00] ); g.log("Found " + rows.length + " products");
// Transaction with callback const result = await g.postgres.transaction(conn, async (tx) => { await tx.execute("INSERT INTO orders (product_id, qty) VALUES ($1, $2)", [42, 3]); await tx.execute("UPDATE products SET stock = stock - $1 WHERE id = $2", [3, 42]); return await tx.scalar("SELECT count(*) FROM orders"); }); g.log("Total orders: " + result);
// Bulk insert via COPY (much faster than row-by-row INSERT) const copyResult = await g.postgres.copyFrom(conn, "products", [ ["Widget A", 9.99, 100], ["Widget B", 14.99, 50], ["Widget C", 24.99, 25] ], { columns: ["name", "price", "stock"] }); g.log("Imported " + copyResult.rowsCopied + " rows"); } catch (e) { g.log("Error: " + e.message); }}## g.elasticsearch.* — Elasticsearch
Section titled “## g.elasticsearch.* — Elasticsearch”Native support for querying and indexing data in external Elasticsearch clusters using Elastic.Clients.Elasticsearch. The conn parameter is a secret name containing the connection JSON object (url and optional apiKey or username/password). Blocked for MCP-origin scripts.
| Method | Signature | Async | Description |
|---|---|---|---|
ping | (conn) → Promise<boolean> | Yes | Verify connection to the cluster. Returns true if successful. |
info | (conn) → Promise<ElasticsearchInfoResult> | Yes | Retrieve cluster metadata (name, version, tagline, etc.). |
createIndex | (conn, indexName, mappingJson?) → Promise<boolean> | Yes | Create an index with an optional JSON mapping string. |
deleteIndex | (conn, indexName) → Promise<boolean> | Yes | Delete an existing index. |
index | (conn, indexName, id, document) → Promise<boolean> | Yes | Index a single JS object into the cluster. |
get | (conn, indexName, id) → Promise<any> | Yes | Retrieve a single document by ID. Returns the parsed _source object. |
bulk | (conn, indexName, documents, chunkSize?) → Promise<ElasticsearchBulkResult> | Yes | High-throughput ingestion. Automatically chunks large arrays to prevent payload limits. |
search | (conn, indexName, queryDsl) → Promise<any> | Yes | Execute a raw JSON query DSL string or JS object and return deserialized hits. |
ElasticsearchInfoResult:
{ name: string clusterName: string clusterUuid: string version: string tagline: string}ElasticsearchBulkResult:
{ total: number successful: number failed: number}Example
Section titled “Example”async function main() { const conn = "my-elastic"; // secret name
// Check connection const isUp = await g.elasticsearch.ping(conn); if (!isUp) return g.log("Connection failed");
// Bulk index documents const docs = [{ id: 1, text: "A" }, { id: 2, text: "B" }]; const bulkRes = await g.elasticsearch.bulk(conn, "products", docs, 1000); g.log(`Indexed ${bulkRes.successful} out of ${bulkRes.total}`);
// Query DSL search const searchRes = await g.elasticsearch.search(conn, "products", { query: { match_all: {} } }); g.log(`Total hits: ${searchRes.hits.total.value}`);}