## Inspiration
I'm a junior at the University of Maryland. I have ten different portals — Testudo, ELMS, Handshake, Starfish, Financial Aid, CAPS, Stamp, ShopUMD, Bursar, Career Center — and I still miss deadlines and never know what help exists.
The data is all there. It just lives behind ten different login screens nobody opens.
But every UMD student already lives in one app: iMessage. So we built terp4you — not a portal, not another download. An iMessage conversation, and a phone number that actually answers. A single Claude brain that knows your schedule,
your assignments, your money, your advisor's flag on you, and where the Counseling Center walk-ins are open until.
## What it does
terp4you is every UMD student's personal assistant, delivered across three surfaces with one shared brain:
- iMessage — text the gray bubble like a friend. "yo what's due this week and what should I start first." It calls the right tools, factors in your late-submission history, and texts back in your voice.
- Phone — a real number, +1 (443) 441-0081. Pick up, talk to it. "Where do I go if I'm stressed?" It speaks back the CAPS walk-in hours, building, and after-hours line.
- Web dashboard — streams every tool call live. You watch terp4you think, query your data, and remember new facts.
The /connect onboarding page lets a student tap to authorize 12 integrations — Canvas/ELMS, Gmail/terpmail, Google Calendar, Handshake, Starfish, ShopUMD, Spotify, Venmo, Apple Health, GitHub, Testudo SIS, and a live UMD-buildings index
— and instantly synthesizes a profile of themselves: GPA, hardest deadline, recruiter heat, sleep trend, advisor flag, money state. The more you connect, the sharper every reply becomes.
## How we built it
- Brain. Claude Opus 4.7 with 8 tools —
get_schedule,get_assignments,get_resume,find_jobs,find_umd_resource,find_scholarships,remember,search_umd_web. Per-conversation history (Map keyed by handle, capped at 20 turns) so context survives across iMessage and call turns. - Knowledge base. Firecrawl-scraped 48 live UMD pages — registrar deadlines, CAPS hours, building locations, Iribe rooms, McKeldin library hours, financial-aid scholarships, Stamp dining, shuttle routes, accessibility entrances.
Thesearch_umd_webtool ranks the corpus per query and returns the most relevant snippet for the model to ground answers on. - iMessage bridge. A Node daemon polls macOS
~/Library/Messages/chat.dbevery 1.5 seconds, decodesattributedBodyBLOBs (modern iMessage stops writing to thetextcolumn), POSTs to a Next.js API route, and replies via
AppleScriptosascript. A triple SQL filter and an invisible zero-width self-marker prevent it from ever talking to anyone but the demo thread or replying to its own messages. - Voice. Vapi assistant pointing at a Server URL on our Next.js app — same tools, same brain, lower-latency model (Claude Sonnet 4.6) for sub-second turn-taking.
- Dashboard. Next.js 16 + React 19 + Tailwind v4 + Turbopack. SSE-streamed events render channel pills (voice/sms/iMessage/web), live tool chips, a knowledge memory panel, and a turn-by-turn event log. The
/connectpage is built withmotion, spotlight-cursor cards, animated count-ups, an aurora background, and a 21st.dev / Linear-style nav.
## Challenges we ran into
- Same-Apple-ID iMessage demo. Both my iPhone and Mac were signed into one iCloud, so iPhone-typed messages arrive on the Mac as
is_from_me=1— indistinguishable from Mac-typed ones. We pivoted to a teammate-phone setup with a hard handle whitelist after the daemon briefly auto-replied to incoming messages from friends in group chats. Lesson: never run an "answer everyone" daemon on a personal Mac. - Empty
textcolumn. Modern iMessage stores message content in astreamtyped/NSAttributedStringBLOB rather than thetextcolumn. We wrote a length-prefixed UTF-8 decoder (anchored on the0x2Btypedstream marker) that pulls "Yo" and "Whats due" cleanly out of raw bytes. - Vapi server timeout. Vapi's default
serverRequestTimeoutis 1 second — way too short for a Claude tool-calling round-trip. Once we cranked it to 30s, the brain plugged in. - 90 minutes. Bootstrapping Next.js, scraping UMD via Firecrawl in parallel, wiring Vapi, debugging Full-Disk-Access permissions, and rebranding mid-build — all without breaking a running iMessage demo.
## Accomplishments we're proud of
- A real working iMessage agent that texts back in 2–3 seconds with grounded UMD answers.
- A live phone number that picks up and talks to you with the same brain.
- 48 live UMD pages scraped, indexed, and searchable mid-conversation.
- A
/connectpage that genuinely feels like a real product — aurora gradients, animated count-ups, mouse-tracking spotlights, and a bento "knows about you" panel.
## What we learned
- The fastest path to "feels like magic" is meeting students where they already are — iMessage and a phone number — instead of building yet another portal.
- Tool-calling beats RAG-only. The brain is sharper when it can pick
get_assignmentsand thensearch_umd_webin the same turn. - A hard handle whitelist beats clever filtering, every time.
## What's next for terp4you
- Real OAuth into Canvas/ELMS, terpmail, Handshake, Starfish — replace the mock data layer with live student data.
- Per-student Apple ID provisioning so every Terp can text terp4you, not just one demo line.
- Group-chat terp4you (study groups ask collectively).
- Background agents — daily 8 AM brief, deadline nudges, recruiter triage.
- Campus-wide deploy.
Built With
- python
- supabase
Log in or sign up for Devpost to join the conversation.