The AI era’s paper bloom is exhausting to track. If you are tired of endlessly chasing new publications, use this repository to curate a daily recommendation & summary tailored exactly to your vibe.
The recommendation can be produced via two sources (enable either one or both):
Go to your GitHub repository → Settings → Secrets and variables → Actions → Secrets. Then create these secrets as needed:
| Key | Description | Example |
|---|---|---|
RECEIVER |
Required Email address for receiving recommendations. |
reader@example.com |
SENDER |
Required Email account used to send recommendations via SMTP server. |
example@qq.com |
SENDER_PASSWORD |
Required Sender account password or SMTP authentication code. |
app-password-or-token |
SMTP_SERVER |
Required SMTP server of the sender account. Get to know SMTP in English / Chinese. |
smtp.example.com |
SMTP_PORT |
Required Corresponding SMTP server port. |
465 |
OPENAI_BASE_URL |
Recommended OpenAI-compatible LLM API used for summarying paper. If the API is not set, the summary of recommended papers will be the corresponding abstract. You can get FREE API in SiliconFlow for using open source LLMs (e.g., Qwen/Qwen3-8B). |
https://api.siliconflow.cn/v1 |
OPENAI_API_KEY |
Recommended Set corresponding API key if you use API for TLDR summaries. |
sk-... |
ZOTERO_ID |
Recommended Set it when using Zotero Library. Get ZOTERO_ID from Zotero Settings. See steps 1&2 in Zotero API Key Guide. |
1234567 |
ZOTERO_KEY |
Recommended Corresponding Zotero API key with read access. Get ZOTERO_KEY from Zotero Settings. |
zotero-api-key |
EMBEDDING_BASE_URL |
Optional Embeddings API for text matching. Generally leave it empty, since the performance of local embedding model is acceptable. |
https://api.openai.com/v1 |
EMBEDDING_API_KEY |
Optional Set corresponding key if you use Embeddings API. |
sk-... |
APP_CONFIGIn Settings → Secrets and variables → Actions → Variables, create a variable named APP_CONFIG.
[!TIP]
- Keep passwords and API keys in GitHub Secrets, not directly in
APP_CONFIG. The default secret names from step 2 will be read automatically.- You can enable either one or both interest sources: Textual profile and Zotero.
- Below examples show minimal configs for each source. You can add additional parameters by refering to full
APP_CONFIGtemplate inconfig/app.example.jsoncto achieve more customization.
APP_CONFIG:{
"interests": {
"profile": {
"enabled": true,
"summary": "Urban mobility, transport equity, and climate adaptation."
}
}
}
APP_CONFIG:{
"interests": {
"zotero": {
"enabled": true,
"includeCollections": ["2026/survey/**"],
"excludeCollections": ["archive/**"]
}
}
}
The default schedule in .github/workflows/daily.yml is 0 1 * * *, which is 09:00 at UTC+8. To change when the daily workflow runs, edit the workflow cron value directly.
npm install
cp .env.example .env.local
cp config/app.example.jsonc config/app.jsonc
npm run test:config
npm run preview-email
npm run test:feeds:live
For local development, keep non-secret app settings in config/app.jsonc and secrets in .env.local.
npm start -- run
npm run preview-email
npm run setup-profile
npm run test:config
Modes:
run: fetch, match, summarize if enabled, render, and send.preview-email: fetch, match, render HTML, and print it without sending.setup-profile: print a starter profile JSON fragment.test-config: validate that APP_CONFIG, config/app.jsonc, or config/app.json can load.The app supports bundled catalog feeds and direct RSS feeds.
feeds.catalogSelections: names or abbreviations from data/journals.config.ts; empty means all bundled feeds.feeds.customRss: direct RSS entries with name and rss.Run npm run test:feeds:live to smoke-test the current bundled publisher feeds against live RSS. Default tests use fixtures and do not require network access.
Inspired by TideDra/zotero-arxiv-daily.