/github
Emulated GitHub REST API for local development and testing. Use when the user needs to interact with GitHub API endpoints locally, test GitHub integrations, emulate repos/issues/PRs, set up GitHub OAuth flows, configure GitHub Apps, test webhooks, or work with actions/checks
$ npx -y skills add vercel-labs/emulate --skill github --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/github
Context preview
The summary Claude sees to decide when to auto-load this skill.
Emulated GitHub REST API for local development and testing. Use when the user needs to interact with GitHub API endpoints locally, test GitHub integrations, emulate repos/issues/PRs, set up GitHub OAuth flows, configure GitHub Apps, test webhooks, or work with actions/checks
SKILL.md
github.SKILL.mdname: github
description: Emulated GitHub REST API for local development and testing. Use when the user needs to interact with GitHub API endpoints locally, test GitHub integrations, emulate repos/issues/PRs, set up GitHub OAuth flows, configure GitHub Apps, test webhooks, or work with actions/checks without hitting the real GitHub API. Triggers include "GitHub API", "emulate GitHub", "mock GitHub", "test GitHub OAuth", "GitHub App JWT", "local GitHub", or any task requiring a local GitHub API.
allowed-tools: Bash(npx emulate:*), Bash(emulate:*), Bash(curl:*)
GitHub API Emulator
Fully stateful GitHub REST API emulation. Creates, updates, and deletes persist in memory and affect related entities.
Start
# GitHub only
npx emulate --service github
# Default port
# http://localhost:4001
Or programmatically:
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>`.
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.
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
GITHUB_EMULATOR_URL=http://localhost:4001
Octokit
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
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
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: [hello, world]
default_branch: main
private: false
- owner: my-org
name: org-repo
description: An organization repository
language: TypeScript
oauth_apps:
- client_id: Iv1.abc123
client_secret: secret_abc123
name: My Web App
redirect_uris:
- http://localhost:3000/api/auth/callback/githubRepos are auto-initialized with a commit, branch, and README unless `auto_init: false` is set.
Pagination
All list endpoints support `page` and `per_page` query params with `Link` headers:
curl "http://localhost:4001/repos/octocat/hello-world/issues?page=1&per_page=10" \
-H "Authorization: Bearer $TOKEN"
API Endpoints
Users
# Authenticated user
curl http://localhost:4001/user -H "Authorization: Bearer $TOKEN"
# Update profile
curl -X PATCH http://localhost:4001/user \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"bio": "Hello!"}'
# Get user by username
curl http://localhost:4001/users/octocat
# List users
curl http://localhost:4001/users
# User repos / orgs / followers / following
curl http://localhost:4001/users/octocat/repos
curl http://localhost:4001/users/octocat/orgs
curl http://localhost:4001/users/octocat/followers
curl http://localhost:4001/users/octocat/following
# User hovercard
curl http://localhost:4001/users/octocat/hovercard
# User emails
curl http://localhost:4001/user/emails -H "Authorization: Bearer $TOKEN"Repositories
# Get repo
curl http://localhost:4001/repos/octocat/hello-world
# Create user repo
curl -X POST http://localhost:4001/user/repos \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "new-repo", "private": false}'
# Create org repo
curl -X POST http://localhost:4001/orgs/my-org/repos \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "org-project"}'
# Update repo
curl -X PATCH http://localhostRead more
name: github description: Emulated GitHub REST API for local development and testing. Use when the user needs to interact with GitHub API endpoints locally, test GitHub integrations, emulate repos/issues/PRs, set up GitHub OAuth flows, configure GitHub Apps, test webhooks, or work with actions/checks without hitting the real GitHub API. Triggers include "GitHub API", "emulate GitHub", "mock GitHub", "test GitHub OAuth", "GitHub App JWT", "local GitHub", or any task requiring a local GitHub API. allowed-tools: Bash(npx emulate:*), Bash(emulate:*), Bash(curl:*)
GitHub API Emulator
Fully stateful GitHub REST API emulation. Creates, updates, and deletes persist in memory and affect related entities.
Start
# GitHub only npx emulate --service github # Default port # http://localhost:4001
Or programmatically:
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>`.
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.
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
GITHUB_EMULATOR_URL=http://localhost:4001
Octokit
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
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
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: [hello, world]
default_branch: main
private: false
- owner: my-org
name: org-repo
description: An organization repository
language: TypeScript
oauth_apps:
- client_id: Iv1.abc123
client_secret: secret_abc123
name: My Web App
redirect_uris:
- http://localhost:3000/api/auth/callback/githubRepos are auto-initialized with a commit, branch, and README unless `auto_init: false` is set.
Pagination
All list endpoints support `page` and `per_page` query params with `Link` headers:
curl "http://localhost:4001/repos/octocat/hello-world/issues?page=1&per_page=10" \ -H "Authorization: Bearer $TOKEN"
API Endpoints
Users
# Authenticated user
curl http://localhost:4001/user -H "Authorization: Bearer $TOKEN"
# Update profile
curl -X PATCH http://localhost:4001/user \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"bio": "Hello!"}'
# Get user by username
curl http://localhost:4001/users/octocat
# List users
curl http://localhost:4001/users
# User repos / orgs / followers / following
curl http://localhost:4001/users/octocat/repos
curl http://localhost:4001/users/octocat/orgs
curl http://localhost:4001/users/octocat/followers
curl http://localhost:4001/users/octocat/following
# User hovercard
curl http://localhost:4001/users/octocat/hovercard
# User emails
curl http://localhost:4001/user/emails -H "Authorization: Bearer $TOKEN"Repositories
# Get repo
curl http://localhost:4001/repos/octocat/hello-world
# Create user repo
curl -X POST http://localhost:4001/user/repos \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "new-repo", "private": false}'
# Create org repo
curl -X POST http://localhost:4001/orgs/my-org/repos \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "org-project"}'
# Update repo
curl -X PATCH http://localhostLocal drop-in replacement services for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation. Not mocks.
Repo: vercel-labs/emulate
Other skills on emulate.
- /apple
Emulated Sign in with Apple / Apple OIDC for local development and testing. Use when the user needs to test Apple sign-in locally, emulate Apple OIDC discovery, handle Apple token exchange, configure Apple OAuth clients, or work with Apple userinfo without hitting real Apple
Open skill - /aws
Emulated AWS cloud services (S3, SQS, IAM, STS) for local development and testing. Use when the user needs to interact with AWS API endpoints locally, test S3 bucket and object operations, emulate SQS queues and messages, manage IAM users/roles/access keys, test STS assume role,
Open skill - /emulate
Local drop-in API emulator for Vercel, GitHub, Google, Slack, Apple, Microsoft, AWS, Linear, and other developer APIs. Use when the user needs to start emulated services, configure seed data, write tests against local APIs, set up CI without network access, or work with the
Open skill - /google
Emulated Google OAuth 2.0, OpenID Connect, Gmail, Calendar, and Drive for local development and testing. Use when the user needs to test Google sign-in locally, emulate OIDC discovery, handle Google token exchange, configure Google OAuth clients, work with Gmail
Open skill - /linear
Emulated Linear GraphQL API for local development and testing. Use when the user needs to test Linear integrations locally, emulate Linear issues, comments, teams, workflow states, OAuth apps, webhooks, agent sessions, or work with the Linear API without hitting the real Linear
Open skill - /microsoft
Emulated Microsoft Entra ID (Azure AD) OAuth 2.0 / OpenID Connect for local development and testing. Use when the user needs to test Microsoft sign-in locally, emulate Entra ID OIDC discovery, handle Microsoft token exchange, configure Azure AD OAuth clients, work with Microsoft
Open skill

