メインコンテンツへスキップ
Kanau Tech™ - かなうテック
← ブログ一覧に戻る
AI開発ツール

Claude Code Remote Control で /goal を外部制御 — GitHub Actions / curl / API統合パターン

2026-05-22by DO XUAN HIEN
Claude Code Remote Control で /goal を外部制御 — GitHub Actions / curl / API統合パターン

Claude Code を CI/CDパイプラインから自動実行 すれば、デプロイ前検証・自動レビュー・夜間バッチ等をAIに任せられる。

この記事では claude -p の Headless mode を中心に、GitHub Actions・curl・JavaScript・Python の 実装パターンを完全形 で示す。

Headless mode とは

Headless mode は、対話UIなしでClaude Codeを1回限りで実行するモードだ。 CI/CDジョブ内・cron・別アプリからの呼び出しに使う。

# 基本形
claude -p "<プロンプト or /goal文>"

# /goal を非対話で実行
claude -p "/goal test/auth 全件通過, or stop after 10 turns"

# 認証はAPI Keyまたは保存済みOAuthトークン
ANTHROPIC_API_KEY=sk-... claude -p "/goal ..."

完了すると exit code(0=成功、非0=失敗) を返してプロセス終了。ジョブのpass/fail判定に直接使える。

パターン1: GitHub Actions 統合

CIでテストカバレッジが80%未満になったらAIに自動で改善させる例。

.github/workflows/auto-improve-coverage.yml

name: Auto Improve Test Coverage

on:
  pull_request:
    branches: [main]

jobs:
  check-and-improve:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Run coverage
        id: coverage
        run: |
          npm test -- --coverage
          COVERAGE=$(jq '.total.lines.pct' coverage/coverage-summary.json)
          echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT

      - name: Install Claude Code
        if: ${{ steps.coverage.outputs.coverage < 80 }}
        run: npm install -g @anthropic-ai/claude-code

      - name: Auto improve via /goal
        if: ${{ steps.coverage.outputs.coverage < 80 }}
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          claude -p "/goal カバレッジ80%未満のモジュールにテストを追加し、
          全体のtotal.lines.pctが80以上になる状態, or stop after 15 turns"

      - name: Commit changes
        if: ${{ steps.coverage.outputs.coverage < 80 }}
        run: |
          git config user.name "claude-bot"
          git config user.email "[email protected]"
          git add .
          git commit -m "test: auto-improved coverage via /goal" || echo "no changes"
          git push

特徴

  • PR作成時にカバレッジ80%未満なら自動で改善PR
  • Anthropic API Key は GitHub Secrets で管理
  • ターン上限15で暴走防止
  • 変更がなければ commit をスキップ

パターン2: curl から呼び出す

シェルスクリプトや別言語からの呼び出し。SSH先のサーバーで定期実行する想定。

#!/bin/bash
# scripts/nightly-report.sh — 毎晩02:00に cron で実行

export ANTHROPIC_API_KEY="$(cat ~/.config/claude/api-key)"

claude -p "/goal 前日のGitHub PR一覧を取得し、
レビュー観点別にカテゴリ分けして report-$(date +%Y-%m-%d).md に出力, or stop after 10 turns" \
  --permission-mode auto \
  --verbose 2>&1 | tee logs/nightly-$(date +%Y-%m-%d).log

EXIT_CODE=${PIPESTATUS[0]}
if [ $EXIT_CODE -eq 0 ]; then
  curl -X POST -H 'Content-Type: application/json' \
    -d "{\"text\":\"夜間 /goal 完了: $(date +%Y-%m-%d)\"}" \
    "$SLACK_WEBHOOK_URL"
else
  curl -X POST -H 'Content-Type: application/json' \
    -d "{\"text\":\"夜間 /goal 失敗 (exit $EXIT_CODE): $(date +%Y-%m-%d)\"}" \
    "$SLACK_WEBHOOK_URL"
fi

cron設定:

0 2 * * * /home/user/scripts/nightly-report.sh

パターン3: JavaScript(Node.js)から呼び出す

Webアプリのバックエンドから /goal を起動するパターン。Express ルートからジョブをキック。

// src/routes/trigger-goal.js
import { spawn } from 'node:child_process'
import express from 'express'

const router = express.Router()

router.post('/api/trigger-goal', async (req, res) => {
  const { goalCondition, maxTurns = 10 } = req.body

  // セキュリティ: ホワイトリスト形式で許可済みゴールのみ受け付け
  const allowedGoals = ['daily-report', 'weekly-summary', 'health-check']
  if (!allowedGoals.includes(req.body.goalKey)) {
    return res.status(400).json({ error: 'goalKey not allowed' })
  }

  const child = spawn('claude', [
    '-p',
    `/goal ${goalCondition}, or stop after ${maxTurns} turns`,
    '--permission-mode', 'auto',
  ], {
    env: { ...process.env, ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY },
    detached: true,
  })

  child.unref()  // バックグラウンド実行

  return res.json({
    status: 'started',
    pid: child.pid,
    goalKey: req.body.goalKey,
  })
})

