Build a GitHub agent with eve
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.
import { defineAgent } from 'eve'
export default defineAgent({
model: 'anthropic/claude-sonnet-5',
})
import { createGithubTools } from '@github-tools/sdk/eve'
export default createGithubTools({
preset: 'maintainer',
})
Run it:
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
npm install @github-tools/sdk eve ai zod
yarn add @github-tools/sdk eve ai zod
bun 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:
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:
| Value | Maps to | Behavior |
|---|---|---|
true / 'always' | always() | Require approval on every call |
false / 'never' | never() | Skip approval |
'once' | once() | Approve once per session, then auto-allow |
| predicate | custom Approval | Input-dependent gate (toolInput, session context) |
always() / once() / never() | passthrough | Import 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:
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:
| Option | Description |
|---|---|
token | GitHub PAT (defaults to GITHUB_TOKEN) |
preset | Single preset or array to merge |
requireApproval | Global, per-tool, or predicate approval (eve) |
overrides | Per-tool description, approval, toModelOutput, outputSchema |
author / committer / coAuthors | Commit 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:
| Tool | Idempotency |
|---|---|
createOrUpdateFile | Natural when content + sha unchanged |
closeIssue | Natural when already closed |
createBranch | Natural 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 SDK | eve | Workflow SDK | |
|---|---|---|---|
| Import | @github-tools/sdk | @github-tools/sdk/eve | @github-tools/sdk/workflow |
| Tool registration | createGithubTools() object | defineDynamic in agent/tools/ | createGithubTools() in workflow |
| Approval | boolean needsApproval | always / once / predicates | boolean needsApproval (durable pause) |
| Durability | in-process | eve 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
- eve documentation
- Dynamic capabilities (bundled with the
evepackage) - Human-in-the-loop