Leporello
Opera & classical music event schedule remote MCP. Also available as a web app at leporello.app.
支持的场地
错过你最喜欢的场地?PR欢迎!阅读 贡献.md 有关添加新场地刮板的分步说明。
| 地点 | 城市 |
|---|
斯图加特国家歌剧院 Stuttgart 斯图加特爱乐乐团 Stuttgart Philharmonic |维也纳国家歌剧院|维也纳| |大都会歌剧院|纽约| 法兰克福歌剧院法兰克福 |旧金山歌剧院|旧金山| Gran Teatre del Liceu 巴塞罗那 |森佩罗珀|德累斯顿| |巴黎国家歌剧院|巴黎| |卡内基音乐厅|纽约| |皇家剧院|马德里| 柏林国家歌剧院 Unter den Linden |悉尼歌剧院|悉尼| 巴黎爱乐乐团 Paris Philharmonie 巴伐利亚国家歌剧院 慕尼黑
运作原理
特定场地的抓取器从歌剧院和音乐厅获取日程页面(HTML或JSON),用Cheerio解析它们,并将事件存储在本地SQLite数据库中。节点cron调度器每天03:00 UTC重新抓取所有场馆,用最新数据替换每个场馆的事件。服务器通过 模型上下文协议 (MCP)端点,因此任何兼容MCP的AI助手都可以查询即将到来的性能。静态Astro前端在构建时读取相同的数据库,并在以下位置提供可过滤的事件列表 Leporello.app.
MCP工具
| 工具 | 说明 |
|---|---|
list_countries | 所有有城市/场馆数量的国家 |
list_cities | 所有有场馆的城市,可选择按国家过滤 |
list_venues | 所有场馆,可选择按国家或城市过滤 |
list_events | 按国家、城市或地点筛选的即将举行的活动 |
隐私
托管实例位于 Leporello.app 日志聚合了MCP的使用情况(工具名称、参数、响应时间、用户代理和客户端IP的每日轮换盐哈希),这样我就可以看到哪些有效,哪些无效。没有原始IP,没有个人数据,没有身份验证令牌。
在本地运行
npm install
npm test # run scraper tests
npm run scrape # one-off scrape all venues
#or
npm run scrape -- wiener-staatsoper # scrape a single venue
npm run dev # start server on http://localhost:3000
# or
npm run dev:fresh # scrape, then serve每天03:00 UTC报废。跑 npm run scrape 首次使用时填充数据库。
码头工人
两个容器: 网络 (HTTP服务器+MCP+静态前端)和 爬虫 (将场地数据提取到SQLite中)。它们共享一个数据量。scraper运行一次并退出——用主机cron作业安排它。
# Start the web server
docker compose up -d
# Run all scrapers (one-off, container stops when done)
docker compose run --rm scraper
# Scrape a single venue
docker compose run --rm scraper node dist/scrape.js wiener-staatsoper
# Rebuild the Astro frontend (e.g. after a manual scrape)
docker compose exec web node -e "
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
await promisify(execFile)('npm', ['run', 'build', '--prefix', 'web'], { cwd: '/app', timeout: 60000 });
console.log('done');
"
# Tail logs
docker compose logs -f webweb容器在每次启动时都会重建Astro前端。要按计划运行抓取器,请添加一个抓取然后重新启动web的主机cron作业:
0 3 * * * cd /home/phil/docker/lep && docker compose run --rm scraper && docker compose restart web