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 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"
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(())
}
For production, use environment variables for credentials instead of hardcoding them in your connection string.
Vector Search
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
- What is ANDI? — Understand the Agent-Native Data Infrastructure category
- Architecture in 60 Seconds — Two-plane design overview
- Core Concepts — Deep dive into agent identity, memory, and more
- Python SDK — Full SDK reference
- SQL Functions — Complete SQL compatibility reference