https://conferenceagent.vercel.app
An AI agent that automatically compiles a table of major conferences. Includes
website links, color-coded prior and upcoming submission deadlines and dates, and
biweekly updates (every two weeks).
Keeps it searchable in a web table, and exports each conference's deadlines and dates
as a subscribable calendar feed (.ics). Discovery is seeded across medicine,
genomics/bioinformatics, and data science; see TAXONOMY.md
for the field map and SEED_CONFERENCES in config.py to add more.
conda activate conference_agent
pip install -e ".[dev]" # core + test tooling
pip install -e ".[discover]" # discovery agent helpers
pip install -e ".[web]" # FastAPI web table + calendar feedconference-agent discover --subcategory radiology --email # find + store (+ email summary)
conference-agent list # print the stored table
conference-agent serve # launch the web table at :8000To enter or correct dates by hand — no API, no discovery agent — use
conference-agent add. The flags mirror the table columns (the only extra is
--url, the link behind the conference name); dates are ISO YYYY-MM-DD, and the
submission/conference month columns are derived from the dates automatically. By
default only the fields you supply are written, so an existing series keeps the
rest of its data:
# Add (or update) a single conference via flags.
conference-agent add \
--conference "RSNA - Radiological Society of North America Annual Meeting" \
--subcategory radiology "machine learning" \
--format abstract poster oral \
--location "Chicago, IL" \
--attendance 39000 --attendance-year 2025 \
--remote-option hybrid \
--cost "\$1,095 (member, early-bird)" \
--abstract-due 2026-05-06 \
--conference-dates 2026-11-29 2026-12-03 \
--url https://www.rsna.org/annual-meetingThe Size column (large / medium / small) is derived automatically from
--attendance — there is no size flag to set. A figure of 1,000+ is large,
100–999 medium, under 100 small; with no attendance, size is left blank. (The
thresholds live in conference_agent/models.py.)
--conference takes the table's first column verbatim — ACRONYM - Full Name.
A bare acronym (or the ACRONYM - Full Name form) that matches a row already in
the table counts as a match: the command shows that entry and asks you to confirm
before updating it, so a typo can't silently overwrite an existing series. Pass
-y/--yes to skip the prompt (required when running unattended). If the series
already exists, the command updates only the fields you pass — add --overwrite
to replace the whole row instead, clearing anything you omit.
To load several at once, point --csv at a file whose header columns are the same
column names as the flags — conference, subcategory, format, location,
attendance,
attendance_year, attendance_source, remote_option, cost, abstract_due,
paper_due, conference_dates, url — with one conference per row (the derived
size and category columns, as in a table export, are accepted but ignored).
conference_dates is a single cell holding the start
and (optional) end date separated by a space, and a multi-value subcategory or
format (any of abstract / paper / poster / oral) is quoted
so its comma stays inside one cell. The broad category is derived from the
subcategory automatically, so you never set it. The raw stored field names
(acronym, name, upcoming_start_date, …) are also accepted, so the web
table's "Export CSV" re-imports unchanged.
conference-agent add --csv my_conferences.csvconference,subcategory,location,attendance,remote_option,abstract_due,conference_dates,url
RSNA - Radiological Society of North America,radiology,"Chicago, IL",45000,hybrid,2026-05-06,2026-11-29 2026-12-03,https://www.rsna.org/annual-meeting
SPR - Society for Pediatric Radiology,"radiology, pediatrics","Austin, TX",1200,in-person,2025-12-01,2026-05-12 2026-05-16,https://www.pedrad.org
MICCAI - Medical Image Computing & Computer Assisted Intervention,"radiology, machine learning","Daejeon, South Korea",3500,hybrid,2026-03-05,2026-09-23 2026-09-27,https://miccai.orgDiscovery re-runs on three cadences: daily the targeted auto-check
(--cadence due — only series whose next edition is plausibly about to be
announced, each re-checked at most every RECHECK_INTERVAL_DAYS (14) days),
weekly the flagship fields (--cadence weekly), and monthly the rest
(--cadence monthly). The "due" auto-check is gated by a last_checked column,
so it needs a persistent CONFERENCE_DATABASE_URL to work across runs.
These cadences are scheduled in the AWS SAM stack via EventBridge Scheduler
rules that invoke a refresh Lambda (web/refresh_handler.py); enable them by
deploying with EnableScheduledRefresh=true (see DEPLOY_AWS.md). They replaced
the former .github/workflows/{weekly_update,monthly_update,auto_check}.yml cron
workflows. You can also run any cadence locally with daily_update.py (below).
See TAXONOMY.md for the field map and cadence policy.
If you want to refresh on demand (outside of the scheduled refresh)
— run daily_update.py yourself. By default these use the
claude-code backend (the local claude CLI / your subscription), so no
ANTHROPIC_API_KEY is required:
# Refresh a single field immediately, ignoring the staleness window entirely.
# --subcategory overrides the cadence selection, so the 6–12-month window and the
# 14-day re-check interval do NOT apply — it re-discovers that field right now.
python scripts/daily_update.py --subcategory genomics
# Refresh several fields at once.
python scripts/daily_update.py --subcategory genomics --subcategory radiology
# Refresh everything (every seeded field), also bypassing the due-window gating.
python scripts/daily_update.py --cadence all
# Run the same auto-check the scheduled job runs (only series currently "due").
python scripts/daily_update.py --cadence due
# Add --no-email to skip the summary email; add --backend api to use the
# metered Anthropic API instead of the local claude CLI.For a one-off discovery of a single field without the refresh wrapper:
conference-agent discover --subcategory genomics --emailThe web layer is a read-only, credential-free REST API, so any AI agent or
script that can make an HTTP GET can pull the data directly — no MCP server or
custom integration required. Interactive docs are at
/docs.
| Endpoint | Purpose |
|---|---|
GET /api/search?q=<query>&format=json |
Boolean search; returns the conference rows as JSON (format=csv for a CSV export). |
GET /api/fields |
Self-describing list of queryable fields, aliases, and controlled vocabularies — call this first to learn the query grammar at runtime. |
GET /api/calendar.ics?q=<query> |
The selected conferences as a subscribable iCalendar feed. |
The q parameter uses the same boolean query language as the web table (see
Boolean search below); an empty q matches everything. An
agent that needs to construct valid queries should read /api/fields first,
since it returns the exact field names, aliases, and allowed values the parser
accepts.
Generally no. The REST API above is public, self-documenting (via
/api/fields), and already structured for programmatic use, so scripts, the
Claude Agent SDK, web-fetch-capable models, and the discovery pipeline can all
consume it as-is. An MCP server would mostly be a thin wrapper over these two
endpoints; it is worth adding only to give MCP-client users (e.g. Claude
Desktop / Claude Code) a one-click, typed search_conferences tool without
each writing their own HTTP integration. For everything else, point the agent
at /api/fields and /api/search.
- Discover —
discover.pyruns an Anthropic web-search loop (research) then a structured-output call (extraction) to produce typedConferencerecords. A seed list of well-known conferences (SEED_CONFERENCESinconfig.py) bootstraps the search; the reference pages those seeds were compiled from are recorded alongside it inSEED_CONFERENCE_SOURCES. - Store — records are upserted into a SQL database, idempotent on the acronym, so re-running discovery rolls a newly announced edition into the "upcoming" columns instead of duplicating the row.
- Search — a web table (
conference-agent serve) supports a boolean query language, a "Subscribe (.ics)" calendar feed, and a per-row "📅 cal" button that downloads that conference as a calendar file. - Calendar — each conference's upcoming abstract deadline, paper deadline,
and conference dates are served as a credential-free iCalendar feed
(
GET /api/calendar.ics) that mirrors the active search. A user subscribes from any calendar app (Google "Add by URL", Apple/Outlook "Add from URL") or downloads a one-off.ics— no sign-in, no Google account. Each event carries a stable id, so re-fetching updates events in place rather than duplicating, plus reminders four weeks, one week, and one day ahead. - Notify — an optional email summarizes a discovery / daily refresh.
The web table accepts queries like:
(virtual OR hybrid) AND size:largesubcategory:radiology NOT cost:*category:medicine AND size:largeformat:poster AND format:oralupcoming:>=2026-06-01
Fields support field:value, field:"quoted value", presence tests (field:*),
date comparisons (>, >=, <, <=, =), AND/OR/NOT, and parentheses.
The "✨ Ask" box turns a plain-English request — "big radiology conferences between September and January" — into the boolean query above, then drops it into the search box (visible and editable) and runs it. The translation runs on a free, local Ollama model — no API key and no external network call — and the model's output is validated against the real parser (with one repair round) before it is shown.
It is entirely optional: if no local model is running, the box reports that and the manual boolean search keeps working. To enable it:
# one-time: install Ollama, then pull a small instruction model
ollama pull qwen2.5:1.5b # the default; tiny and fast
ollama serve # if not already running as a serviceGET /api/translate?q=<plain English> returns the compiled {"query": ...}.
The default qwen2.5:1.5b is the lightest option and handles direct requests
well, but it can stumble on multi-step phrasing — e.g. a wrap-around month range
like "September through January of any year." A larger model translates those
more reliably; point CONFERENCE_NL_QUERY_MODEL at one you have pulled:
CONFERENCE_NL_QUERY_MODEL=llama3.2:3b conference-agent serve # or qwen2.5:7bANTHROPIC_API_KEY— required only for theapidiscovery backend. The defaultclaude-codebackend uses the localclaudeCLI / your Claude Code subscription and needs no key (for unattended runs it usesCLAUDE_CODE_OAUTH_TOKENfromclaude setup-tokeninstead).SMTP_HOST/SMTP_PORT/SMTP_USER/SMTP_PASSWORDandCONFERENCE_NOTIFY_EMAIL— optional, enable the summary email.CONFERENCE_DATABASE_URL— optional, overrides the default SQLite location.OLLAMA_BASE_URL(defaulthttp://localhost:11434),CONFERENCE_NL_QUERY_MODEL(defaultqwen2.5:1.5b), andCONFERENCE_NL_QUERY_TIMEOUT— optional, configure the local model used for plain-English search.
The live site is a static bundle served directly on Vercel — no per-request compute and no AWS in the request path. Snapshot the catalog and publish:
python scripts/build_static.py # snapshot DB + UI into dist/
( cd dist && npx vercel deploy --prod --yes ) # publish to conferenceagent.vercel.appSearch, sort, CSV export, and per-row .ics download all run client-side over
the JSON snapshot. Cloudflare Pages (npx wrangler pages deploy dist) is an
equivalent static host. See DEPLOY.md.
Legacy AWS path (no longer the deploy target). The web table can also run as a FastAPI app on AWS Lambda + RDS PostgreSQL via the SAM template in
infra/(pip install -e ".[web,deploy]"; cd infra && sam build && sam deploy --guided). It is kept as a dynamic-backend alternative — see DEPLOY.md.
To test locally:
python -m conference_agent.cli servethen follow URL
MIT