Skip to content

agentailor/cameron

Repository files navigation

Cameron AI

The companion finance agent for the Agentailor blog — a personal finance agent you own and run yourself. Built in public, one tagged release per article, maturing alongside the agent ecosystem.

Demo

Complete agent workflow: user input → tool approval → execution → streaming response

TypeScript Next.js LangGraph PostgreSQL Drizzle


What is Cameron?

Cameron is a personal finance agent that tracks spending, manages budgets, watches subscriptions, ingests receipts and statements, prepares reports, and — over the arc of the series — learns to build its own capabilities. It's built for two audiences at once:

  • the owner, who dogfoods it daily on real finances;
  • the reader, a developer learning agent engineering by running Cameron against seed data.

Hard rules, never relaxed:

  1. Cameron never moves money or mutates financial records without explicit human approval.
  2. Every capability — built-in, skill, connector, or self-written — passes through the same approval gate.
  3. All financial data stays on infrastructure the owner controls.

Built in public, one tag per article

Cameron ships as a linear series of tagged releases — v0, v1, v2, … — one (or two) per article. A reader learning a given topic checks out the tag for the article that taught it. This is v0: the foundation — the chat loop, streaming, persistence, dynamic MCP tool loading, human-in-the-loop approvals, and multi-model support that everything else is built on.

Seeded from a starter. Cameron's v0 foundation is copied from fullstack-langgraph-nextjs-agent, a generic LangGraph.js + Next.js agent starter. Cameron is its own project with its own identity and roadmap; the starter keeps its job as the reusable scaffold. Full credit and thanks to it.


Need help taking this to production?

I help teams design and optimize LangGraph-based AI agents (RAG, memory, latency, architecture).

If you're building something serious on top of this and want hands-on help:

DM me on LinkedIn

Happy to jump on a short call.


Features (v0 foundation)

Dynamic Tool Loading with MCP

  • Model Context Protocol integration for dynamic tool management
  • Add tools via web UI - no code changes required
  • Support for both stdio and HTTP MCP servers
  • Tool name prefixing to prevent conflicts

Human-in-the-Loop Tool Approval

  • Interactive approval before mutating tools run (logging or importing transactions); read-only and MCP tools run without interruption
  • Approve or deny each pending action
  • Optional auto-approval mode for trusted environments
  • Real-time streaming with tool execution pauses
Tool Approval Dialog

Tool approval dialog with detailed parameter inspection

Persistent Conversation Memory

  • LangGraph checkpointer with PostgreSQL backend
  • Full conversation history preservation
  • Thread-based organization
  • Seamless resume across sessions

Multimodal File Uploads

File upload

Upload images, PDFs, and text files alongside your messages

  • Upload images, PDFs, and text files with messages
  • S3-compatible storage (MinIO for development)
  • Automatic file processing for AI consumption
  • Production-ready with AWS S3, Cloudflare R2 support

Real-time Streaming Interface

  • Server-Sent Events (SSE) for live responses
  • Optimistic UI updates with React Query
  • Type-safe message handling
  • Error recovery and graceful degradation

Persistent Model Settings

  • Provider and model selection saved to localStorage automatically
  • Settings survive page reloads and thread navigation
  • No backend required — zero latency reads on startup

LLM Observability with Langfuse

  • End-to-end tracing of agent runs, LLM calls, tool invocations, and token usage
  • Works with Langfuse Cloud or a self-hosted instance
  • Toggle via LANGFUSE_ENABLED env var — zero overhead when disabled
  • See docs/OBSERVABILITY.md for setup instructions

Modern Tech Stack

  • Frontend: Next.js 15, React 19, TypeScript, Tailwind CSS
  • Backend: Node.js, Drizzle ORM, PostgreSQL, MinIO/S3
  • AI: LangGraph.js, OpenAI/Google/Anthropic models
  • UI: shadcn/ui components, Lucide icons

Roadmap

Cameron grows one tagged release at a time. Highlights of what's ahead:

