Skip to main content

Quickstart

Go from zero to your first agent-native query in under 5 minutes. This guide uses the hati CLI with the embedded query engine — no cloud account or Docker required.

60-Second MCP Setup

Already using Claude, Cursor, or another MCP-compatible agent? Add HatiData as a tool in one step:

{
"mcpServers": {
"hatidata": {
"command": "hatidata-mcp-server",
"args": ["--host", "localhost", "--port", "5439"]
}
}
}

Then install and start:

pip install hatidata-agent[mcp]
hati init

Your agent now has query, list_tables, describe_table, and get_context tools — plus memory, chain-of-thought, triggers, and branching. For the full MCP reference, see MCP Tools.


Install

Choose your preferred installation method:

# Python (recommended for AI agent workflows)
pip install hatidata-agent

# CLI (macOS, Linux)
curl -fsSL https://hatidata.com/install.sh | sh

# Node.js
npm install @hatidata/sdk
Python Requirements

Python 3.9 or later. The hatidata-agent package includes psycopg2-binary for Postgres wire protocol connectivity.

Step 1: Initialize Your Data Layer

hati init

This creates a .hati/ directory in your project with an embedded query engine. No cloud connection needed — everything runs locally.

.hati/
config.toml # Connection and runtime settings
warehouse.db # Your local database
cache/ # Query and transpilation cache

Step 2: Create a Table

hati query "CREATE TABLE users (id INT, name VARCHAR, email VARCHAR)"

You can use Snowflake-compatible SQL syntax. HatiData automatically transpiles it for execution:

# Snowflake types work too — they're auto-converted
hati query "CREATE TABLE events (id INT, payload VARIANT, created_at TIMESTAMP_NTZ)"
# VARIANT -> JSON, TIMESTAMP_NTZ -> TIMESTAMP

Step 3: Insert Data

hati query "INSERT INTO users VALUES (1, 'Alice', 'alice@example.com')"
hati query "INSERT INTO users VALUES (2, 'Bob', 'bob@example.com')"
hati query "INSERT INTO users VALUES (3, 'Carol', 'carol@example.com')"

Step 4: Query Your Data

hati query "SELECT * FROM users"

Output:

+----+-------+--------------------+
| id | name | email |
+----+-------+--------------------+
| 1 | Alice | alice@example.com |
| 2 | Bob | bob@example.com |
| 3 | Carol | carol@example.com |
+----+-------+--------------------+
3 rows returned in 0.8ms

Snowflake-compatible functions are transpiled automatically:

# NVL -> COALESCE
hati query "SELECT NVL(email, 'unknown') FROM users"

# IFF -> IF
hati query "SELECT IFF(id > 1, 'yes', 'no') FROM users"

Step 5: Connect an Agent

Local Path

Use the Python SDK to connect an AI agent to your local data layer:

from hatidata_agent import HatiDataAgent

agent = HatiDataAgent(
host="localhost",
port=5439,
agent_id="quickstart-agent",
framework="custom",
)

# Query data
rows = agent.query("SELECT * FROM users")
for row in rows:
print(row["name"], row["email"])

# Store a memory
agent.store_memory(
content="There are 3 users in the system",
memory_type="fact",
importance=0.7,
)

# Search memories
results = agent.search_memory("how many users")

Cloud Path

When connecting to HatiData Cloud, your agent self-registers on first connection — no pre-registration needed:

from hatidata_agent import HatiDataAgent

# Your agent self-registers on first connection — no pre-registration needed
agent = HatiDataAgent(
host="your-org.proxy.hatidata.com",
agent_id="architect-agent", # claimed name
password="hd_live_...", # org-level key
)
# HatiData assigns fingerprint: hd_agt_a3f2c1d4
# Trust level starts at: provisional
# Auto-promotes to verified after 10 executions
print(agent.fingerprint) # → "hd_agt_a3f2c1d4"
note

In cloud mode, your agent_id is auto-assigned by HatiData as hd_agt_xxx — you don't pick it. The agent_id you pass at connection time is your claimed display name. HatiData returns the immutable fingerprint in agent.fingerprint. See Agent Registry for details.

