| name | dinobase |
| description | Set up and query business data across 100+ sources (Stripe, HubSpot, Salesforce, etc.) via SQL. Agent-driven setup, cross-source joins, mutations. |
| version | 0.2.0 |
| metadata | {"openclaw":{"emoji":"🦕","homepage":"https://github.com/DinobaseHQ/dinobase","requires":{"bins":["dinobase"]},"install":[{"id":"uv","kind":"uv","package":"dinobase","bins":["dinobase"],"label":"Install Dinobase (uv)"}]}} |
Dinobase
Dinobase is an agent-first database. It syncs data from 100+ SaaS APIs, databases, and files into a SQL database (DuckDB). You query across all sources with standard SQL.
When to use
- Setting up data connections for a user (first time or adding new sources)
- Answering questions that span multiple business tools (CRM + billing + support)
- Querying synced business data via SQL (Stripe, HubSpot, Salesforce, GitHub, etc.)
- Cross-source joins and aggregations (e.g., customers with overdue invoices AND open tickets)
- Writing data back to sources (UPDATE/INSERT with preview + confirm)
When NOT to use
- Real-time API calls to a single service (use the service's API directly)
- File system operations or general shell tasks
- Data that hasn't been added to Dinobase yet (check with
dinobase status first)
Setup (agent-driven)
You can fully set up Dinobase for the user. It runs entirely locally — no account required.
Step 1: Check existing state
dinobase status
This shows any sources that are already configured. If Dinobase isn't initialized yet, proceed with setup below.
Step 2: Set up locally
dinobase init
This initializes a local Dinobase database. Everything works locally — connecting sources, syncing, and querying.
Step 3: Discover what the user needs
Ask the user what tools and data sources they use. Then check what's available:
dinobase sources --available
This returns JSON with full metadata per source:
[
{
"name": "stripe",
"description": "Stripe payments (customers, subscriptions, charges, invoices)",
"supports_oauth": false,
"credential_help": "Stripe Dashboard > Developers > API keys (use the Secret key)",
"credentials": [{"name": "stripe_secret_key", "cli_flag": "--api-key", ...}]
},
{
"name": "hubspot",
"description": "HubSpot CRM (contacts, companies, deals, tickets)",
"supports_oauth": true,
"credential_help": "HubSpot > Settings > Integrations > Private Apps > create app > copy token",
"credentials": [{"name": "api_key", "cli_flag": "--api-key", ...}]
}
]
Step 4: Connect sources
For each source the user wants, connect it with an API key:
- Check
credential_help from the sources list
- Tell the user where to find the key
- Run:
dinobase add <source_type> --<cli_flag> <value>
Example:
dinobase add stripe --api-key sk_live_...
Step 5: Sync data
dinobase sync
This runs the sync directly. Check status:
dinobase status
Step 6: Verify
dinobase info
Confirm that sources appear with non-zero table and row counts.
Workflow (querying data)
Always follow this sequence when answering data questions:
- Run
dinobase info to see what sources and tables exist
- Run
dinobase describe <schema>.<table> on relevant tables to see columns, types, and sample data
- Write SQL and run it with
dinobase query "<sql>"
- If the query returns a mutation preview, ask the user before running
dinobase confirm <mutation_id>
Commands
All commands output JSON by default (machine-readable). Add --pretty for human-readable output.
Connect sources
dinobase sources --available
dinobase add stripe --api-key sk_test_...
Discover data
dinobase info
dinobase status
dinobase describe stripe.customers
Query data
dinobase query "SELECT c.email, s.status FROM stripe.customers c JOIN stripe.subscriptions s ON c.id = s.customer_id WHERE s.status = 'past_due'"
dinobase query "SELECT * FROM hubspot.contacts" --max-rows 500
Cross-source queries
Join across sources using shared columns (email, company name, IDs):
dinobase query "
SELECT c.email, c.name, i.amount_due, t.subject as ticket_subject
FROM stripe.customers c
JOIN stripe.invoices i ON c.id = i.customer_id
JOIN zendesk.tickets t ON c.email = t.requester_email
WHERE i.status = 'past_due' AND t.status = 'open'
"
Mutations (write-back)
UPDATE and INSERT queries return a preview first. Nothing executes until confirmed.
dinobase query "UPDATE hubspot.contacts SET lifecycle_stage = 'customer' WHERE email = 'jane@acme.com'"
dinobase confirm <mutation_id>
dinobase cancel <mutation_id>
Keep data fresh
dinobase refresh stripe
dinobase refresh --stale
dinobase sync
Tips
- Tables are always referenced as
schema.table (e.g., stripe.customers, hubspot.contacts)
- Use
describe before writing queries to find correct column names and types
- DuckDB SQL dialect: supports
ILIKE, LIST, STRUCT, regexp_matches(), date functions
- JSON output is default; only use
--pretty when showing results directly to the user
- If data seems stale, check
dinobase status for freshness info and run dinobase refresh <source>
- Cross-source joins work via shared columns — use
describe on both tables to find join keys
- For new users: start with
dinobase init and API key auth