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.
Complete agent workflow: user input → tool approval → execution → streaming response
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:
- Cameron never moves money or mutates financial records without explicit human approval.
- Every capability — built-in, skill, connector, or self-written — passes through the same approval gate.
- All financial data stays on infrastructure the owner controls.
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.
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:
Happy to jump on a short call.
- 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
- 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
- LangGraph checkpointer with PostgreSQL backend
- Full conversation history preservation
- Thread-based organization
- Seamless resume across sessions
- 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
- Server-Sent Events (SSE) for live responses
- Optimistic UI updates with React Query
- Type-safe message handling
- Error recovery and graceful degradation
- Provider and model selection saved to
localStorageautomatically - Settings survive page reloads and thread navigation
- No backend required — zero latency reads on startup
- 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_ENABLEDenv var — zero overhead when disabled - See docs/OBSERVABILITY.md for setup instructions
- 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
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. |
- Node.js 18+ and pnpm
- Docker (for PostgreSQL and MinIO)
- OpenAI API key, Google AI API key, or Anthropic API key
git clone https://github.com/agentailor/cameron.git
cd cameron
pnpm installcp .env.example .env.localEdit .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"docker compose up -d # Starts PostgreSQL and MinIOpnpm db:migrate # apply migrations (or `pnpm db:push` to sync schema in dev)pnpm dev # serves on http://localhost:3100
# Or override the port
pnpm dev --port=3200Visit http://localhost:3100 to start chatting with Cameron!
- Navigate to Settings - Click the gear icon in the sidebar
- Add MCP Server - Click "Add MCP Server" button
- Configure Server:
- Name: Unique identifier (e.g., "filesystem")
- Type: Choose
stdioorhttp - Command: For stdio servers (e.g.,
npx @modelcontextprotocol/server-filesystem) - Args: Command arguments (e.g.,
["/path/to/allow"]) - URL: For HTTP servers
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.
{
"name": "filesystem",
"type": "stdio",
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/Users/yourname/Documents"]
}{
"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.
Only mutating tools pause for approval (log_expense, import_transactions_csv); read-only and MCP tools execute directly.
- Agent Requests a Mutating Tool - Cameron proposes a write (e.g. logging a transaction)
- Approval Prompt - Interface shows the tool details and asks for approval
- User Decision:
- ✅ Allow: Execute the tool as requested
- ❌ Deny: Skip execution; Cameron acknowledges nothing was changed
- Continue Conversation - Cameron responds with the tool result
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 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) │
└──────────────────────────────┘
- Builds the agent with LangChain v1's
createAgent(a prebuilt ReAct agent over LangGraph) - Installs
humanInTheLoopMiddlewareto gate mutating tools (approval);approveAllToolsskips it - Assembles the model (
createChatModel), built-in + MCP tools, and the system prompt
- Dynamic tool loading from database-stored MCP servers
- Support for stdio and HTTP transports
- Tool name prefixing for conflict prevention
- Server-Sent Events for real-time responses
- Message processing and chunk aggregation
- Tool approval workflow handling
- React Query integration for optimistic UI
- Stream management and error handling
- Tool approval user interface
- 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.
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.
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)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)
- 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
Contributions and issues are welcome — Cameron is developed in the open.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Commit:
git commit -m 'Add amazing feature' - Push:
git push origin feature/amazing-feature - Open a Pull Request
- Follow TypeScript strict mode
- Use Prettier for formatting
- Add JSDoc comments for public APIs
- Test MCP server integrations thoroughly
- Update documentation for new features
This project is licensed under the MIT License - see the LICENSE file for details.
fullstack-langgraph-nextjs-agent— the starter Cameron's v0 foundation is seeded from- LangChain for the incredible AI framework
- Model Context Protocol for the tool integration standard
- Next.js team for the amazing React framework
Follow Cameron as it grows, one release at a time.
If this repo helped you and you’d like guidance implementing it in production, feel free to reach out on LinkedIn.






