touch-grass
🌿 touch-grass
外に出ることを思い出させてくれるClaude Codeプラグイン。
天気・日没・セッション状況を考慮し、作業の流れを妨げません。
インストール · 仕組み · ツール · プライバシー · サイト
なぜこれが必要なのか
ポモドーロタイマーは作業の流れを中断させます。カレンダーのブロックは無視されがちです。エディタから離れるのに最適なタイミングは、天気、時間帯、継続状況、そして今何をしているかによって変わる流動的なものです。単純なインターバルタイマーには、これらを判断できません。
あなたのAIコーディングエージェントは、あなたが自然な休憩タイミングを迎えたことをすでに知っています。 機能の実装が終わったとき、質問への回答を待っているとき、テストが成功したとき。これこそが促しの最適なタイミングであり、25分おきに機械的に通知することではありません。
touch-grassは、あなたのエージェントを状況を理解する「休憩の相棒」に変えます。SessionStartフックがセッション開始時に天気と日没時間を伝えます。スキルによって、エージェントは(説教臭くなく、温かく具体的な)適切なトーンで話しかけるようになります。MCPサーバーにより、実際に外に出たことを記録できます。あなたは作業の流れを維持し、エージェントはあなたの健康を維持します。
機能
ポモドーロタイマーのようですが、天気、日没時間、コーディングの継続状況を把握しており、作業を中断させる代わりにAIエージェントを通じて話しかけてきます。
SessionStartフック: Claude Codeのセッションが開始されるたびに、現在の天気、日没時間、継続状態をエージェントのコンテキストに注入します。
MCPサーバー: エージェント(Claude Code、Cursor、Claude Desktop、Codex)が必要に応じて呼び出せる4つのツールを提供します。
スキル: エージェントに対し、いつ促し、いつ静かにし、どのようなトーン(説教臭くない、親身な母親のような)を使うべきかを教えます。
これは、画面をブロックするタイマーで作業を中断されるよりも、コーディングエージェントに外に出るよう促されたい人のための、Claude Code用ポモドーロ代替ツールです。
インストール
Claude Code(フル体験 — フック + MCP + スキル):
/plugin install nalediym/touch-grass以上です。新しいセッションを開くとフックが作動し、コンテキストが読み込まれ、エージェントが対応を開始します。
git clone https://github.com/nalediym/touch-grass
cd touch-grass/plugin/mcp-server && npm install次に、クライアントのMCP設定に追加します:
{
"mcpServers": {
"touch-grass": {
"command": "node",
"args": ["/absolute/path/to/touch-grass/plugin/mcp-server/index.mjs"]
}
}
}4つのMCPツールは利用できますが、Claude Code専用のSessionStartフックは使用できません。エージェントは、あなたが明示的に尋ねた場合にのみ草について言及します。
仕組み
flowchart LR
A[Claude Code<br/>session starts] --> B[SessionStart hook fires]
B --> C[ip-api.com<br/>location]
B --> D[open-meteo.com<br/>weather + sunset]
B --> E[~/.touch-grass/state.json<br/>streak + sessions]
C --> F[Context injection]
D --> F
E --> F
F --> G[Agent<br/>decides when to nudge]
G -.calls.-> H[MCP tools]
H --> Eセッション開始時にフックスクリプトが実行されます。パブリックIPから現在地を検出し(24時間キャッシュ)、open-meteoから現在の天気と日没時間を取得し、ローカルの継続ファイル(streak file)を読み取って、エージェント用の短いコンテキストブロックを生成します。エージェントはそれを読み込み、自然な休憩タイミング(機能完了、バグ修正、入力待ちなど)で、実際の状況に合わせた言葉で外に出るよう促します。
外に出たことを確認すると、エージェントはMCPサーバー経由でlog_touch_grassを呼び出し、ローカルの状態ファイルで継続回数を増やします。
MCPツール
ツール | 目的 | 戻り値 |
| 天気、気温、日没までの時間、ユーザーの継続状態。判断用コンテキスト。 |
|
| 時間帯に応じたランダムなアクティビティの提案。ゴールデンアワーには日没特有の提案。 |
|
| ユーザーが外に出たことを記録。継続回数を更新。確認時のみ呼び出し。 | 新しい継続回数を含む確認 |
| セッションの生データと継続履歴。 | JSONブロック |
これら4つは、MCP対応エージェントから呼び出し可能です。Claude Codeでは、フックが注入するコンテキストを通じてエージェントがこれらを使用するため、手動で呼び出す必要はほとんどありません。
プロンプト例
このプラグインは環境的に動作しますが、自分から話題にしたい場合は以下のフレーズが有効です:
"今、外に出るべきかな?"
"今の継続回数は?"
"日没前に外に出るようリマインドして。"
"散歩に行ってきたから、記録して。"
"外はいい天気?"
プライバシー
すべてローカルファーストです。
マシン内に保存:
~/.touch-grass/state.json(継続回数、セッション数、最終外出日)および~/.touch-grass/config.json(キャッシュされた場所、天気のしきい値)。マシン外へ送信: パブリックIPは24時間に1回
ip-api.comに送信され都市座標を解決します。その座標はセッション開始ごとにapi.open-meteo.comに送信され、天気と日没時間を取得します。マシン外へ送信されないもの: 継続回数、アクティビティのメモ、コーディングスケジュール、プロンプト、Claude Codeセッションの内容など。
アカウントなし。APIキーなし。テレメトリなし。分析なし。認証なし。ネットワークアクセスを完全に無効にしたい場合は、~/.touch-grass/config.json で "location" を手動で指定すれば、IP検索は実行されません。
設定
{
"location": {
"lat": 40.7128,
"lon": -74.0060,
"city": "New York",
"timezone": "America/New_York",
"fetchedAt": 9999999999999
},
"niceWeatherThresholdC": 15,
"breakIntervalHours": 2,
"enabled": true,
"customActivities": [
{ "label": "walk to the corner store", "emoji": "🛒" },
{ "label": "sit on the fire escape", "emoji": "🪜" }
]
}キー | デフォルト | 説明 |
| auto (ip-api) | 特定の場所に固定。自動更新を無効にするには |
|
| 「良い天気」とみなす気温(°C)のしきい値。 |
|
| 連続コーディングがこの時間を超えると、促しが強くなります。 |
|
|
|
|
| デフォルトのアクティビティリストを独自のものに置き換えます。各エントリは |
トラブルシューティング
フックを手動で実行して動作を確認してください:
node plugin/hooks/session-start.mjshookSpecificOutput.additionalContext に促しの内容が含まれるJSONオブジェクトが表示されるはずです。additionalContext が空文字列の場合、フックが ip-api.com や open-meteo.com に到達できていません。ネットワークを確認してください。フックは正常だがClaude Codeが呼び出さない場合は、プラグインが正しく接続されていません。新しいセッションで /plugin install nalediym/touch-grass を再実行してください。
~/.touch-grass/state.json を確認してください。sessionStart、lastSessionStart、totalCodingSessions フィールドはフックが実行されるたびに更新されます。sessionStart が直近の claude 起動よりも古い場合、フックは実行されていません。
はい。~/.touch-grass/config.json で場所を手動で指定してください:
{
"location": {
"lat": 40.7128,
"lon": -74.0060,
"city": "New York",
"timezone": "America/New_York",
"fetchedAt": 9999999999999
}
}fetchedAt に大きなタイムスタンプを設定することで24時間のキャッシュ期限切れを防ぎ、IP検索が実行されないようにします。天気は引き続き open-meteo.com から取得されます。
~/.touch-grass/config.json で "enabled": false を設定してください。フックは引き続きセッションのテレメトリを書き込みますが、空のコンテキストを出力するため、エージェントは草のリマインダーを表示しなくなります。
~/.touch-grass/state.json を削除または編集してください。次のセッションでデフォルト値で再作成されます。
/plugin uninstall touch-grass
rm -rf ~/.touch-grass~/.touch-grass ディレクトリには状態とキャッシュされた場所のみが保存されているため、削除しても安全です。
開発
git clone https://github.com/nalediym/touch-grass
cd touch-grass/plugin/mcp-server && npm install
# Test the hook directly (outputs JSON context)
node ../hooks/session-start.mjs
# Test the MCP server with the inspector
npx @modelcontextprotocol/inspector node ./index.mjs3つの主要パーツで構成されています:
plugin/hooks/session-start.mjs— 依存関係なしのNodeスクリプト。Claude Codeのセッション開始時に呼び出され、JSONをstdoutに出力します。plugin/mcp-server/index.mjs— MCPサーバー。@modelcontextprotocol/sdkを使用。stdioトランスポート。plugin/lib/grass.mjsおよびplugin/lib/nudge.mjs— 共通ロジック(天気、日没、状態、促しのテキスト)。
フックとMCPサーバーは同じ状態ファイルを読み取るため、同期が保たれます。
関連
open-meteo.com — 無料、キー不要の天気API
ip-api.com — 無料、キー不要のIPジオロケーション
ライセンス
MIT · 日陰で構築されました。
サポート
touch-grassは無料でMITライセンスです。画面から離れる助けになったなら、サポートを検討してください:
Polarでサポート → — 9ドル(1回限り)。サポーターリストに名前が掲載され、優先的な問題対応を受けられ、設定でカスタムアクティビティリストがアンロックされます。
サポーター
最初のサポーターになりましょう。Polarでサポート →
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nalediym/touch-grass'
If you have feedback or need assistance with the MCP directory API, please join our Discord server