おそらくはそれさえも平凡な日々

RSS新着をまとめてMarkdown化するmetabol

https://github.com/Songmu/metabol

このAI Agent時代にエンジニアたちが少なからず自分用のRSSリーダーを開発している雰囲気を感じていますが、私も作ってしまいました。とは言っても、作ったのはリーダーではなく、RSS新着をまとめてMarkdown化してローカル保存してくれるツールです。名付けて metabol。 Feedを食べて蓄える。ただしメタボり過ぎに注意、という所。

やることは、設定ファイル上に一覧されたRSSを読んで、新着をMarkdown化してローカルに保存してくれるだけ。閲覧は別のツールでやれば良い。テキスト化されていれば何でもできる。

取得状態の管理とかもやりたくないので、基本的に指定した日付に対する固定ウィンドウ内の記事を取得するだけにしている。それを日次で動かす想定。

使い方

インストール

ローカルで動かす場合、brew等でインストールできます。内部で mdhq コマンドも使うのでそれもインストールしてください。

$ brew install Songmu/tap/metabol
$ npm install -g @songmu/mdhq

セットアップ

適当なディレクトリで、 metabol init を実行すると metabol.yaml という設定ファイルの雛形が作成されます。

$ metabol init
Created metabol.yaml.

Next steps:
  1. Edit metabol.yaml and replace the example source list.
  2. Install mdhq if needed: npm install --global @songmu/mdhq
  3. Run metabol.

設定ファイルの編集

生成される metabol.yaml を以下のように編集します。ここでは私の2つのブログを対象にしています。ブログURLでも極力RSSを見つけようとしますが、RSSのURL直指定のほうが本当はおすすめです。

timezone でタイムゾーンを、window.daily で取得する区切りの時刻を設定します。これにより、以下の例では実行時に日本時間の前日の朝7時から当日の7時までの間に公開された記事を取得するようになります。catchuptrue にすることで、当日の7時以降から現在までの記事も取得してくれます。

# yaml-language-server: $schema=https://raw.githubusercontent.com/Songmu/metabol/main/schema.yaml

timezone: Asia/Tokyo # Optional, but recommended.
# catchup: false # Include the ongoing window up to the latest feed contents.

window:
  daily: "07:00"

sources:
  - https://songmu.jp/riji/
  - https://blog.song.mu/

その他、 --at オプションで、取得日付を選べたり、 --window-count オプションでまとめて複数日数分の記事を取得することも可能です。

実行例

先の設定ファイルが配置されたディレクトリで metabol を実行してみます。私のブログはそこまで更新頻度が高くないので、50日分まとめて取得してみます。ホスト毎への取得インターバルなどは気をつけているつもりなので、多少時間はかかります。

$ metabol --window-count 50
{"requestedUrl":"https://blog.song.mu/entry/agents-md-and-agent-skills","sourceUrl":"https://blog.song.mu/entry/agents-md-and-agent-skills","path":"blog.song.mu/entry/agents-md-and-agent-skills.md","status":"saved"}
{"requestedUrl":"https://songmu.jp/riji/entry/2026-08-11-codoc.html","sourceUrl":"https://songmu.jp/riji/entry/2026-08-11-codoc.html","path":"songmu.jp/riji/entry/2026-08-11-codoc.md","status":"saved"}
{"requestedUrl":"https://songmu.jp/riji/entry/2026-08-14-voice-input-with-foot-pedal.html","sourceUrl":"https://songmu.jp/riji/entry/2026-08-14-voice-input-with-foot-pedal.html","path":"songmu.jp/riji/entry/2026-08-14-voice-input-with-foot-pedal.md","status":"saved"}
{"requestedUrl":"https://songmu.jp/riji/entry/2026-08-23-tagpr-documentation.html","sourceUrl":"https://songmu.jp/riji/entry/2026-08-23-tagpr-documentation.html","path":"songmu.jp/riji/entry/2026-08-23-tagpr-documentation.md","status":"saved"}
{"requestedUrl":"https://songmu.jp/riji/entry/2026-09-06-mdhq.html","sourceUrl":"https://songmu.jp/riji/entry/2026-09-06-mdhq.html","path":"songmu.jp/riji/entry/2026-09-06-mdhq.md","status":"saved"}

標準出力へのログ出力の通り、5件の記事が取得され、Markdown化されて保存されました。tree コマンドで確認すると、以下のようにディレクトリが作成され、記事が保存されていることがわかります。

$ tree .
.
├── blog.song.mu
│   └── entry
│       └── agents-md-and-agent-skills.md
├── metabol.yaml
└── songmu.jp
    └── riji
        └── entry
            ├── 2026-08-11-codoc.md
            ├── 2026-08-14-voice-input-with-foot-pedal.md
            ├── 2026-08-23-tagpr-documentation.md
            └── 2026-09-06-mdhq.md

6 directories, 6 files

テキストになっているので、あとはAIにサマリを作ってもらったり、翻訳してもらったりもやりやすいはずです。私は毎日新聞的に一枚のMarkdownにまとめてもらうなどしています。

GitHub Actions

metabol はGitHub Actions上で簡単に動かすためのカスタムアクションを提供しています。

まず注意点として、サーバー負荷やコンテンツ著作権の観点から、これを頻度高く、そして、公開リポジトリで動かすことは避けて下さい。

以下は、毎日7時15分に実行し、取得結果をコミットするworkflowの例です。手動で実行する場合は、 workflow_dispatchat 入力を指定することで、任意の日付の取得も可能にしています。

name: Collect feeds
on:
  schedule:
    - cron: "15 7 * * *"
      timezone: Asia/Tokyo
  workflow_dispatch:
    inputs:
      at:
        description: Date selecting the window to process (YYYY-MM-DD)
        type: string
jobs:
  collect:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v7
      - id: metabol
        uses: Songmu/metabol@v0
        with:
          config: metabol.yaml
          root: articles
          timezone: Asia/Tokyo
          catchup: true
          at: ${{ inputs.at }}
      - name: Commit and push articles
        if: ${{ !cancelled() && steps.metabol.outputs.count > 0 }}
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add articles
          if git diff --cached --quiet; then
            exit 0
          fi
          git commit -m "Update articles"
          git push

是非ご利用下さい。

設計思想

取得タイミングなどの状態管理、スケジューラー、SQLiteなどのデータベースを持たない単純なツールを作りたくてこうなった。

内部的にはRSSからURLを抽出する rssnip と、URLから本文を抽出してMarkdown化する @songmu/mdhq を組み合わせたcomposition的な構成になっているのも特徴的だと思う。

RSS回帰(?)の流れ

最近、特にAI関連での情報の流れが早いので、多くの人が改めてRSSを含めた情報収集パイプラインを組み直しているのを感じていますし、私もその一人です。

改めて購読RSSリストをメンテナンスしていこうと思っていますが、おすすめあったら教えてください。

created at
last modified at

2026-09-15T00:55:22+0900

comments powered by Disqus