All integrations

GitHub

Channel

Drive your agent from issues, pull requests, and comments.

At a glance

From Eve docs · synced Jul 22, 2026

Webhook route

POST /eve/v1/github

Environment variables

GITHUB_APP_ID
GitHub App id
GITHUB_APP_PRIVATE_KEY
GitHub App private key (PEM)
GITHUB_WEBHOOK_SECRET
verifies the webhook signature
GITHUB_APP_SLUG
supplies botName when it is not set in config

Capabilities

  • Human-in-the-loopGitHub comments have no interactive button or card affordance.
  • Proactive sessionsStart a session without an inbound mention through receive(github, { message, target, auth }) from a schedule run handler, or args.receive(github, ...) from another channel.
  • AttachmentsInbound file attachments are not supported on this channel today.

Derived from Eve's GitHub docs.

Install

Install the framework:

npm install eve@latest

Quick start

Create agent/channels/github.ts:

// agent/channels/github.tsimport { githubChannel } from "eve/channels/github";export default githubChannel({  appId: () => process.env.GITHUB_APP_ID!,  privateKey: () => process.env.GITHUB_APP_PRIVATE_KEY!,  webhookSecret: () => process.env.GITHUB_WEBHOOK_SECRET!,});

Configure

Create a GitHub App, subscribe to issue and pull-request events, and set the webhook URL to eve's route (/eve/v1/github). Provide the app ID, private key, and webhook secret through environment variables. See the GitHub channel docs for required permissions.

How it behaves

Excerpts from Eve's GitHub docs. Prefer the source when something looks out of date.

Dispatch

Inbound hooks return { auth } to dispatch, or null to ignore. Use defaultGitHubAuth(ctx) to derive auth from the actor.

import { defaultGitHubAuth, githubChannel } from "eve/channels/github";

export default githubChannel({
  botName: "my-agent",
  // Replaces the @mention gate. ctx.conversation.kind is "issue", "pull_request", or "review_thread".
  onComment: (ctx, comment) => ({ auth: defaultGitHubAuth(ctx) }),
  // Opt in; no default dispatch on these events.
  onIssue: (ctx, issue) => (issue.action === "opened" ? { auth: defaultGitHubAuth(ctx) } : null),
  onPullRequest: (ctx, pr) => (pr.action === "opened" ? { auth: defaultGitHubAuth(ctx) } : null),
  onCheckSuite: (ctx, suite) =>
    suite.action === "completed" &&
    suite.conclusion === "failure" &&
    suite.app.slug === "github-actions" &&
    suite.pullRequests.length > 0
      ? {
          auth: defaultGitHubAuth(ctx),
          context: [`Triage failed check suite ${suite.checkSuiteId} at ${suite.headSha}.`],
        }
      : null,
});

The CI hooks expose normalized action, status, conclusion, app.slug, headSha, and pullRequests fields, plus checkSuiteId, checkRunId, or workflowRunId. workflow_run is a GitHub Actions-only event, so its normalized app.slug is "github-actions". A dispatched CI turn is anchored to the first number in pullRequests; the hook still runs when the array is empty, but it must return null because there is no issue or PR thread for the session.

Delivery

When a turn starts, the channel adds an eyes reaction to the triggering comment (turn this off with progress: { reactions: false }). The reply comes back as a comment, on the timeline or in the review thread, and splits across multiple comments when it runs long. If the turn fails, you get a short error comment carrying an error id.

Human-in-the-loop (HITL)

GitHub comments have no interactive button or card affordance. A human-in-the-loop (HITL) input.requested event is posted as a comment prompt, and the user's reply comment maps back to the pending input request. Declare an events["input.requested"] handler to customize the prompt.

Proactive sessions

Start a session without an inbound mention through receive(github, { message, target, auth }) from a schedule run handler, or args.receive(github, ...) from another channel. The target requires owner, repo, and exactly one of issueNumber or pullRequestNumber.

Attachments

Inbound file attachments are not supported on this channel today. Repository contents reach the agent through the sandbox checkout below, not as message attachments.

PR context

Summon the agent on a PR and it always sees the diff. PR metadata and the changed-file patch land in context. Large generated files still appear in the list, but their patch body is dropped; add more paths to the skip list with pullRequestContext.excludedFiles.

Agents using GitHub