---
title: "API"
description: "Every entry point the packages publish, with each function's signature, options and return value."
canonical_url: "https://github-tools.com/reference/api"
---
# API

> Every entry point the packages publish, with each function's signature, options and return value.

`@github-tools/sdk` publishes eight entry points, and `@github-tools/eve-extension` one more. Each section lists what an entry point exports; the guides linked from each one explain when to use it.

<table>
<thead>
  <tr>
    <th>
      Entry point
    </th>
    
    <th>
      For
    </th>
    
    <th>
      Peer packages
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <a href="#github-toolssdk">
        <code>
          @github-tools/sdk
        </code>
      </a>
    </td>
    
    <td>
      AI SDK tools and agent
    </td>
    
    <td>
      <code>
        ai
      </code>
      
      , <code>
        zod
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="#github-toolssdkworkflow">
        <code>
          @github-tools/sdk/workflow
        </code>
      </a>
    </td>
    
    <td>
      Durable agent
    </td>
    
    <td>
      <code>
        ai
      </code>
      
      , <code>
        zod
      </code>
      
      , <code>
        workflow
      </code>
      
      , <code>
        @ai-sdk/workflow
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="#github-toolssdkconnect">
        <code>
          @github-tools/sdk/connect
        </code>
      </a>
    </td>
    
    <td>
      Tokens from Vercel Connect
    </td>
    
    <td>
      <code>
        ai
      </code>
      
      , <code>
        zod
      </code>
      
      , <code>
        @vercel/connect
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="#github-toolssdktanstack">
        <code>
          @github-tools/sdk/tanstack
        </code>
      </a>
    </td>
    
    <td>
      TanStack AI tools and agent
    </td>
    
    <td>
      <code>
        @tanstack/ai
      </code>
      
      , <code>
        zod
      </code>
      
      , and <code>
        @tanstack/ai-vercel-gateway
      </code>
      
       for the default decision adapter
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="#github-toolssdktanstackinterrupts">
        <code>
          @github-tools/sdk/tanstack/interrupts
        </code>
      </a>
    </td>
    
    <td>
      The approval interrupt, safe in the browser
    </td>
    
    <td>
      <code>
        @tanstack/ai
      </code>
      
      , <code>
        zod
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="#github-toolssdkeve-runtime">
        <code>
          @github-tools/sdk/eve-runtime
        </code>
      </a>
    </td>
    
    <td>
      Building blocks of the eve extension
    </td>
    
    <td>
      <code>
        eve
      </code>
      
      , <code>
        ai
      </code>
      
      , <code>
        zod
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="#github-toolseve-extension">
        <code>
          @github-tools/eve-extension
        </code>
      </a>
    </td>
    
    <td>
      GitHub tools in an eve agent
    </td>
    
    <td>
      <code>
        eve
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        @github-tools/sdk/eve
      </code>
      
      , <code>
        @github-tools/sdk/connect/eve
      </code>
    </td>
    
    <td>
      Deprecated. See <a href="https://github-tools.com/reference/upgrade">
        Upgrade
      </a>
    </td>
    
    <td>
      <code>
        eve
      </code>
    </td>
  </tr>
</tbody>
</table>

## `@github-tools/sdk`

### `createGithubTools`

```ts
function createGithubTools(options?: GithubToolsOptions): ToolSet
```

Returns an AI SDK `ToolSet` keyed by tool name, typed to the preset you pass. With no `preset`, it holds all 97 [tools](https://github-tools.com/reference/tools).

<table>
<thead>
  <tr>
    <th>
      Option
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        token
      </code>
    </td>
    
    <td>
      <code>
        GithubTokenInput
      </code>
    </td>
    
    <td>
      <code>
        process.env.GITHUB_TOKEN
      </code>
    </td>
    
    <td>
      A token, or an async provider called before every tool call. A missing string token throws <code>
        TOKEN_REQUIRED
      </code>
      
       when the tools are created
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        preset
      </code>
    </td>
    
    <td>
      <code>
        GithubToolPreset | GithubToolPreset[]
      </code>
    </td>
    
    <td>
      all tools
    </td>
    
    <td>
      Keep only the tools of one or more <a href="https://github-tools.com/presets">
        presets
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        requireApproval
      </code>
    </td>
    
    <td>
      <code>
        ApprovalConfig
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Which writes ask first. See <a href="https://github-tools.com/approval#configure">
        Approval
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        evaluation
      </code>
    </td>
    
    <td>
      <code>
        GithubEvaluationOptions
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      Tuning for <code>
        'auto'
      </code>
      
      . See <a href="#githubevaluationoptions">
        below
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        context
      </code>
    </td>
    
    <td>
      <code>
        GithubToolsContext
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      Default <code>
        owner
      </code>
      
      , <code>
        repo
      </code>
      
      , <code>
        pullNumber
      </code>
      
      , <code>
        issueNumber
      </code>
      
       and <code>
        ref
      </code>
      
      . See <a href="https://github-tools.com/context">
        Context
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        overrides
      </code>
    </td>
    
    <td>
      <code>
        Partial<Record<GithubToolName, ToolOverrides>>
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      Per-tool <code>
        description
      </code>
      
      , <code>
        title
      </code>
      
      , <code>
        needsApproval
      </code>
      
      , <code>
        strict
      </code>
      
      , <code>
        providerOptions
      </code>
      
      , <code>
        toModelOutput
      </code>
      
      , <code>
        onInputStart
      </code>
      
      , <code>
        onInputDelta
      </code>
      
      , <code>
        onInputAvailable
      </code>
      
      . <code>
        execute
      </code>
      
       and the schemas can't be overridden
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        author
      </code>
    </td>
    
    <td>
      <code>
        CommitIdentity
      </code>
    </td>
    
    <td>
      the token's user
    </td>
    
    <td>
      Commit author for <code>
        createOrUpdateFile
      </code>
      
       and <code>
        editFiles
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        committer
      </code>
    </td>
    
    <td>
      <code>
        CommitIdentity
      </code>
    </td>
    
    <td>
      the token's user
    </td>
    
    <td>
      Committer for the same tools
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        coAuthors
      </code>
    </td>
    
    <td>
      <code>
        CommitIdentity[]
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      <code>
        Co-authored-by
      </code>
      
       trailers on <code>
        createOrUpdateFile
      </code>
      
      , <code>
        editFiles
      </code>
      
      , <code>
        mergePullRequest
      </code>
      
       and <code>
        enablePullRequestAutoMerge
      </code>
      
      . See <a href="https://github-tools.com/commits">
        Commits
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        guardrails
      </code>
    </td>
    
    <td>
      <code>
        GithubGuardrails
      </code>
    </td>
    
    <td>
      <code>
        { secrets: 'block' }
      </code>
    </td>
    
    <td>
      Repositories and branches any call may act on, whoever approves it. A blocked call throws <code>
        GUARDRAIL_BLOCKED
      </code>
      
      . See <a href="https://github-tools.com/approval#guardrails">
        Guardrails
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        dryRun
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Shadow mode: reads run, and writes return a <code>
        GithubDryRunResult
      </code>
      
       without reaching GitHub or asking anyone. See <a href="https://github-tools.com/approval#shadow-mode">
        Shadow mode
      </a>
    </td>
  </tr>
</tbody>
</table>

Object results carry a `rateLimit` field (`GithubRateLimit`) from the last GitHub response. `createGithubTools` strips it from what the model sees; your hooks and UI still get it.

### `createGithubAgent`

```ts
function createGithubAgent(options: CreateGithubAgentOptions): ToolLoopAgent
```

Returns an AI SDK `ToolLoopAgent` with the tools, the preset's system prompt and call-level approval. It takes every `createGithubTools` option, every `ToolLoopAgent` setting except `tools` and `instructions` (such as `stopWhen`, `prepareCall` or `experimental_toolApprovalSecret`), and these:

<table>
<thead>
  <tr>
    <th>
      Option
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        model
      </code>
    </td>
    
    <td>
      <code>
        LanguageModel
      </code>
    </td>
    
    <td>
      required
    </td>
    
    <td>
      A Gateway model ID or a model instance
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        preset
      </code>
    </td>
    
    <td>
      <code>
        GithubToolPreset | GithubToolPreset[] | 'auto'
      </code>
    </td>
    
    <td>
      all tools
    </td>
    
    <td>
      <code>
        'auto'
      </code>
      
       lets the decision model pick the tools. See <a href="https://github-tools.com/presets">
        Presets
      </a>
      
      . Needs <code>
        ai
      </code>
      
       7.0.105 or later
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        instructions
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      the preset's prompt
    </td>
    
    <td>
      Replaces the system prompt. <code>
        context
      </code>
      
       is still appended
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        additionalInstructions
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      Appended to the preset's prompt. Ignored when <code>
        instructions
      </code>
      
       is set
    </td>
  </tr>
</tbody>
</table>

With `requireApproval: 'auto'`, an approval request carries the decision model's reason, and a call it let through is recorded with `isAutomatic: true`. A write that `guardrails` block is denied with the reason, before anyone is asked. A tool from outside the GitHub catalog, for example one added in `prepareCall`, keeps its own `needsApproval`. Passing your own `toolApproval` replaces this policy.

### `GithubEvaluationOptions`

Tunes `requireApproval: 'auto'` and `preset: 'auto'`. Every field is optional.

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        model
      </code>
    </td>
    
    <td>
      <code>
        Experimental_EvaluationModel
      </code>
    </td>
    
    <td>
      <code>
        'typesafe-ai/jev-1.14.0'
      </code>
    </td>
    
    <td>
      Decision model: a Gateway ID or an instance
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        providerOptions
      </code>
    </td>
    
    <td>
      <code>
        Record<string, Record<string, JSONValue>>
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      Passed to every decision call
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        maxRisk
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Highest risk that runs without asking, from <code>
        0
      </code>
      
       to <code>
        2
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        minIntent
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.6
      </code>
    </td>
    
    <td>
      Lowest probability that the user asked for this call
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        selection
      </code>
    </td>
    
    <td>
      <code>
        'tools' | 'presets'
      </code>
    </td>
    
    <td>
      <code>
        'tools'
      </code>
    </td>
    
    <td>
      What <code>
        preset: 'auto'
      </code>
      
       picks
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scope
      </code>
    </td>
    
    <td>
      <code>
        'session' | 'turn'
      </code>
    </td>
    
    <td>
      <code>
        'session'
      </code>
      
       (<code>
        'turn'
      </code>
      
       with <code>
        selection: 'presets'
      </code>
      
      )
    </td>
    
    <td>
      Pick once per conversation, or again for each request
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        minToolProbability
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Lowest probability for a tool to be listed
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        maxTools
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        8
      </code>
    </td>
    
    <td>
      Most tools listed beyond the core read tools
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        minPresetProbability
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.7
      </code>
    </td>
    
    <td>
      Lowest probability for a preset to be picked
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        maxPresets
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      Most presets combined
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        store
      </code>
    </td>
    
    <td>
      <code>
        { get, set }
      </code>
    </td>
    
    <td>
      in memory
    </td>
    
    <td>
      Keeps <code>
        preset: 'auto'
      </code>
      
       picks across processes
    </td>
  </tr>
</tbody>
</table>

`createGithubAgent` throws `SESSION_SCOPE_NEEDS_TOOL_SELECTION` for `scope: 'session'` with `selection: 'presets'`.

### Tool factories

Each of the 97 tools is also exported as a factory, for building a tool set by hand:

```ts
getRepository(token: GithubTokenInput): GithubTool
createIssue(token: GithubTokenInput, options?: ToolOptions): GithubTool
createOrUpdateFile(token: GithubTokenInput, options?: CommitToolOptions): GithubTool
mergePullRequest(token: GithubTokenInput, options?: ToolOptions & { coAuthors?: CommitIdentity[] }): GithubTool
```

Read factories take only the token. Write factories take `needsApproval` (a boolean or an AI SDK approval function), `true` by default. `CommitToolOptions` adds `author`, `committer` and `coAuthors`. `editFiles` takes the same options as `createOrUpdateFile`, and `enablePullRequestAutoMerge` the same as `mergePullRequest`. `mergePullRequest` and `enablePullRequestAutoMerge` also take `branches`, and `updatePullRequestBranch` takes `guardrails`, to check the pull request's branches. Factories don't apply `context`, `guardrails` or `dryRun`, or strip `rateLimit`; `createGithubTools` does.

### `withGithubGuardrails`

```ts
function withGithubGuardrails(token: GithubTokenInput | undefined, guardrails: GithubGuardrails | undefined): (call?: GithubTokenCall) => Promise<string>
```

Wraps a token so every call it resolves for is checked against `guardrails` first, including the default credential check. A blocked call throws `GUARDRAIL_BLOCKED` before any request reaches GitHub. Use it with the factories; `createGithubTools({ guardrails })` applies it for you. See [Guardrails](https://github-tools.com/approval#guardrails).

### `resolveGithubToken`

```ts
function resolveGithubToken(token?: GithubTokenInput, call?: GithubTokenCall): Promise<string>
```

Resolves a token string, a provider, or `GITHUB_TOKEN` to a string. Throws `TOKEN_REQUIRED` when none is available.

### `createOctokit`

```ts
function createOctokit(token: string): Octokit
```

Returns an [`octokit`](https://github.com/octokit/octokit.js) client that sends the GitHub API version header the tools use and turns failures into `githubToolsErrors`. Use it for calls your code makes without a model:

```ts
const octokit = createOctokit(await resolveGithubToken())
const { data } = await octokit.rest.repos.get({ owner: 'vercel-labs', repo: 'github-tools' })
```

### `githubToolsErrors`

The [evlog](https://evlog.dev) error catalog behind every `github_tools.*` error, each with `why` and `fix`. [Errors](https://github-tools.com/errors) lists the codes.

### `selectTools` and `selectPresets`

```ts
function selectTools(messages: ModelMessage[], options?: GithubEvaluationOptions, abortSignal?: AbortSignal): Promise<GithubToolName[]>
function selectPresets(messages: ModelMessage[], options?: GithubEvaluationOptions, abortSignal?: AbortSignal): Promise<GithubToolPreset[]>
```

The routing behind `preset: 'auto'`, for your own `prepareStep` or `activeTools`. `selectTools` returns the core read tools plus up to `maxTools` others; `selectPresets` returns up to `maxPresets` presets, never `maintainer`. When the decision call fails, both fall back to `repo-explorer` and log `EVALUATION_FAILED`.

### Constants

<table>
<thead>
  <tr>
    <th>
      Export
    </th>
    
    <th>
      Value
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        PRESET_TOOLS
      </code>
    </td>
    
    <td>
      <code>
        Record<GithubToolPreset, readonly GithubToolName[]>
      </code>
      
      : the tools of each preset
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GITHUB_TOOL_NAMES
      </code>
    </td>
    
    <td>
      <code>
        { [name]: name }
      </code>
      
       for all 97 tools. <code>
        Object.keys()
      </code>
      
       gives the list
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GITHUB_WRITE_TOOLS
      </code>
    </td>
    
    <td>
      <code>
        { [name]: name }
      </code>
      
       for the 48 write tools
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CORE_READ_TOOLS
      </code>
    </td>
    
    <td>
      <code>
        ['getRepository', 'getFileContent', 'getRepositoryTree', 'searchCode', 'listCommits']
      </code>
      
      , in every preset
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        AUTO_APPROVAL_TOOLS
      </code>
    </td>
    
    <td>
      The 14 write tools <code>
        requireApproval: 'auto'
      </code>
      
       evaluates
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        DEFAULT_EVALUATION_MODEL
      </code>
    </td>
    
    <td>
      <code>
        'typesafe-ai/jev-1.14.0'
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CALL_GITHUB_TOOL
      </code>
    </td>
    
    <td>
      <code>
        'callGithubTool'
      </code>
      
      , the tool <code>
        preset: 'auto'
      </code>
      
       adds to reach unlisted tools
    </td>
  </tr>
</tbody>
</table>

### Types

<table>
<thead>
  <tr>
    <th>
      Type
    </th>
    
    <th>
      Shape
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        GithubTokenInput
      </code>
    </td>
    
    <td>
      <code>
        string | ((call?: GithubTokenCall) => Promise<string>)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GithubTokenCall
      </code>
    </td>
    
    <td>
      <code>
        { toolName, input, owner?, repo? }
      </code>
      
      : the call a provider mints for. <code>
        owner
      </code>
      
       and <code>
        repo
      </code>
      
       are unset for search, gist and notification tools
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ApprovalConfig
      </code>
    </td>
    
    <td>
      <code>
        boolean | 'auto' | Partial<Record<GithubWriteToolName, boolean | 'auto'>>
      </code>
      
      . <code>
        StaticApprovalConfig
      </code>
      
       is the same without <code>
        'auto'
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GithubToolsContext
      </code>
    </td>
    
    <td>
      <code>
        { owner?, repo?, pullNumber?, issueNumber?, ref? }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CommitIdentity
      </code>
    </td>
    
    <td>
      <code>
        { name: string, email: string }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GithubToolPreset
      </code>
    </td>
    
    <td>
      One of the ten <a href="https://github-tools.com/presets">
        preset
      </a>
      
       names
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GithubGuardrails
      </code>
    </td>
    
    <td>
      <code>
        { repositories?: string[], branches?: string[], secrets?: 'block' | 'allow' }
      </code>
      
      . <code>
        repositories
      </code>
      
       takes <code>
        owner/repo
      </code>
      
       or <code>
        owner/*
      </code>
      
      , <code>
        branches
      </code>
      
       takes names or patterns such as <code>
        agent/*
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GithubDryRunResult
      </code>
    </td>
    
    <td>
      <code>
        { dryRun: true, tool, input, approval?, message }
      </code>
      
      : what a write returns under <code>
        dryRun
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GithubDryRunApproval
      </code>
    </td>
    
    <td>
      <code>
        { required: boolean, reason? }
      </code>
      
      : whether approval would have asked a person, with the decision model's verdict under <code>
        'auto'
      </code>
    </td>
  </tr>
</tbody>
</table>

Also exported: `GithubToolName`, `GithubWriteToolName`, `ToolApprovalMode`, `ToolOverrides`, `ToolOptions`, `CommitToolOptions`, `GithubTool`, `GithubTools`, `GithubToolsOptions`, `CreateGithubAgentOptions`, `AllGithubTools`, `GithubToolsForPreset`, `PickGithubTools`, `PresetToolName`, `CombinedPresetToolNames`, `GithubRateLimit`, `Octokit`.

## `@github-tools/sdk/workflow`

### `createDurableGithubAgent`

```ts
function createDurableGithubAgent(options: CreateDurableGithubAgentOptions): DurableGithubAgent
```

Returns an agent built on `WorkflowAgent`. Call it inside a `"use workflow"` function: each model call and tool call runs as a workflow step, and a write that needs approval pauses the run. It takes every `WorkflowAgent` option except `tools` and `instructions` (such as `stopWhen` or `experimental_toolApprovalSecret`), and `model`, `token`, `preset`, `overrides`, `context`, `instructions`, `additionalInstructions`, `author`, `committer`, `coAuthors`, `guardrails` and `dryRun` as above, with two differences:

<table>
<thead>
  <tr>
    <th>
      Option
    </th>
    
    <th>
      Difference
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        preset
      </code>
    </td>
    
    <td>
      No <code>
        'auto'
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        requireApproval
      </code>
    </td>
    
    <td>
      <code>
        StaticApprovalConfig
      </code>
      
      : no <code>
        'auto'
      </code>
      
      , because the decision call can't run inside a workflow function
    </td>
  </tr>
</tbody>
</table>

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      What it does
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        stream({ messages, writable })
      </code>
    </td>
    
    <td>
      Writes <code>
        ModelCallStreamPart
      </code>
      
      s to the writable, for chat UIs
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        generate(options)
      </code>
    </td>
    
    <td>
      Returns the finished result, for bots and jobs. Needs <code>
        @ai-sdk/workflow
      </code>
      
       2.0.59 or later, otherwise throws <code>
        DURABLE_GENERATE_UNAVAILABLE
      </code>
      
      . Stops after 20 steps unless <code>
        stopWhen
      </code>
      
       says otherwise
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tools
      </code>
    </td>
    
    <td>
      The agent's tool set
    </td>
  </tr>
</tbody>
</table>

The entry point also re-exports `createGithubTools`, `createGithubAgent`, `resolveGithubToken`, the constants and the types above. See [Vercel Workflow](https://github-tools.com/integrations/workflow).

## `@github-tools/sdk/connect`

### `connectGithubTools`

```ts
function connectGithubTools(connector: GithubConnectorInput, options?: ConnectGithubToolsOptions): ToolSet
```

`createGithubTools` with a token from a Vercel Connect connector. It takes every `createGithubTools` option except `token`, plus `connect`, and scopes the token to `preset`.

### `connectGithubToken`

```ts
function connectGithubToken(connector: GithubConnectorInput, options?: ConnectGithubTokenOptions): GithubTokenInput
```

A token provider for any `token` option. It mints a token on each call; Connect caches it per connector and parameters.

<table>
<thead>
  <tr>
    <th>
      Option
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        preset
      </code>
    </td>
    
    <td>
      <code>
        GithubToolPreset | GithubToolPreset[]
      </code>
    </td>
    
    <td>
      Scopes the token to these presets. Pass the same presets as the tools
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        include
      </code>
      
      , <code>
        exclude
      </code>
    </td>
    
    <td>
      <code>
        GithubToolName[]
      </code>
    </td>
    
    <td>
      Scopes the token to an exact tool selection instead
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        params
      </code>
    </td>
    
    <td>
      <code>
        GithubConnectParams | (call?) => GithubConnectParams
      </code>
    </td>
    
    <td>
      Token parameters, static or per call
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        connectOptions
      </code>
    </td>
    
    <td>
      <code>
        ConnectOptions
      </code>
    </td>
    
    <td>
      Passed to <code>
        @vercel/connect
      </code>
    </td>
  </tr>
</tbody>
</table>

<table>
<thead>
  <tr>
    <th>
      Type
    </th>
    
    <th>
      Shape
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        GithubConnectorInput
      </code>
    </td>
    
    <td>
      <code>
        string | (() => string | Promise<string>)
      </code>
      
      : a connector name, or a resolver called on every token request
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GithubConnectParams
      </code>
    </td>
    
    <td>
      Connect's <code>
        ConnectTokenParams
      </code>
      
       with <code>
        subject
      </code>
      
       (default <code>
        { type: 'app' }
      </code>
      
      , or <code>
        { type: 'user', id }
      </code>
      
       for <a href="https://github-tools.com/auth#per-user-tokens">
        per-user tokens
      </a>
      
      ) and <code>
        repositories
      </code>
      
       to limit the token. <code>
        scopes
      </code>
      
       replaces the preset's scopes
    </td>
  </tr>
</tbody>
</table>

An app token targets the installation that owns the call's repository unless `installationId`, `authorizationDetails` or `repositories` pins one. See [Auth](https://github-tools.com/auth#vercel-connect).

### Scope helpers

<table>
<thead>
  <tr>
    <th>
      Export
    </th>
    
    <th>
      Returns
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        connectGithubScopesForPreset(preset?)
      </code>
    </td>
    
    <td>
      Scopes for one or more presets, or every tool's scopes without one
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        connectGithubScopesForTools(names)
      </code>
    </td>
    
    <td>
      Scopes covering exactly these tools, always with <code>
        metadata:read
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        connectGithubScopesForSelection({ preset?, include?, exclude? })
      </code>
    </td>
    
    <td>
      The scopes <code>
        connectGithubToken
      </code>
      
       requests when <code>
        params.scopes
      </code>
      
       is unset
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        PRESET_CONNECT_SCOPES
      </code>
      
      , <code>
        TOOL_CONNECT_SCOPES
      </code>
    </td>
    
    <td>
      The scopes per preset and per tool. Gist and notification tools have none, because installation tokens can't call those APIs
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        resolveGithubConnector(connector)
      </code>
    </td>
    
    <td>
      The connector name a <code>
        GithubConnectorInput
      </code>
      
       resolves to
    </td>
  </tr>
</tbody>
</table>

## `@github-tools/sdk/tanstack`

Native [TanStack AI](https://github-tools.com/integrations/tanstack-ai) server tools, with the same names and inputs.

### `createGithubTools` for TanStack

```ts
function createGithubTools(options?: CreateGithubToolsOptions): GithubTanstackTool[]
```

Returns an array of server tools. Takes `token`, `preset`, `requireApproval`, `context`, `author`, `committer`, `coAuthors`, `guardrails` and `dryRun` as in the AI SDK version, and `overrides` limited to `description` and a boolean `needsApproval`. `true` and `false` approval use TanStack's own approval; `'auto'` needs the middleware below, and without it those writes keep asking.

### `createGithubAgent` for TanStack

```ts
function createGithubAgent(options: CreateGithubAgentOptions): GithubAgent
```

Takes the tool options, every TanStack `chat()` setting such as `adapter` (required) and `modelOptions`, and:

<table>
<thead>
  <tr>
    <th>
      Option
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        preset
      </code>
    </td>
    
    <td>
      A preset, an array, or <code>
        'auto'
      </code>
      
       to route each new request
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        instructions
      </code>
      
      , <code>
        additionalInstructions
      </code>
    </td>
    
    <td>
      As in the AI SDK version
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        evaluation
      </code>
    </td>
    
    <td>
      <code>
        { adapter?, maxRisk?, minIntent?, minPresetProbability?, maxPresets? }
      </code>
      
      . The default adapter is <code>
        vercelGatewayDecider('typesafe-ai/jev')
      </code>
      
       from <code>
        @tanstack/ai-vercel-gateway
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        middleware
      </code>
    </td>
    
    <td>
      More TanStack middleware, run after the approval middleware
    </td>
  </tr>
</tbody>
</table>

`agent.stream({ prompt })` returns TanStack's event stream, including approval interrupts. `agent.generate({ prompt })` returns `Promise<string>` and throws when the run stops for an approval. Both take `messages` instead of `prompt`; the agent keeps no history between calls.

### Other exports

<table>
<thead>
  <tr>
    <th>
      Export
    </th>
    
    <th>
      What it is
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        createGithubApprovalMiddleware({ tools, evaluation? })
      </code>
    </td>
    
    <td>
      Runs the <code>
        'auto'
      </code>
      
       decision before each write and raises <code>
        githubToolApproval
      </code>
      
       when a person must answer. Pass it the same tools as <code>
        chat()
      </code>
      
      . <code>
        createGithubAgent
      </code>
      
       adds it for you
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getRepository(token, options?)
      </code>
      
       and the 96 other factories
    </td>
    
    <td>
      One server tool. <code>
        options
      </code>
      
      : <code>
        description
      </code>
      
      , <code>
        needsApproval
      </code>
      
       (<code>
        boolean | 'auto'
      </code>
      
      ), <code>
        context
      </code>
      
      , <code>
        author
      </code>
      
      , <code>
        committer
      </code>
      
      , <code>
        coAuthors
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        selectPresets(messages, evaluation?, signal?)
      </code>
    </td>
    
    <td>
      Preset routing with the TanStack adapter
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        PRESET_TOOLS
      </code>
      
      , <code>
        GITHUB_TOOL_NAMES
      </code>
      
      , <code>
        GITHUB_WRITE_TOOLS
      </code>
      
      , <code>
        AUTO_APPROVAL_TOOLS
      </code>
      
      , <code>
        DEFAULT_EVALUATION_MODEL
      </code>
    </td>
    
    <td>
      As above
    </td>
  </tr>
</tbody>
</table>

## `@github-tools/sdk/tanstack/interrupts`

`githubToolApproval` is the interrupt definition (`id: 'github-tools.approval'`) to register on both the server and the client. Its payload is `{ toolCallId, toolName, input }` and its response `{ approved: boolean }`. An answer applies only to that call with that input.

## `@github-tools/sdk/eve-runtime`

The building blocks `@github-tools/eve-extension` is made of. Mount the extension instead unless you're building your own eve integration.

<table>
<thead>
  <tr>
    <th>
      Export
    </th>
    
    <th>
      What it does
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        createEveGithubToolsDynamic(options)
      </code>
    </td>
    
    <td>
      A <code>
        defineDynamic
      </code>
      
       tool set from <code>
        EveGithubToolsOptions
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        buildEveToolMap(options)
      </code>
      
      , <code>
        buildEveToolDefinition(...)
      </code>
    </td>
    
    <td>
      eve <code>
        defineTool
      </code>
      
       values for the selected tools
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        listEveToolDescriptors(options)
      </code>
    </td>
    
    <td>
      Tool descriptors without <code>
        execute
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        listResolvedEveToolNames({ preset?, include?, exclude? })
      </code>
    </td>
    
    <td>
      The tool names a selection resolves to
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        executeGithubEveTool(name, input, options)
      </code>
    </td>
    
    <td>
      Runs one tool by name, and throws when the call fails
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        formatGithubEveToolOutput
      </code>
      
      , <code>
        hasGithubEveToolModelOutput
      </code>
    </td>
    
    <td>
      The model-facing output of a tool's result
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mapEveApprovalValue
      </code>
      
      , <code>
        resolveEveApproval
      </code>
      
      , <code>
        resolveEveToolApproval
      </code>
      
      , <code>
        isEveApprovalDisabled
      </code>
    </td>
    
    <td>
      Map <code>
        true
      </code>
      
      , <code>
        'once'
      </code>
      
      , <code>
        'never'
      </code>
      
       and predicates to eve approval policies
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        needsAutoApproval
      </code>
      
      , <code>
        evaluateTools
      </code>
      
      , <code>
        evaluatePresets
      </code>
      
      , <code>
        selectTools
      </code>
      
      , <code>
        selectPresets
      </code>
      
      , <code>
        fallbackTools
      </code>
      
      , <code>
        fallbackPresets
      </code>
      
      , <code>
        latestUserText
      </code>
    </td>
    
    <td>
      The decision model calls behind the <code>
        'auto'
      </code>
      
       options
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        autoApprovalDecision
      </code>
    </td>
    
    <td>
      Asks the decision model about one GitHub write and returns <code>
        { ask, reason }
      </code>
      
      , the verdict the extension adds to approval prompts
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        githubGuardrailViolation(name, input, { context, guardrails })
      </code>
    </td>
    
    <td>
      Why <code>
        guardrails
      </code>
      
       block a call after <code>
        context
      </code>
      
       defaults, or <code>
        undefined
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        resolveToolGuidance(options)
      </code>
    </td>
    
    <td>
      The tool-usage instructions without the preset's "You are" opener
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        withGithubCallerAccess(token, { login, repository? })
      </code>
    </td>
    
    <td>
      Wraps a token so each call is first checked against what <code>
        login
      </code>
      
       may do: their role on the call's target repository, and for a search, a token that reaches <code>
        repository
      </code>
      
       only. A refused call throws <code>
        CALLER_FORBIDDEN
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        githubRoleRank({ permission, roleName })
      </code>
      
      , <code>
        GITHUB_ROLES
      </code>
    </td>
    
    <td>
      GitHub's repository roles in order, and the rank of a collaborator permission answer
    </td>
  </tr>
</tbody>
</table>

It also exports `resolveGithubToken`, `githubToolsErrors`, the constants and the types, including `EveGithubToolsOptions`, `EveApprovalValue`, `EveToolOverrides`, `GithubGuardrails` and `GithubDryRunResult`.

## `@github-tools/eve-extension`

```ts
import githubExtension from '@github-tools/eve-extension'

export default githubExtension({ connector: 'github/my-connector', preset: 'code-review' })
```

The default export mounts the tools in an eve agent from a file under `agent/extensions/`. The file name becomes the namespace, so `agent/extensions/github.ts` exposes `github__listPullRequests` and so on. It takes `token`, `connector`, `actAs`, `approvers`, `connect`, `preset` (including `'auto'`), `include`, `exclude`, `context`, `requireApproval` (adding `'once'` and predicates), `evaluation`, `overrides`, `author`, `committer`, `coAuthors`, `guardrails` and `dryRun`; [eve](https://github-tools.com/integrations/eve) documents each one. Needs Node 24 or later and `eve` as a peer.

`@github-tools/eve-extension/channels` exports `githubChannel`, which is eve's `githubChannel` plus `respondTo` (`'anyone'`, `'triagers'`, `'writers'`, `'maintainers'` or `'admins'`), and the `GithubChannelConfig` and `GithubRespondTo` types. See [Choose who the agent answers](https://github-tools.com/integrations/eve#choose-who-the-agent-answers).


## Sitemap

See the full [sitemap](https://github-tools.com/sitemap.md) for all pages.
