Inspiration
Most finance apps show you charts after the damage is already done. We wanted something different — an agent that works like a 24/7 financial bodyguard. One that watches your accounts while you sleep, catches dangerous spending patterns before they compound, and speaks to you honestly, not through a dashboard. The name Kadmus comes from Greek mythology — the founder who laid the groundwork for civilization. That is what this agent does: it builds the financial groundwork for you invisibly in the background.
What We Built
CockroachDB as the entire memory core:
Every piece of financial data lives in CockroachDB across 6 tables and 2 analytical views:
accounts— Plaid-linked bank accountstransactions— full transaction history (Plaid sign convention: positive = money out, negative = money in)plaid_sync_cursors— cursor state for incremental Plaid syncspending_history— a SQL view that filters positive-amount transactions with year/month columns for GROUP BY queriesincome_history— a SQL view that filters negative-amount transactions and flips the sign to positiveanomalies— flagged events of typesHIGH_SINGLE_PURCHASE,SPENDING_SPIKE,DUPLICATE_CHARGE, andRECURRING_SUBSCRIPTIONwith severities from LOW to CRITICALagent_memory— every AI recommendation stored with aVECTOR(768)embedding and a verified outcome (pending,success,failed,revoked)
CockroachDB Distributed Vector Indexing — Outcome-Verified Memory:
This is the core innovation. When Kadmus answers a question it saves the recommendation into agent_memory as a 768-dimensional embedding using VECTOR(768). A dedicated L2 Approximate Nearest Neighbor index (CREATE VECTOR INDEX ... vector_l2_ops) enables semantic similarity search on every future question. The distance threshold is 1.1 in L2 space. On each new question the agent runs three possible decisions:
REUSE— if a semantically similar past question exists and its outcome wassuccess, reuse the verified answer instantlyABSTAIN— if the similar past outcome wasfailedorrevoked, explicitly warn the user and run a fresh audit instead of repeating bad adviceFRESH_ANALYSIS— no similar precedent found or outcome stillpending, run the full MCP reasoning loop
CockroachDB Managed MCP Server — Dynamic SQL Reasoning:
The AI agent connects to the CockroachDB MCP binary over stdio transport. Instead of hardcoded queries it uses three tools autonomously: list_tables to discover available tables, get_table_schema to inspect columns, and select_query to run analytical SQL against spending_history, income_history, anomalies, and agent_memory. This lets the agent answer any open-ended financial question with real numbers.
Multi-Provider AI Cascade:
Groq (models: openai/gpt-oss-120b, openai/gpt-oss-20b, qwen/qwen3.6-27b) → Gemini (gemini-3.6-flash) → Anthropic (Claude). The agent tries each provider in order and falls back automatically if one fails.
AWS Serverless Deployment:
- AWS Lambda
telegram.ts— receives Telegram webhook instantly and responds with 200 - AWS SQS — decouples the webhook from AI inference to avoid Telegram's 5-second timeout
- AWS Lambda
telegram-worker.ts— pulls from SQS and runs the full MCP reasoning loop - AWS Lambda
heartbeat.ts— triggered by AWS EventBridge on a cron schedule for 24/7 anomaly monitoring - AWS Secrets Manager — stores all credentials securely outside the deployment bundle
Challenges
- Empty answers after tool loops: Groq would complete all MCP tool calls but return no text in the final response. Fixed by adding a forced synthesis call after the loop if
finalAnsweris still empty. - Wrong table names in prompts: System prompt originally referenced
bank_accountswhich does not exist. Every SQL query failed silently. Fixed after a full schema mismatch audit. - Telegram does not render markdown tables: Pipe tables rendered as raw broken text. Built a
markdownToTelegramHtmlconverter that transforms**bold**and*italic*into proper Telegram HTML tags before sending. - Schema wiping on restart:
schema.sqlusedDROP TABLE IF EXISTS users CASCADEwhich cascaded and silently wiped all financial tables every time the daemon restarted. Converted all statements toCREATE TABLE IF NOT EXISTS. - Telegram webhook timeout: Telegram requires a 200 response within 5 seconds but AI inference takes 15 to 30 seconds. Solved with the SQS decoupling pattern — webhook Lambda acknowledges immediately and pushes to SQS for async processing.
Built With
- amazon-web-services
- amazonbedrock
- aws-lambda
- awssqs
- cockroachdb
- cockroachdb-distributed-vector-indexing
- cockroachdbmanagedmcpserver
- gemini
- groq
- node.js
- telegram
- typescript
Log in or sign up for Devpost to join the conversation.