ObsidianとGitHub Actions、Claudeで構築する、AIプロジェクト管理術
はじめに
「あの案件のToDo、どこに書いたっけ?」「複数のプロジェクトのタスクが散らばって管理しきれない…」多くの知識労働者が抱えるこの悩みを、Obsidianの柔軟な知識ベースと、GitHub Actionsの強力な自動化、そしてClaude(AI)の知的分析能力を組み合わせることで解決できる可能性があります。
この記事では、日々のメモやプロジェクト情報を集約したObsidian Vaultを元に、Claudeが毎日自動でToDoを分析し、GitHubのIssueとしてレポートしてくれるAIプロジェクト管理システムを構築する全手順を解説します。
この記事を読み終える頃には、あなたも自分だけのAI執事を手に入れ、タスク管理のあり方を根本から変革できるでしょう。
システムアーキテクチャ
このシステムの全体像は以下の通りです。ローカルのObsidianが「知の源泉」となり、それをGitHub Actionsが吸い上げ、Claudeが分析し、GitHub Issuesという「ダッシュボード」に届ける流れです。
┌─────────────────────────────────────────────────────────────────┐
│ ローカル環境 (Your PC) │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Obsidian Vault │ │
│ │ (案件・ToDo・議事録など全情報) │ │
│ └───────────────────────────────────────────────────────────┘ │
└─────────────────────────────────┬───────────────────────────────┘
│ git push
↓
┌──────────────────────────────────────────────────────────────────┐
│ クラウド / 自動化 (GitHub) │
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ GitHub Repository │ │
│ │ (Obsidian Vaultのバックアップ先) │ │
│ └─────────────────────┬─────────────────────────────────────┘ │
│ │ Trigger (schedule) │
│ ↓ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ GitHub Actions │ │
│ │ (スケジュール実行) │ │
│ └─────┬───────────────────────────────────────┬─────────────┘ │
│ │ 1. Read all .md files │ 3. Create Issue│
│ ↓ ↓ with Report │
│ ┌─────────────────────────────┐ ┌─────────────────────────┐ │
│ │ Anthropic API │ │ GitHub Issue │ │
│ │ (Claudeによる分析) │ │ (ToDoレポート) │ │
│ └─────────────────────────────┘ └─────────────────────────┘ │
│ ↑ ↓ │
│ └──────────────────────┘ │
│ 2. Analyze & Generate Report │
└──────────────────────────────────────────────────────────────────┘
実際の画面
Obsidianの画面
GitHubから定期的に通知が来るToDoリスト
Step 1: Obsidian - 知の拠点を構築する
システムの土台となるのは、情報を一元管理するObsidianのVaultです。ここでは、情報を構造化するためのフォルダ構成と、情報のコンシステンシー(一貫性)を保つためのテンプレートを定義します。
フォルダ構成
まず、以下のようなフォルダ構成で情報を整理します。
-
📁 01_Projects/
: 案件ごとのノートを格納 -
📁 02_Resources/
: 顧客情報やメンバー情報など、案件をまたぐ情報を格納-
📁 Members/
: メンバーのプロフィールノート
-
-
📁 03_Meetings/
: 議事録ノート -
📁 04_Assignments/
: 誰がどの案件にアサインされているかの「関係性」を定義するノート -
📁 05_Daily/
: 案件に紐づかない日々のタスクやメモを記録するデイリーノート -
📁 _Templates/
: 各ノートのひな形を保存
【重要】必須プラグイン:システムの心臓部
このシステムを再現するには、Obsidianの標準機能に加え、以下のコアプラグインとコミュニティプラグインが不可欠です。これらを組み合わせることで、静的なメモが動的なデータベースへと変わります。
設定
> コミュニティプラグイン
から、コミュニティプラグインを有効にし、以下のプラグインをインストール・有効化してください。
コミュニティプラグイン (要インストール)
-
Dataview
- 役割: Vault内のノートのメタデータ(フロントマター)を元に、SQLのようにデータを集計・表示するプラグイン。この記事の「アサイン履歴」や「担当メンバー一覧」などの自動リストはすべてDataviewで実現しています。これがなければ、このシステムは成り立ちません。
-
Templater
-
役割:
Templates
コアプラグインの超高機能版。<% tp.date.now() %>
のように、日付やファイル名を動的に挿入したり、カーソル位置を制御したりできます。ノート作成の効率と精度を飛躍的に高めます。
-
役割:
-
Tasks
-
役割: Vault内のすべての
- [ ]
形式のタスクを横断的に検索・集計するプラグイン。GitHub Actionsが生成するレポートとは別に、Obsidian内のダッシュボードで全タスクを一覧表示するために使用します。(記事の最後のダッシュボード例で活用)
-
役割: Vault内のすべての
コアプラグイン (標準搭載・有効化するだけ)
-
デイリーノート
-
役割:
Cmd/Ctrl + T
のようなショートカットで、その日の日付を名前にしたノートを瞬時に作成・表示します。個人的なタスク管理の起点として必須です。
-
役割:
テンプレートとDataviewによる情報のリンク
情報の入力と集約を自動化するために、前述のプラグインを活用します。以下に主要なテンプレートのコードを記載します。
---
client:
project_name:
status: "仕掛中"
due_date:
type:
tags: []
created: <% tp.date.now("YYYY-MM-DD") %>
---
# 案件名: <% tp.file.title %>
## 概要
<% tp.file.cursor() %>
---
## ✅ ToDoリスト
- [ ]
---
## 🤝 関連情報
- **クライアント**: <%+ client %>
### 担当アサインメンバー
```dataview
TABLE member.name AS "氏名", member.employee_id AS "従業員ID", start_date AS "開始", end_date AS "終了", role_in_project AS "役割"
FROM "04_Assignments"
WHERE project = [[]] AND status = "Active"
SORT start_date ASC
````'
-----
## 📂 関連ファイル (Attachments)
-
---
employee_id: ""
name: ""
role: ""
tags: [member]
---
# <% tp.file.title %>
## スキル・経歴
-
---
## アサイン履歴
```dataview
TABLE project AS "プロジェクト", start_date AS "開始日", end_date AS "終了日", role_in_project AS "役割"
FROM "04_Assignments"
WHERE member = [[]]
SORT start_date DESC
````'
---
member:
project:
start_date:
end_date:
role_in_project: ""
status: "Active"
---
<% tp.file.title %>
---
tags: [daily]
date: <% tp.date.now("YYYY-MM-DD") %>
---
# <% tp.date.now("YYYY年MM月DD日 (dddd)") %>
## 🎯 今日の目標 (Top 3)
-
-
-
---
## ✅ ToDoリスト
- [ ]
---
## 📝 メモ・日記
<% tp.file.cursor() %>
Step 2: GitHub Actions & Claude - 全自動ToDoアナリストを召喚する
次に、Obsidian Vaultと同期されたGitHubリポジトリ上で、AI執事を動かすための設定を行います。
ワークフローファイルの作成
リポジトリの.github/workflows/
ディレクトリに、以下の内容でtodo-reminder.yml
ファイルを作成します。
name: Claude ToDo Analysis and Issue Creation
on:
schedule:
# 日本時間 午前6:00 (UTC 21:00 前日)
- cron: '0 21 * * *'
# 日本時間 午後6:00 (UTC 9:00)
- cron: '0 9 * * *'
# 手動実行も可能
workflow_dispatch:
jobs:
analyze-and-create-issue:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Get current time in JST
id: time
run: |
echo "jst_date=$(TZ='Asia/Tokyo' date +'%Y年%m月%d日')" >> $GITHUB_OUTPUT
echo "jst_time=$(TZ='Asia/Tokyo' date +'%H:%M')" >> $GITHUB_OUTPUT
echo "greeting=$(if [ $(TZ='Asia/Tokyo' date +'%H') -lt 12 ]; then echo '🌅 おはようございます'; else echo '🌆 お疲れさまです'; fi)" >> $GITHUB_OUTPUT
- name: Collect all markdown content into a file
run: |
echo "--- markdown content ---" > all_content.txt
find . -name "*.md" ! -path "./_Templates/*" ! -name "obsidian_vault_context.md" -print0 | xargs -0 -I {} sh -c 'echo "\n\n--- File: {} ---"; cat "{}"' >> all_content.txt
- name: Analyze with Claude and Create Issue
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
// 2つの外部ファイルを読み込む
const mdContent = fs.readFileSync('all_content.txt', 'utf8');
let promptTemplate = fs.readFileSync('.github/prompts/todo_prompt.txt', 'utf8');
const apiKey = process.env.ANTHROPIC_API_KEY;
if (!apiKey) {
core.setFailed('ANTHROPIC_API_KEY is not set.');
return;
}
// ステップから値を取得
const greeting = "${{ steps.time.outputs.greeting }}";
const jst_date = "${{ steps.time.outputs.jst_date }}";
const jst_time = "${{ steps.time.outputs.jst_time }}";
const repoName = "${{ github.event.repository.name }}";
// プロンプトテンプレートのプレースホルダーを実際の値で置換する
const prompt = promptTemplate
.replace('{GREETING}', greeting)
.replace('{REPO_NAME}', repoName)
.replace('{MD_CONTENT}', mdContent);
// Anthropic APIを呼び出す
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': apiKey,
'anthropic-version': '2023-06-01',
'content-type': 'application/json'
},
body: JSON.stringify({
model: 'claude-sonnet-4-20250514',
max_tokens: 4000,
messages: [{ role: 'user', content: prompt }]
})
});
if (!response.ok) {
const errorText = await response.text();
core.setFailed(`API call failed with status ${response.status}: ${errorText}`);
return;
}
const responseData = await response.json();
const claudeReport = responseData.content[0].text;
// GitHub Issueを作成する
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `📋 ToDoリスト (${jst_date})`,
body: claudeReport,
labels: ['todo-report', 'automated'],
assignees: ['${{ github.repository_owner }}']
});
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
プロンプトファイルの作成
AIへの指示書となるプロンプトを外部ファイルとして管理します。.github/prompts/
ディレクトリを作成し、以下の内容でtodo_prompt.txt
ファイルを保存します。
あなたは、渡されたテキストから「未完了のタスク」を抽出してリストアップする自動化スクリプトです。
コンサルティング、アドバイス、提案、励ましのメッセージは一切不要です。指示された形式でタスクのみを抽出してください。
以下のテキストは、プロジェクト「{REPO_NAME}」内の全マークダウンファイルの内容です。
この中から、下記の検索パターンに一致する「未完了」のタスクをすべて抽出してください。
# 検索パターン
- `- [ ]` (チェックボックス形式)
- `TODO`
- `FIXME`
- `タスク:`
- `課題:`
# 出力形式
抽出したタスクを、以下の形式でマークダウンとして出力してください。
- 各タスクの前に、それが含まれていたファイル名を必ず記載してください。
- 期限が設定されているタスク(例: 📅YYYY-MM-DD)は、その日付も記載してください。
- 案件に紐づくタスクと、デイリーノートなどの個人的なタスクを分けてリストアップしてください。
---
{GREETING}
## 🚀 案件関連のタスク
*ここに案件ノートや議事録ノートから抽出したタスクをリストアップ*
## 👤 個人的なタスク
*ここにデイリーノートなどから抽出したタスクをリストアップ*
---
*もし未完了のタスクが一つも見つからなかった場合は、「現在、対応が必要なタスクはありません。素晴らしい状態です!🎉」とだけ表示してください。*
--- 以下が解析対象のテキストです ---
{MD_CONTENT}
必要な設定
リポジトリの Settings
> Secrets and variables
> Actions
で、以下のシークレットを登録します。
-
ANTHROPIC_API_KEY
: あなたのAnthropic APIキー
完成形:AIが届けるToDoリスト
上記の設定が完了すると、指定した時間にGitHub Actionsが実行され、以下のようなIssueが自動で作成されます。
📋 ToDoリスト (2025年06月15日)
🌅 おはようございます
🚀 案件関連のタスク
- ./01_Projects/XXX_XXX案件.md: - [ ] 〇〇さん△△さんとの打ち合わせ📅 2025-06-16
- ./01_Projects/XXX_XXX案件.md: - [ ] 〇〇に向けた概算見積もり📅 2025-06-16
- ./01_Projects/XXX_XXX.md: - [ ] 〇〇業務について、△△をベースにLLMに全自動化案を作らせてみる 📅 2025-06-16
👤 個人的なタスク
- ./05_Daily/2025-06-16.md: - [ ] 懇親会店アレンジ。その前に関係者へリマインド
まとめと今後の展望
今回構築したシステムは、単なるタスク管理ツールではありません。
- 情報の集約: Obsidianに情報を書き留めるだけで、自動的に構造化・集約されます。
- タスクの自動棚卸し: 毎日Claudeがすべてのノートを巡回し、やるべきことを教えてくれます。
- 拡張性: プロンプトを工夫すれば、「今週の進捗レポート」や「停滞している案件のアラート」など、様々なレポートを自動生成できます。
この「Obsidian x GitHub Actions x Claude」の組み合わせは、個人の生産性を飛躍的に向上させる可能性を秘めています。ぜひ、あなたも自分だけのAI執事を育て、より創造的な活動に時間を使ってみてはいかがでしょうか。
補足:Claude Code Actionを使った実装
本記事の執筆後、よく見たらClaude Code Actionを使っておらずClaudeのAPIを使っていることがわわかりました。。。Anthropic公式のClaude Code Actionを活用して、API直接呼び出しではなく、GitHubのネイティブな仕組みでClaudeと対話する仕組みに変えました。以下、変更点を解説します。
新しいアーキテクチャ
┌─────────────────────────────────────────────────────────────────┐
│ ローカル環境 (Your PC) │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Obsidian Vault │ │
│ │ (案件・ToDo・議事録など全情報) │ │
│ └───────────────────────────────────────────────────────────┘ │
└─────────────────────────────────┬───────────────────────────────┘
│ git push
↓
┌─────────────────────────────────────────────────────────────────┐
│ クラウド / 自動化 (GitHub) │
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ GitHub Repository │ │
│ │ (Obsidian Vaultのバックアップ先) │ │
│ └─────────────────────┬─────────────────────────────────────┘ │
│ │ Schedule Trigger │
│ ↓ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ GitHub Actions (todo-scheduler.yml) │ │
│ │ 1. PAT認証でIssue作成(ユーザーとして) │ │
│ │ 2. Issue本文に@claudeメンション │ │
│ └─────────────────────┬─────────────────────────────────────┘ │
│ │ @claude trigger │
│ ↓ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Claude Code Action (claude.yml) │ │
│ │ 1. @claudeメンションを検知 │ │
│ │ 2. リポジトリ内の全.mdファイルを分析 │ │
│ │ 3. 指定フォーマットでToDoレポートを生成 │ │
│ └─────────────────────┬─────────────────────────────────────┘ │
│ │ Comment on Issue │
│ ↓ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ GitHub Issue │ │
│ │ (完成したToDoレポート) │ │
│ └───────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Step 1: Claude Code Actionのセットアップ
まず、Claude Code Actionを有効化します。
# 1. Claude GitHub Appをインストール
# ブラウザで以下にアクセス
https://github.com/apps/claude
# 2. 対象リポジトリを選択してインストール
次に、Claude Code Action用のワークフローファイルを作成:
name: Claude Assistant
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude-response:
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.2.11"
- name: Run Claude Code Action
uses: anthropics/claude-code-action@beta
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
trigger_phrase: "@claude"
Step 2: Personal Access Token (PAT) の設定
GitHub Actionsがユーザーとして動作するためのPATを設定します。
# 1. GitHubの設定画面を開く
Settings → Developer settings → Personal access tokens → Tokens (classic)
# 2. 「Generate new token」をクリック
# 3. 以下を設定
- Note: Obsidian ToDo Bot
- Expiration: 90 days(お好みで)
- Scopes: ✅ repo(チェックを入れる)
# 4. 「Generate token」をクリックし、表示されたトークンをコピー
# 5. リポジトリのシークレットに登録
Settings → Secrets and variables → Actions → New repository secret
- Name: PERSONAL_ACCESS_TOKEN
- Value: [コピーしたトークンを貼り付け]
Step 3: 定期実行ワークフローの修正
既存のtodo-reminder.yml
を以下のように置き換えます:
name: Schedule ToDo Analysis
on:
schedule:
- cron: '0 21 * * *' # 日本時間 午前6:00
- cron: '0 9 * * *' # 日本時間 午後6:00
workflow_dispatch:
jobs:
create-todo-issue:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
sparse-checkout: |
.github/prompts/todo_prompt.txt
- name: Get current time in JST
id: time
run: |
echo "jst_date=$(TZ='Asia/Tokyo' date +'%Y年%m月%d日')" >> $GITHUB_OUTPUT
echo "jst_time=$(TZ='Asia/Tokyo' date +'%H:%M')" >> $GITHUB_OUTPUT
echo "today=$(TZ='Asia/Tokyo' date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
echo "greeting=$(if [ $(TZ='Asia/Tokyo' date +'%H') -lt 12 ]; then echo 'おはようございます'; else echo 'お疲れさまです'; fi)" >> $GITHUB_OUTPUT
- name: Close previous ToDo issues
uses: actions/github-script@v7
with:
github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
script: |
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: 'todo-report,automated',
state: 'open'
});
for (const issue of issues.data) {
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
state: 'closed'
});
}
- name: Create ToDo Issue with PAT
uses: actions/github-script@v7
with:
github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
script: |
const fs = require('fs');
const date = '${{ steps.time.outputs.jst_date }}';
const greeting = '${{ steps.time.outputs.greeting }}';
const today = '${{ steps.time.outputs.today }}';
// プロンプトを読み込んで変数を置換
let prompt = fs.readFileSync('.github/prompts/todo_prompt.txt', 'utf8');
prompt = prompt.replace(/\{GREETING\}/g, greeting);
prompt = prompt.replace(/\{TODAY\}/g, today);
prompt = prompt.replace(/\{JST_DATE\}/g, date);
// Issue番号を計算(オプション)
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: 'todo-report',
state: 'all'
});
const issueNumber = issues.data.length + 1;
// PATを使ってあなた自身としてIssueを作成
const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `📋 ToDoリスト (${date}) #${issueNumber}`,
body: `@claude
プロジェクト内のすべてのマークダウンファイル(_Templates/フォルダとobsidian_vault_context.mdは除外)から未完了タスクを抽出して、以下のフォーマットで整理してください。
${prompt}`,
labels: ['todo-report', 'automated'],
assignees: ['${{ github.repository_owner }}']
});
console.log(`Created issue #${issue.data.number} as ${{ github.repository_owner }}`);
Step 4: Claude用プロンプトファイルの作成
.github/prompts/todo_prompt.txt
を新規作成:
あなたは、渡されたテキストから「未完了のタスク」を抽出してリストアップする自動化スクリプトです。
コンサルティング、アドバイス、提案、励ましのメッセージは一切不要です。指示された形式でタスクのみを抽出してください。
以下のテキストは、プロジェクト「Obsidian」内の全マークダウンファイルの内容です。
この中から、下記の検索パターンに一致する「未完了」のタスクをすべて抽出してください。
# 検索パターン
- `- [ ]` (チェックボックス形式)
- `TODO`
- `FIXME`
- `タスク:`
- `課題:`
## 注意事項
- 完了済み(`- [x]`)は含めない
- 期限は 📅YYYY-MM-DD 形式で記載されているものを認識
- ファイル名は簡潔に(拡張子.mdは省略)
- 同じファイル内の複数タスクはインデントでグループ化
- 長いタスク内容は要約して1行に収める
- 案件名が判別できる場合は、ファイル名の先頭に記載
# 出力形式
抽出したタスクを、以下の形式でマークダウンとして出力してください。
- 各タスクの前に、それが含まれていたファイル名を必ず記載してください。
- 期限が設定されているタスク(例: 📅YYYY-MM-DD)は、その日付も記載してください。
- 案件に紐づくタスクと、デイリーノートなどの個人的なタスクを分けてリストアップしてください。
---
{GREETING}
## 🚀 案件関連のタスク
*ここに案件ノートや議事録ノートから抽出したタスクをリストアップ*
## 👤 個人的なタスク
*ここにデイリーノートなどから抽出したタスクをリストアップ*
### 📊 サマリー
- 総タスク数: X件
- 本日締切: Y件 🔥
- 期限切れ: Z件 ⚠
- 今週締切: W件
---
*もし未完了のタスクが一つも見つからなかった場合は、「現在、対応が必要なタスクはありません。素晴らしい状態です!🎉」とだけ表示してください。*
変更のメリット:
- GitHubネイティブ: IssueやPRでの@claudeメンションという自然な操作
- 拡張性: ToDoレポート以外にも、コードレビューや質問応答など多様な用途に対応
- トレーサビリティ: すべてのやり取りがGitHub上に記録される
- メンテナンス性: API呼び出しコードを自前で管理する必要がない
Discussion