API And MCP Rollout Checklist
Status
Current checklist for reviewing the public API and MCP platform foundation as one PR.
Readiness has three distinct levels:
pnpm check:api-mcp-rolloutis an advisory rollout summary. It validates checked-in rollout structure and reports unresolved external evidence, but does not require every manual client row to pass.- A green Baseline Checks run is PR implementation readiness. The combined
Verify API and MCPjob enforces contracts and local MCP behavior with one dependency install. Hosted evidence is no longer part of that run: request a preview with@vrdex previewsoHosted MCP Preview Smokeruns, and it fails unless it exercises data-backed reads, DCR, and CIMD against a same-branch Convex preview. Neither declares the platform externally ready. pnpm verify:api-mcp-rollout:externalis the strict external launch gate. It composes API contract, MCP, and docs verification withcheck:api-mcp-rollout -- --require-ready. Dispatch the manualExternal API and MCP Readinessworkflow for the authoritative CI result and an uploaded client session pack.
The current foundation implements owner token and OAuth-app revocation, route-class rate limiting, durable rate-limit and credential events, OAuth grant outcome summaries, MCP tool-call events, and API write-audit events. Active user-grant UI, suspicious-client detail views, account-level token creation suspension, and OAuth app metadata history are explicitly deferred from this foundation and are not implied by a green PR.
Contract And Docs
- OpenAPI is generated from shared schemas, not hand-written in parallel.
docs/api/openapi.jsonanddocs/api/openapi.yamlmatch the generated contract./api/v0/openapi.jsonand/api/v0/openapi.yamlserve the same generated document in JSON and YAML forms./api/v0responses and automatic preflight responses expose the documented CORS methods, request headers, and response metadata for browser clients.- Baseline Checks runs API contract verification in the combined
Verify API and MCPjob, so OpenAPI drift, route/OpenAPI parity, contract typechecking, and contract tests are enforced in PR CI. - Developer docs cover public API, auth, OAuth apps, rate limits, MCP tools, self-hosting variables, and changelog notes.
- The Docusaurus docs build succeeds.
Authentication And Security
- Bearer tokens are accepted only through
Authorization. - Personal API tokens are displayed once and stored as hashes.
- OAuth client secrets are displayed once and stored as hashes.
- OAuth access tokens are short-lived JWTs with issuer, audience, client id, token id, scope, and expiry validation.
- OAuth signing-key rotation keeps previous public keys in JWKS and bearer verification until outstanding access tokens expire.
- Refresh tokens rotate on successful refresh.
- Refresh tokens can be revoked through
/oauth/revoke; revocation also revokes active access tokens for the same client, user, and resource where stored token state supports that relationship. - Authorization Code uses PKCE with
S256. - Redirect URI matching is exact.
- API and MCP resources are validated separately.
- Hosted MCP OAuth is tested through Dynamic Client Registration.
- Dynamic Client Registration limits cover the requesting network, hashed software identity, and hashed redirect hosts.
- The
/oauth/registerroute has deterministic route-handler coverage for schema normalization, registration mutation inputs, rate-limit errors, and backend failures. - The
/oauth/tokenroute has deterministic route-helper coverage for Authorization Code, refresh-token rotation, Client Credentials, and no-store OAuth errors before malformed exchanges reach Convex. - Client Credentials traffic is bounded per token, per OAuth client, and by a hashed application-owner aggregate cap.
- Client ID Metadata Document support is smoke-tested through the checked-in public MCP client metadata document when a same-branch Convex preview backend is available.
- Revoked credentials are rejected and produce durable event metadata for personal API-token and OAuth access-token validation.
Rate Limits And Operations
- Anonymous API reads, authenticated API reads, hosted MCP reads, OAuth token requests, and developer credential management use separate route classes.
- Hosted high-volume deployments use a Redis-compatible counter store, with
BASIC BIT hosted production/staging provisioning owned by
infra/terraform/rate-limit-redis. - Local development can use the memory store.
pnpm ops:api-rate-limitsprints standard and trusted-partner policy tables.pnpm ops:api-rate-limit-countsprints current Redis REST aggregate request counts and TTLs by route class when the hosted counter env vars are present.pnpm ops:api-platform-observabilityprints a sanitized Convex summary of durable API/MCP event rows, including rate-limit blocks, token validation, OAuth grant outcomes, MCP tool calls, and write-audit rows over a bounded time window.- Rate-limited responses include
Retry-After,RateLimit-Limit,RateLimit-Remaining, andRateLimit-Reset. - API request counts are tracked through aggregate route-class counter keys in the active rate-limit backend, separate from identity buckets used for enforcement.
- Rate-limit blocks are recorded in
apiRateLimitEventsby route class and identity kind without storing IP addresses, credential ids, Redis keys, or bearer values. - Accepted hosted MCP tool calls are recorded in
mcpToolEventsby curated tool name and accepted MCP route class for anonymous/authenticated usage counts. - Public API profile writes, event writes, API upload-intent creation, and API
upload completion are recorded in
apiWriteAuditEventsby action, route class, actor kind, resource type, result, owner reference where available, and target resource ids. - OAuth grant outcomes and OAuth access-token validation failures are
summarized from
oauthClientEvents; personal API-token validation failures are summarized fromapiTokenEvents. - Trusted partner quota changes remain manual and revocable, and the runtime limiter applies the trusted-partner tier only after credential validation.
MCP Compatibility
- Hosted
/mcpsupports anonymous public read tools. - Self-hosted operators can set
VRDEX_HOSTED_MCP_ANONYMOUS_READS=falseto require OAuth for hosted tools; anonymous requests then receive a protected resource challenge and tool metadata drops thenoauthscheme. - Hosted
/mcpexposes OpenAI/ChatGPT-compatible anonymoussearchandfetchaliases over the public profile, event, and world read surfaces. - Hosted
/mcpaccepts MCP-resource OAuth tokens withmcp:read. - Hosted
/mcpreturns protected-resource metadata andmcp:readscope hints in bearer challenges for invalid or insufficient OAuth tokens. - Local stdio MCP supports hosted and self-hosted API base URLs.
- Local stdio MCP can run with anonymous reads, personal API tokens, or API-resource OAuth access tokens.
- Baseline Checks runs
pnpm verify:api-contractsandpnpm verify:vrdex-mcpin oneVerify API and MCPjob. The MCP verifier includespnpm smoke:mcp-compatfor package typechecking, package tests, and shared local stdio protocol coverage across every curated read tool. The verifier also validatesdocs/developers/mcp-client-smoke-results.jsonso the manual matrix keeps every required day-one client row and every production-like hosted-readiness evidence row. The smoke can optionally probe a deployed hosted/mcpendpoint with--hosted-url, and can include constrained Dynamic Client Registration and Client ID Metadata Document probes with--dcrand--cimd. - The manual
On-Demand Vercel Previewworkflow runsHosted MCP Preview Smokeafter the Vercel preview it deploys. Request it by commenting@vrdex previewon the pull request. It is fail-closed: both a Vercel preview URL and same-branch Convex preview are required. A pass covers data-backed anonymousvrdex_search,search, andfetch, OAuth metadata, bearer challenges, Dynamic Client Registration, and Client ID Metadata Document authorization. Baseline Checks does not run it, so a pull request with no requested preview has no hosted MCP evidence. - Baseline Checks does not generate a client session pack on every PR. The
manual
External API and MCP Readinessworkflow always generates and uploads that pack as part of the strict external launch gate. - The manual
Deployed Health Checksworkflow targethosted-mcp-smokecan run the same hosted smoke against a staging, production-like, or same-branch Convex preview target. Use itsmcp_dcrandmcp_cimdinputs for external-readiness evidence when the on-demandOn-Demand Vercel Previewworkflow cannot enable those probes, or when no preview was requested at all. There is no automatic PR preview lane; previews are manual only. The manual workflow keeps selected hosted diagnostics running after a subcheck failure, so one run can expose data-backed read, DCR, and CIMD blockers separately while still failing if any selected probe fails. Usemcp_oauth=truewhen the run should use configured repository OAuth smoke secrets or, on staging/same-branch targets, mint temporary smoke credentials from hosted E2E auth and developer-credential helpers. Record the production-like hosted-readiness rows withpnpm record:mcp-hosted-evidenceso the aggregate readiness gate can verify data-backed anonymous reads, Dynamic Client Registration, and Client ID Metadata Document evidence separately from client UI smoke rows. Ahosted-data-backed-anonymous-readpass must include the stricter--hosted-dataevidence shape:vrdex_search, OpenAI-compatiblesearch, andfetchdocument text from the same target. docs/developers/mcp-client-compatibility.mdlists the current major-client matrix. External readiness requires representative launch-gating rows rather than every named product row. Record client-specific passes or failures withpnpm record:mcp-client-smokeso entries include a run date, target environment, and sanitized evidence pointer.- The major-client matrix source check was refreshed on 2026-07-09 against the current official docs for VS Code, Claude Code, Cursor, and Devin Desktop / Windsurf Cascade. Those docs keep remote HTTP/Streamable HTTP, local stdio, and hosted OAuth behavior in scope. Untested installed-app behavior remains a compatibility follow-up rather than another protocol redesign or launch blocker.
- Required hosted matrix rows cannot be recorded or verified as
passunless the matrix target environment names a same-branch Convex preview, staging, production-like, or production target. Lightweight PR preview transport evidence must stay separate from external-readiness evidence. Generated recorder commands are templates; replace every<placeholder>value before recording pass/fail evidence. pnpm ops:mcp-client-smokesgenerates the current day-one client smoke run plan from the matrix, including repo preflight commands, manual evidence prompts, recorder command templates for pending rows, and an Open Blocker Summary that groups remaining work by the prerequisite needed to unlock it.pnpm ops:mcp-installed-clientsperforms a read-only local preflight for installed Claude Code, Gemini CLI, VS Code, Cursor, and Windsurf CLI versions plus MCP configuration support. It also reports Claude Desktop process or common app-path availability on Windows, OpenAI Responses API and Gemini CLI auth readiness, and hosted OAuth smoke credential readiness by variable name only, including thedeployed-health.ymltemporary credential-generation gate (VRDEX_HOSTED_E2E_AUTH_HELPERS,VRDEX_HOSTED_E2E_DEVELOPER_CREDENTIALS, andVRDEX_HOSTED_E2E_BROWSER_TOKEN). It catches client drift and OAuth evidence blockers before manual smoke sessions but does not replace manual matrix evidence. Its credential tables load repo-root.env.localif present, then read the current process environment without printing secret values; runpnpm ops:mcp-hosted-oauth-prereqsfor the GitHub repository variable/secret audit. Its CLI automation notes distinguish Cursor's standalone transcript-capableagent/cursor-agentCLI from manual-only IDE launchers.pnpm smoke:mcp-cursor-agentcounts only after structured output contains a completedvrdex_searchevent and terminal success. VS Codechat, Cursor--chat, and Windsurf setup-only CLI checks remain manual until the real client session lists tools and callsvrdex_search; OpenAI / ChatGPT-compatible surfaces still requiresearchplusfetch.- Current 2026-07-13 repository audit for PR #159: the temporary credential
generation gate passes through
VRDEX_HOSTED_E2E_AUTH_HELPERS=true,VRDEX_HOSTED_E2E_DEVELOPER_CREDENTIALS=true, and theVRDEX_HOSTED_E2E_BROWSER_TOKENsecret. Deployed Health Checks run29275502404used that path against same-branch preview09a48b6and passed hosted data, DCR, and CIMD. A later harness audit found the Inspector OAuth subcheck could silently skip generated client credentials because it checked the wrong option shape. Deployed Health Checks run29288588007revalidated the corrected path against same-branch preview8144d47: generated credentials authenticated bootstrap and Inspectortools/listrequests. The Inspector OAuth row now passes; 14 named-client rows remain as nonblocking compatibility follow-ups. Reviewed OAuth smoke secrets andVRDEX_MCP_INSPECTOR_OAUTH_TOKENremain absent, and shared staging promotion still waits on the Terraform-ownedVRDEX_RATE_LIMIT_STORE,VRDEX_RATE_LIMIT_REDIS_REST_URL, andVRDEX_RATE_LIMIT_REDIS_REST_TOKEN. pnpm ops:mcp-client-session-packwrites disposable VS Code, Cursor, Windsurf, and Gemini CLI MCP setup files under.tmp-gh-artifacts/, including local stdio, hosted anonymous HTTP, hosted token-header fallback configs, launch commands or settings snippets where supported, smoke prompts, evidence templates, recorder commands, and the same Open Evidence Summary as the smoke planner. It also writes manual-only worksheets for Claude Desktop, Claude Code hosted OAuth, OpenAI/ChatGPT hosted rows, and MCP Inspector hosted OAuth. It does not replace manual matrix evidence; use it to keep those smoke sessions repeatable and to capture sanitized screenshot or transcript evidence before recording a row. PR Baseline Checks upload the same pack asmcp-client-session-packso reviewers and operators do not have to regenerate it before client smoke sessions. Filled evidence templates can be recorded withpnpm record:mcp-client-smoke -- --evidence-file <template.md>; the recorder rejects untouched pending worksheets, placeholders, and evidence summaries that appear to contain tokens, secrets, or authorization headers. The session pack reads the checked matrix by default and fails if any required row that is not alreadypasslacks a generated worksheet. VS Code-family setup commands use isolated--user-data-dirpaths and escaped JSON arguments because the current Windows CLIs reject fresh named profiles and raw PowerShell JSON for--add-mcp.pnpm ops:mcp-add-mcp-preflightwrites disposable VS Code, Cursor, and Windsurf config/user-data directories and verifies that the installed CLIs accept the generated local stdio, hosted anonymous HTTP, and hosted token-header fallback--add-mcpdefinitions. It skips missing clients by default and fails rejected definitions. It does not replace manual matrix evidence because it does not list tools or callvrdex_searchinside a real client session. Use comma-separated selectors or repeated flags to narrow the run; for example,--client vscode,cursorand--client vscode --client cursorare equivalent.pnpm ops:mcp-oauth-smoke-credentialsmints a temporary confidential OAuth app. It creates its account through the Clerk Backend API and signs in with a one-time ticket, so alongsideVRDEX_E2E_BROWSER_TOKENit needsCLERK_SECRET_KEYandNEXT_PUBLIC_CLERK_PUBLISHABLE_KEYfor the development instance backing the target — a production secret key is rejected. Registering an OAuth app by hand and supplyingVRDEX_MCP_OAUTH_CLIENT_IDwithVRDEX_MCP_OAUTH_CLIENT_SECRET, orVRDEX_MCP_INSPECTOR_OAUTH_TOKEN, remains the alternative.pnpm ops:mcp-hosted-oauth-prereqsreads GitHub Actions variable values and secret names throughghand reports whether hosted MCP OAuth evidence can use reviewed OAuth smoke secrets or the deployed-health temporary credential-generation path. It prints only variable/secret names plus boolean readiness, never secret values. Use--require-readywhen the hosted OAuth path must be treated as a hard external-readiness gate.pnpm check:api-mcp-rolloutis the advisory rollout summary. It summarizes the generated OpenAPI contract, required docs, verification scripts, hosted rate-limit Terraform owner, MCP client matrix, and hosted MCP production-like evidence state. The gate asserts every current checked-in/api/v0OpenAPI path, theinfra/terraform/rate-limit-redisfiles, lockfile, README entry, and Terraform workflow wiring, plus both MCP evidence recorder commands. It reports launch-gating items that are not pass in normal mode and labels required failed evidence rows asfail. Non-gating client rows remain visible in the matrix summary without blocking strict readiness.pnpm verify:api-mcp-rollout:externalcomposes the authoritative API contract, MCP, and docs verifiers before running the rollout checker with--require-ready. The manualExternal API and MCP Readinessworkflow is the authoritative CI launch gate and always uploads the client session pack, including when the strict gate fails. It also runs live data-backed read, Dynamic Client Registration, and Client ID Metadata Document smokes against the selected host. Dispatch the workflow with the exact deployedevidence_revision; the checked-in matrix target must name that host and deployed revision before the strict gate can pass. The workflow checkout SHA remains separate provenance and is not self-referential launch evidence.- Claude Code local stdio and hosted anonymous HTTP can be real-client smoked
with
pnpm smoke:mcp-claude-code, which runs the installed Claude Code CLI through a strict temporary MCP config. Use hosted mode with--hosted-dataagainst a same-branch or production-like backend before recording Claude Code hosted anonymous-read readiness. For Claude Code hosted OAuth evidence, set a reviewed OAuth app client id and secret throughVRDEX_MCP_OAUTH_CLIENT_ID/VRDEX_MCP_OAUTH_CLIENT_SECRETor theVRDEX_CLAUDE_CODE_OAUTH_CLIENT_*overrides; the smoke exchanges them for a short-lived MCP-resource token and validates an authenticatedvrdex_searchcall without printing the token or client secret.VRDEX_CLAUDE_CODE_OAUTH_TOKENremains supported for pre-minted token fallback runs. - MCP Inspector hosted anonymous HTTP can be smoke-tested with
pnpm smoke:mcp-inspector, which uses the Inspector CLI to validate hosted tool listing and public-read auth metadata. Use--hosted-dataagainst a same-branch or production-like backend before recording Inspector hosted anonymous-read readiness. For Inspector hosted OAuth evidence, set the same reviewed OAuth app credentials or theVRDEX_MCP_INSPECTOR_OAUTH_CLIENT_*overrides; the smoke exchanges them for a short-lived MCP-resource token and validates an authenticatedtools/listwithout printing the token or client secret. - OpenAI Responses API remote MCP hosted anonymous-read evidence can be
smoke-tested with
pnpm smoke:mcp-openaiafter settingOPENAI_API_KEY; the smoke also loads repo-root.env.localif present, without overriding already-set variables or printing secret values. Live Responses API requests time out after 90 seconds by default, with--request-timeout-msavailable for slower provider runs. The smoke uses the OpenAI-required hostedsearchandfetchtool names. Run it with required--hosted-dataagainst a same-branch or production-like backend before recording API integration evidence. Current 2026-07-14 same-branch preview evidence at0dd64b2passed data-backedvrdex_search,search,fetch, DCR, and CIMD in Hosted MCP Preview Smoke run29311948404, job87018585252. A dedicated OpenAI Responses API run previously passed withgpt-5.6-lunacalling hosted MCPsearchandfetch. This does not replace ChatGPT Apps/Connectors UI or hosted OAuth evidence; those product-surface rows stay pending until the current UI proves no-auth public reads andmcp:readOAuth behavior. - The general hosted MCP compatibility smoke now also checks the
OpenAI-compatible
searchandfetchaliases whenever--hosted-datais set. Use--hosted-queryorVRDEX_MCP_SMOKE_QUERYwhen the target's public seed data needs a known non-empty query. - The
deployed-health.ymlhosted-mcp-smokedispatch can also run the Inspector hosted OAuth smoke whenmcp_oauth=true. WithOPENAI_API_KEYand generic client credentials, the same dispatch runs the OpenAI Responses API hosted OAuth smoke usinggpt-5.6-luna; record it as API evidence while keeping ChatGPT Apps/Connectors UI evidence separate. It prefers repository secrets that provide eitherVRDEX_MCP_OAUTH_CLIENT_IDplusVRDEX_MCP_OAUTH_CLIENT_SECRETorVRDEX_MCP_INSPECTOR_OAUTH_TOKEN. If those are absent andVRDEX_HOSTED_E2E_AUTH_HELPERS=true,VRDEX_HOSTED_E2E_DEVELOPER_CREDENTIALS=true, andVRDEX_HOSTED_E2E_BROWSER_TOKENare configured, the job mints temporary smoke credentials throughpnpm ops:mcp-oauth-smoke-credentials, masks the generated secret, and feeds the credentials to the Inspector OAuth smoke. It skips that OAuth subcheck cleanly when neither credential source is available, so anonymous/data/DCR/CIMD health evidence is not blocked on reviewed OAuth credentials. EnablingVRDEX_HOSTED_E2E_DEVELOPER_CREDENTIALSis an operator decision, not a routine PR edit; keep it unset until the staging target has the developer credential routes and token endpoint under test.
Use a command shaped like this for each manual matrix row:
pnpm record:mcp-client-smoke -- \
--client mcp-inspector \
--check hosted-anonymous-read \
--status pass \
--environment "<client/version/env>" \
--evidence "<sanitized evidence link>"
Use a command shaped like this for each hosted production-like evidence row:
pnpm record:mcp-hosted-evidence -- \
--check hosted-data-backed-anonymous-read \
--status pass \
--target-environment "<same-branch Convex preview / staging / production-like target>" \
--environment "<runner / target>" \
--evidence "<sanitized workflow link showing vrdex_search plus search and fetch>"
Validation Commands
Run the narrow checks for changed areas plus the aggregate checks required by the PR:
pnpm check:api-openapi
pnpm typecheck:api-contracts
pnpm typecheck:vrdex-mcp
pnpm test:vrdex-mcp
pnpm test:scripts
pnpm smoke:mcp-compat
pnpm check:mcp-client-matrix
pnpm ops:mcp-installed-clients
pnpm ops:mcp-client-smokes -- --hosted-url <preview-or-production-like-/mcp-url> --hosted-query <known-public-query>
pnpm ops:mcp-client-session-pack -- --hosted-url <preview-or-production-like-/mcp-url> --hosted-query <known-public-query>
pnpm ops:mcp-add-mcp-preflight -- --hosted-url <preview-or-production-like-/mcp-url>
pnpm ops:mcp-hosted-oauth-prereqs
pnpm ops:api-platform-observability
pnpm check:api-mcp-rollout
pnpm smoke:mcp-compat -- --hosted-only --hosted-url <preview-or-production-like-/mcp-url>
pnpm smoke:mcp-compat -- --hosted-only --hosted-url <production-like-/mcp-url> --hosted-data --hosted-query <known-public-query> --dcr --cimd --continue-on-failure
VRDEX_MCP_OAUTH_CLIENT_ID=<reviewed-client-id> VRDEX_MCP_OAUTH_CLIENT_SECRET=<client-secret> pnpm smoke:mcp-claude-code -- --mode hosted-http --hosted-url <production-like-/mcp-url> --hosted-data --hosted-query <known-public-query>
pnpm smoke:mcp-inspector -- --hosted-url <preview-or-production-like-/mcp-url>
VRDEX_MCP_OAUTH_CLIENT_ID=<reviewed-client-id> VRDEX_MCP_OAUTH_CLIENT_SECRET=<client-secret> pnpm smoke:mcp-inspector -- --hosted-url <production-like-/mcp-url> --hosted-data --query <known-public-query>
pnpm smoke:mcp-openai -- --hosted-url <production-like-/mcp-url> --hosted-data --hosted-query <known-public-query>
gh workflow run deployed-health.yml --ref <branch> -f target=hosted-mcp-smoke -f base_url=<production-like-/mcp-url> -f mcp_data=true -f mcp_dcr=true -f mcp_cimd=true -f mcp_oauth=true
pnpm typecheck:backend
pnpm test:backend
pnpm typecheck:web
pnpm lint:web
pnpm lint:markdown
node --import tsx --test tests/web/**/*.test.ts
git diff --check
Use visual verification for changed UI surfaces. This checklist adds no visual requirement for docs-only or backend-only edits.