A full-stack chat application that lets you interact with your Gmail using AI. Built with React, Express, and Claude AI.
- Chat Interface: Natural language interface to interact with your Gmail
- Email Operations: Read, search, and send emails through conversation
- Label Management: Create and manage Gmail labels
- Streaming Responses: Real-time streaming of AI responses
- Session Persistence: Conversation history preserved across page reloads
- Node.js 18+
- Google Cloud Project with Gmail API enabled
- Anthropic API key
cd oscar
npm install- Go to Google Cloud Console
- Create a new project or select an existing one
- Enable the Gmail API
- Configure OAuth consent screen
- Create OAuth 2.0 credentials (Web application)
- Add
http://localhost:3001/auth/google/callbackas an authorized redirect URI - Note your Client ID and Client Secret
Copy the example environment file and fill in your values:
cp .env.example .envEdit .env:
# Backend
PORT=3001
FRONTEND_URL=http://localhost:5173
# Google OAuth
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=http://localhost:3001/auth/google/callback
# Token encryption (generate with: openssl rand -hex 32)
TOKEN_ENCRYPTION_KEY=your-32-byte-hex-key
# Anthropic API
ANTHROPIC_API_KEY=sk-ant-your-api-key
# Frontend
VITE_API_URL=http://localhost:3001Start both backend and frontend:
# Terminal 1 - Backend
npm run dev:backend
# Terminal 2 - Frontend
npm run dev:frontendOr run both concurrently:
npm run devOpen http://localhost:5173 in your browser.
- Click "Connect Gmail" to authorize the app
- Start chatting! Try:
- "Show me my unread emails"
- "Search for emails from john@example.com"
- "Read the latest email"
- "Send a reply saying I'll get back to them tomorrow"
- "Create a label called 'Important'"
oscar/
├── packages/
│ ├── backend/ # Express + Claude AI backend
│ │ └── src/
│ │ ├── agent/ # Gmail tools for Claude
│ │ ├── routes/ # API endpoints
│ │ └── services/ # Gmail client, token storage
│ │
│ └── frontend/ # React + Tailwind frontend
│ └── src/
│ ├── components/ # UI components
│ ├── hooks/ # React hooks
│ └── store/ # Zustand store
│
├── .env.example
└── README.md
The app requests these Gmail permissions:
gmail.modify- Read and modify emailsgmail.labels- Manage labelsgmail.send- Send emails
- OAuth tokens are encrypted at rest using AES-256-GCM
- No credentials stored in frontend
- CORS restricted to frontend origin
- Session isolation per user
- Frontend: React, TypeScript, Tailwind CSS, Zustand, Vite
- Backend: Express, TypeScript, Anthropic SDK
- APIs: Gmail API, Claude AI