Project Info
Inspiration
Scheduling meetings and managing a busy schedule as students with a lot of commitments is hard. We each manage 3+ calendars, with events ranging from classes, club and work meetings, and dinners with friends. Keeping track of what you're doing and who you're meeting is something that can easily slip through the cracks, and when people reach out over email, it gets even harder navigating back and forth between calendars, mail clients, and your own personal preferences.
What it does
To address this, we built sched, an AI agent that lives in your email and intelligently schedules meetings based on your calendar and what it knows about you and the person requesting to meet. When someone reaches out to you asking to meet, you reply and cc our sched agent, which will then spin up and effectively become your personal executive assistant: intelligently creating an event and invite depending on the urgency of the request (based on both who sends it and the content of the initial email) and your schedule + what sched has learned over time about you (morning/afternoon meeting preference, spacing preferences between meetings, time zones, etc.) and the other user. Sched responds naturally (from its own email) to the inviter with some proposed times, and intelligently handles multi-turn conversations in the thread to come to a time that works for both of you (erring on the side of giving you times that you prefer). If the inviter has a sched account for themself, then sched already knows their preferences and thus performs the entire back-and-forth internally, with no human-to-human conversation needed because your personal agents handle it themselves. Depending on the context of the meeting, sched will either create a Google Meet link for the event or just make a regular calendar event. Sched resides entirely in your email, including the onboarding! Just send an email to sched@agentmail.to and it'll walk you through connecting your calendar and providing any initial preference information (which gets learned additionally over time). While the primary functionality of sched is fully in the email inbox, we've built two web interfaces to make sched even more powerful. The first is an interactive chat and calendar view, where Sched can easily ask you for your permission or opinion on an event it might be scheduling, which it can then learn from and not ask you about in the future. The second is more about the broader implication of the future of agent-to-agent communication for the sake of human meetings: the connection graph. The 3D graph visualizer shows you all the users in your organization and draws weighted edges between people who have met and introduces you to their mutuals, allowing you to directly email them and schedule a time to meet!
How we built it
To build the mail agent, we used the AgentMail API to handle reading incoming emails to a fixed inbox and send the responses to each person. We developed the agent architecture around the Claude Agent SDK and added custom tools to link into the AgentMail sending functions + read/write access to user Google and Outlook calendars via Composio connectors. Our backend is built with Hono in TypeScript and NodeJS, with endpoints for general database access (we used Supabase and the Prisma ORM) as well as webhooks for AgentMail. The frontend visualizer is built with NextJS using the ReactForceGraph library to make the 3d simulated connection graph, with a custom Three.JS shader for the glowing effects.
Challenges we ran into
A major challenge we ran into was latency with the API. For testing purposes, we created a proxy tunnel with ngrok, but we faced major issues with the speed of email reception and sending via AgentMail. We unfortunately don't have much control with how fast the email servers send or recieve emails, but we addressed this by tightening up our agent loop as much as possible to keep the latency that we could control as minimal as possible.
Accomplishments we're proud of
We're very proud of having our agent be intelligent to handle multi-turn conversation with the requester and using the tone as well as user preferences to allow scheduling based on inherent priority of certain events. This is something that differentiates our product from most other calendar assistants because this inherent understanding of what each human involved needs for scheduling is something that is not easy to do unless it's your main focus, which it was for us. We're also very proud of how our agent is proactive at learning its owners preferences correctly. When the agent asks its owner for permission to schedule time, it'll learn the preference and won't ask again unless it makes sense given the context. Especially when the agent is interacting with another user who has their own sched agent, the competing preferences result in the best compromise for both parties.
What we learned
We learned how important maintaining context in multi-turn conversations is, especially when the agents really have motivations to give their owners the preferred time, we see truly smart scheduling behavior where the agents act correctly on the owner's behalf. Additionally, we learned how powerful using connectors is: using Composio to access Google Calendar rather than just using the Google Calendar API or MCP by itself allowed enabling Outlook access to be a 5 minute change rather than a major one.
What's next
Sched currently resides fully in email, which is where most (but not all) meeting scheduling occurs. In order to make Sched a truly useful personal assistant, it should be able to connect to other messaging tools like Slack, iMessage, and more.
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
- You're emailing someone about meeting up
- CC
sched-agent@agentmail.tointo the thread - The agent reads the conversation, checks your Google Calendar, and proposes 2-3 times
- The other party replies to pick a time
- 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
- Runtime: Node.js + TypeScript (ESM)
- Server: Hono
- AI: Claude Haiku 4.5 via
@anthropic-ai/claude-agent-sdk - Calendar: Google Calendar via Composio
- Email: AgentMail
- Database: PostgreSQL (Supabase) via Prisma
- Hosting: Railway
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 checkPOST /webhooks— AgentMail webhook (message.received)POST /users— Register a new userGET /oauth/callback— Composio OAuth redirect
Analysis
View
Metric
- 19
- 13
- 8
- 5
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- CSSIn code
- JavaScriptIn code
- Next.jsIn code
- ReactIn code
- SQLIn code
- SupabaseIn code
- TypeScriptIn code
- AnthropicClaimed
7 of 8 appear in the indexed code. 1 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
- CursorCommits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
113 KB
Source files
26
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
Not-Aryan/sched
41 files · 633 KB · @ 6f3cc0f
Structure
Interface
4 files · 10%Screens, components and styles rendered to the user.
API & routing
1 file · 2%Request entry points: routes, handlers and controllers.
Application logic
12 files · 29%Domain rules, services and shared utilities.
Data & schema
1 file · 2%Schema definitions, migrations and data access.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- TypeScript80%
- Markdown8%
- CSS6%
- JavaScript3%
- SQL1%
- YAML1%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
package.json
npm · 14- @anthropic-ai/claude-agent-sdk
- @composio/claude-agent-sdk
- @composio/client
- @composio/core
- @hono/node-server
- @prisma/client
- agentmail
- dotenv
- hono
- zod
- +4 more
web/package.json
npm · 12- @supabase/supabase-js
- @types/three
- next
- react
- react-dom
- react-force-graph-3d
- three
- +5 more
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.