# How the League App Drafts Email Replies for a Person to Send

> The youth league app now reads the league's inbox, and Claude, an AI model, drafts replies that a person approves and sends. What it may do, and why sending stays with a person.

By Conner Contreras, ShirePath Solutions. Published 2026-11-03.
Source: https://shirepathsolutions.com/blog/inbox-assistant-for-a-youth-league

Families write to the league's info@ address all season. They ask about game schedules and weather calls, registration, payments, coaching and volunteering, rosters, picture day, and uniforms. I answer that mail, and much of it can be answered from records the league app already holds or from answers the league has written before.

Since the evening of October 25, the app that runs the league, [Advantage Sports](https://shirepathsolutions.com/work/advantage-sports), reads that inbox. Claude, an AI model, sorts each new message by who needs to handle it and drafts a reply when one is needed. I read every draft before it goes anywhere, and I send every reply myself from Outlook.

## What the assistant is allowed to do

Each limit below is in the code, and the most important ones are checked by tests that fail the build.

**It can read mail and write drafts, and it cannot send.** The app connects to the league's Microsoft 365 mailbox with permission to read and change mail, which is what it needs to write drafts and tag messages. It never asked for permission to send, so Microsoft would refuse a send even if the app tried one.

**There is no send call in the code.** The app's mailbox code has no way to send mail. A test fails the build if any inbox code imports the app's own email or text senders, or names one of Microsoft's calls that send right away: send, reply, reply all, or forward. A later change cannot start sending without that test failing first.

**Some subjects always come to me.** Before the model sees a message, fixed rules check it for refunds and money disputes, injuries and safety, harassment or abuse, complaints, legal questions or a reporter, and custody. A thread with more than one family on it also comes to me, and so does mail from league staff that needs an answer. When a rule matches, the thread goes to the inbox owner whatever the model decides. Nothing in a message can talk the assistant out of a rule, because the rules are plain code that runs before the model is called.

**Message text is treated as data.** Each message is marked off as message text when it is handed to the model. The model also has no tool that writes, changes, or sends anything, so an instruction hidden in a message could not make it do any of those things.

**It looks things up read-only, and only for the sender's family.** To draft a reply, Claude can look up the family's balance, schedule, team, waitlist spot, and uniform status, plus the league's public schedule, standings, policies, and a set of answers I have approved. Every lookup only reads. The model never chooses which family to look up; family lookups reach only the family the app matched the sender to. Those lookups leave out birth dates, home addresses, phone numbers, and medical, insurance, and waiver details. Balances come from posted payment totals, and a second test fails the build if inbox code touches the league's Zelle records.

**Gaps are marked, and unsupported claims are flagged.** When a question has no answer in any lookup, the draft leaves a marked gap where the answer belongs. Approval is refused while any gap remains, so a reply never reaches Outlook with a blank in it. Each claim the draft lists is checked against the lookups that were actually made and the league's own reference text, and every dollar amount in the reply must appear in one of those. Anything without a source is flagged for me.

**Some mail never reaches the model.** Mail from banks, vendors, bulk senders, and automated senders is kept only as a record that it arrived, without its text, and is never sent to Claude. Mail that Outlook sorts into its Other tab is not stored at all.

**Only the owner sees it, and the owner approves every draft.** The assistant's pages open only for the inbox owner, which is me. Every other account, league admins included, gets a not-found page. A draft reaches Outlook only when I approve it, as a reply in the league's Drafts folder, and the message it answers is tagged "AI drafted" in Outlook. If I change the draft in Outlook, the app sees the edit and never writes over it. Then I send it from Outlook, the way I always have.

**Replies go back to the person who wrote.** A reply that carries family details goes to the address that wrote in, or to the family's email on file when the app matched the family from what the message says. It never goes to another address the message asks for. The app never replies to everyone on a thread.

**Spending and storage have limits.** There is a daily cap on what the assistant can spend on the model, and when it is reached, sorting pauses until the next day. Every model call writes an audit row with the model, the cost, and what the call was for. The text of messages and drafts is deleted after 90 days.

## An invented example

Here is an invented example; no real message is quoted:

> (Invented message) Hi, what time is our game this Saturday? Also, can my son wear his jersey from last season, or do we need a new one?

No fixed rule matched, and Claude sorted it as a schedule question the league's records can answer. It looked up the family's schedule and searched the approved answers, and none of them covered last season's jerseys.

> (Invented draft) Hi, thanks for writing. Your Saturday game starts at 9:00 a.m. on Field A. [ANSWER: whether a jersey from last season is allowed] See you Saturday.

The game time came from the schedule lookup, so it passed the claim check. Nothing answered the jersey question, so the draft left a gap and approval stayed off. I would type the answer, approve the draft, and it would land in Outlook for me to send.

## How it fits together

A scheduled job checks the inbox every five minutes through Microsoft Graph, asking only for what changed since the last check. New mail becomes work for the same background worker that reads check deposits: one job sorts a thread, and another drafts the reply. Threads, drafts, and an audit row for every model call live in the league's Postgres database, and Claude is called through Anthropic's API.

After I send an approved draft, the next check sees it in Sent Items, and the app compares what I sent with what it drafted. The [drawing on the case sheet](https://shirepathsolutions.com/work/advantage-sports) shows where each piece runs.

## What the first days looked like

These are early numbers from about nine days of live mail, as of November 3, 2026.

- From October 25 to November 3 it sorted 67 new threads, and none of its sorting calls failed. It also went back through older mail from before it was connected.
- Of the 232 threads sorted so far, older mail included, 91 came to me as the owner, 43 of them because a fixed rule required it. Another 76 needed no reply.
- It wrote 72 drafts. I approved 29, and 28 of those have been sent from Outlook.
- The app compares each live draft with the reply that actually went out. Of 31 compared so far, 15 were sent as drafted, 9 partly matched, and 7 were different.
- A draft is ready a median of about three minutes after a message arrives. For drafts I approved, the median from arrival to sent was about four hours.
- Live model cost was $13.29 from October 25 to November 3, about $1.48 for each day it made calls.

## Why it does not send on its own

Alongside the live inbox, I replayed past questions the league had already answered. For each one, the app drafted a reply as if the question were new, and a separate Claude call compared the draft with the reply that was actually sent. In the larger of two runs, across 798 past questions, the draft matched what was actually said only 9 times. Another 468 partly matched, 321 said something different, and 267 drafts contradicted the real reply somewhere.

The live drafts did better, with 15 of 31 sent as drafted, but that is a small sample from nine days of mail. Even a good draft needs someone who knows the league to read it, which is why I approve and send every reply. Auto-send is not on, and those replay numbers are the reason.

Drafting is being tuned release by release. The newest round went into production on October 31, too recently to say what it changed.

The league's email blasts follow the same pattern: Claude Code, Anthropic's AI coding tool, writes blast drafts into the app through the app's own API, and an admin reviews and sends each one.

The assistant does the sorting and writes the first draft, and I still read, approve, and send every reply.
