---
name: sentryrelay
description: Solve 2FA, Email/SMS OTP, Magic-Link, and RFC 6238 TOTP Authenticator verification challenges in autonomous browser agents (Playwright, Stagehand, Browser Use), multi-agent workflows, and CLI scripts using Sentry Relay (sentryrelay.com).
---

# Sentry Relay — 2FA, OTP, Magic-Link & TOTP Skill for AI Agents

Use this skill whenever an autonomous agent, browser automation script (Playwright, Stagehand, Browser Use, Skyvern), or CLI workflow needs to:
1. Provision a dedicated agent inbox (`<handle>@in.sentryrelay.com`) or US local carrier phone number (DID) for receiving 2FA challenges.
2. Wait for and extract incoming Email or SMS verification codes (`otpCode`) or magic links (`magicLink`) in `<200ms`.
3. Vault and generate live 6- or 8-digit RFC 6238 TOTP authenticator codes with automatic expiring-window rollover protection.

## 1. Prerequisites & Environment Variable

Ensure `SENTRY_RELAY_API_KEY` (`sr_live_...` or `sr_test_...`) is set in the environment:

```bash
export SENTRY_RELAY_API_KEY="sr_live_..."
```

## 2. Choose Your Integration Surface

### Option A: Model Context Protocol (MCP) Server (`@sentryrelay/mcp`)

Register the Sentry Relay MCP server in Claude Code:
```bash
claude mcp add sentryrelay -e SENTRY_RELAY_API_KEY="$SENTRY_RELAY_API_KEY" -- npx -y @sentryrelay/mcp
```

Or connect directly to the zero-install Streamable HTTP MCP endpoint:
- **URL:** `https://sentryrelay.com/api/mcp`
- **Header:** `Authorization: Bearer $SENTRY_RELAY_API_KEY`

**Available MCP Tools:**
- `wait_for_verification_code`: Long-poll up to `timeoutSeconds` (default 30s) for an incoming Email or SMS OTP / magic link (`identity`, `channel`, `sender`, `subject`, `timeoutSeconds`, `consume`).
- `get_latest_verification_code`: Non-blocking check for the latest verification code received within `lookbackSeconds` (default 60s).
- `get_totp_code`: Generate a live 6/8-digit RFC 6238 code (`identity`, `secretId`, `autoWaitFreshWindow: true`).
- `list_identities`: List accessible agent Identities (`@in.sentryrelay.com` emails & SMS DIDs).
- `create_identity`: Provision a new Identity inbox (`name`, `slug`, `emailHandle`).
- `store_totp_secret`: Vault an `otpauth://totp/...` URI or Base32 secret (`identity`, `secretId`, `otpauthUriOrSecret`).

### Option B: CLI (`srelay`)

Install the CLI globally or run via `npx`:
```bash
npm install -g sentryrelay
```

```bash
# Wait for an inbound OTP and capture ONLY the raw code in a shell variable:
CODE=$(srelay wait checkout-bot --sender stripe.com --timeout 30 --raw)

# Generate a live 6-digit TOTP token:
TOTP=$(srelay totp get checkout-bot github_ops --raw)
```

### Option C: TypeScript / Playwright / Stagehand SDK (`@sentryrelay/sdk`)

```bash
npm install @sentryrelay/sdk
```

```typescript
import { SentryRelay, fillOtpCode } from '@sentryrelay/sdk';

const relay = new SentryRelay({ apiKey: process.env.SENTRY_RELAY_API_KEY! });

// Record timestamp BEFORE clicking submit so lookback never claims a stale code
const since = Date.now();
await page.fill('input[type="email"]', 'checkout-bot@in.sentryrelay.com');
await page.click('button[type="submit"]');

const auth = await relay.identities.wait('checkout-bot', {
  channel: 'email',
  sender: 'stripe.com',
  since,
  timeout: 30,
});

if (!auth.matched || !auth.event) {
  throw new Error('Timed out waiting for verification code');
}

// Automatically fills single-input or 6-box split OTP inputs
await fillOtpCode(page, 'input[name="otp"]', auth);
```

### Option D: Python SDK (`sentryrelay-sdk`)

```bash
pip install sentryrelay-sdk
```

```python
from sentryrelay import AsyncSentryRelay, fill_otp_code

async with AsyncSentryRelay() as relay:
    auth = await relay.wait("checkout-bot", sender="stripe.com", timeout=30)
    if auth.matched and auth.otp_code:
        await fill_otp_code(page, 'input[name="otp"]', auth)
```

## 3. Best Practices for Reliable 2FA Automation

1. **Always pass `since` when triggering logins:** Capture `const since = Date.now()` immediately before clicking the login/2FA trigger button so `/wait` only matches codes generated by the current login attempt.
2. **Use `@in.sentryrelay.com` for all Identity emails:** Every Identity's inbound email domain is `@in.sentryrelay.com` (e.g., `checkout-bot@in.sentryrelay.com`).
3. **Co-deploy with 1Password for static credentials:** Use `@1password/sdk` (`op.secrets.resolve(...)`) for static username/password injection and `@sentryrelay/sdk` (`relay.identities.wait(...)`) for dynamic out-of-band Email/SMS OTPs and magic links.
4. **Reference Docs:** Full machine-readable reference is available at `https://sentryrelay.com/llms-full.txt` and `https://sentryrelay.com/openapi.json`.
