---
title: "GitHub agents"
description: "What a GitHub agent is, how a model uses tools in a loop, and why writes wait for approval and presets narrow the tools."
canonical_url: "https://github-tools.com/learn/github-agents"
---
# GitHub agents

> What a GitHub agent is, how a model uses tools in a loop, and why writes wait for approval and presets narrow the tools.

A GitHub agent is a program in which a language model reads and changes things on GitHub by calling tools, one step after another, until it has answered a request. Ask it "label the new bug reports on my repository" and it lists the issues, reads them, and adds the labels, choosing each call from what the previous one returned.

`@github-tools/sdk` gives that model its GitHub tools. You bring the model and the place the agent runs.

## Model, tools and loop

An agent has three parts:

<table>
<thead>
  <tr>
    <th>
      Part
    </th>
    
    <th>
      What it does
    </th>
    
    <th>
      In this SDK
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Model
    </td>
    
    <td>
      Reads the conversation and decides what to do next: call a tool, or answer
    </td>
    
    <td>
      Any <a href="https://ai-sdk.dev" rel="nofollow">
        AI SDK
      </a>
      
       model that supports tool calling, such as <code>
        anthropic/claude-opus-5.5
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Tools
    </td>
    
    <td>
      Functions the model can ask your code to run, each with a name, a description and a typed input
    </td>
    
    <td>
      97 GitHub operations, such as <code>
        listIssues
      </code>
      
       and <code>
        addLabels
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Loop
    </td>
    
    <td>
      Runs the tool the model picked, hands it the result, and calls the model again
    </td>
    
    <td>
      <code>
        createGithubAgent()
      </code>
      
      , or <code>
        generateText
      </code>
      
       with <code>
        stopWhen
      </code>
    </td>
  </tr>
</tbody>
</table>

<agent-loop>



</agent-loop>

Each turn around the loop is a step. The model never talks to GitHub itself: it only asks for a tool by name, and your process makes the request. That is what lets you check, limit or stop each request before it runs.

## What a tool is

A tool is one GitHub operation the model can call. Each tool has:

- A name, such as `getIssue`.
- A description the model reads to decide when to call it.
- An input schema, written with [Zod](https://zod.dev), that says which fields the model must fill, such as `owner`, `repo` and `issueNumber`.
- An `execute` function that calls the GitHub API and returns a result.

The result is shaped: it keeps the fields a model needs, such as an issue's title, state, labels and author, and drops the rest of GitHub's response. Long bodies are cut to about 500 characters unless the model asks for the full text. Smaller results leave more of the model's context for the task. [Tool calls](https://github-tools.com/learn/tool-calls) follows one call from start to finish.

## Read tools and write tools

A read tool only looks: `listIssues`, `getFileContent`, `getCiFailureContext`. A write tool changes something on GitHub: `addLabels`, `closeIssue`, `mergePullRequest`. Of the 97 tools, 48 are writes.

<approval-flow>



</approval-flow>

Reads run as soon as the model calls them. Writes stop and wait for a person to approve them, which is called [approval](https://github-tools.com/approval).

## Why writes wait for approval

A model can pick the wrong issue, misread a request, or follow instructions it found in the content it reads. An issue body that says "close every open issue" is text the model sees, and nothing stops it from acting on it except a check outside the model.

Approval is that check. When the model calls a write tool, the agent returns an approval request with the tool name and its input instead of running it. Your code shows the request to a person, and the write runs only after a yes. You can turn approval off for writes that are cheap to undo, such as adding a label, or let a fast decision model approve the routine ones with `requireApproval: 'auto'`.

## Why presets narrow the tools

The model reads the definition of every tool it is given on every request, whether it calls it or not. With all 97 tools, that's a lot of context spent on tools the job never uses, and more chances to pick the wrong one.

A [preset](https://github-tools.com/presets) is a named list of tools for one job. `issue-triage` has 32 tools for issues, labels, comments and assignees. `code-review` has 28 for diffs, reviews and checks. An agent created with a preset also gets a system prompt written for that job. `preset: 'auto'` lets a decision model pick the tools from the user's first request instead.

## Where the token comes in

Every tool call reaches GitHub with a token, and GitHub, not the model, decides what that token can do. A token without write access to issues can't close one, whatever the model asks for.

The SDK reads `GITHUB_TOKEN` from the environment by default. You can also pass a token, a function that returns one for each call, or a [Vercel Connect](https://github-tools.com/auth#vercel-connect) connector that mints a short-lived token per call. Give the agent only the permissions its preset needs: [Auth](https://github-tools.com/auth#permissions-per-preset) lists them.

The preset decides what the model sees, approval decides what runs, and the token decides what GitHub allows. Each one limits the agent on its own.

## Where the agent runs

The tools work in any AI SDK call, and in eve, TanStack AI, Vercel Workflow and Chat SDK through their [integrations](https://github-tools.com/integrations). [Your first agent](https://github-tools.com/learn/first-agent) builds one with the AI SDK in a terminal.

## FAQ

<accordion>
<accordion-item label="Do I need an agent framework to use the tools?">

No. `createGithubTools()` returns an AI SDK `ToolSet` that works in `generateText` and `streamText`, which run the loop when you set `stopWhen`. Your own code can also call a tool's `execute` without a model.

</accordion-item>

<accordion-item label="Which models can drive a GitHub agent?">

Any model the AI SDK supports that can call tools. The docs use `anthropic/claude-opus-5.5`, which the AI SDK routes through [AI Gateway](https://vercel.com/docs/ai-gateway).

</accordion-item>

<accordion-item label="Can a GitHub agent change my repository without asking?">

Only when you turn off approval for that write, or let `'auto'` approve it, and the token has the permission. With the defaults, every write waits for a person.

</accordion-item>
</accordion>


## Sitemap

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