Skip to content

ability-arcadedb

ArcadeDB wrapper — database admin, backup/restore

ability-arcadedb is a KADI “kadi-ability” that exposes ArcadeDB (v26.2.1) as broker-callable tools. It wraps vendored ArcadeDB manager APIs and an HTTP client to provide container lifecycle, database management, data import/export, query/command execution, and backup/restore with a distributed file-sharing helper. The package exists to make a single, broker-accessible ability that other agents can call to operate and administrate ArcadeDB instances (including cross-host backup transfer).

  • Core runtime: a KadiClient registers tools that are callable via the KADI broker.
  • Managers and HTTP client:
    • createManagers (./lib/arcade-admin.js) — provides vendored CJS manager instances (container, database, import/export, backup managers).
    • ArcadeHttpClient (./lib/http-client.js) — REST client used for queries, commands, and API health checks.
  • Backup staging: uses @kadi.build/file-sharing’s FileSharingServer to temporarily serve local backup files over HTTP so backups produced on one host can be downloaded by another (distributed deployments).
  • Configuration & secrets:
    • config.toml holds non-sensitive configuration (broker, arcadedb username).
    • Secrets (ARCADE_USERNAME, ARCADE_PASSWORD, KADI_TUNNEL_TOKEN) are delivered via a vault and kadi secret.
  • Deployment:
    • The build stages embed the arcadedb docker image’s files into the ability image. The container entrypoint starts ArcadeDB (scripts/start-arcadedb.sh) then starts the KADI ability runtime (kadi run start).
    • The agent declares a remote broker: wss://broker.dadavidtseng.com/kadi so tools are available to remote callers.

Data flow (high-level):

  • Tool call arrives at KadiClient (registered tool handler).
  • Handlers either call vendored managers (container/database/importExport/backup) or ArcadeHttpClient for REST operations.
  • For backups, the ability creates a .zip locally and starts a FileSharingServer that returns a download URL + authKey; clients may then download the file and call arcade-restore with either local path or sourceUrl.

The ability registers 17 tools. Below is a table summarizing each tool (name, short description, key input fields as defined by the z schemas in the source).

Tool nameDescriptionKey input fields
arcade-startStart the ArcadeDB container. Returns early if already running.withTestData?: boolean
arcade-stopStop the ArcadeDB container.force?: boolean
arcade-statusGet current status (container, ports, uptime).(none)
arcade-healthRun multi-point health check (container, API, DB).(none)
arcade-db-createCreate a new ArcadeDB database.name: string, schema?: string
arcade-db-listList all databases on the server.(none)
arcade-db-infoGet schema/types/indexes/stats for a database.database: string
arcade-db-dropDrop (delete) a database. (Safety checks used)(typically database: string, confirm: boolean)
arcade-db-statsGet statistics for databases (records, size).database?: string
arcade-queryExecute a read query via HTTP API.database: string, query: string, language?: string, params?: Record<string,unknown>
arcade-commandExecute a write command via HTTP API.database: string, command: string, language?: string, params?: Record<string,unknown>
arcade-batchExecute multiple write commands in a single transaction.(batched commands array — see batch tool schema in code)
arcade-importImport JSON/CSV/TSV into a database.database: string, filePath: string, format?: ‘json'
arcade-exportExport data from a database to file.database: string, outputPath: string, format?: ‘json'
arcade-backupCreate backup, compress, and serve file via temporary FileSharingServer.(tool returns path, downloadUrl, authKey; options available in code)
arcade-restoreRestore a database from backup — accepts local path or sourceUrl.path?: string, sourceUrl?: string, authKey?: string
arcade-backup-cleanupStop the temporary file-sharing server started by arcade-backup.(none / optional id)