Step 6: Push to Cloud

When you are ready to share data or connect remote agents, push to the cloud:

hati push --target cloud

This uploads your local data to HatiData Cloud ($29/month). Once complete, you get a connection string:

Connection ready!
Host: your-org.proxy.hatidata.com
Port: 5439
Database: hatidata

Connect with psql:
psql -h your-org.proxy.hatidata.com -p 5439 -U analyst -d hatidata

What Happens Next

After pushing to cloud, your data is available via any Postgres-compatible client:

# psql
psql -h your-org.proxy.hatidata.com -p 5439 -U analyst -d hatidata

# Python
from hatidata_agent import HatiDataAgent
agent = HatiDataAgent(host="your-org.proxy.hatidata.com", port=5439)
rows = agent.query("SELECT * FROM users")

# Node.js
import { Client } from 'pg';
const client = new Client({ host: 'your-org.proxy.hatidata.com', port: 5439 });

Try Hybrid SQL

HatiData's hybrid SQL lets you combine structured queries with semantic search. Get a free API key at hatidata.com/signup to unlock 50 hybrid queries/day.

from hatidata_agent import HatiDataAgent

agent = HatiDataAgent(
host="localhost",
port=5439,
cloud_key="hd_live_..." # from hatidata.com/signup
)

# Semantic search — find tickets about billing
result = agent.query("""
SELECT ticket_id, subject, body
FROM support_tickets
WHERE semantic_match(embedding, 'billing dispute refund')
ORDER BY semantic_rank(embedding, 'billing dispute refund') DESC
LIMIT 10
""")

# Hybrid join — enrich with knowledge base
result = agent.query("""
SELECT t.ticket_id, t.subject, k.article_title, k.solution
FROM support_tickets t
JOIN_VECTOR knowledge_base k ON semantic_match(k.embedding, t.subject)
WHERE t.status = 'open'
LIMIT 5
""")

Standard SQL queries work without a cloud key — hybrid SQL features require a free account.

Connect from Your Application

HatiData speaks the Postgres wire protocol, so any Postgres-compatible client works out of the box. Replace localhost with your HatiData host and hd_live_YOUR_KEY_HERE with your API key.

psql

psql "postgres://agent:hd_live_YOUR_KEY_HERE@localhost:5439/main"

Python (psycopg2)

import psycopg2

conn = psycopg2.connect(
host="localhost",
port=5439,
user="agent",
password="hd_live_YOUR_KEY_HERE",
dbname="main",
)
cur = conn.cursor()
cur.execute("SELECT 1 AS hello")
print(cur.fetchone())
conn.close()

Node.js (pg)

const { Client } = require('pg');

const client = new Client({
host: 'localhost',
port: 5439,
user: 'agent',
password: 'hd_live_YOUR_KEY_HERE',
database: 'main',
});

await client.connect();
const res = await client.query('SELECT 1 AS hello');
console.log(res.rows);
await client.end();

Rust (sqlx)

use sqlx::PgPool;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let pool = PgPool::connect(
"postgres://agent:hd_live_YOUR_KEY_HERE@localhost:5439/main"
).await?;

let rows = sqlx::query("SELECT 1 AS hello")
.fetch_all(&pool)
.await?;

println!("Connected! Got {} rows", rows.len());
Ok(())
}
tip

For production, use environment variables for credentials instead of hardcoding them in your connection string.

HatiData extends standard SQL with semantic search functions. Embeddings are auto-generated when you use semantic_match or semantic_rank:

-- Store products with embeddings (embeddings auto-generated from description)
CREATE TABLE products (id INTEGER, name TEXT, description TEXT, embedding FLOAT[384]);

-- Find similar products
SELECT name, semantic_rank(embedding, 'organic coffee') AS score
FROM products
ORDER BY score DESC
LIMIT 5;

For the full vector search reference, see SQL Functions.

Next Steps

Stay in the loop

Product updates, engineering deep-dives, and agent-native insights. No spam.