mcpbeat Sign in

Emulate Agent Skill

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 emulate CLI or programmatic API. Triggers include "start the emulator", "emulate services", "mock API locally", "create emulator config", "test against local API", "npx emulate", or any task requiring local service emulation.

3k tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
1539
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/vercel-labs/emulate --skill emulate

What it tells the agent to use

found in the instruction text
Bash runs shell commands — read the instruction before connecting

The instruction itself

18 sections, as written by the author

Service Emulation with emulate

Local drop-in replacement services for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation, not mocks.

Quick Start

npx emulate

All services start with sensible defaults:

| Service | Default Port |

|-----------|-------------|

| Vercel | 4000 |

| GitHub | 4001 |

| Google | 4002 |

| Slack | 4003 |

| Apple | 4004 |

| Microsoft | 4005 |

| Okta | 4006 |

| AWS | 4007 |

| Resend | 4008 |

| Stripe | 4009 |

| MongoDB Atlas | 4010 |

| Clerk | 4011 |

| Linear | 4012 |

| Twilio | 4013 |

CLI

# Start all services (zero-config)
npx emulate

# Start specific services
npx emulate --service vercel,github

# Custom base port (auto-increments per service)
npx emulate --port 3000

# Use a seed config file
npx emulate --seed config.yaml

# Generate a starter config
npx emulate init

# Generate config for a specific service
npx emulate init --service vercel

# List available services
npx emulate list

Options

| Flag | Default | Description |

|------|---------|-------------|

| -p, --port | 4000 | Base port (auto-increments per service) |

| -s, --service | all | Comma-separated services to enable |

| --seed | auto-detect | Path to seed config (YAML or JSON) |

| --base-url | none | Override advertised base URL (supports {service} template) |

| --portless | off | Serve over HTTPS via portless (auto-registers aliases) |

The port can also be set via EMULATE_PORT or PORT environment variables.

The advertised base URL (used in OAuth redirects, webhook URLs, etc.) can be overridden via --base-url, the EMULATE_BASE_URL env var (supports {service} template), or per-service baseUrl in the seed config. When running under portless, the PORTLESS_URL env var is also detected automatically.

Programmatic API

npm install emulate

Each call to createEmulator starts a single service:

import { createEmulator } from 'emulate'

const github = await createEmulator({ service: 'github', port: 4001 })
const vercel = await createEmulator({ service: 'vercel', port: 4002 })

github.url   // 'http://localhost:4001'
vercel.url   // 'http://localhost:4002'

await github.close()
await vercel.close()

Options

| Option | Default | Description |

|--------|---------|-------------|

| service | *(required)* | 'vercel', 'github', 'google', 'slack', 'apple', 'microsoft', 'okta', 'aws', 'resend', 'stripe', 'mongoatlas', 'clerk', 'linear', or 'twilio' |

| port | 4000 | Port for the HTTP server |

| seed | none | Inline seed data (same shape as YAML config) |

| baseUrl | none | Override advertised base URL. Per-service baseUrl in seed config takes highest priority, then this option, then EMULATE_BASE_URL env var (supports {service}), then PORTLESS_URL (supports {service}, automatically set by the portless CLI wrapper), then http://localhost:<port>. |

Instance Methods

| Method | Description |

|--------|-------------|

| url | Base URL of the running server |

| reset() | Wipe the store and replay seed data |

| close() | Shut down the HTTP server, returns a Promise |

Vitest / Jest Setup

import { createEmulator, type Emulator } from 'emulate'

let github: Emulator
let vercel: Emulator

beforeAll(async () => {
  ;[github, vercel] = await Promise.all([
    createEmulator({ service: 'github', port: 4001 }),
    createEmulator({ service: 'vercel', port: 4002 }),
  ])
  process.env.GITHUB_EMULATOR_URL = github.url
  process.env.VERCEL_EMULATOR_URL = vercel.url
})

afterEach(() => { github.reset(); vercel.reset() })
afterAll(() => Promise.all([github.close(), vercel.close()]))

Configuration

Configuration is optional. The CLI auto-detects config files in this order:

  • emulate.config.yaml / .yml
  • emulate.config.json
  • service-emulator.config.yaml / .yml
  • service-emulator.config.json

Or pass --seed <file> explicitly. Run npx emulate init to generate a starter file.

Config Structure

tokens:
  my_token:
    login: admin
    scopes: [repo, user]

vercel:
  users:
    - username: developer
      name: Developer
      email: [email protected]
  teams:
    - slug: my-team
      name: My Team
  projects:
    - name: my-app
      team: my-team
      framework: nextjs
  integrations:
    - client_id: oac_abc123
      client_secret: secret_abc123
      name: My Vercel App
      redirect_uris:
        - http://localhost:3000/api/auth/callback/vercel

