Getting Started

Prerequisites

  • .NET 10 SDK
  • PostgreSQL with the pgvector extension
  • Node.js 20+ (for the web frontend)

Installation

Clone the repository

# Public URL not verified from this agent host — use the org repo your team actually ships from.
git clone <your-atamaia-repo-url>
cd atamaia

Set up the database

CREATE DATABASE atamaia;
\c atamaia
CREATE EXTENSION IF NOT EXISTS vector;

Configure the application

Committed config lives under src/Atamaia.Server/:

  • appsettings.json — non-secret structure (includes ConnectionStrings:Atamaia, Kestrel on port 5000)
  • appsettings.Development.json / appsettings.Production.json — environment overlays

There is no appsettings.Development.json.example in the tree as of 2026-08-13. Secrets must not go in committed JSON. The file itself says so: use environment variables (e.g. /etc/atamaia/atamaia.env, mode 600). Double underscore maps to colon: Encryption__KeyEncryption:Key.

Minimal local connection string shape (from committed defaults — change password):

{
  "ConnectionStrings": {
    "Atamaia": "Host=localhost;Port=5432;Database=atamaia;Username=atamaia;Password=yourpassword"
  }
}

JWT and encryption material are supplied via environment in real deployments. Do not invent secret keys into git.

Run migrations

cd src/Atamaia.Server
dotnet ef database update --project ../Atamaia.Mind.Migration

Build and run

# API server
cd src/Atamaia.Server
dotnet run

# Frontend (separate terminal)
cd src/Atamaia.Web
npm install
npm run dev
  • API: http://localhost:5000 (launch profile + Kestrel config)
  • Frontend dev: http://localhost:5174, proxies API to :5000

First run

1. Bootstrap the admin user

On a fresh install with no users, bootstrap creates the first admin and returns login tokens:

curl -X POST http://localhost:5000/api/auth/bootstrap \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin",
    "password": "your-secure-password",
    "email": "[email protected]"
  }'

The controller forces Role = Admin and Type = Human regardless of any role/type fields on the body. If any user already exists → 400 ALREADY_BOOTSTRAPPED.

Save the accessToken from the envelope’s data.

2. Create an AI identity

curl -X POST http://localhost:5000/api/identities \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-ai",
    "displayName": "My AI Assistant",
    "bio": "A helpful AI partner",
    "type": "AI",
    "userId": 1
  }'

Field is userId, not linkedUserId.

3. Configure personality (optional)

curl -X PUT http://localhost:5000/api/identities/1/personality \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tone": "warm, direct",
    "traits": ["helpful", "thorough", "honest"],
    "focusAreas": ["software development"],
    "greetingStyle": "casual",
    "uncertaintyHandling": "acknowledge",
    "proactiveSuggestions": true
  }'

4. Create an API key

curl -X POST http://localhost:5000/api/identities/1/api-keys \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "claude-code",
    "scopes": "all"
  }'

scopes is a string (e.g. "memory,hydration,facts" or "all" / null for all), not a JSON array. Response includes rawKey once — value looks like atamaia_…. Store it; it cannot be retrieved again.

5. Test hydration

curl "http://localhost:5000/api/hydrate?aiName=my-ai&preset=lean" \
  -H "Authorization: Bearer atamaia_your_key_here"
  • Method is GET
  • Identity keys use Authorization: Bearer atamaia_… (not ApiKey atm_…)

You should get ApiEnvelope JSON whose data includes identity, personality-related blocks, and any memories/context that exist. Lean also includes standing rules and system health when those sources fire.

6. Create your first memory

curl -X POST http://localhost:5000/api/identities/1/memories \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Project uses PostgreSQL",
    "content": "The Atamaia project uses PostgreSQL with pgvector for all data storage. No separate vector database.",
    "type": "Instruction",
    "provenance": "Asserted",
    "importance": 8,
    "tags": ["tech-stack", "database"]
  }'

Field is type, not memoryType. Include provenance (Asserted | Reported | Inferred | Ambiguous).

7. Create a project (optional)

curl -X POST http://localhost:5000/api/projects \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "my-project",
    "name": "My Project",
    "description": "First project in Atamaia"
  }'

8. Create a task (optional)

Task create requires classification at runtime — see Tasks:

curl -X POST http://localhost:5000/api/projects/1/tasks \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Wire hydrate into my agent loop",
    "kind": "Feature",
    "subsystem": "Agent",
    "priority": "Normal"
  }'

Setting up Claude Code / MCP

Option A: MCP server (recommended)

{
  "mcpServers": {
    "atamaia": {
      "type": "url",
      "url": "http://localhost:5000/mcp",
      "headers": {
        "Authorization": "Bearer atamaia_your_key_here"
      }
    }
  }
}

Production MCP base commonly pairs with the API host:

https://api.atamaia.ai/mcp

Add to CLAUDE.md:

## HYDRATE FIRST

Call `hydrate` before doing anything else. This loads identity, memories,
standing rules, and current project context from Atamaia.

When you learn something important during this session, save it:
- Use `memory_create` for observations, decisions, and learnings (work store)
- Use `fact_upsert` for structured key-value data
- Use `session_save_handoff` before the session ends
- Use `rule_check` before deploy / claim-done / other gated moments

Hot tools are advertised directly; cold tools are reached via atamaia_call after help_route / help_search.

Option B: Hook-based auto-hydration

#!/bin/bash
# ~/.claude/scripts/atamaia-hydrate.sh
curl -s "http://localhost:5000/api/hydrate?aiName=my-ai&preset=lean" \
  -H "Authorization: Bearer $ATAMAIA_API_KEY"
export ATAMAIA_API_KEY="atamaia_your_key_here"

Next steps