Skip to content

Not-Aryan/sched

Repository files navigation

Sched

AI scheduling agent. CC it into an email thread and it coordinates a meeting — checks your calendar, proposes times, and books when confirmed.


How It Works

  1. You're emailing someone about meeting up
  2. CC sched-agent@agentmail.to into the thread
  3. The agent reads the conversation, checks your Google Calendar, and proposes 2-3 times
  4. The other party replies to pick a time
  5. The agent creates the calendar event and confirms to everyone
You                  Guest                Agent
 │                     │                    │
 │── email ───────────>│                    │
 │<──── reply ─────────│                    │
 │── reply + CC agent─>│───────────────────>│
 │                     │                    │── check calendar
 │                     │<── propose times ──│
 │                     │── "Tuesday works"─>│
 │                     │                    │── create event
 │<── "Booked!" ───────│<── "Booked!" ──────│

The agent only manages your calendar. Guests don't need accounts.

Onboarding

Email the agent directly for the first time and it sends a Google Calendar OAuth link. Once connected, it can manage your calendar.


Tech Stack


Project Structure

File Purpose
src/index.ts Hono server, webhook handler, routing logic
src/agent.ts Claude agent — system prompt, email processing, tool wiring
src/tools.ts MCP mail tools (reply, save_preferences)
src/composio.ts Google Calendar integration via Composio
src/mail.ts AgentMail client wrapper
src/onboarding.ts Onboarding flow — welcome email + OAuth link
src/onboarding-tools.ts Onboarding-specific agent tools
src/utils.ts Email parsing, participant classification
src/types.ts Shared types and thread formatting
src/db.ts Prisma client

Setup

1. Install

npm install

2. Environment Variables

Create a .env file:

Variable Required Description
AGENTMAIL_API_KEY Yes From AgentMail
COMPOSIO_API_KEY Yes From Composio
CLAUDE_CODE_OAUTH_TOKEN Yes Claude Code OAuth token (or ANTHROPIC_API_KEY)
INBOX_USERNAME Yes Inbox name (e.g. sched-agent -> sched-agent@agentmail.to)
WEBHOOK_URL Yes Webhook URL (ngrok for local, Railway URL for prod)
DATABASE_URL Yes PostgreSQL connection string (pooled)
DIRECT_URL Yes PostgreSQL direct connection string
PORT No Default 3000

3. Local Development

# Terminal 1: expose localhost
ngrok http 3000

# Terminal 2: dev server (auto-restarts on changes)
npm run dev

Set WEBHOOK_URL in .env to the ngrok HTTPS URL. The server registers the inbox and webhook on startup.


Deployment (Railway)

The app is deployed on Railway as a long-running Node.js service using Docker.

Why Railway over Vercel

The Claude Agent SDK spawns a subprocess that can run for 30+ seconds per request. Vercel's serverless functions time out too quickly. Railway runs the app as a persistent server — no timeout issues.

Dockerfile

The Dockerfile handles:

  • OpenSSL for Prisma
  • Non-root user — Claude Code refuses to run as root (security restriction)
  • Prisma client generation at build time

Deploy

# Install Railway CLI
npm i -g @railway/cli

# Login
railway login

# Init project (first time)
railway init

# Deploy
railway up

Environment Variables

Set all env vars from the table above on Railway:

railway variables set KEY=value ...

Set WEBHOOK_URL to https://<your-app>.up.railway.app/webhooks.

Public Domain

railway domain

Scripts

Command Purpose
npm run dev Dev server with file watching
npm start Production server
npm run chat CLI chat with the agent (no email)
npm run simulate E2E simulation with real AgentMail

API

  • GET / — Health check
  • POST /webhooks — AgentMail webhook (message.received)
  • POST /users — Register a new user
  • GET /oauth/callback — Composio OAuth redirect

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors