
Github
Spin up a stateful local GitHub REST API emulator to build and test integrations without rate limits or production risk.
Overview
github is an agent skill most often used in Build integrations (also Ship testing) that runs the emulate package’s stateful local GitHub REST API for dev and test.
Install
npx skills add https://github.com/vercel-labs/emulate --skill githubWhat is this skill?
- Stateful GitHub REST emulation with create/update/delete persistence in memory
- Start via npx emulate --service github on default port 4001
- Supports Bearer or token Authorization and GitHub App JWT with RS256 seed config
- Public repo reads without auth; private repos and writes require valid tokens
- Programmatic createEmulator({ service: 'github', port: 4001 }) TypeScript API
- Default emulator URL http://localhost:4001
- Allowed-tools entries for Bash(npx emulate:*), Bash(emulate:*), Bash(curl:*)
Adoption & trust: 92 installs on skills.sh; 1.3k GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need to exercise GitHub API, OAuth, Apps, webhooks, or Actions flows locally without calling the real API or corrupting live repos.
Who is it for?
Indie developers building GitHub Apps, CI glue, or agent tools that call the REST API and want curl- and npx-friendly local fixtures.
Skip if: Production GitHub hosting, compliance audits of real org data, or teams that only need static JSON mocks with no stateful entity graph.
When should I use this skill?
User mentions GitHub API, emulate GitHub, mock GitHub, test GitHub OAuth, GitHub App JWT, local GitHub, webhooks, or actions/checks without the real API.
What do I get? / Deliverables
After setup, you have a persistent in-memory GitHub API at localhost:4001 so integrations and tests run deterministically before pointing at github.com.
- Running local GitHub API emulator instance
- Authenticated curl or SDK calls against emulated endpoints
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Integrations is the canonical shelf because the skill centers on emulating GitHub’s REST API for app and OAuth development. Builders wire GitHub Apps, webhooks, and repo automation here before those flows reach ship-time CI or launch webhooks.
Where it fits
Develop a GitHub App webhook handler against seeded repos on port 4001.
Run automated issue and PR lifecycle tests without GitHub rate limits.
Demo OAuth login flow to stakeholders using emulated users and tokens.
How it compares
Skill package for the emulate CLI service, not the live GitHub MCP server or github.com itself.
Common Questions / FAQ
Who is github (emulate) for?
It is for solo builders and small teams using coding agents to develop GitHub REST integrations, OAuth, Apps, and webhooks with vercel-labs/emulate.
When should I use github (emulate)?
Use it in Build while wiring GitHub API clients and App JWT auth, in Ship while running integration tests for issues and PRs, and in Validate prototype when you demo GitHub-backed flows offline.
Is github (emulate) safe to install?
The emulator is local-only test infrastructure; still review skill and npm package sources, avoid pointing production secrets at it, and check the Security Audits panel on this Prism page.
SKILL.md
READMESKILL.md - Github
# GitHub API Emulator Fully stateful GitHub REST API emulation. Creates, updates, and deletes persist in memory and affect related entities. ## Start ```bash # GitHub only npx emulate --service github # Default port # http://localhost:4001 ``` Or programmatically: ```typescript import { createEmulator } from 'emulate' const github = await createEmulator({ service: 'github', port: 4001 }) // github.url === 'http://localhost:4001' ``` ## Auth Pass tokens as `Authorization: Bearer <token>` or `Authorization: token <token>`. ```bash curl http://localhost:4001/user \ -H "Authorization: Bearer test_token_admin" ``` Public repo endpoints work without auth. Private repos and write operations require a valid token. When no token is provided, requests fall back to the first seeded user. ### GitHub App JWT Configure apps in the seed config with a private key. Sign a JWT with `{ iss: "<app_id>" }` using RS256. The emulator verifies the signature and resolves the app. ```yaml github: apps: - app_id: 12345 slug: my-github-app name: My GitHub App private_key: | -----BEGIN RSA PRIVATE KEY----- ... -----END RSA PRIVATE KEY----- permissions: contents: read issues: write events: [push, pull_request] webhook_url: http://localhost:8080/github/webhook webhook_secret: my-webhook-secret description: My CI/CD bot installations: - installation_id: 100 account: my-org repository_selection: all permissions: contents: read events: [push] repositories: [my-org/org-repo] ``` ## Pointing Your App at the Emulator ### Environment Variable ```bash GITHUB_EMULATOR_URL=http://localhost:4001 ``` ### Octokit ```typescript import { Octokit } from '@octokit/rest' const octokit = new Octokit({ baseUrl: process.env.GITHUB_EMULATOR_URL ?? 'https://api.github.com', auth: 'test_token_admin', }) ``` ### OAuth URL Mapping | Real GitHub URL | Emulator URL | |-----------------|-------------| | `https://github.com/login/oauth/authorize` | `$GITHUB_EMULATOR_URL/login/oauth/authorize` | | `https://github.com/login/oauth/access_token` | `$GITHUB_EMULATOR_URL/login/oauth/access_token` | | `https://api.github.com/user` | `$GITHUB_EMULATOR_URL/user` | ### Auth.js / NextAuth.js ```typescript import GitHub from '@auth/core/providers/github' GitHub({ clientId: process.env.GITHUB_CLIENT_ID, clientSecret: process.env.GITHUB_CLIENT_SECRET, authorization: { url: `${process.env.GITHUB_EMULATOR_URL}/login/oauth/authorize`, }, token: { url: `${process.env.GITHUB_EMULATOR_URL}/login/oauth/access_token`, }, userinfo: { url: `${process.env.GITHUB_EMULATOR_URL}/user`, }, }) ``` ## Seed Config ```yaml tokens: test_token_admin: login: admin scopes: [repo, user, admin:org, admin:repo_hook] github: users: - login: octocat name: The Octocat email: octocat@github.com bio: I am the Octocat company: GitHub location: San Francisco blog: https://github.blog twitter_username: github site_admin: false orgs: - login: my-org name: My Organization description: A test organization email: org@example.com repos: - owner: octocat name: hello-world description: My first repository language: JavaScript topics: