Always someone at the desk.
Front Desk is a small AI receptionist for your personal website. Most personal sites give visitors a wall and maybe an email address they're nervous to use. This puts a friendly face at the door instead — it says hello, listens, answers what it can, and makes you feel reachable, while quietly noting which conversations are worth your time.
One Python file. No dependencies. You write the rules; it sets the tone.
demo: www.kellyjia.com/front-desk
Visitor → yoursite.com/front-desk → Pikachu → you (for the conversations that matter)
The default receptionist is named Pikachu. Rename it in one flag — see below.
A contact form is a closed door with a mail slot. It asks a stranger to write a cold email to someone they've never met and hope for a reply — so most people don't bother, and you never hear from them at all.
Front Desk lowers that barrier. Anyone can walk up and have a real conversation: ask a question, introduce themselves, get a warm and useful answer on the spot. You become more approachable to everyone — and, at the same time, more selective, because you read the transcripts later and choose which conversations to pick up. No one is turned away at the door; you simply decide what's worth your time.
Front Desk speaks to any OpenAI-compatible API. It points at DeepSeek out of the box (cheap and fast), but a base URL and a model name are all it takes to use any provider you like.
# 1. Hand it your key (DEEPSEEK_API_KEY / OPENAI_API_KEY also work)
export FRONTDESK_API_KEY=«redacted:sk-…»
# 2. (Optional) Point it at a different provider
export FRONTDESK_API_BASE="https://api.your-provider.com/v1" # default: https://api.deepseek.com/v1
export FRONTDESK_MODEL="your-model-name" # default: deepseek-chat
# 3. Give it something to say
cp SOUL.example.md SOUL.md # then edit SOUL.md (see "The Soul" below)
# 4. Open the desk
python3 frontdesk.py
# 5. Let the world in
cloudflared tunnel --url http://localhost:8765Now visit http://localhost:8765/front-desk and say hello to your receptionist.
SOUL.md is the agent's brief — who it works for, what you're open to, and where
the line is. It's just a prompt, so write it like you'd brief a real person on
their first day.
cp SOUL.example.md SOUL.mdOpen SOUL.md and fill in the blanks: replace [PRINCIPAL NAME] with your name
and [AGENT NAME] with whatever you call your receptionist. Be specific about
what you're always glad to hear about and what's better pointed elsewhere — that
warmth and that judgment are the whole job.
The more of yourself you pour into it, the more it sounds like you. Don't stop at a job title — give it your story, your voice, the things you care about. A receptionist who actually knows you makes everyone feel like they've reached the right place.
Edits take effect on restart.
The receptionist answers to Pikachu out of the box. Call it anything:
python3 frontdesk.py --name YourAgentNameThe name shows up in the page title, the header, the greeting, and the footer.
python3 frontdesk.py --port 8080 # port (default: 8765)
python3 frontdesk.py --name YourAgentName # agent name (default: Pikachu)
python3 frontdesk.py --key sk-... # API key on the command line
python3 frontdesk.py --soul desk.md # a different soul filePrefer a file over an environment variable? Drop your key here:
# ~/.frontdesk/.env
FRONTDESK_API_KEY=sk-your-key-hereVisitor opens /front-desk
│
▼
frontdesk.py
├─ loads SOUL.md ............. your rules
├─ calls the LLM .............. OpenAI-compatible API, temp 0.5
├─ trusts nothing ............ sanitizes every message from the browser
├─ rate limits ............... 20 requests / minute / visitor IP
├─ hears a goodbye ........... wraps up and closes the chat
├─ caps the visit ............ auto-closes after 10 messages
└─ writes it down ............ sessions/<id>.json
Every conversation lands in sessions/ as JSON, from the visitor's second
message onward — so even the ones who wander off leave a note behind.
{
"timestamp": "2026-06-28 09:15:00",
"user_messages": 4,
"first_message": "Hi, I'm a startup founder...",
"conversation": [
{"role": "user", "content": "..."},
{"role": "assistant", "content": "..."}
]
}Session files are written owner-only (0600). The folder is git-ignored — your
visitors' words never leave your machine.
sessions/ is just a folder of plain JSON, which means any AI agent can read it
for you. Instead of opening files one by one, hand the day's transcripts to an
agent — Claude Code, a small script calling an LLM, whatever you like — and ask
for a briefing, the way you'd ask a chief of staff "who came by yesterday?"
A prompt like this goes a long way:
Read today's files in
sessions/. Give me a short morning recap: who stopped by, what each person wanted, anything worth following up on, and skip the time-wasters. Flag anyone I'd genuinely want to reply to.
Make it a habit by running it on a schedule. For example, a launchd job or a
cron line that wakes an agent each morning:
# 8am daily — summarize yesterday's visitors into recap-YYYY-MM-DD.md
0 8 * * * cd /path/to/frontdesk && your-agent "Summarize today's sessions/ \
files: who came by, what they wanted, who's worth a reply." \
> "recaps/recap-$(date +\%F).md"Now the front desk doesn't just take messages — it briefs you each morning, and you decide who's worth your time over coffee instead of in the moment.
To run the desk around the clock, hand it to launchd:
# 1. Edit com.example.frontdesk.plist — fix the paths
# 2. Install it
cp com.example.frontdesk.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.example.frontdesk.plistFor a real domain, point a Cloudflare Tunnel at it:
cloudflared tunnel create my-front-desk
# then configure DNS and run it as a servicefrontdesk.sb walls the process off from your home directory — it can read its
own folder and your .env, write to sessions/, and nothing else.
sandbox-exec -f frontdesk.sb python3 frontdesk.pyOne honest caveat: this is filesystem isolation, not network isolation. The
profile uses (allow default), so the process can still reach any host — macOS
sandboxes can't filter outbound traffic by domain. Treat it as a lock on the
filing cabinet, not on the phone line.
The API is OpenAI-compatible — point FRONTDESK_API_BASE at any provider you like.
The default, DeepSeek V3 (deepseek-chat), costs about $0.27/M input tokens, so a
full ten-message visit runs well under a cent. Swap in any model behind an
OpenAI-compatible endpoint — the only thing that changes is the key and the URL.
MIT