---
title: "Quick start"
description: "Give a model GitHub tools, narrow them to one job, and approve the write it wants to make."
canonical_url: "https://github-tools.com/start/quick-start"
---
# Quick start

> Give a model GitHub tools, narrow them to one job, and approve the write it wants to make.

To give an AI SDK model GitHub tools, pass `createGithubTools()` as its `tools`, narrow them to one job with a preset, and approve each write before it runs. The three steps below go from a script that reads a repository to an agent that labels an issue once you say yes. They assume the SDK is [installed](https://github-tools.com/start/installation) and `GITHUB_TOKEN` is set.

Building on eve? The [eve extension](https://github-tools.com/integrations/eve) is one file and handles approval for you; come back to this page for how the parts fit.

## 1. Hand the model the tools

`createGithubTools()` returns an AI SDK `ToolSet`, so it goes wherever `tools` goes:

```ts [ask.ts]
import { createGithubTools } from '@github-tools/sdk'
import { generateText, stepCountIs } from 'ai'

const { text } = await generateText({
  model: 'anthropic/claude-opus-5.5',
  tools: createGithubTools(),
  stopWhen: stepCountIs(5),
  prompt: 'What are the three most commented open issues on vercel/ai?',
})
```

The model calls `listIssues`, reads the comment counts from the result, and answers. `stopWhen` lets it take more than one step: without it, `generateText` stops after the first tool call. Each tool returns the fields a model needs, not GitHub's whole payload.

## 2. Narrow them to one job

All 97 tools cost context on every request, and most are irrelevant to the job. A [preset](https://github-tools.com/presets) passes only the ones the job needs:

```ts [ask.ts]
tools: createGithubTools({ preset: 'issue-triage' }),
```

`issue-triage` keeps 32 tools: issues, labels, comments, assignees, reactions, milestones, sub-issues and a few repository reads.

## 3. Approve the write

`issue-triage` includes `addLabels`, a write. Writes don't run until someone approves them, so the agent stops and returns an approval request instead:

```ts [triage.ts]
import { createGithubAgent } from '@github-tools/sdk'
import type { ModelMessage } from 'ai'

const agent = createGithubAgent({
  model: 'anthropic/claude-opus-5.5',
  preset: 'issue-triage',
})

const messages: ModelMessage[] = [
  { role: 'user', content: 'Label vercel-labs/github-tools#42 as a bug.' },
]
const result = await agent.generate({ messages })
messages.push(...result.responseMessages)

for (const part of result.content) {
  if (part.type === 'tool-approval-request') {
    console.log(part.toolCall.toolName, part.toolCall.input)
    // addLabels { owner: 'vercel-labs', repo: 'github-tools', issueNumber: 42, labels: ['bug'] }

    messages.push({
      role: 'tool',
      content: [{ type: 'tool-approval-response', approvalId: part.approvalId, approved: true }],
    })
  }
}

const final = await agent.generate({ messages })
```

The second `generate()` runs `addLabels` and lets the model report back. In a chat UI, the same request arrives as a tool part in the `approval-requested` state, and the user answers with a button. [Approval](https://github-tools.com/approval) covers turning it off for a tool, and letting a model approve routine writes.

## Next

- [Integrations](https://github-tools.com/integrations): the same tools in eve, TanStack AI, Vercel Workflow or Chat SDK.
- [Auth](https://github-tools.com/auth): replace the personal token before you deploy.


## Sitemap

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