Notes:

  • Many tool schemas are defined with z.object(…) in each tool registration. For the exact input validation schemas consult the corresponding files in src/tools/*.ts (examples shown below).
  • The ability exposes these tools through the KADI broker URL configured in agent.json (wss://broker.dadavidtseng.com/kadi).

Configuration is provided via config.toml, environment variables in the image, and a secrets vault.

config.toml (present in repo)

  • broker.local
    • URL: “wss://broker.dadavidtseng.com/kadi”
    • NETWORKS: [“arcadedb”]
    • MODE: “native”
  • arcadedb
    • USERNAME: “root”
  • Note: comments indicate that sensitive credentials go in secrets.toml (an encrypted vault).

Environment variables (set in agent.json build env and required by runtime)

  • KADI_DEPLOY_MODE — if set to “container”, the ability assumes ArcadeDB runs as a native process and avoids Docker calls (affects registerContainerTools behavior).
  • ARCADE_HOST — default “localhost” in build env.
  • ARCADE_PORT — default “2480” in build env.
  • ARCADEDB_HOME — default “/home/arcadedb”.
  • JAVA_HOME — default “/opt/java/openjdk”.
  • PATH — includes JAVA_HOME bin.

Secrets (delivered via kadi secret/vault as declared in agent.json deploy)

  • Vault name (in agent.json): “arcadedb”
  • Required secrets (deploy.local and deploy.production):
    • ARCADE_USERNAME
    • ARCADE_PASSWORD
    • KADI_TUNNEL_TOKEN
  • Delivery: “broker” (means the vault is delivered to the ability via the broker-secret mechanism in KADI).

Other config pieces:

  • agent.json defines broker endpoints and deploy/build images. See “build” and “deploy” entries for image name, copy-from stages, and start command:
    • Entrypoint: scripts/start-arcadedb.sh is used to start ArcadeDB before kadi run start.

Secrets vault usage:

  • The ability lists “secret-ability” as an ability dependency so it can request secrets.
  • The container start command in deploy uses: kadi secret receive —vault arcadedb to fetch secrets into the runtime.

Below are representative code excerpts taken directly from the source showing how tools are registered and how the ability bootstraps.

Index (ability startup / tool registration):

/**
* arcadedb-ability -- KADI ability that exposes ArcadeDB as 17 broker-callable tools.
*
* Tools are grouped into five categories:
* - Container (start, stop, status, health)
* - Database (create, list, info, drop, stats)
* - Query (query, command, batch)
* - Data (import, export)
* - Backup (backup, restore, cleanup)
*/
import { readFileSync } from 'fs';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
import { KadiClient } from '@kadi.build/core';
import { createManagers } from './lib/arcade-admin.js';
import { loadArcadeConfig } from './lib/config.js';
import { ArcadeHttpClient } from './lib/http-client.js';
import { registerBackupTools } from './tools/backup.js';
import { registerContainerTools } from './tools/container.js';
import { registerDataTools } from './tools/data.js';
import { registerDatabaseTools } from './tools/database.js';
import { registerQueryTools } from './tools/query.js';
/** Load agent.json from the project root (one level up from src/). */
const __dirname = dirname(fileURLToPath(import.meta.url));
const agentJson = JSON.parse(
readFileSync(join(__dirname, '..', 'agent.json'),
...(truncated)

Container lifecycle tool registration (excerpt):

/**
* Register container lifecycle tools (start, stop, status, health) with a
* {@link KadiClient}.
*
* @param client - The KADI client to register tools on.
* @param managers - Vendored CJS manager instances.
* @param httpClient - HTTP client for direct API health checks.
*/
export function registerContainerTools(
client: KadiClient,
managers: ArcadeManagers,
httpClient: ArcadeHttpClient,
): void {
/** When true, ArcadeDB runs as a native process — skip all Docker calls. */
const isContainerMode = process.env.KADI_DEPLOY_MODE === 'container';
// ---- arcade-start --------------------------------------------------------
client.registerTool(
{
name: 'arcade-start',
description: 'Start the ArcadeDB container. Returns early if already running.',
input: z.object({
withTestData: z.boolean().optional().describe('Include test data on first start'),
}),
},
async (input): Promise<StartResponse> => {
try {
// In container deployments ArcadeDB runs natively — no Docker needed
if (isContainerMode) {
const ready = await httpClient.isReady();
return ready
? { success: true, container: 'embedded', ports: [] }
: { success: false, error: 'ArcadeDB is not ready (container mode — server started by entrypoint)' };
}
const started = await managers.container.start({
withTestData: input.withTestData ?? false,
});
if (!started) {
return { success: false, error: 'Container failed to start' };
}
const status = await managers.container.getStatus();
return {
success: true,
container: status.container?.name ?? 'kadi-arcadedb',
ports: status.container?.ports ?? [],
};
} catch (err: unknown) {
return { success: false, error: errorMessage(err) };
}
},
);
// ---- arcade-stop ---------------------------------------------------------
client.registerTool(
{
name: 'arcade-stop',
description: 'Stop the ArcadeDB container.',
input: z.object({
force: z.boolean().optional().describe('Force stop (docker kill instead of stop)'),
}),
},
async (input): Promise<StopResponse> => {

Data import/export tools (excerpt):

/**
* Register data import/export tools (import, export) with a
* {@link KadiClient}.
*
* @param client - The KADI client to register tools on.
* @param managers - Vendored CJS manager instances.
*/
export function registerDataTools(
client: KadiClient,
managers: ArcadeManagers,
): void {
// ---- arcade-import -------------------------------------------------------
client.registerTool(
{
name: 'arcade-import',
description: 'Import data into an ArcadeDB database from a file (JSON, CSV, or TSV).',
input: z.object({
database: z.string().describe('Target database name'),
filePath: z.string().describe('Path to the import file'),
format: z.enum(['json', 'csv', 'tsv']).optional().describe('File format (auto-detected from extension if omitted)'),
type: z.string().optional().describe('Target vertex type name'),
batchSize: z.number().optional().describe('Records per batch (default: 100)'),
}),
},
async (input): Promise<ImportResponse> => {
try {
const result = await managers.importExport.importData(
input.database,
input.filePath,
{
format: input.format,
type: input.type,
batchSize: input.batchSize,
},
);
return {
success: true,
imported: result.recordsImported ?? result.imported ?? 0,
};
} catch (err: unknown) {
return { success: false, error: errorMessage(err) };
}
},
);
// ---- arcade-export -------------------------------------------------------
client.registerTool(
{
name: 'arcade-export',
description: 'Export data from an ArcadeDB database to a file (JSON, CSV, or TSV).',
input: z.object({
database: z.string().describe('Source database name'),
outputPath: z.string().describe('Path for the output file'),
format: z.enum(['json', 'csv', 'tsv']).optional().describe('Output format (auto-detected from extension if omitted)'),
query: z.string().optional().describe('SQL query to select data (exports all if omitted)'),
type: z.string().optional().describe('Export a specific vertex type'),
}),
},
async (input): Promise<ExportResponse> => {
try {
const result = await managers.importExport.exportData(
input.database,
input.outputPath,
{
format: input.format,
query: input.query,
type: input.type,
},

Query / command tools (excerpt):

/**
* Register query and command tools (query, command, batch) with a
* {@link KadiClient}.
*
* @param client - The KADI client to register tools on.
* @param httpClient - HTTP client for ArcadeDB REST API access.
*/
export function registerQueryTools(
client: KadiClient,
httpClient: ArcadeHttpClient,
): void {
// ---- arcade-query --------------------------------------------------------
client.registerTool(
{
name: 'arcade-query',
description: 'Execute a read query (SELECT, MATCH, TRAVERSE) against an ArcadeDB database.',
input: z.object({
database: z.string().describe('Target database name'),
query: z.string().describe('SQL query to execute'),
language: z.string().optional().describe('Query language: sql (default), cypher, gremlin'),
params: z.record(z.string(), z.unknown()).optional().describe('Query parameters for parameterized queries'),
}),
},
async (input): Promise<QueryResult> => {
try {
return await httpClient.query(
input.database,
input.query,
input.params,
input.language ?? 'sql',
);
} catch (err: unknown) {
return { success: false, error: errorMessage(err) };
}
},
);
// ---- arcade-command ------------------------------------------------------
client.registerTool(
{
name: 'arcade-command',
description: 'Execute a write command (CREATE, INSERT, UPDATE, DELETE, DROP) against an ArcadeDB database.',
input: z.object({
database: z.string().describe('Target database name'),
command: z.string().describe('SQL command to execute'),
language: z.string().optional().describe('Command language: sql (default), cypher, gremlin'),
params: z.record(z.string(), z.unknown()).optional().describe('Command parameters'),
}),
},
async (input): Promise<QueryResult> => {
try {
return await httpClient.command(
input.database,
input.command,
input.params,
input.language ?? 'sql',
);
} catch (err: unknown) {
return { success: false, error: errorMessage(err) };
}
},
);

Backup tool header + staging state (excerpt showing how backups are served):

/**
* Backup & restore tools — create, verify, and restore ArcadeDB database backups.
*
* These tools wrap the vendored BackupManager AND add file-sharing support
* so that backup files can be transferred across machines in distributed
* deployments (e.g., every ability on its own Akash provider).
*
* ... (distributed file transfer description omitted)
*
* ## Tools registered
*
* 1. `arcade-backup` — create backup, compress, serve file
* 2. `arcade-restore` — download (if URL) → decompress → restore
* 3. `arcade-backup-cleanup` — stop the file-sharing server early
*
* @module tools/backup
*/
import { KadiClient, z } from '@kadi.build/core';
import { FileSharingServer } from '@kadi.build/file-sharing';
...
// ── Staging server state (module-level singleton) ─────────────────────
interface StagingState {
server: FileSharingServer;
authKey: string;
localUrl: string;
publicUrl?: string;
servingPath: string;
servingFilename: string;
timeoutHandle: ReturnType<typeof setTimeout>;
}
let activeStagingState: StagingState | null = null;
/** How long to keep the file-sharing server alive (ms). Default: 10 min. */
const STAGING_TIMEOUT_MS = 10 * 60 * 1000;
/**
* Start a temporary file-sharing HTTP server that serves a single file.
*
* Uses `@kadi.build/file-sharing`'s `FileSharingServer` pointing at the
* directory containing the backup file.
*/
async function startStagingServer(

(For full implementation of the backup/restore and staging lifecycle, consult src/tools/backup.ts in the repository.)

Direct runtime dependencies (from source context)

  • @kadi.build/core — Kadi client and tool registration primitives, zod integration.
  • @kadi.build/file-sharing — FileSharingServer used to stage backup files for distributed transfer.
  • Node.js APIs: fs, path, os, crypto, child_process, stream/promises.
  • Vendored ArcadeDB artifacts provided via the arcadedata/arcadedb:26.2.1 stage copied into the image (see build in agent.json).
  • Internal libraries in the package:
    • ./lib/arcade-admin.js (createManagers)
    • ./lib/http-client.js (ArcadeHttpClient)
    • ./lib/config.js (loadArcadeConfig)
    • ./lib/types.js (types used by tool handlers)
    • ./lib/backup-config.js and ./lib/errors.js

Abilities and runtime interactions:

  • ability-arcadedb declares it uses “secret-ability”: ”*” to receive secrets from the vault.
  • It exposes tools that other agents/abilities may call via the configured KADI broker (wss://broker.dadavidtseng.com/kadi). Any ability that needs to perform DB work can call the registered tools remotely.

What depends on it:

  • Other agents/abilities that need ArcadeDB administration, queries, imports/exports, backups, or health checks will call these tools over the broker. The agent.json broker and networks configuration ensures the ability is reachable on the “arcadedb” network.
  • Tool handlers use z schemas for input validation (z.object(…)) — refer to each tool file in src/tools/* to see the exact input shape and return types.
  • Container mode: set KADI_DEPLOY_MODE=container to indicate ArcadeDB is started by the entrypoint (embedded/native mode) and skip Docker manager operations in registerContainerTools.
  • Backup staging uses a module-level singleton activeStagingState to prevent multiple concurrent staging servers; inspect src/tools/backup.ts for lifecycle, timeout, and cleanup behavior.
  • Secrets are required by deploy configurations (ARCADE_USERNAME, ARCADE_PASSWORD, KADI_TUNNEL_TOKEN) and are expected to be provided by kadi secret receive —vault arcadedb at startup (see agent.json deploy commands).
  • To modify or extend tools, add registration code in src/tools/* and call client.registerTool with appropriate z schemas and implementation that uses managers or ArcadeHttpClient.

If you need pointers to the implementation of specific tools or to the vendored manager APIs, check:

  • src/tools/*.ts (tool registrations)
  • src/lib/*.js/.ts (managers, HTTP client, configuration loaders)
  • agent.json for build/deploy/runtime environment and secrets configuration.