github:
  users:
    - login: octocat
      name: The Octocat
      email: [email protected]
  orgs:
    - login: my-org
      name: My Organization
  repos:
    - owner: octocat
      name: hello-world
      language: JavaScript
      auto_init: true
  oauth_apps:
    - client_id: Iv1.abc123
      client_secret: secret_abc123
      name: My Web App
      redirect_uris:
        - http://localhost:3000/api/auth/callback/github

google:
  users:
    - email: [email protected]
      name: Test User
  oauth_clients:
    - client_id: my-client-id.apps.googleusercontent.com
      client_secret: GOCSPX-secret
      redirect_uris:
        - http://localhost:3000/api/auth/callback/google

slack:
  team:
    name: My Workspace
    domain: my-workspace
  users:
    - name: developer
      real_name: Developer
      email: [email protected]
  channels:
    - name: general
      topic: General discussion
  bots:
    - name: my-bot
  oauth_apps:
    - client_id: "12345.67890"
      client_secret: example_client_secret
      name: My Slack App
      redirect_uris:
        - http://localhost:3000/api/auth/callback/slack

linear:
  organization:
    name: Acme
    url_key: acme
  users:
    - email: [email protected]
      name: Admin User
      admin: true
    - email: [email protected]
      name: Developer
  teams:
    - key: ENG
      name: Engineering
  issues:
    - team: ENG
      title: Fix local checkout test
      state: Todo
      assignee: [email protected]
  oauth_apps:
    - client_id: lin_example_client_id
      client_secret: example_client_secret
      name: My Linear App
      redirect_uris:
        - http://localhost:3000/api/auth/callback/linear
      scopes: [read, write, issues:create, comments:create]
  tokens:
    - token: lin_test_admin
      user: [email protected]
      scopes: [read, write, issues:create, comments:create, admin]

apple:
  users:
    - email: [email protected]
      name: Test User
  oauth_clients:
    - client_id: com.example.app
      team_id: TEAM001
      name: My Apple App
      redirect_uris:
        - http://localhost:3000/api/auth/callback/apple

microsoft:
  users:
    - email: [email protected]
      name: Test User
  oauth_clients:
    - client_id: example-client-id
      client_secret: example-client-secret
      name: My Microsoft App
      redirect_uris:
        - http://localhost:3000/api/auth/callback/microsoft-entra-id

aws:
  region: us-east-1
  s3:
    buckets:
      - name: my-app-bucket
  sqs:
    queues:
      - name: my-app-events
  iam:
    users:
      - user_name: developer
        create_access_key: true
    roles:
      - role_name: lambda-execution-role

Auth

Tokens map to users. Pass them as Authorization: Bearer <token> or Authorization: token <token>. When no tokens are configured, a default test_token_admin is created for the admin user.

Each service also has a fallback user. If no token is provided, requests authenticate as the first seeded user.

HTTPS with portless

portless gives emulators trusted HTTPS URLs with auto-generated certs. Use the --portless flag to auto-register each service as a portless alias:

npx emulate start --portless
# github  https://github.emulate.localhost
# google  https://google.emulate.localhost
# ...

This requires the portless proxy to be running (portless proxy start). If portless is not installed, emulate will prompt to install it.

The --portless flag overwrites any existing portless aliases matching *.emulate. Aliases are removed automatically when emulate shuts down.

For a single service behind portless:

portless github.emulate emulate start --service github

For a custom base URL without portless (any reverse proxy):

npx emulate start --base-url "https://{service}.myproxy.test"
# or
EMULATE_BASE_URL="https://{service}.myproxy.test" npx emulate start

The PORTLESS_URL env var is automatically set by the portless CLI wrapper when running a command through it (e.g. portless github.emulate emulate start), typically to a value like https://{service}.emulate.localhost. It supports {service} interpolation, just like --base-url and EMULATE_BASE_URL. When no explicit baseUrl is provided, it is used as a fallback.

Per-service overrides in the seed config (these take highest priority over all other base URL sources):

github:
  baseUrl: https://github.emulate.localhost
google:
  baseUrl: https://google.emulate.localhost

Pointing Your App at the Emulator

Set environment variables to override real service URLs:

VERCEL_EMULATOR_URL=http://localhost:4000
GITHUB_EMULATOR_URL=http://localhost:4001
GOOGLE_EMULATOR_URL=http://localhost:4002
SLACK_EMULATOR_URL=http://localhost:4003
APPLE_EMULATOR_URL=http://localhost:4004
MICROSOFT_EMULATOR_URL=http://localhost:4005
AWS_EMULATOR_URL=http://localhost:4007
LINEAR_EMULATOR_URL=http://localhost:4012

Then use these in your app to construct API and OAuth URLs. See each service's skill for SDK-specific override instructions.

