# ViewportWitness by Apex Labs

**Category:** 💰 Finance & Fintech  
**Repository:** https://github.com/Baffles78/viewport-witness  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/viewportwitness-by-apex-labs

## Description
Paid browser QA for AI agents across phone and desktop viewports, using x402.

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "viewportwitness-by-apex-labs": {
    "command": "npx",
    "args": ["-y","viewportwitness-by-apex-labs"]
  }
}
```

## Documentation & README

# ViewportWitness by Apex Labs

Two low-resource paid agent tools complement browser QA: `extract_page` converts one public HTML page to deterministic Markdown for $0.005 USDC, and `web_release_gate` passively checks one public page's release security controls for $0.05 USDC. Both share the Base/Solana x402 rails, idempotency protection, single-worker queue, and seven-day report lifecycle. They do not accept caller-supplied HTML, credentials, cookies, custom headers, uploads, or private-network targets.

Remote MCP server and x402 API for AI-agent browser QA. Submit a public HTTPS URL and receive
screenshots, accessibility findings, layout analysis, and structured JSON across phone and
desktop viewports.

The live service is at **https://qa.honeygate.app**. A standard report costs $0.08 USDC,
read-only assertions cost $0.10, and a baseline comparison costs $0.12. Local instances can run
in test mode without payment.

- [Official MCP Registry listing](https://registry.modelcontextprotocol.io/v0.1/servers?search=viewport-witness)
- [MCP setup for ChatGPT, Claude, Codex, Cursor, and VS Code](https://github.com/Baffles78/viewport-witness/blob/HEAD/docs/MCP-INSTALL.md)
- [Privacy policy](https://qa.honeygate.app/privacy) · [Terms](https://qa.honeygate.app/terms) · [Support](https://github.com/Baffles78/viewport-witness/issues)

---

## Live service

```bash
# Probe the live service (returns 402 with payment requirements)
curl -s -X POST https://qa.honeygate.app/v1/checks \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://example.com"}'

# Payment discovery
curl -s https://qa.honeygate.app/.well-known/x402 | jq .

# Agent skill manifest
curl -s https://qa.honeygate.app/skill.md
```

Use an x402-aware client (e.g. `@x402/fetch` with a funded wallet) for paid requests.
See [llms.txt](https://github.com/Baffles78/viewport-witness/blob/HEAD/llms.txt) for the full agent usage guide.

---

## Paid product examples

An ordinary HTTP request to any paid endpoint returns **HTTP 402** — an x402 challenge
containing the network, asset, amount, and destination address. An x402-aware client
(such as `@x402/fetch` with a funded wallet) pays the challenge and retries automatically;
your code receives the successful JSON result. The examples below show the request shape only
— do not call the live service or send payment during development; use `PAYMENT_MODE=test`
locally (see [Local development](#local-development)).

### POST /v1/checks — 0.08 USDC

Submit a public HTTPS URL and receive screenshots, accessibility findings, layout analysis,
and browser errors across phone and desktop viewports.

```ts
// x402-aware client pays the 402 challenge and retries automatically
const { id, pollUrl } = await fetch402('https://qa.honeygate.app/v1/checks', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ url: 'https://example.com' }),
}).then(r => r.json())
// Poll GET pollUrl until { status: 'complete' }
```

### POST /v1/verify — 0.10 USDC

Run explicit read-only assertions against a live public HTTPS URL. The worker performs only
non-mutating checks — no forms are submitted, no purchase or delete controls are clicked.

```ts
const { id, pollUrl } = await fetch402('https://qa.honeygate.app/v1/verify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'https://example.com',
    assertions: [
      { type: 'selectorVisible', selector: 'h1' },
      { type: 'titleIncludes', value: 'Example Domain' },
    ],
  }),
}).then(r => r.json())
```

### POST /v1/compare — 0.12 USDC

Diff the current render against a baseline job. `baselineJobId` must identify a completed,
unexpired ViewportWitness check that has screenshots for all three viewports (phonePortrait,
phoneLandscape, desktop). Baselines expire after seven days. The request is rejected if the
baseline job is pending, failed, or missing any viewport screenshot.

```ts
const { id, pollUrl } = await fetch402('https://qa.honeygate.app/v1/compare', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'https://example.com',
    baselineJobId: 'JOB_ID_FROM_PREVIOUS_CHECKS',
  }),
}).then(r => r.json())
```

> **Safety**: Only public HTTPS URLs are accepted. Loopback, private, link-local, and metadata
> addresses are blocked at every hop. The browser worker is non-mutating — no forms are submitted
> and no state-changing interactions are performed.

---

## Local development

```bash
npm install
npx playwright install chromium
cp .env.example .env
npm run dev
```

```bash
# Create a check (test mode — no payment required)
curl -s -X POST http://localhost:3000/v1/checks \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://example.com"}' | jq .

# Poll result
curl -s http://localhost:3000/v1/checks/JOB_ID | jq .status

# Get screenshot
curl -o desktop.png http://localhost:3000/v1/checks/JOB_ID/screenshots/desktop
```

Local defaults to `PAYMENT_MODE=test`. No CDP keys needed for test mode. Results are labeled
`paymentMode: "test"` and do not represent real payment settlements.

---

## API

| Method | Path | Description |
|--------|------|-------------|
| GET | `/` | Service info |
| GET | `/health` | Liveness probe |
| GET | `/ready` | Readiness probe (DB + worker) |
| GET | `/openapi.json` | OpenAPI 3.1 spec |
| GET | `/llms.txt` | Agent usage guide |
| GET | `/skill.md` | Concise agent skill manifest |
| GET | `/privacy` | Privacy policy |
| GET | `/terms` | Terms of service |
| GET | `/logo.png` | Directory and integration logo |
| GET | `/.well-known/x402` | Payment discovery |
| POST | `/v1/checks` | Create a QA check job |
| POST | `/v1/verify` | Check explicit read-only assertions |
| POST | `/v1/compare` | Compare against an unexpired baseline job |
| POST | `/mcp` | Remote MCP interface with x402-paid tools |
| GET | `/v1/checks/:id` | Poll job status / get report |
| GET | `/v1/checks/:id/screenshots/:viewport` | Download screenshot PNG |
| GET | `/v1/checks/:id/diffs/:viewport` | Download comparison diff PNG |

Viewports: `phonePortrait` (375×812), `phoneLandscape` (812×375), `desktop` (1440×900)

---

## Payment modes

| Mode | Payment required | Network |
|------|-----------------|---------|
| `test` | No | — (local dev only) |
| `testnet` | Yes (x402) | Base Sepolia; optional Solana Devnet |
| `production` | Yes (x402, $0.08 USDC) | Base mainnet; optional Solana mainnet |

Production mode requires `ENABLE_MAINNET_PAYMENTS=true` and a reviewed release.
Solana is separately off by default. Enabling it requires `ENABLE_SOLANA_PAYMENTS=true`, the
public test and revenue destinations, facilitator capability confirmation, and its own settlement
test. The application selects the correct destination from `PAYMENT_MODE`.
Paid modes also require a private `CUSTOMER_HASH_SECRET` of at least 32 characters. It creates a
stable, one-way customer label for repeat-use measurements; raw payer wallet addresses are not
stored. Attribution is best-effort and never blocks delivery after a verified payment. Changing
this secret starts a new measurement series and does not rewrite old jobs.
See [docs/RUNBOOK.md](https://github.com/Baffles78/viewport-witness/blob/HEAD/docs/RUNBOOK.md) for activation steps.

---

## Run tests

```bash
npm test              # unit tests (no browser required)
npm run test:e2e      # local e2e (requires Playwright Chromium)
npm run typecheck     # TypeScript strict check
```

---

## Docker

```bash
docker compose build
docker compose up -d
curl http://localhost:3000/health
```

---

## Further reading

- [Build specification](https://github.com/Baffles78/viewport-witness/blob/HEAD/docs/BUILD-SPEC.md) — full product and safety spec
- [Runbook](https://github.com/Baffles78/viewport-witness/blob/HEAD/docs/RUNBOOK.md) — operations, backups, upgrades, mainnet activation
- [Agent guide](https://github.com/Baffles78/viewport-witness/blob/HEAD/llms.txt) — machine-readable usage instructions
- [Skill manifest](https://github.com/Baffles78/viewport-witness/blob/HEAD/skill.md) — concise agent skill guide
- [MCP install guide](https://github.com/Baffles78/viewport-witness/blob/HEAD/docs/MCP-INSTALL.md) — connect ChatGPT, Claude, Codex, Cursor, and VS Code
- [Privacy policy](https://github.com/Baffles78/viewport-witness/blob/HEAD/docs/PRIVACY.md) and [terms](https://github.com/Baffles78/viewport-witness/blob/HEAD/docs/TERMS.md)
- [Customer feedback](https://github.com/Baffles78/viewport-witness/issues/new?template=customer-feedback.yml) — request a capability or report a result without posting secrets
- [Build evidence](https://github.com/Baffles78/viewport-witness/blob/HEAD/docs/BUILD-EVIDENCE.md) — test results and known limits

---

MIT License