Version Theme What ships
v0 Foundation This release — the chat loop, streaming, persistence, MCP, HITL approvals.
v1 Cameron is born Persona, transaction schema, core finance tools, seed data. "Meet Cameron."
v2 Memory Budgets and preferences as long-term memory; summarization of aging history.
v3 External data A standalone bank MCP server Cameron consumes as a client.
v4+ Skills → self-extension Skills, document ingestion, evals, autonomy, channels, delegation, and eventually Cameron writing its own capabilities.

Quick Start

Prerequisites

  • Node.js 18+ and pnpm
  • Docker (for PostgreSQL and MinIO)
  • OpenAI API key, Google AI API key, or Anthropic API key

1. Clone and Install

git clone https://github.com/agentailor/cameron.git
cd cameron
pnpm install

2. Environment Setup

cp .env.example .env.local

Edit .env.local with your configuration:

# Database
DATABASE_URL="postgresql://user:password@localhost:5544/mydb?schema=public"

# AI Models (choose one or more)
OPENAI_API_KEY="sk-..."
GOOGLE_API_KEY="..."
ANTHROPIC_API_KEY="sk-ant-..."

# Optional: Default model
DEFAULT_MODEL="gpt-4o-mini"  # or "gemini-1.5-flash" or "claude-sonnet-4-5"

3. Start Services

docker compose up -d  # Starts PostgreSQL and MinIO

4. Database Setup

pnpm db:migrate   # apply migrations (or `pnpm db:push` to sync schema in dev)

5. Run Development Server

pnpm dev            # serves on http://localhost:3100
# Or override the port
pnpm dev --port=3200

Visit http://localhost:3100 to start chatting with Cameron!

Screenshots

Chat Interface
Main Chat Interface
Clean, responsive design with streaming responses
MCP Configuration
MCP Server Management
Easy setup and configuration of tool servers
Thread Management
Thread Management
Organize conversations with persistent history
Streaming Response
Agent Configurations
Multiple model Providers Support

Usage Guide

Adding MCP Servers

  1. Navigate to Settings - Click the gear icon in the sidebar
  2. Add MCP Server - Click "Add MCP Server" button
  3. Configure Server:
    • Name: Unique identifier (e.g., "filesystem")
    • Type: Choose stdio or http
    • Command: For stdio servers (e.g., npx @modelcontextprotocol/server-filesystem)
    • Args: Command arguments (e.g., ["/path/to/allow"])
    • URL: For HTTP servers

Add MCP Server MCP server configuration form with example filesystem server setup

Want to build your own MCP server? Check out create-mcp-server - scaffold production-ready MCP servers in seconds with TypeScript, multiple frameworks (MCP SDK or FastMCP), and built-in debugging tools.

Example MCP Server Configurations

Filesystem Server (stdio)

{
  "name": "filesystem",
  "type": "stdio",
  "command": "npx",
  "args": ["@modelcontextprotocol/server-filesystem", "/Users/yourname/Documents"]
}

HTTP API Server

{
  "name": "web-api",
  "type": "http",
  "url": "http://localhost:8080/mcp",
  "headers": {
    "Authorization": "Bearer your-token"
  }
}

Note: Some HTTP MCP servers require OAuth 2.0 authentication. See OAuth Documentation for details.

Tool Approval Workflow

Only mutating tools pause for approval (log_expense, import_transactions_csv); read-only and MCP tools execute directly.

  1. Agent Requests a Mutating Tool - Cameron proposes a write (e.g. logging a transaction)
  2. Approval Prompt - Interface shows the tool details and asks for approval
  3. User Decision:
    • Allow: Execute the tool as requested
    • Deny: Skip execution; Cameron acknowledges nothing was changed
  4. Continue Conversation - Cameron responds with the tool result

Architecture

High-Level Overview

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   Next.js UI   │◄──►│  Agent Service   │◄──►│  LangChain      │
│   (React 19)   │    │  (SSE Streaming) │    │ createAgent     │
└─────────────────┘    └──────────────────┘    └─────────────────┘
         │                       │                       │
         ▼                       ▼                       ▼
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   React Query   │    │  Repositories    │    │  MCP Clients    │
│   (State Mgmt)  │    │ (Drizzle → PG)   │    │   (Tools)       │
└─────────────────┘    └──────────────────┘    └─────────────────┘
                                │
                                ▼
                  ┌──────────────────────────────┐
                  │   PostgreSQL  │  MinIO/S3    │
                  │  (Persistence)│ (File Store) │
                  └──────────────────────────────┘