export default router

重要なセキュリティポイント

  • 任意プロンプトを受け付けない(コマンドインジェクション防止)
  • ホワイトリスト形式で許可済みゴールのみ
  • 環境変数 ANTHROPIC_API_KEY を子プロセスに引き継ぐ

パターン4: Python から呼び出す

データ分析パイプラインから呼び出すパターン。Airflow や Prefect のタスクとして組み込める。

# tasks/run_goal.py
import subprocess
import os
import sys
from datetime import datetime

def run_goal(condition: str, max_turns: int = 10, timeout_sec: int = 1800) -> dict:
    """
    Claude Code /goal を非対話で実行。
    timeout_sec: タイムアウト(秒)、デフォルト30分
    """
    env = os.environ.copy()
    if 'ANTHROPIC_API_KEY' not in env:
        raise EnvironmentError('ANTHROPIC_API_KEY not set')

    start = datetime.now()
    result = subprocess.run(
        [
            'claude', '-p',
            f'/goal {condition}, or stop after {max_turns} turns',
            '--permission-mode', 'auto',
        ],
        env=env,
        capture_output=True,
        text=True,
        timeout=timeout_sec,
    )
    duration = (datetime.now() - start).total_seconds()

    return {
        'exit_code': result.returncode,
        'stdout': result.stdout,
        'stderr': result.stderr,
        'duration_sec': duration,
        'success': result.returncode == 0,
    }


if __name__ == '__main__':
    res = run_goal(
        condition='reports/daily-sales-$(date +%Y%m%d).md が生成された状態',
        max_turns=8,
    )
    print(f'Success: {res["success"]}, duration: {res["duration_sec"]:.1f}s')
    sys.exit(0 if res['success'] else 1)

並列ジョブと rate limit

複数 /goal を同時実行する場合、Anthropic APIのレート制限に注意する。

  • 個人プラン: 50リクエスト/分が目安
  • Pro/Enterprise: 上限緩和あり(要確認)

GitHub Actions の matrix strategy 例:

strategy:
  matrix:
    target: [auth, billing, dashboard, settings]
  max-parallel: 3  # 並列度を3に制限

Kanau Tech™ の運用では max-parallel: 3 を推奨。それ以上だと評価器のrate limitで 429 Too Many Requests を踏む。

認証の選び方

認証方式用途設定
ANTHROPIC_API_KEYCI/CD、サーバー実行GitHub Secrets / .env
ChatGPT OAuthローカル開発claude login chatgpt
保存済みOAuthトークン本番デーモン実行~/.claude/auth.json

CI/CDではAPI Key、ローカル開発ではChatGPT OAuthが標準パターン。

CI/CD統合のセキュリティ注意点

注意点対処
API Key の漏洩GitHub Secrets / Vault で管理、ログに出力しない
任意プロンプトの注入ホワイトリスト or 厳格バリデーション
本番DBへの書き込みCI/CD環境では本番接続文字列を渡さない
コスト爆発--timeoutmax_turns 必須、月予算アラート設定
並列暴走max-parallel 制限、Rate Limit監視

よくある質問

Headless mode とは何ですか?

対話画面を出さずに、コマンドラインから1回限りの実行を行うモードだ。claude -p "<プロンプト>" で起動でき、CI/CDジョブ内や定期バッチから呼び出せる。実行が完了するとexit codeを返して終了する。

GitHub Actions のシークレットはどう設定する?

Repository Settings → Secrets and variables → Actions で、ANTHROPIC_API_KEY または CLAUDE_AUTH_TOKEN を登録する。ジョブ内で env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} で参照する。

結果を後続ジョブに渡せますか?

可能だ。/goal 完了時にファイル(例: result.json)に出力させ、後続ジョブで読み取る。GitHub Actionsの upload-artifact でアーティファクト経由、または outputs でジョブ間変数として渡せる。

Webhook で通知できますか?

可能だ。/goal の done when に「Slack Webhook URL に POST して通知」を含めるか、CI/CD側で完了時にSlack/Discord通知を実装する。Webhook URLはシークレット管理してほしい。

並列ジョブは可能ですか?

可能だ。GitHub Actionsのmatrix strategyで複数 /goal を並列実行できる。ただしAnthropic APIのレート制限(個人プラン50リクエスト/分など)を超えないよう注意。Kanau Tech™の運用では max-parallel: 3 を推奨している。

関連記事

参照

御社のDX力、3分でチェックしませんか?

10問の簡単な質問でIT基盤・業務デジタル化・AI活用度を無料診断。改善のヒントもわかります。

無料DX診断を受ける →