はじめに
エンジニアの皆さん、日々の技術キャッチアップはどうしていますか?
Qiita、Zenn、X (Twitter)、TechCrunch... 巡回するサイトが多すぎて、「情報を追うだけで時間が溶ける」なんてことになっていないでしょうか。
今回は、Anthropicが提供するCLIツール 「Claude Code」 を活用して、以下のフローを全自動化する仕組みを作りました。
- 週3回、朝7時に自動起動(寝ている間に実行)
- ClaudeがWebを検索し、最新のITトレンド記事を収集
- 内容を要約し、重要度でフィルタリング
- Slack に通知(スマホでサクッと確認用)
- Obsidian に保存(ナレッジベース蓄積用)
APIキーの管理や複雑なPythonスクリプトは不要。Claude CodeのCLI機能とシェルスクリプトだけで実装した、"最強の自分専用ニュースフィード" の裏側を解説します。
成果物
📱 Slack通知
朝起きると、厳選された記事の要約が届いています。
URLのプレビュー崩れを防ぐため、専用のフォーマットで見やすく整形しています。
📘 Obsidian保存
ローカルのObsidianには、日付ごとのファイルとしてMarkdownが蓄積されます。
フロントマター付きなので、後からタグ検索やDataviewでの集計も可能です。
システム構成
「Claude Code」を単なるチャットツールとしてではなく、 「パイプラインの一部」 として組み込んでいるのが特徴です。
graph TD
Cron["cron (月水金 7:00)"] --> Script["weekly-it-news.sh"]
subgraph Pipeline ["Claude Code Pipeline"]
Script -->|--print mode| ClaudeSearch["Claude (Web検索 & 整形)"]
ClaudeSearch -->|WebSearch| Internet
ClaudeSearch -->|stdout| RawOutput["整形済みテキスト"]
end
RawOutput -->|awk| Parser
subgraph Outputs
Parser -->|Slack Section| ClaudeSlack["Claude (Slack投稿)"]
ClaudeSlack -->|MCP| SlackApp["Slack #channel"]
Parser -->|Obsidian Section| LocalFile["Obsidian (.md)"]
Parser -->|URL Section| LogFile["重複チェック用ログ"]
end
技術スタック
| 技術 | 役割 |
|---|---|
| Claude Code CLI | 情報収集エンジン + Slack投稿エージェント |
| --print モード | CLI出力をパイプラインで扱うためのモード |
| WebSearch | Claude Code組み込みの検索ツール |
| Slack MCP |
slack_send_message による投稿 |
| bash + awk | 出力のパース・分割・制御 |
| cron | 定期実行トリガー |
実装のポイント:Claude Codeの「2つのモード」使い分け
このシステムの肝は、Claude Codeを用途に合わせて2回呼び出している点です。
1回目:情報収集(--print モード)
claude --print --allowedTools 'WebSearch' << EOF > output.txt
(プロンプト:検索して、整形して出力して)
EOF
-
--print: 結果を標準出力 (stdout) に出すモード。これにより、出力をファイルに保存したりawkで加工したりできます。 -
--allowedTools 'WebSearch': 使えるツールを検索のみに制限し、余計な挙動(ファイル編集など)を防ぎます。 - 注意点: このモードではMCPツール(Slack投稿など)は実行できません。あくまでテキスト生成用です。
2回目:Slack投稿(通常モード)
claude --allowedTools 'mcp__claude_ai_Slack__slack_send_message' --max-turns 3 << EOF
チャンネルID C0AEDCZAECB に投稿して
${SLACK_MESSAGE}
EOF
- 通常モード: ここで初めてMCPツール(Slack)を実行させます。
-
--max-turns 3: 投稿→完了報告で終わるよう、無限ループを防止します。 -
チャンネルID指定: チャンネル名(
#general等)だと解決に失敗することがあるため、ID(Cxxxx)を直接指定するのが安定のコツです。
プロンプトエンジニアリングの工夫
Claudeを「システムの一部」として安定動作させるために、プロンプトにはいくつかの魔術を仕込んでいます。
1. 「パイプラインの一部」であると宣言する
あなたはデータ収集パイプラインの一部です。人間と会話しているのではありません。
出力は必ず「---SLACK-FORMAT---」から開始してください。
挨拶、感想、まとめ、コメント等の余計なテキストは一切出力しないでください。
これを書かないと、CLAUDE.md で設定した性格(私の場合はギャル口調)が漏れ出し、収集結果の前に**「よっしゃ〜!いい記事見つけたで!」**のようなノイズが入ってパースに失敗します。
2. 年フィルターで「2026年問題」を防ぐ
単に「最新記事」と頼むと、SEOの強い数年前の記事を拾ってくることがあります。
- 投稿日: $(date +%Y) を基準に過去48時間以内のみ。
- 検索クエリに必ず「$(date +%Y)」を含めて、今年の記事に絞ること
- 重要な注意:$(date +%Y - 1)年以前の古い記事は絶対に含めない。
プロンプト内で date コマンドを展開し、年号を明示的に指定することで、情報の鮮度を担保しています。
3. セクション区切りで構造化する
1回の生成で3つの用途(Slack用、Obsidian用、ログ用)を出力させるため、独自の区切り文字を定義しています。
---SLACK-FORMAT---
(Slack用のmrkdwn)
---OBSIDIAN-FORMAT---
(Obsidian用のMarkdown)
---NEW-URLS---
(URL一覧)
これを awk で分割することで、APIコールを節約しつつ多目的な出力を得ています。
ハマりポイントと解決策
開発中にぶつかった壁とその乗り越え方です。
🤯 Slackの表示崩れ (mrkdwnの罠)
Slackの記法(mrkdwn)はMarkdownと微妙に異なります。
特にURLの扱いで、[タイトル](URL) 形式や、絵文字とURLを同じ行に書くと、Slackが勝手に <URL|タイトル> のように解釈しようとして表示が壊れることがありました。
👉 解決策
URLは必ず単独行に配置する。これだけでプレビューも綺麗に出るようになり、リンク切れも防げます。
📜 記事の質が低い
初期はQiitaのニッチな個人の備忘録ばかり拾ってしまうことがありました。
👉 解決策
「品質フィルター」をプロンプトに定義しました。
- はてブ: 50以上
- Qiita/Zenn: いいね10以上
- X: いいね50以上
ただし、「速報性が高い場合はこの限りではない」という注釈を入れることで、バズる前の最新ニュースも拾えるようにしています。
🛑 安全設計 (暴走防止)
自動実行スクリプトなので、安全性には気を使っています。
-
set -euo pipefail: エラーがあったら即停止。 - Slack投稿失敗時: Slackへの投稿がコケても、Obsidianへの保存(ローカル処理)は続行するよう、エラーハンドリングを分離。
-
ツール制限:
WebSearchとSlack以外のツール権限を剥奪し、意図しないファイル操作を防ぐ。
ソースコード全文
実際に使用しているシェルスクリプトです。パスなどは環境に合わせて書き換えてください。
weekly-it-news.sh (クリックして展開)
#!/bin/bash
set -euo pipefail
# ======================
# 設定エリア
# ======================
SLACK_CHANNEL_ID="C0AEDCZAECB"
OBSIDIAN_DIR="$HOME/projects/IF-Vault/team/guchi/notes/IT-News"
LOG_FILE="$HOME/.claude-automation/processed-urls.log"
# Cron実行用PATH設定(which claudeの結果を含むように)
export PATH=$PATH:/usr/local/bin:/opt/homebrew/bin
mkdir -p "$OBSIDIAN_DIR" "$HOME/.claude-automation" "$HOME/logs"
touch "$LOG_FILE"
DATE=$(date +%Y-%m-%d)
CURRENT_YEAR=$(date +%Y)
LAST_YEAR=$((CURRENT_YEAR - 1))
# ======================
# プロンプト定義
# ======================
PROMPT=$(cat <<EOF
【役割】
あなたはIT情報収集パイプラインの一部です。余計な会話はせず、データのみを出力してください。
【タスク】
X(Twitter)、Qiita、Zenn、TechCrunchなどから最新のIT情報を検索してください。
【検索条件】
- 投稿日: ${DATE} を基準に過去48時間以内。
- キーワード: AI OR データベース OR クラウド OR IT OR "Claude Code" OR OpenClaw
- **重要**: 検索クエリに必ず「${CURRENT_YEAR}」を含めること。
- ${LAST_YEAR}年以前の記事は除外。
【除外URL】
$(tail -n 100 "$LOG_FILE")
【出力フォーマット】
以下のセクション区切りを使用し、3つのパートを出力してください。
---SLACK-FORMAT---
📰 *IT情報収集 - $(date +%Y/%m/%d)*
新着記事 5件
━━━━━━━━━━━━━━━━━━━━
*1. [タイトル]*
\`Category\` | Source | YYYY-MM-DD
• 要約ポイント1
• 要約ポイント2
URL
---OBSIDIAN-FORMAT---
### 1. タイトル
- **URL**: URL
- **ソース**: Source
- **カテゴリ**: Category
- **要約**: ...
---NEW-URLS---
URL1
URL2
...
EOF
)
# ======================
# 実行処理
# ======================
OUTPUT_FILE=$(mktemp)
trap 'rm -f "$OUTPUT_FILE"' EXIT
# 1. 情報収集 (--printモード)
claude --print --allowedTools 'WebSearch' "$PROMPT" > "$OUTPUT_FILE"
# 2. Slack投稿 (通常モード)
SLACK_CONTENT=$(awk '/---SLACK-FORMAT---/{flag=1;next}/---OBSIDIAN-FORMAT---/{flag=0}flag' "$OUTPUT_FILE")
if [ -n "$SLACK_CONTENT" ]; then
claude --allowedTools 'mcp__claude_ai_Slack__slack_send_message' --max-turns 3 << SLACK_EOF > /dev/null 2>&1
以下の内容をSlackのチャンネルID ${SLACK_CHANNEL_ID} に投稿してください。
編集せずそのまま投稿すること。
${SLACK_CONTENT}
SLACK_EOF
fi
# 3. Obsidian保存 & ログ更新
# (省略: awkで抽出してファイル書き出し)
# ...
⚠️ 【重要】macOS Cron設定の落とし穴
ここが最大の難関です。macOS (Catalina以降) でCronを動かすには、以下の2つの設定が必須です。これをやらないと動きません。
1. 初回の手動実行と認証
スクリプトをCronに登録する前に、必ずターミナルで一度手動実行してください。
bash ~/scripts/weekly-it-news.sh
Claude CodeとSlack MCPの連携には、初回のみブラウザ経由での認証(OAuth)が必要です。これを済ませておかないと、Cronが認証画面を出せずにエラーになります。
2. フルディスクアクセスの許可
macOSのセキュリティ機能により、cron から Documents フォルダ(Obsidian)への書き込みがブロックされることがあります。
- 「システム設定」 → 「プライバシーとセキュリティ」 → 「フルディスクアクセス」 を開く。
- リストの下にある 「+」 ボタンを押す。
-
Command+Shift+Gを押し、/usr/sbin/cronと入力して移動。 -
cronを選択して追加し、スイッチを ON にする。
3. Cronの設定
crontab -e で設定しますが、PATH を明示的に通すのが安全です。
# 月水金の朝7時に実行
0 7 * * 1,3,5 export PATH=$PATH:/usr/local/bin:/opt/homebrew/bin; /bin/bash $HOME/scripts/weekly-it-news.sh >> $HOME/logs/it-news-$(date +\%Y-\%m).log 2>&1
まとめ
Claude Codeを使うことで、従来の「Pythonでスクレイピングして、APIを叩いて…」という面倒な実装が、 「自然言語で指示して、パイプで繋ぐ」 というシンプルな形に昇華されました。
コスト:
- Claude Code CLI (Pro/Teamプラン内)
- Slack MCP (無料)
- サーバー代 (ローカルMac + cronなので無料)
「週3回、勝手に情報が集まってくる」体験は、一度味わうと戻れません。
ぜひ皆さんも、自分専用の全自動情報収集エージェントを作ってみてください!