Core Components

Agent Factory (src/lib/agent/index.ts)

  • Builds the agent with LangChain v1's createAgent (a prebuilt ReAct agent over LangGraph)
  • Installs humanInTheLoopMiddleware to gate mutating tools (approval); approveAllTools skips it
  • Assembles the model (createChatModel), built-in + MCP tools, and the system prompt

MCP Integration (src/lib/agent/mcp.ts)

  • Dynamic tool loading from database-stored MCP servers
  • Support for stdio and HTTP transports
  • Tool name prefixing for conflict prevention

Streaming Service (src/services/agentService.ts)

  • Server-Sent Events for real-time responses
  • Message processing and chunk aggregation
  • Tool approval workflow handling

Chat Hook (src/hooks/useChatThread.ts)

  • React Query integration for optimistic UI
  • Stream management and error handling
  • Tool approval user interface

File Storage (src/lib/storage/)

  • S3-compatible storage with MinIO (development) or AWS S3 (production)
  • File validation, upload, and content processing for AI
  • Multimodal message building with base64 conversion

For detailed architecture documentation, see docs/ARCHITECTURE.md.

API Documentation

The app serves an interactive OpenAPI 3.1 explorer at /api-docs and the raw spec at /api/openapi — generated from per-route Zod schemas. See docs/API.md for how it works and how to document new routes.

Development

Available Scripts

pnpm dev                 # Start development server with Turbopack
pnpm build              # Production build
pnpm start              # Start production server
pnpm lint               # Run ESLint
pnpm format             # Format with Prettier
pnpm format:check       # Check formatting

# Database (Drizzle)
pnpm db:generate        # Generate a migration after editing schema.ts
pnpm db:migrate         # Apply pending migrations
pnpm db:push            # Push schema directly (dev convenience)
pnpm db:studio          # Open Drizzle Studio (database UI)

Project Structure

src/
├── app/                 # Next.js App Router
│   ├── api/            # API routes (stream, upload, mcp-servers)
│   └── thread/         # Thread-specific pages
├── components/         # React components
├── hooks/              # Custom React hooks
├── lib/                # Core utilities
│   ├── agent/          # Agent-related logic
│   └── storage/        # File upload & S3 utilities
├── lib/
│   ├── database/       # Drizzle schema.ts + db.ts client
│   └── repositories/   # DB access seam (thread + mcpServer repositories)
├── services/           # Business logic
└── types/              # TypeScript definitions

drizzle.config.ts       # Drizzle Kit config (schema path, migrations dir)

Key Files

  • Agent Configuration: src/lib/agent/index.ts, src/lib/agent/mcp.ts
  • Agent Persona: src/lib/agent/prompt.ts
  • API Endpoints: src/app/api/agent/stream/route.ts, src/app/api/agent/upload/route.ts
  • File Storage: src/lib/storage/ (validation, upload, content processing)
  • Database: src/lib/database/schema.ts (Drizzle schema), src/lib/repositories/ (access seam)
  • Main Chat Interface: src/components/Thread.tsx, src/components/MessageInput.tsx
  • Streaming Logic: src/hooks/useChatThread.ts

Contributing

Contributions and issues are welcome — Cameron is developed in the open.

Getting Started

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes
  4. Commit: git commit -m 'Add amazing feature'
  5. Push: git push origin feature/amazing-feature
  6. Open a Pull Request

Development Guidelines

  • Follow TypeScript strict mode
  • Use Prettier for formatting
  • Add JSDoc comments for public APIs
  • Test MCP server integrations thoroughly
  • Update documentation for new features

Learning Resources

LangGraph.js

Model Context Protocol (MCP)

Next.js & React

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments


Follow Cameron as it grows, one release at a time.

Get Started


If this repo helped you and you’d like guidance implementing it in production, feel free to reach out on LinkedIn.

About

Cameron — a personal finance agent you own and run yourself. Built in public alongside the Agentailor blog, one tagged release per article.

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors