Build a GitHub agent with eve (direct import)
@github-tools/sdk/eve (the direct import documented on this page) is deprecated in favor of @github-tools/eve-extension, the recommended way to add GitHub tools to an eve agent. This direct import keeps working and isn't being removed, but new agents should mount the extension instead. See migrating from the direct import.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 53 tools registered from a single file, with durable human-in-the-loop approval that actually pauses the session until a person approves. This page documents the legacy direct-import path; for new agents, see the eve extension guide instead.
Add GitHub tools to an eve agent (deprecated direct import)
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.
For Vercel Connect, use connectGithubTools from @github-tools/sdk/connect/eve. It mints the token lazily. Do not top-level await getToken(...) in agent/tools/ modules.
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. Alternatively, pass include: ['listPullRequests', ...] to createGithubTools for the same exact set from a single file, see Presets and options below.
Presets and options
All presets (code-review, issue-triage, repo-explorer, ci-ops, security-audit, release-manager, 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 |
include | Tool names to add on top of preset (union), or the full set standalone |
exclude | Tool names to remove from the resolved preset + include set |
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 extension vs direct import vs AI SDK vs Workflow SDK
See the full comparison table on the eve extension page. This direct-import path occupies the "deprecated" column.
Vercel Connect
Skip GITHUB_TOKEN entirely and mint the token from a Connect connector. connectGithubTools derives scopes from preset and fetches the token lazily inside each tool call:
import { defineAgent } from 'eve'
export default defineAgent({
model: 'anthropic/claude-sonnet-5',
// TODO(eve-connect-bundle): remove when eve externalizes transitive @vercel/connect
build: {
externalDependencies: ['@vercel/connect'],
},
})
import { connectGithubTools } from '@github-tools/sdk/connect/eve'
export default connectGithubTools('github/my-connector', {
preset: 'maintainer',
})
See Vercel Connect for the connector setup checklist and multi-tenant scoping. connector also accepts a () => string | Promise<string> resolver for picking a connector per environment or tenant, see dynamic connector selection.
Prefer the eve extension for new agents
@github-tools/eve-extension packages the same tools as a mountable eve extension instead of importing @github-tools/sdk/eve directly into agent/tools/: a single pnpm add and a one-line mount under agent/extensions/, no CLI setup. This is now the recommended way to add GitHub tools to an eve agent; everything on this page is the deprecated predecessor.
See the full eve extension guide for install, mount, config schema, and Vercel Connect examples, and migrating from the direct import if you have an existing agent using @github-tools/sdk/eve.
External references
- How to build a GitHub agent with eve and GitHub tools
- eve documentation
- Dynamic capabilities (bundled with the
evepackage) - Human-in-the-loop