# Agent Integration URL: /docs/tutorials/agent-integration/ Section: tutorials Tags: tutorial, amp, agents, github-action -------------------------------------------------------------------------------- Agent Integration This tutorial walks through setting up an AI agent to produce structured code reviews that render as formatted PR comments via the Agent Message Protocol (AMP). By the end, you'll have: Agent instructions that produce AMP JSON A GitHub Actions workflow that collects and renders agent output Formatted PR comments with severity badges, file links, and diff suggestions Prerequisites A GitHub repository An AI coding agent: Claude Code, GitHub Copilot, or Cursor The Kida GitHub Action (lbliii/kida) Step 1: Add agent instructions Agent instruction files tell your AI agent how to produce AMP-formatted output. Each agent reads instructions from a different location. Claude Create .claude/CLAUDE.md (or add to your existing file): When performing code reviews, wrap findings in a JSON code block tagged `amp:code-review`: ~~~ ```amp:code-review { "agent": "Claude", "model": "<your model>", "confidence": 0.85, "summary": "One-line review summary.", "findings": [ { "file": "path/to/file.py", "line": 42, "severity": "warn", "category": "security", "title": "Short finding title", "message": "Detailed explanation.", "suggestion": "How to fix.", "diff": "- old\n+ new", "confidence": 0.9 } ], "stats": { "files_reviewed": 5, "findings_count": 3, "by_severity": {"error": 0, "warn": 2, "info": 1, "suggestion": 0} } } ``` A full instruction file is available at `examples/amp/agent-instructions/CLAUDE.md` covering code-review, pr-summary, and security-scan message types. ### GitHub Copilot Create `.github/copilot-instructions.md` with the same JSON schema. Copilot reads this file automatically. See `examples/amp/agent-instructions/copilot-instructions.md`. ### Cursor Create `.cursorrules` at your repo root. See `examples/amp/agent-instructions/cursorrules.md`. ### Severity guide All agents should follow the same severity levels: | Severity | Meaning | When to use | | --- | --- | --- | | `error` | Blocking | Security vulnerabilities, data loss, crashes. Must fix. | | `warn` | Should fix | Bugs, race conditions, missing validation. | | `info` | FYI | Naming, style, minor improvements. | | `suggestion` | Optional | Alternative approaches, nice-to-haves. | Instruct agents to set `confidence` honestly. Findings below 0.5 are auto-collapsed in the rendered output so reviewers can focus on high-signal items. ## Step 2: Create the GitHub Actions workflow Create `.github/workflows/amp-review.yml`: ```yaml name: AMP Review on: pull_request: types: [opened, synchronize] permissions: contents: read pull-requests: write jobs: review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.14' - name: Install kida run: python -m pip install --quiet kida-templates - name: Collect AMP messages id: collect env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail mkdir -p .amp/collected # Source 1: .amp/ directory files for f in .amp/*.json; do [ -f "$f" ] || continue cp "$f" ".amp/collected/$(basename "$f")" done # Source 2: PR body amp: code blocks PR_BODY=$(gh pr view "${{ github.event.pull_request.number }}" \ --json body --jq '.body // ""') export PR_BODY if [ -n "$PR_BODY" ]; then python3 -c " import re, json, os body = os.environ['PR_BODY'] for msg_type, content in re.findall(r'\`\`\`amp:(\w[\w-]*)\s*\n(.*?)\`\`\`', body, re.DOTALL): try: data = json.loads(content.strip()) path = f'.amp/collected/{msg_type}.json' if not os.path.exists(path): json.dump(data, open(path, 'w'), indent=2) except json.JSONDecodeError: pass " fi # Count collected messages shopt -s nullglob FILES=(.amp/collected/*.json) echo "count=${#FILES[@]}" >> "$GITHUB_OUTPUT" - name: Render AMP messages if: steps.collect.outputs.count != '0' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail declare -A TEMPLATE_MAP=( ["code-review"]="code-review" ["pr-summary"]="pr-summary" ["security-scan"]="security-scan" ["dependency-review"]="dependency-review" ["deploy-preview"]="deploy-preview" ) PR_NUMBER="${{ github.event.pull_request.number }}" REPO="${{ github.repository }}" SHA="${{ github.event.pull_request.head.sha }}" for f in .amp/collected/*.json; do [ -f "$f" ] || continue BASENAME=$(basename "$f" .json) MSG_TYPE="${BASENAME%-comment}" TEMPLATE="${TEMPLATE_MAP[$MSG_TYPE]:-}" [ -z "$TEMPLATE" ] && continue # Inject repo context python3 -c " import json with open('$f') as fh: data = json.load(fh) data.setdefault('repository', '$REPO') data.setdefault('sha', '$SHA') data.setdefault('pr_number', $PR_NUMBER) json.dump(data, open('$f', 'w'), indent=2) " # Render OUTPUT=$(kida render "templates/${TEMPLATE}-report.md" \ --data "$f" --mode markdown) [ -z "$OUTPUT" ] && continue # Post with deduplication MARKER="<!-- amp:${MSG_TYPE} -->" BODY=$(printf '%s\n%s' "$MARKER" "$OUTPUT") EXISTING_ID=$(gh api \ "repos/${REPO}/issues/${PR_NUMBER}/comments" \ --paginate --jq ".[] | select(.body | startswith(\"$MARKER\")) | .id" \ 2>/dev/null | head -1) if [ -n "$EXISTING_ID" ]; then gh api "repos/${REPO}/issues/comments/${EXISTING_ID}" \ -X PATCH -f body="$BODY" --silent else gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" \ -f body="$BODY" --silent fi done ``` ### How collection works The workflow collects AMP messages from two sources, in priority order: 1. **`.amp/` directory** — Agents or CI steps write JSON files here (e.g., `.amp/code-review.json`). Highest priority. 2. **PR body** — Agents like Claude Code can embed `` ```amp:type `` code blocks directly in the PR description. File-based sources take precedence — if `.amp/code-review.json` exists, a code-review block in the PR body is ignored. > [!NOTE] > The full workflow in `.github/workflows/amp-review.yml` also collects from PR comments. The simplified workflow above omits that step for clarity. ### How rendering works For each collected message: 1. The message type is derived from the filename (e.g., `code-review.json` maps to `code-review`) 2. Repository and SHA context are injected for file permalink generation 3. The matching Kida template renders the JSON to markdown 4. The output is posted as a PR comment with an HTML marker (`<!-- amp:code-review -->`) for deduplication 5. On subsequent pushes, existing comments are updated in place ## Step 3: Test locally Before pushing, verify rendering locally with the example data: ```bash # Install kida pip install kida-templates # Render a code review kida render templates/code-review-report.md \ --data examples/amp/code-review.json \ --mode markdown # Render a PR summary kida render templates/pr-summary-report.md \ --data examples/amp/pr-summary.json \ --mode markdown # Render to terminal (with ANSI colors) kida render templates/code-review-report.md \ --data examples/amp/code-review.json \ --mode terminal ``` ## Step 4: Trigger a review 1. Push a branch and open a PR 2. If your agent is configured (e.g., Claude Code in a CI step, or Copilot's auto-review), it produces AMP JSON 3. The `amp-review.yml` workflow collects the JSON and renders it 4. A formatted PR comment appears with severity badges, file permalinks, and diff suggestions 5. On subsequent pushes, the comment updates in place ## Composing multiple agents When Claude and Copilot both review the same PR, you get separate AMP messages that render as separate PR comments (one per message type, deduplicated by the `<!-- amp:type -->` marker). The current `kida render` CLI does not expose a `--compose` flag, so composition is handled as an upstream data-preparation step, not at render time. - **One comment per message type** (default) — The workflow above already deduplicates by type using `<!-- amp:type -->` markers, so each agent's output gets its own auto-updating comment. - **Threaded or aggregated views** — Merge multiple agent outputs into a single AMP JSON payload in a CI step before passing it to `kida render`. For example, combine Claude and Semgrep security findings into one `security-scan.json`, then render once. See [[docs/usage/amp#composition|AMP Composition]] for the four composition models defined by the protocol. ## Adding new message types To support a new AMP message type: 1. **Define the schema** — Create `schemas/amp/v1/my-type.schema.json` 2. **Write a template** — Create `templates/my-type-report.md` using Kida syntax 3. **Update the workflow** — Add the type to the `TEMPLATE_MAP` in `amp-review.yml` 4. **Add agent instructions** — Tell agents how to produce the new JSON format See [[docs/usage/agent-templates#customizing-templates|Customizing Templates]] for template authoring patterns. ## Next steps - [[docs/usage/amp|Agent Message Protocol]] — protocol spec, surfaces, and composition - [[docs/usage/agent-templates|Agent Templates]] — schema details and customization for all built-in templates - [[docs/usage/github-action|GitHub Action]] — CI report rendering beyond agent messages -------------------------------------------------------------------------------- Metadata: - Word Count: 1185 - Reading Time: 6 minutes