SKILL: CData CLI
Data Model
The driver exposes the data source as a relational model:
- Tables that represent queriable entities
- Columns that make up the attributes of tables
- Procedures that support performing actions
Java-Native Foundation
CData CLI is Java-native and runs on the CData JDBC Driver. All connection management, schema discovery, and SQL execution in this skill use JDBC under the hood.
If your target application is Java or another JVM language (Kotlin, Scala), the same JDBC jar and license the CLI already set up carry straight into your app — no additional driver install needed. That's the simplest path and the recommended starting point when the target language hasn't been decided yet.
For other languages — Python, C#/.NET, Node.js, Go, and others — CData publishes separate runtime driver editions (Python Connectors, ADO.NET Data Providers, ODBC Drivers). These require a separate download, install, and license step that the CLI cannot perform. The build skills guide you through that setup, but expect more steps than the Java path.
CLI Invocation
The CLI installs as cdatacli and is on PATH after install:
cdatacli <group> <subcommand> [options]
Requires Java 17+. Drivers are discovered from ./ or ./lib/ relative to the CLI executable.
Shell syntax: Examples below use bash/zsh syntax. On Windows PowerShell, adapt them:
mkdir -p <dir>→New-Item -ItemType Directory -Force <dir>\line-continuation → backtick`> filewrites UTF-16 on Windows PowerShell 5.1, which can corrupt a generatedSKILL.md; use| Out-File -Encoding utf8 fileinstead (PowerShell 7+ already writes UTF-8).- Wrap a connection string in single quotes if it contains
$or other characters the shell would expand.- Connection-string quoting: When a value contains
;or other special characters (e.g. a password), wrap the outer--connectionstringin double quotes and each inner value in single quotes — this survives both PowerShell 7 and CMD unchanged:--connectionstring "AuthScheme=Basic;User=me;Password='p;w=d';Other='MaxThreads=10'"
If cdatacli --version is missing, install:
- Windows (PowerShell):
irm https://downloads.cdata.com/cdatabuilds/builds/free/cdatacli/install-cdatacli-windows.ps1 | iex - macOS:
curl -fsSL https://downloads.cdata.com/cdatabuilds/builds/free/cdatacli/install-cdatacli-macos.sh | bash - Linux:
curl -fsSL https://downloads.cdata.com/cdatabuilds/builds/free/cdatacli/install-cdatacli-linux.sh | bash
Command Reference
| Goal | Command |
|---|---|
| Accept EULA (required first run) | license [-y] |
| List installed drivers | drivers list |
| Search remote driver catalog | drivers search [--driver <name-or-artifact-id>] |
| Download driver jar | drivers download --artifact-id <id> [--output <dir>] |
| Download driver jar (by URL) | drivers download --url <jar-url> [--output <dir>] |
| Activate (trial) | drivers activate <Driver> --name "First Last" --email E --trial |
| Activate (key) | drivers activate <Driver> --name "First Last" --email E --key KEY |
| Inspect connection properties | drivers connectionprops <Driver> [--full] |
| Generate driver-specific skill | drivers skill <Driver> |
| Create connection | connection create --driver <Driver> --name N --connectionstring CS |
| Update connection (merge) | connection update --name N --connectionstring CS |
| Update connection (replace) | connection update --name N --connectionstring CS --replace |
| Update, skip validation | connection update --name N --connectionstring CS --force |
| Remove properties | connection update --name N --unset "Key1,Key2" |
| List connections | connection list |
| Delete connection | connection delete --name N |
| List catalogs | metadata catalogs --connection N |
| List schemas | metadata schemas --connection N |
| List tables | metadata tables --connection N |
| Get columns | metadata columns --connection N --table T |
| List procedures | metadata procedures --connection N |
| Procedure params | metadata parameters --connection N --procedure P |
| Run SQL (SELECT/DML) | query sql --connection N --sql "SQL" [--metadata] |
| Execute procedure | query sql --connection N --sql "EXEC Proc Param='val'" |
Every subcommand supports --help — returns purpose, required args, optional args, and flags. Use when Command Reference doesn't cover your case.
Source-Specific Skills
For popular sources, CData drivers ship source-specific instructions (connection patterns, schema notes, query examples). The driver must be installed first — this command reads the instructions bundled in the driver jar. Once it's installed, generate a ready-to-use skill with:
cdatacli drivers skill <Driver>
This prints a ready-to-use YAML skill frontmatter prefix (name: cdata-<source> plus a description) followed by the driver's source-specific instructions.
Save the output as a SKILL.md in whichever directory the user's AI coding tool loads skills (or rules/instructions) from — the right location depends on the tool and on the intended scope: user-level (available across all of the user's projects) or project-level (committed with a single project). Don't assume a fixed path. For example:
- Claude Code:
~/.claude/skills/cdata-<source>/SKILL.md(user-level) or.claude/skills/cdata-<source>/SKILL.md(project-level) - Other agents (Cursor, GitHub Copilot, Gemini CLI, Codex, etc.): use that tool's own skills/rules/instructions directory and file convention
If you're not sure where the current tool loads skills from, ask the user before writing the file. Then load the new skill for future work on that source. Example (replace <skills-dir> with the correct location for your tool):
mkdir -p <skills-dir>/cdata-<source>
cdatacli drivers skill <Driver> > <skills-dir>/cdata-<source>/SKILL.md
If the driver has no checked-in instructions, the command returns No instructions available for <driver> — in that case, proceed with the generic workflow below.
Best Practices
- Get columns before querying — use exact names from schema discovery.
- LIMIT first — sample before full queries.
- [Bracket] table and column names — handles reserved words and spaces.
- Filter before joining — apply WHERE first, add JOINs one at a time.
- Date filters prevent timeouts — large sources time out on unfiltered queries.
- Check procedures before concluding impossible — file operations, bulk exports, auth flows are often stored procedures.
- Enum/picklist fields — look for a dedicated table (e.g.
PickListValues) before filtering. Don't guess values.
Recommended Workflow
Step 1: Ensure the CLI is Installed
Confirm the CLI is available before anything else:
cdatacli --version
If that fails (command not found), install it and then re-check cdatacli --version:
- Windows (PowerShell):
irm https://downloads.cdata.com/cdatabuilds/builds/free/cdatacli/install-cdatacli-windows.ps1 | iex - macOS:
curl -fsSL https://downloads.cdata.com/cdatabuilds/builds/free/cdatacli/install-cdatacli-macos.sh | bash - Linux:
curl -fsSL https://downloads.cdata.com/cdatabuilds/builds/free/cdatacli/install-cdatacli-linux.sh | bash
The CLI requires Java 17+.
First-run EULA: On first use the CLI requires accepting the CData End User License Agreement — until then, commands exit with a license-agreement error. If you hit that message, run once:
cdatacli license -y
This accepts the EULA at https://www.cdata.com/company/legal/eula/; acceptance is stored per-machine, so there's no re-prompt on later commands.
Step 2: Understand the Goal
Confirm the source and goal (what to query or accomplish) before proceeding.
If a source-specific SKILL is already installed in the AI tool's skills directory (cdata-<source>), invoke it. Otherwise, don't generate one yet — cdatacli drivers skill <Driver> reads the instructions bundled in the driver jar, so it only works once the driver is installed. Wait until you've confirmed the driver is installed (Step 3), then run cdatacli drivers skill <Driver>: if it returns content, save it as a new skill in the location appropriate for the user's AI tool (see Source-Specific Skills above) and invoke it; if it returns No instructions available for <driver>, continue with the generic workflow.
Step 3: Verify Driver is Available and Activated
cdatacli drivers list
drivers list output includes licenseType (Trial, or a human-readable type like Enterprise/Developer/Server for a purchased license) and, for trial licenses only, trialDaysLeft (clamped to 0 once expired — at which point active becomes false).
If the driver appears with "activated": true, check licenseType:
TrialwithtrialDaysLeftlow (e.g. ≤ 7) or0: let the user know how many days remain (or that the trial has expired) and point them to https://www.cdata.com/jdbc to purchase before continuing — don't just silently proceed.- Otherwise, skip to Step 4.
If the driver is missing, download it from the CData driver catalog:
cdatacli drivers search --driver <source> # find the artifactId
cdatacli drivers download --artifact-id <id> # downloads to ./lib by default
cdatacli drivers download --url <jar-url> # alternative: direct URL
drivers download resolves the URL from CData's published artifacts.json catalog and writes the jar to --output <dir> (default ./lib/) — the same location the CLI auto-discovers. Re-run drivers list to confirm discovery. As a manual fallback, place a CData JDBC JAR in ./ or ./lib/ next to the CLI executable.
Activate
⚠️ License-key notice — show this to the user before running
drivers activate --key:It is not recommended to paste a license key into this AI session. A
--trialactivation is safe to run here, but a purchased--keyis a secret credential — anything typed into the session is visible to the AI and may be persisted in transcripts.If you need to activate with a purchased key, do it outside the AI session:
- Run
cdatacli drivers activate <Driver> --name ... --email ... --key ...in a non-AI terminal, or- Double-click
cdata.jdbc.<source>.jarto activate via the GUI wizard.Once the driver is activated, the license is saved alongside the jar —
drivers listwill show"activated": trueand no further activation is needed in the AI session.
Ask before activating — don't default to a trial. First ask the user whether they have a purchased license key or want a 30-day trial. Only run --trial if they confirm they don't have a key (or explicitly choose the trial); if they have a key, follow the license-key notice above rather than activating in this session.
The driver is a positional argument (e.g. Salesforce). --name and --email are the registrant's name and email — the individual registering the license. --trial requests a 30-day trial; --key activates a purchased license.
cdatacli drivers activate <Driver> --name "John Doe" --email "you@example.com" --trial
cdatacli drivers activate <Driver> --name "John Doe" --email "you@example.com" --key "XXXXX-XXXXX"
If the driver shows an expired trial (trialDaysLeft: 0, active: false), let the user know the 30-day trial period has ended and that a purchased license is required to continue. Direct them to https://www.cdata.com/jdbc to purchase a JDBC driver license, then follow the license-key notice above to activate with their key outside the AI session.
After activating a trial (or on any later drivers list check), report trialDaysLeft to the user so they aren't surprised by expiry — remind them the trial is time-limited and that they can purchase a license anytime at https://www.cdata.com/jdbc to convert before it runs out.
Step 4: Check Connection Properties
If a saved connection already exists (connection list), confirm with the user they would like to use it. Otherwise, inspect the driver's connection properties to determine what credentials to ask for:
cdatacli drivers connectionprops <Driver> # basic properties (default)
cdatacli drivers connectionprops <Driver> --full # advanced properties instead
By default connectionprops returns the basic properties — the set most connections need. Have the user confirm the connection string before building the connection. If they need advanced properties not in the basic set, add --full to the connectionprops command.
Don't carry connection settings over from a previous connection or session into a new connection without acknowledging it to the user.
Hierarchy rules describe how properties depend on each other. A property's hierarchyRules is keyed by that property's possible values, and each key lists the properties that become relevant for that choice. For example, Salesforce's AuthScheme has rules for Basic, OAuth, OAuthClient, etc.: choosing AuthScheme=Basic surfaces User and Password (both RequiredBasic) plus SecurityToken (UnrequiredBasic). Use these rules to ask the user only for the properties that the chosen auth scheme actually requires.
Key properties across all sources:
AuthScheme— OAuth, Basic, etc.InitiateOAuth— OFF, GETANDREFRESH, REFRESHOAuthClientId/OAuthClientSecret— for custom OAuth appsOAuthSettingsLocation— where OAuth tokens are cached
Step 5: Create a Saved Connection
⚠️ Credential notice — show this to the user before running
connection create:It is not recommended to paste passwords, API tokens, or other secret credentials into this AI session. Even though
cdatacli connection createwill accept them in a connection string, anything typed here is visible to the AI and may be persisted in transcripts.Recommended for AI-assisted use:
AuthScheme=OAuth(embedded OAuth) — credentials never enter the connection string; the browser flow handles auth.If your data source requires Basic / PAT / API-token auth, set up the connection outside the AI session:
- Run
cdatacli connection create ...in a non-AI terminal, or- Double-click
cdata.jdbc.<source>.jarto use the GUI setup wizard, or- Reuse a connection from a prior non-AI setup.
Afterward,
cdatacliuses the saved connection by name only — credentials never re-enter the terminal.
Confirm the (non-secret) connection string values with the user, then save:
cdatacli connection create --driver "<Driver>" --name "<connection-name>" \
--connectionstring "<properties>"
Common patterns:
| Auth Type | Connection String |
|---|---|
| OAuth (browser flow) | AuthScheme=OAuth;InitiateOAuth=GETANDREFRESH |
| Basic (user/pass) | AuthScheme=Basic;User=you@example.com;Password=pass |
| API Token | User=you@example.com;APIToken=yourtoken |
| Read-only | Append ReadOnly=true to any connection string |
cdatacli connection list
cdatacli connection update --name "<connection-name>" --connectionstring "<new-or-changed-properties>"
cdatacli connection update --name "<connection-name>" --connectionstring "<properties>" --replace
cdatacli connection update --name "<connection-name>" --unset "Key1,Key2"
cdatacli connection delete --name "<connection-name>"
connection update merges new properties into the existing connection by default — useful for changing a single property without recreating the connection. Use --replace to swap the entire connection string, or --unset to remove specific properties. Property names are case-insensitive. --replace and --unset cannot be combined. Use --force to skip connection validation — useful for placeholder connections or testing without a live source.
Connections are saved as encrypted .conn files (AES-256):
| OS | Location |
|---|---|
| Windows | %APPDATA%\CData\<Driver Name> Data Provider\ |
| macOS | ~/Library/Application Support/CData/<Driver Name> Data Provider/ |
| Linux | ~/.config/CData/<Driver Name> Data Provider/ |
Step 6: Discover Schema
cdatacli metadata tables --connection <name>
cdatacli query sql --connection <name> --sql "SELECT TableName, TableType, Description FROM sys_tables WHERE TableName LIKE '%<keyword>%'"
cdatacli metadata columns --connection <name> --table <TableName>
cdatacli metadata procedures --connection <name>
cdatacli metadata parameters --connection <name> --procedure <ProcedureName>
cdatacli metadata catalogs --connection <name>
cdatacli metadata schemas --connection <name>
Most metadata subcommands accept optional --catalog / --schema filters. metadata tables also takes a --table name pattern; metadata columns requires --table and accepts --column; metadata procedures accepts --procedure; metadata parameters requires --procedure and accepts --parameter.
Name patterns use % as a wildcard and are case-insensitive. A bare value is an exact match — --table Order returns only Order, not OrderItem; use --table "%Order%" to match substrings. _ is treated literally (not a wildcard), so --column "%__c" matches Salesforce custom fields. Quote any pattern containing %.
Step 7: Execute Queries
Use only column names confirmed by previous steps. Build incrementally.
query sql accepts these optional flags beyond --connection and --sql:
--timeout <seconds>— query timeout (default30). Raise it for slow or large sources.--max-rows <n>— maximum rows returned per result set (default1000). Results are silently capped at this number, so aSELECT *on a larger table returns only the first 1000 rows unless you raise--max-rows. Use a SQLLIMITto sample deliberately, and raise--max-rowswhen you need a full extract.--metadata— include the column schema (names, types) in the output. Omitted by default; add it only when you need column type information.
SELECT
cdatacli query sql --connection <name> --sql "SELECT * FROM [TableName] LIMIT 5"
cdatacli query sql --connection <name> --sql "SELECT [Id], [Name], [Status] FROM [TableName] WHERE [Status] = 'Active' LIMIT 10"
cdatacli query sql --connection <name> --sql "SELECT a.[Id], a.[Name], b.[Name] AS Related FROM [TableA] a LEFT JOIN [TableB] b ON a.[ForeignKey] = b.[Id] LIMIT 10"
Reading the output. query sql returns the same JSON shape for every data source (--compact only removes whitespace). By default the output contains only the data. The top-level shape depends on the query kind:
// SELECT (one result set) — default:
{ "resultset": [ { "cnt": 368 } ] }
// SELECT with --metadata — adds a column-schema array:
{ "metadata": [ { "name": "cnt", "typeName": "INT", ... } ], "resultset": [ { "cnt": 368 } ] }
// INSERT / UPDATE / DELETE, or a statement that returns nothing:
{ "affectedRows": 3 }
// Multiple result sets (batch): each entry is one of the shapes above
{ "results": [ { "resultset": [...] }, { "affectedRows": 2 } ] }
- Row data for a SELECT is always under
resultset— an array of row objects keyed by column name. To count rows, count theresultsetarray (above, 1 row whosecntis 368). For batches, readresults[].resultset. metadata(column names/types) is omitted by default and only appears when you pass--metadata; it's schema, not data, so ignore it when reading values.- There is no
rowskey, for any source. A SELECT returned no data only whenresultsetis[]. Do not infer "0 rows" from a missingrowsfield, and do not assume the table name is wrong because you can't find row data — look underresultset.
Pipe to jq with --compact, reading rows from .resultset:
cdatacli query sql --connection <name> --sql "SELECT Id, Name FROM Account" --compact | jq '.resultset[].Name'
INSERT / UPDATE / DELETE
cdatacli query sql --connection <name> --sql "INSERT INTO [TableName] (Col1, Col2) VALUES ('val1', 'val2')"
cdatacli query sql --connection <name> --sql "UPDATE [TableName] SET [Col1] = 'new' WHERE [Id] = '123'"
cdatacli query sql --connection <name> --sql "DELETE FROM [TableName] WHERE [Id] = '123'"
If writes fail, the connection may have ReadOnly=true. Do not change this on your own — point it out to the user and ask whether they want to remove it. If they confirm, use connection update --unset "ReadOnly" rather than recreating the connection.
Stored Procedures
cdatacli query sql --connection <name> --sql "EXEC ProcedureName Param1='value1', Param2='value2'"
Step 8: Generate Application Code
Steps 1–7 (connect, discover schema, validate SQL) are language-agnostic and are this skill's job. Once the goal shifts from exploring data to writing application code, hand off to the specialized building skill for the target driver technology.
If the target language hasn't been decided yet, propose Java first. The JDBC jar and license the CLI already set up are exactly what the app needs — no separate driver install, no additional licensing step. It is the fastest path from discovery to a working app. Other languages (Python, Node.js, C#, Go, etc.) are fully supported, but each requires a separate runtime driver download, install, and license activation that the CLI cannot perform — explain this trade-off so the user can make an informed choice.
If the target language is already clear from context (existing codebase, files, or the user has stated it), skip the proposal and go straight to the matching building skill.
Building skill by language / driver technology:
| Building in… | Invoke skill | Driver technology |
|---|---|---|
| Java / JVM (also Kotlin, Scala) — recommended | cdata-cli-java |
JDBC Driver (already set up by the CLI) |
| Python | cdata-cli-python |
CData Python Connector (separate install) |
| C# / .NET (also VB.NET, F#) | cdata-cli-adonet |
ADO.NET Data Provider (separate install) |
| Node.js / JavaScript / TypeScript, or any non-JVM language (Go, PHP, Ruby, Rust, C/C++) | cdata-cli-odbc |
ODBC Driver (separate system install) |
Invoke the matching building skill before writing code. Treat cdata-cli-odbc as the
cross-language fallback for any environment not covered by the other skills.