GitHub Tools
Frameworks
Create a complete GitHub agent in 3 files with eve — defineDynamic registers all 42 tools, with durable human-in-the-loop approval (always, once, predicates).

eve is Vercel's filesystem-first agent framework: an agent is a folder with instructions, a model config, and tools. With @github-tools/sdk/eve, that folder becomes a complete GitHub agent in 3 files — all 42 tools registered from a single file, with durable human-in-the-loop approval that actually pauses the session until a person approves.

Add GitHub tools to an eve agent

The whole agent

Three files. That's the entire thing:

You are a GitHub assistant. Use the GitHub tools to inspect repos, PRs, and issues.
Ask before merging or closing anything destructive.

Run it:

Terminal
npx eve dev

You now have a GitHub agent that can read repos, review PRs, triage issues, and manage CI — with every write operation gated behind durable approval by default. The full example lives in examples/eve-agent/ (or pnpm dev:eve-agent from the monorepo root).

Install

Add eve and ai v7 (required peer of eve v0.19+) alongside the SDK:

pnpm add @github-tools/sdk eve ai zod

Ensure ai resolves to v7 — eve v0.19+ is not compatible with AI SDK v6. You still need GITHUB_TOKEN (or pass token explicitly). See Installation.

One file, all tools

createGithubTools() returns a defineDynamic value: eve resolves the tool set on session.started, so a single default export registers every tool. Scope and gate as needed:

agent/tools/github.ts
import { createGithubTools } from '@github-tools/sdk/eve'

export default createGithubTools({
  preset: ['code-review', 'issue-triage'],
  requireApproval: {
    mergePullRequest: true,
    createIssue: 'once',
    addPullRequestComment: false,
    createOrUpdateFile: ({ toolInput }) => toolInput?.owner !== 'vercel-labs',
  },
})

Map keys become tool names — the model sees listPullRequests, createIssue, and so on (same names as the AI SDK package). There is no automatic file-slug prefix when returning a tool map.

Durable approval, done right

This is eve's headline advantage over the boolean needsApproval on the AI SDK and Workflow paths: approval pauses the session durably until a human responds, and policies are expressive:

ValueMaps toBehavior
true / 'always'always()Require approval on every call
false / 'never'never()Skip approval
'once'once()Approve once per session, then auto-allow
predicatecustom ApprovalInput-dependent gate (toolInput, session context)
always() / once() / never()passthroughImport helpers from eve/tools/approval

Default (no requireApproval): all write tools → always(). Unlisted write tools keep the always() fail-safe default. Read tools never require approval.

For durable HITL with the standard boolean/per-tool config, use durable Workflow agents with WorkflowAgent. See also Control write safety for the AI SDK surface.

Cherry-pick one tool per file

For the filesystem-native eve layout, import individual factories:

agent/tools/list_pull_requests.ts
import { listPullRequests } from '@github-tools/sdk/eve'

export default listPullRequests()

Each factory returns a defineTool value. The filename slug becomes the tool name when exported alone.

Presets and options

All presets (code-review, issue-triage, repo-explorer, ci-ops, maintainer) work with createGithubTools. Options mirror the AI SDK surface:

OptionDescription
tokenGitHub PAT (defaults to GITHUB_TOKEN)
presetSingle preset or array to merge
requireApprovalGlobal, per-tool, or predicate approval (eve)
overridesPer-tool description, approval, toModelOutput, outputSchema
author / committer / coAuthorsCommit attribution for file/merge tools

High-volume read tools (listPullRequestFiles, getCommit, getFileContent) include conservative default toModelOutput projections — full payloads still reach channels; the model sees trimmed diffs/content.

Idempotency

eve replays completed steps but re-runs steps interrupted mid-execution:

ToolIdempotency
createOrUpdateFileNatural when content + sha unchanged
closeIssueNatural when already closed
createBranchNatural when branch exists at same SHA
addIssueComment, createIssue, mergePullRequest, …Not idempotent

Gate non-idempotent writes behind always() or once() where replay safety matters.

eve vs AI SDK vs Workflow SDK

AI SDKeveWorkflow SDK
Import@github-tools/sdk@github-tools/sdk/eve@github-tools/sdk/workflow
Tool registrationcreateGithubTools() objectdefineDynamic in agent/tools/createGithubTools() in workflow
Approvalboolean needsApprovalalways / once / predicatesboolean needsApproval (durable pause)
Durabilityin-processeve session (filesystem-first)"use workflow" steps

Roadmap

Per-session GitHub tokens via eve connections (auth: 'eve') are planned, backed by Vercel Connect — for now pass token explicitly or set GITHUB_TOKEN.

External references