A reference implementation of a GitHub API integration that an AI agent can drive. It builds IssueTriage, a small issue and pull request inbox where a Claude agent reads from and acts on GitHub through tools that are served by Nango.
The integration itself is the interesting part. Nango handles the GitHub App OAuth, syncs issues and pull requests into a queryable store, exposes write operations as actions, and serves those actions to the agent over a hosted MCP server. You write the integration logic once as Nango functions and reuse it from both the UI and the agent.
Read the full walkthrough on the Nango blog: Build a GitHub API integration for AI agents.
- GitHub App OAuth through Nango Connect, so the browser never touches tokens.
- A sync (
fetch-issues-and-pull-requests) that pulls repositories, issues, and pull requests into Nango and keeps them fresh. - Six actions that perform GitHub writes: create an issue, comment on an issue, create a pull request, update an issue, list issues, and list repositories.
- An AI agent whose tools are those Nango actions, served over Nango's hosted MCP server. The agent reasons over a natural-language request and calls the tools to get the work done.
frontend/ React and Vite UI. Talks only to the backend at /api.
backend/ Node API proxy. Holds the Nango secret key and runs the agent loop.
nango-integrations/ The Nango functions: one sync and six actions for the GitHub App integration.
Ports: the frontend dev server runs on http://localhost:5173 and proxies /api to the backend on http://localhost:8787.
- Node 22 or newer.
- A Nango account.
- The GitHub App integration configured in Nango with the unique key
github-app-oauth. The code references that key, so keep the default or changeNANGO_PROVIDER_CONFIG_KEYand the integration to match. - A connection created through the Connect flow, with at least one repository shared to the GitHub App. An empty or unshared connection has nothing to sync.
- Optional: an Anthropic API key to enable the AI Helper. The rest of the app works without it.
Run the steps in order. The backend must be running before you connect, sync, or use the agent, because the browser talks only to the backend.
cd nango-integrations
npm install
cp .env.example .env # set NANGO_SECRET_KEY_DEV
# Deploy only the functions in this repo (one sync, six actions).
npx nango deploy --sync fetch-issues-and-pull-requests dev
npx nango deploy --action create-issue dev
npx nango deploy --action create-comment dev
npx nango deploy --action create-pull-request dev
npx nango deploy --action list-repositories dev
npx nango deploy --action list-issues dev
npx nango deploy --action update-issue devThe deploy step is required, not optional. The sync and actions have to be deployed before the backend can list records, trigger a sync, or call an action through MCP.
cd backend
npm install
cp .env.example .env # set NANGO_SECRET_KEY, optionally ANTHROPIC_API_KEY
npm run dev # http://localhost:8787cd frontend
npm install
npm run dev # http://localhost:5173Open the frontend URL and click Connect GitHub. Pick a repository that is shared to the GitHub App, let the first sync finish, and the issues and pull requests appear in the inbox.
The sync runs hourly and the Refresh button triggers it on demand, so the app works without webhooks. To react to GitHub activity the moment it happens, wire up the two webhook hops below. The sync subscribes to issues and pull_request events and updates records from them in its onWebhook handler, then the backend pushes a live reload to the browser.
This is a manual step on the GitHub App. GitHub delivers events to Nango, which verifies the signature and forwards them to the sync.
- In the Nango dashboard, open the integration's settings page and copy its webhook URL.
- In GitHub, go to Developer settings > GitHub Apps > your app, and set Webhook URL to the Nango URL you copied. Set a webhook secret.
- Add the same secret in the integration's settings in Nango, so Nango can verify the
X-Hub-Signature-256signature on each delivery. - Under the app's Permissions and events, subscribe to the Issues and Pull requests events.
After a sync run finishes, Nango emits a sync-completion webhook that the backend forwards to the browser over Server-Sent Events, so the list reloads without a manual refresh. For Nango to reach a local backend, expose it with a tunnel.
- Start the backend, then run a tunnel to its port, for example
ngrok http 8787. - In Nango, go to Environment Settings > Webhooks and set the callback URL to
https://<your-tunnel-host>/api/nango/webhook. - Copy the webhook signing key from that page into
backend/.envasNANGO_WEBHOOK_SIGNING_KEY, then restart the backend. Without this key the backend skips signature verification and logs a warning, which is fine for local testing.
- The integration key must match the code. The backend defaults to
github-app-oauth. Keep that as the integration's unique key in Nango, or changeNANGO_PROVIDER_CONFIG_KEYinbackend/.envto match. - A connection with shared content is required. If no repository is shared to the GitHub App, the sync returns nothing.
- Deploy is a one-time build step. Listing records, triggering a sync, and the agent's tool calls all need the functions deployed first.
- The AI Helper is optional. Without
ANTHROPIC_API_KEYthe agent endpoint returns a clear error response (HTTP 503) and everything else keeps working. - The browser holds no secrets. The Nango secret key and the Anthropic key live in the backend only.
React 18, Vite 6, TypeScript, and Tailwind CSS v4 on the frontend. A small Node HTTP server on the backend. Nango functions written in TypeScript with Zod schemas.