Framework Integration (Embedded Mode)

The @emulators/adapter-next package embeds emulators directly into a Next.js app on the same origin. See the next skill (skills/next/SKILL.md) for full setup, Auth.js configuration, persistence, and font tracing details.

The @emulators/adapter-nuxt package embeds emulators directly into a Nuxt app on the same origin. See the nuxt skill (skills/nuxt/SKILL.md) for the server route, Nuxt config, OAuth configuration, and persistence setup.

Persistence

By default, all emulator state is in-memory. For persistence across process restarts and serverless cold starts, use a PersistenceAdapter.

Built-in file persistence

import { filePersistence } from '@emulators/core'

// CLI or local dev: persists to a JSON file
const adapter = filePersistence('.emulate/state.json')

Custom adapters

import type { PersistenceAdapter } from '@emulators/core'

const kvAdapter: PersistenceAdapter = {
  async load() { return await kv.get('emulate-state') },
  async save(data) { await kv.set('emulate-state', data) },
}

State is loaded on cold start and saved after every mutating request (POST, PUT, PATCH, DELETE). Saves are serialized to prevent race conditions.

Architecture

packages/
  emulate/           # CLI entry point + programmatic API
  @emulators/
    core/            # HTTP server, Store, plugin interface, middleware
    adapter-next/    # Next.js App Router integration
    adapter-nuxt/    # Nuxt server route integration
    vercel/          # Vercel API service plugin
    github/          # GitHub API service plugin
    google/          # Google OAuth 2.0 / OIDC plugin
    slack/           # Slack Web API, OAuth, incoming webhooks plugin
    linear/          # Linear GraphQL API, OAuth, webhooks plugin
    twilio/          # Twilio Messaging, Verify, Voice, webhooks plugin
    apple/           # Sign in with Apple / OIDC plugin
    microsoft/       # Microsoft Entra ID OAuth 2.0 / OIDC plugin
    aws/             # AWS S3, SQS, IAM, STS plugin

The core provides a generic Store with typed Collection<T> instances supporting CRUD, indexing, filtering, and pagination. Each service plugin registers routes with the shared internal app and uses the store for state.

Other skills for the same job

different authors, same section of the catalogue
React Email
by resend
×1

Use when building HTML email templates with React components, adding a visual email editor to an application using the React Email visual editor, rendering emails to HTML, or sending emails with Resend. Covers welcome emails, password resets, notifications, order confirmations, newsletters, transactional emails, and the embeddable email editor component.

28k tokens
Agent Mail
by ComeOnOliver
×1

MCP Agent Mail - Mail-like coordination layer for multi-agent workflows. Identities, inbox/outbox, file reservations, contact policies, threaded messaging, pre-commit guard, Human Overseer, static exports, disaster recovery. Git+SQLite backed. Python/FastMCP.

9k tokens
Chat UI
by ComeOnOliver
×1

Chat UI building blocks for React/Next.js from ui.inference.sh. Components: container, messages, input, typing indicators, avatars. Capabilities: chat interfaces, message lists, input handling, streaming. Use for: building custom chat UIs, messaging interfaces, AI assistants. Triggers: chat ui, chat component, message list, chat input, shadcn chat, react chat, chat interface, messaging ui, conversation ui, chat building blocks

3k tokens
Chat UI
by ComeOnOliver
×1

\"Chat UI building blocks for React/Next.js from ui.inference.sh. Components: container, messages, input, typing indicators, avatars. Capabilities: chat interfaces, message lists, input handling, streaming. Use for: building custom chat UIs, messaging interfaces, AI assistants. Triggers: chat ui, chat component, message list, chat input, shadcn chat,\" react chat, chat interface, messaging ui, conversation ui, chat building blocks

3k tokens
Add Deltachat
by nanocoai

Add DeltaChat channel integration via @deltachat/stdio-rpc-server. Native adapter — no Chat SDK bridge. Email-based messaging with end-to-end encryption.

3k tokens
Add Resend
by nanocoai

Add Resend (email) channel integration via Chat SDK.

2k tokens
Build Zoom Bot
by anthropics
vendor

Build a Zoom meeting bot, recorder, or real-time media workflow. Use when joining meetings programmatically, processing live media or transcripts, or combining Meeting SDK, RTMS, and backend services.

312 tokens
Build Zoom Meeting SDK App
by anthropics
vendor

Reference skill for Zoom Meeting SDK. Use after routing to a meeting-embed workflow when implementing real Zoom meeting joins, platform-specific SDK behavior, auth and join flows, waiting room issues, or meeting bot patterns.

187k tokens

How to use it

Copy the folder

Take vercel-labs/emulate from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.

Install what it needs

The instructions reference npm, npx. Without those the skill loads but fails at the first command.