Inspiration
Applying for a Master's or PhD abroad means emailing dozens of professors, and every email has to show you've actually read their work. You have to find the right professors, find their email addresses, and write each email by hand. It takes weeks, and most students give up after a handful. I built ScholarReach (https://scholarreach.faraz-khan.xyz) to automate that. For this hackathon I turned it into an Alexa+ agent, so the whole job becomes a short conversation.
What it does
ScholarReach MCP is a self-hosted MCP server (spec 2025-11-25, Streamable HTTP) that lets Alexa+, or any MCP host, run a student's professor outreach:
- "Where am I?":
whats_nextremembers every earlier session: emails sent, replies, drafts waiting, professors who haven't replied in 10+ days, and whether Gmail is connected. It answers with the next best step. - "Find professors working on agentic AI in Europe and write to them.":
plan_outreachruns a multi-step workflow in one request. It searches recent papers, ranks professors by fit, skips anyone already emailed in past sessions, discovers email addresses (paper affiliations → ORCID → homepages → web search, 3 lookups in parallel), and writes a personal draft with Gemini that cites the professor's own papers. It streams progress while it works. - "Read me the first one" / "Make it shorter" / "Send it.":
review_drafts,read_email,edit_email,regenerate_email,approve_email. On screens, drafts render as an interactive MCP App review card. - Safe by design: emails go out from the student's real Gmail, so sending always needs an explicit yes through MCP elicitation. The card's Approve button calls an app-only tool the model can't see, and the backend blocks duplicates and honours do-not-contact.
Every tool returns a short speech line written to be read aloud, plus structured data for screens.
What's new during the hackathon
ScholarReach was a web app only. Everything in this repo was built during the submission period: the Alexa+ MCP interface, the one-request plan_outreach workflow (the website needs separate manual steps per professor), cross-session whats_next, the confirm-before-send layer, and the MCP App card. While testing on my live account I also fixed the backend so Gemini drafts keep their paragraph breaks.
How I built it
- Python + MCP Python SDK 2.3 (
MCPServer), served over Streamable HTTP with uvicorn. It negotiates 2025-11-25 (verified with a rawinitializehandshake) and also serves 2026-07-28 clients. - MCP features: tool annotations (read-only / destructive hints), progress notifications, elicitation via the SDK's
Resolve/Elicit(works on both protocol eras), MCP Apps (ui://resource + app-only tool visibility), resources, prompts and server instructions. - Backend: ScholarReach (FastAPI, PostgreSQL on Neon, OpenAlex, ORCID, Europe PMC, CSRankings, Gemini 2.5 Flash, Gmail API) on Vercel.
- End-to-end tests drive the real server with the SDK's MCP client against an in-memory fake API, plus live runs against my own account.
Challenges
- SDK 2.x changes: FastMCP was renamed to
MCPServer, andctx.elicit()fails on 2026-07-28 connections. I switched to resolver-based elicitation, which works on both eras. - Email discovery is slow: about 45 s per professor. The first live run gave up with no drafts. Now
plan_outreachuses known addresses first and looks up the rest in parallel within a time budget. - Gemini dropped line breaks inside a JSON string, so emails read as one block. It now returns a list of paragraphs, and the signature block is added in code.
What I learned
Voice changes the design: answers need to be one or two sentences, one request should do a lot of work, and anything irreversible, like sending an email from someone's Gmail, needs a confirmation the model can't skip.
What's next
OAuth so many students can share one hosted server, reply detection from Gmail, and weekly check-ins ("2 professors replied, 3 drafts waiting").
Built With
- alexa
- fastapi
- gemini
- gmail-api
- httpx
- mcp-python-sdk
- model-context-protocol
- neon
- openalex
- orcid
- postgresql
- pydantic
- python
- uvicorn
- vercel
Log in or sign up for Devpost to join the conversation.