MCP Client Compatibility Matrix
Status
Implementation-time compatibility matrix for the public API and MCP platform foundation.
Last reviewed: 2026-07-14.
This matrix separates repo-verified protocol behavior from real-client smokes. External readiness uses representative launch-gating rows rather than requiring every named client to be exercised. Non-gating rows remain explicit compatibility follow-ups and must not be described as directly verified.
Current official client-doc refresh, 2026-07-13:
- VS Code MCP docs
document MCP server configuration through
mcp.jsonand command-line--add-mcp, with remote HTTP servers usingtype: "http"andurl. - Claude Code MCP docs document remote
HTTP as the recommended cloud-service transport, support bearer headers, and
treat
streamable-httpas an alias forhttpin JSON MCP config. - Cursor MCP docs document
stdio, SSE, and Streamable HTTP transports, with OAuth for hosted transports and static OAuth client credentials when Dynamic Client Registration is not available. - Cursor Agent CLI docs document
project
.cursor/mcp.jsondiscovery, while the headless and output-format docs document--printplus structuredstream-jsontool-call transcripts. - Devin Desktop / Windsurf Cascade MCP docs
document
stdio, Streamable HTTP, and SSE transports, OAuth support for each transport type, andserverUrl/urlconfiguration for remote HTTP MCPs.
Those source checks keep the remaining installed-app batch focused on real client evidence. Cursor local and hosted-anonymous rows can use the headless Agent CLI; Cursor IDE, Windsurf, and OAuth-product behavior remain manual paths.
Source-backed client requirements from the current docs pass:
- hosted MCP must keep Streamable HTTP working for remote clients
- local MCP must keep stdio working for clients that run command-based servers
- hosted OAuth must support protected-resource metadata discovery, scope-aware bearer challenges, and constrained Dynamic Client Registration for clients that register automatically
- Client ID Metadata Documents are supported for hosted MCP public clients that prefer URL-form client IDs
- hosted public read tools should be callable without OAuth in clients that understand no-auth tool metadata, while OAuth remains available for authenticated MCP reads and future privileged tools
- OpenAI/ChatGPT-style clients need per-tool auth metadata to distinguish
anonymous public-read tools from OAuth-required tools. The current MCP SDK
emits this through
_meta["securitySchemes"]. - OpenAI Responses API, ChatGPT deep research, and company-knowledge-style
connectors require hosted read-only tools named
searchandfetchwith URL-backed structured document results. VRDex keeps those as hosted compatibility aliases over the canonical public read tools. - static bearer-token headers remain a diagnostic fallback, not the preferred hosted OAuth setup
- do not publish client-specific setup snippets unless that client's current docs or a manual smoke confirms the config shape
Launch Readiness Policy
Current recommendation: launch on representative client and protocol coverage, not exhaustive confirmation of every MCP product release.
The strict external gate requires:
- at least two distinct launch-gating clients for local stdio
- at least two distinct launch-gating clients for hosted anonymous HTTP
- at least one launch-gating client for authenticated hosted HTTP
- passing hosted data-backed reads, DCR, and CIMD protocol evidence
- every selected launch-gating row to be
pass
The current selection exceeds those minimums: Claude Code, Gemini CLI, VS Code, and MCP Inspector cover stdio; Gemini CLI, VS Code, OpenAI Responses, and MCP Inspector cover anonymous hosted HTTP; MCP Inspector covers authenticated hosted HTTP alongside the separate DCR and CIMD smokes.
Claude Desktop, Cursor, Windsurf/Devin, ChatGPT UI, and untested native OAuth
flows remain in the matrix as nonblocking follow-ups. A pending row means
VRDex is expected to interoperate from its protocol/configuration evidence but
has not directly confirmed that product surface. A fail caused before a VRDex
tool call, such as stale client-account authentication, remains visible but is
not treated as evidence that the VRDex transport failed. Any reproducible
protocol incompatibility discovered in a follow-up becomes a release bug.
Repo-Verified Protocol Checks
| Surface | Evidence |
|---|---|
| Hosted Streamable HTTP MCP | node --import tsx --test tests/web/**/*.test.ts covers initialization and curated tool listing. |
| Hosted anonymous public reads | Hosted /mcp allows no-bearer public read tools through the anonymous_mcp_public_read route class. Manual client smokes must also confirm the client UI does not force OAuth before public read calls. |
| Hosted data-backed public reads | pnpm smoke:mcp-compat -- --hosted-data requires non-empty anonymous vrdex_search to reach a production-like Convex backend and return structured content without a tool error. Use --hosted-query or VRDEX_MCP_SMOKE_QUERY when the target's seed data needs a specific query. |
| Hosted OpenAI-compatible public reads | node --import tsx --test tests/web/vrdex-mcp.test.ts covers the hosted search/fetch compatibility aliases, including URL-backed search results and public-safe fetch text from the same public profile/event/world queries. pnpm smoke:mcp-compat -- --hosted-data also requires deployed targets to return at least one search result and a non-empty fetch document for that result. |
| Hosted public-read auth metadata | Hosted /mcp tools/list exposes _meta["securitySchemes"] with noauth plus optional oauth2/mcp:read on every curated public read tool. |
| Hosted OAuth bearer handling | Web MCP and OAuth JWT tests cover MCP-resource audience validation, mcp:read scope validation, and protected-resource bearer challenges. |
| Hosted Client ID Metadata Documents | Web OAuth helper tests cover URL-form client IDs, exact client_id matching, redirect rejection, response-size limits, and special-use address rejection. |
| Local stdio MCP | pnpm --filter @basicbit/vrdex-mcp test runs JSON-RPC stdio calls for every curated read tool against a local API fixture. |
| Local API token config | packages/vrdex-mcp tests cover bearer forwarding to /api/v0. |
| Self-hosted base URL config | packages/vrdex-mcp tests cover origin and explicit /api/v0 normalization. |
Repo Smoke Command
Run this before manual client smokes:
pnpm smoke:mcp-compat
For hosted data-backed evidence, add --hosted-data. The hosted compatibility
smoke then requires both the VRDex-specific vrdex_search tool and the
OpenAI-compatible search plus fetch aliases to return real public data. Use
--hosted-query or VRDEX_MCP_SMOKE_QUERY when the default club query is
not populated on the target:
pnpm smoke:mcp-compat -- \
--hosted-only \
--hosted-url https://staging.vrdex.net/mcp \
--hosted-data \
--hosted-query a
Claude Code has an additional real-client harness. In local stdio mode, it
starts the repo API fixture, runs the installed Claude Code CLI with a strict
temporary --mcp-config, calls vrdex_search, and fails unless the fixture
receives the expected search request:
pnpm smoke:mcp-claude-code
In hosted HTTP mode, it points Claude Code at a deployed Streamable HTTP MCP
endpoint and parses Claude Code's stream JSON to prove the exact hosted
vrdex_search tool call and structured result. The default hosted command keeps
the lightweight empty-query transport check:
pnpm smoke:mcp-claude-code -- \
--mode hosted-http \
--hosted-url https://staging.vrdex.net/mcp
For external-readiness evidence, add --hosted-data so the real Claude Code
client must call a non-empty public search and receive structured content from
the target backend:
pnpm smoke:mcp-claude-code -- \
--mode hosted-http \
--hosted-url https://staging.vrdex.net/mcp \
--hosted-data
Use --hosted-query, --hosted-type, and --hosted-limit when the staging
seed data needs a different public search fixture. The equivalent environment
variables are VRDEX_CLAUDE_CODE_HOSTED_DATA,
VRDEX_CLAUDE_CODE_HOSTED_QUERY, VRDEX_CLAUDE_CODE_HOSTED_TYPE, and
VRDEX_CLAUDE_CODE_HOSTED_LIMIT.
For Claude Code hosted OAuth evidence, prefer a reviewed OAuth app that allows
the Client Credentials grant and mcp:read. Set
VRDEX_MCP_OAUTH_CLIENT_ID and VRDEX_MCP_OAUTH_CLIENT_SECRET, or the
client-specific VRDEX_CLAUDE_CODE_OAUTH_CLIENT_ID and
VRDEX_CLAUDE_CODE_OAUTH_CLIENT_SECRET, before running the hosted smoke. The
script exchanges those credentials at /oauth/token for the hosted /mcp
resource, writes the resulting short-lived bearer token only to a temporary MCP
config, validates an authenticated vrdex_search call, suppresses MCP debug
logging for that authenticated run, and does not print the token or client
secret:
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 https://staging.vrdex.net/mcp \
--hosted-data
If an operator already has a short-lived MCP-resource token with mcp:read,
VRDEX_CLAUDE_CODE_OAUTH_TOKEN remains supported as a fallback.
Pair that Claude Code run with pnpm smoke:mcp-compat -- --hosted-only --hosted-url <target> --hosted-data --dcr --cimd when recording the
claude-code/hosted-oauth matrix row, so the evidence covers both DCR/CIMD
protocol behavior and an authenticated client call.
Gemini CLI also has a real-client harness. In local stdio mode, it writes a
temporary .gemini/settings.json, starts the repo API fixture, runs Gemini CLI
headlessly with stream-json output, calls vrdex_search, and fails unless the
fixture receives the expected search request:
pnpm smoke:mcp-gemini-cli
If Gemini CLI is not installed globally, run the current package through
npx without making a permanent install:
pnpm smoke:mcp-gemini-cli -- --gemini-package @google/gemini-cli@latest
On Windows, the disposable package path is routed through cmd.exe so the
smoke does not trip Node's spawn EINVAL behavior for .cmd shims. A
2026-07-09 local smoke reached Gemini CLI 0.50.0, called vrdex_search,
returned club-night, and the fixture captured
/api/v0/search?q=club&type=event&limit=1.
In hosted HTTP mode, the harness points Gemini CLI at a deployed Streamable
HTTP MCP endpoint, requires Gemini's own mcp list preflight to report the
server connected, and parses stream-json output for the fully qualified
mcp_vrdex_vrdex_search call and structured result:
pnpm smoke:mcp-gemini-cli -- \
--mode hosted-http \
--hosted-url https://staging.vrdex.net/mcp \
--hosted-data
The disposable project is trusted only for the child process through
GEMINI_CLI_TRUST_WORKSPACE=true; the harness does not modify the user's
trusted-folder configuration. Timeout failures retain a bounded, redacted
stdout/stderr diagnostic so provider, MCP connection, and model tool-selection
failures remain distinguishable.
A 2026-07-10 hosted anonymous smoke passed with Gemini CLI 0.50.0 and the
current stable gemini-3.1-flash-lite model after the default
gemini-3.5-flash free-tier quota was exhausted:
pnpm smoke:mcp-gemini-cli -- \
--gemini-package @google/gemini-cli@latest \
--model gemini-3.1-flash-lite \
--mode hosted-http \
--hosted-url https://staging.vrdex.net/mcp \
--hosted-data \
--hosted-query a
Use --hosted-query, --hosted-type, and --hosted-limit when the staging
seed data needs a different public search fixture. The equivalent environment
variables are VRDEX_GEMINI_CLI_HOSTED_DATA,
VRDEX_GEMINI_CLI_HOSTED_QUERY, VRDEX_GEMINI_CLI_HOSTED_TYPE, and
VRDEX_GEMINI_CLI_HOSTED_LIMIT.
For Gemini CLI hosted OAuth evidence, prefer the current client's native OAuth
discovery and /mcp auth behavior when collecting interactive evidence. For a
repeatable token-backed smoke, set VRDEX_MCP_OAUTH_CLIENT_ID and
VRDEX_MCP_OAUTH_CLIENT_SECRET, or the client-specific
VRDEX_GEMINI_CLI_OAUTH_CLIENT_ID and
VRDEX_GEMINI_CLI_OAUTH_CLIENT_SECRET, before running the hosted smoke. The
script exchanges those credentials for a short-lived MCP-resource token, writes
it only to a temporary Gemini settings file as an HTTP Authorization header,
validates an authenticated vrdex_search call, and does not print the token or
client secret. VRDEX_GEMINI_CLI_OAUTH_TOKEN is also supported as a fallback.
Pair the Gemini OAuth run with pnpm smoke:mcp-compat -- --hosted-only --hosted-url <target> --hosted-data --dcr --cimd when recording the
gemini-cli/hosted-oauth matrix row, so the evidence covers both DCR/CIMD
protocol behavior and an authenticated client call.
MCP Inspector has a hosted CLI wrapper that runs npx --yes @modelcontextprotocol/inspector, validates the hosted tool list, and confirms
each public read tool advertises noauth plus optional oauth2 metadata:
pnpm smoke:mcp-inspector -- \
--hosted-url https://staging.vrdex.net/mcp
For external-readiness evidence, add --hosted-data so Inspector must call a
non-empty public search against the target backend:
pnpm smoke:mcp-inspector -- \
--hosted-url https://staging.vrdex.net/mcp \
--hosted-data
Use --query, --type, and --limit when the staging seed data needs a
different public search fixture. The equivalent environment variables are
VRDEX_MCP_INSPECTOR_HOSTED_DATA, VRDEX_MCP_INSPECTOR_QUERY,
VRDEX_MCP_INSPECTOR_TYPE, and VRDEX_MCP_INSPECTOR_LIMIT.
For Inspector hosted OAuth evidence, prefer the same reviewed OAuth app client
credentials path. Set VRDEX_MCP_OAUTH_CLIENT_ID and
VRDEX_MCP_OAUTH_CLIENT_SECRET, or the client-specific
VRDEX_MCP_INSPECTOR_OAUTH_CLIENT_ID and
VRDEX_MCP_INSPECTOR_OAUTH_CLIENT_SECRET, before running the same smoke. The
script exchanges those credentials for a short-lived MCP-resource token,
passes that token as an HTTP Authorization header, validates an authenticated
tools/list, and does not print the token or client secret:
VRDEX_MCP_OAUTH_CLIENT_ID="<reviewed-client-id>" \
VRDEX_MCP_OAUTH_CLIENT_SECRET="<client-secret>" \
pnpm smoke:mcp-inspector -- \
--hosted-url https://staging.vrdex.net/mcp \
--hosted-data
If an operator already has a short-lived MCP-resource token with mcp:read,
VRDEX_MCP_INSPECTOR_OAUTH_TOKEN remains supported as a fallback.
Pair that Inspector run with pnpm smoke:mcp-compat -- --hosted-only --hosted-url <target> --hosted-data --dcr --cimd when recording the
mcp-inspector/hosted-oauth matrix row, so the evidence covers both
DCR/CIMD protocol behavior and an authenticated mcp:read client call.
OpenAI Responses API remote MCP has a hosted anonymous-read harness. It first
preflights the hosted /mcp target directly, requiring tools/list to expose
search and fetch, search to return at least one data-backed result, and
fetch to return non-empty document text. Only after that target preflight
passes does it send a remote MCP tool definition with server_url, constrain
allowed_tools to search and fetch, set require_approval to never, and
fail unless the Responses payload includes both MCP tool calls and the expected
final answer:
pnpm smoke:mcp-openai -- \
--hosted-url https://staging.vrdex.net/mcp \
--hosted-data
The smoke loads the repo-root .env.local file before reading
OPENAI_API_KEY, without overriding variables that are already set in the
process environment and without printing secret values. Set
VRDEX_LOAD_ENV_LOCAL=0 for deterministic tests or shell sessions that should
ignore local secret files. Live Responses API requests time out after 90
seconds by default; use --request-timeout-ms or
VRDEX_OPENAI_MCP_REQUEST_TIMEOUT_MS for slower provider runs. For hosted OAuth
evidence, provide VRDEX_OPENAI_MCP_OAUTH_TOKEN or client credentials through
VRDEX_OPENAI_MCP_OAUTH_CLIENT_ID and
VRDEX_OPENAI_MCP_OAUTH_CLIENT_SECRET; the generic
VRDEX_MCP_OAUTH_CLIENT_ID/VRDEX_MCP_OAUTH_CLIENT_SECRET pair is also
accepted. The smoke exchanges client credentials for a scoped token and sends
it only through the Responses remote MCP tool authorization field.
This is OpenAI API integration evidence, not ChatGPT Apps/Connectors UI
evidence. Keep the ChatGPT product-surface row pending until the current UI
surface proves whether public read tools stay anonymous/no-auth and how hosted
OAuth behaves. --hosted-data is required for this harness because fetch
must resolve a real search result.
Current 2026-07-14 hosted protocol evidence targets the same-branch Vercel and
Convex preview at 0dd64b2. Hosted MCP Preview Smoke run 29311948404, job
87018585252, passed data-backed anonymous vrdex_search, OpenAI-compatible
search/fetch, Dynamic Client Registration, and public-client Client ID
Metadata Document authorization. A real Gemini CLI 0.50.0 rerun also passed
hosted anonymous vrdex_search against that exact target. Previously recorded
MCP Inspector and OpenAI Responses API gpt-5.6-luna evidence remains valid;
the latter is API integration evidence, not ChatGPT Apps/Connectors UI
evidence. Claude Code's preview rerun stopped at the client's own stale account
authentication with the same HTTP 401 on a non-MCP prompt, so it does not
establish a VRDex transport failure and remains open for rerun after client
reauthentication.
PR Baseline Checks run the same local stdio protocol smoke through
pnpm verify:vrdex-mcp.
The manual On-Demand Vercel Preview workflow runs Hosted MCP Preview Smoke
after the Vercel preview it deploys; comment @vrdex preview on a pull request
to request it. Baseline Checks no longer runs this lane, so a pull request
without a requested preview produces no hosted MCP evidence. That lane runs this
smoke against the
preview /mcp endpoint for anonymous Streamable HTTP, an anonymous
empty-query vrdex_search tool call, OAuth metadata, and bearer challenge
coverage, plus data-backed non-empty public reads, Dynamic Client Registration,
and Client ID Metadata Document authorization. It is fail-closed: when
CONVEX_DEPLOY_KEY_PREVIEW does not provision a same-branch Convex preview
backend, the lane fails and names that prerequisite instead of downgrading
coverage.
The command starts the local stdio MCP package against a local API fixture and replays initialize, tool-list, and every curated read-tool call with protocol profiles for Claude Desktop, Claude Code, Gemini CLI, VS Code, Cursor, Devin Desktop / Windsurf Cascade, and MCP Inspector. It verifies the shared MCP protocol path these clients use, not the clients' UI or account flows.
The manual smoke result artifact is
docs/developers/mcp-client-smoke-results.json. pnpm verify:vrdex-mcp
validates that the artifact still lists every required day-one client and
required smoke row. Run this explicit check when updating matrix evidence:
pnpm check:mcp-client-matrix
Generate the next smoke-run plan from the current matrix before coordinating manual client sessions:
pnpm ops:mcp-client-smokes -- \
--hosted-url https://staging.vrdex.net/mcp \
--hosted-query a
The planner prints every open required row, the repo preflight command to
run first, client-specific setup hints, the client-side evidence to capture,
the production-like hosted MCP evidence rows, and the exact recorder command
shapes for recording passes. It starts with an Open Evidence Summary that
groups remaining rows by the operator prerequisite that unlocks them: installed
app tool-call sessions, installed app OAuth sessions, missing client install or
account setup, desktop/custom connector access, hosted product surface access,
hosted protocol target evidence, or OAuth smoke credentials. Setup hints are
not evidence by themselves; record a matrix row only after the real client
lists tools and calls vrdex_search or completes the required mcp:read OAuth
path. Add --include-passed when producing a full day-one evidence packet
instead of only the open work.
Before coordinating desktop/client sessions on a local machine, run the installed-client preflight:
pnpm ops:mcp-installed-clients
This read-only check records the detected Claude Code, Gemini CLI, VS Code,
Cursor, and Windsurf CLI versions, verifies that installed clients still expose
the MCP configuration surface their matrix rows depend on, reports Claude
Desktop process or common app-path availability on Windows, and reports whether
OpenAI Responses API, Gemini CLI auth, and hosted OAuth smoke credential
variables are present. It also reports whether the deployed-health.yml
hosted-mcp-smoke workflow has the temporary OAuth credential-generation gate
configured through VRDEX_HOSTED_E2E_AUTH_HELPERS,
VRDEX_HOSTED_E2E_DEVELOPER_CREDENTIALS, and
VRDEX_HOSTED_E2E_BROWSER_TOKEN. It prints variable names only, never secret
values. The credential tables read the current process environment after
loading repo-root .env.local if present; use
pnpm ops:mcp-hosted-oauth-prereqs below for the GitHub repository
variable/secret audit. It does not write client configuration, launch GUI smoke
sessions, call provider APIs, or turn any manual row green by itself. Use it to
catch local client drift and OAuth/model-provider evidence blockers before the
human smoke pass.
The preflight also distinguishes automation-capable and manual-only client
surfaces. Cursor's standalone agent / cursor-agent CLI is accepted only
when its help output exposes --print, stream-json, and mcp list-tools;
pnpm smoke:mcp-cursor-agent then requires a completed vrdex_search tool
event and terminal success before producing evidence. Cursor --chat and VS
Code chat remain GUI handoffs without a stdout tool transcript, and Windsurf
still exposes setup-only --add-mcp behavior. A CLI launch or config preflight
does not count as a matrix pass.
After the preflight, generate a disposable smoke-session pack for installed VS Code-family clients and Gemini CLI, plus manual-only worksheets for hosted product surfaces, missing desktop apps, and OAuth rows that need reviewed credentials:
pnpm ops:mcp-client-session-pack -- \
--hosted-url https://staging.vrdex.net/mcp \
--hosted-query a
The pack is written to .tmp-gh-artifacts/mcp-client-smoke-session/ by
default. PR Baseline Checks also upload this directory as the
mcp-client-session-pack artifact after pnpm verify:vrdex-mcp, using the
staging hosted MCP target. It contains compact --add-mcp JSON definitions for
VS Code, Cursor, and Windsurf plus Gemini CLI settings.json snippets for local
stdio, hosted anonymous HTTP, and hosted token-header fallback setups. It also
includes manual-only worksheets for Claude Desktop, Claude Code hosted OAuth,
OpenAI/ChatGPT hosted rows, and MCP Inspector hosted OAuth. The generated
VS Code, Cursor, and Windsurf PowerShell commands use an isolated
--user-data-dir and escape JSON quotes before passing --add-mcp; direct
fresh-profile --add-mcp and raw (Get-Content -Raw ...) JSON both fail on
the current Windows CLIs. The generated
README includes the same Open Evidence Summary as the smoke planner so the
downloaded artifact can be used directly for smoke-session batching. The
generated evidence/ templates are pending worksheets for each row; fill them
with sanitized real-client screenshot or transcript evidence before running the
recorder command. A pass worksheet must show the tool list, the vrdex_search
call, and the first returned slug. A fail worksheet must name the exact failed
step, client-visible error, client version, auth mode, and any upstream issue
link without including credentials. The pack is not evidence by itself; use it
to run the real client session and then record the matrix row only after the
client lists tools and calls vrdex_search, completes the required mcp:read
OAuth path, or produces a sanitized failure that should remain in the matrix.
Completed worksheets can be recorded directly:
pnpm record:mcp-client-smoke -- \
--evidence-file .tmp-gh-artifacts/mcp-client-smoke-session/evidence/vscode-hosted-anonymous-read.md
The worksheet recorder infers the matrix row, environment, target environment,
status, and evidence summary from the file. It rejects untouched pending
worksheets, generated placeholder text, placeholder target values, and evidence
summaries that appear to contain tokens, secrets, or authorization headers.
The session-pack generator reads
docs/developers/mcp-client-smoke-results.json by default and fails if any
required row that is not already pass lacks a generated worksheet. Use
--matrix <path> or VRDEX_MCP_CLIENT_MATRIX_PATH=<path> when rehearsing a
matrix change against a temporary copy.
Before opening the installed VS Code-family apps for manual evidence, run the isolated add-MCP preflight against the generated JSON shapes:
pnpm ops:mcp-add-mcp-preflight -- \
--hosted-url https://staging.vrdex.net/mcp
This writes disposable config and user-data directories under
.tmp-gh-artifacts/mcp-client-add-mcp-preflight/, then asks VS Code, Cursor,
and Windsurf to accept local stdio, hosted anonymous HTTP, and hosted
token-header fallback definitions. Missing clients are skipped unless
--require-installed is set. A passing preflight proves only that the current
CLI accepts the setup definitions; it is still not matrix evidence because it
does not list tools or call vrdex_search inside the app.
Use comma-separated selectors or repeated flags to narrow the run; both
--client vscode,cursor and --client vscode --client cursor are supported.
The same applies to --config.
Latest local preflight: on 2026-07-09,
pnpm ops:mcp-installed-clients detected VS Code 1.128.0, Cursor 3.10.17,
and Windsurf 1.110.1. pnpm ops:mcp-add-mcp-preflight -- --hosted-url https://staging.vrdex.net/mcp accepted all generated local-stdio,
hosted-anonymous-read, and hosted-token-fallback definitions for those
installed clients. Those rows remain pending until the real app session lists
tools and calls vrdex_search.
The VS Code, Cursor IDE, and Windsurf launcher paths remain manual-only for
evidence capture: setup and chat launch success are not enough unless the
client session itself shows the VRDex tool list and a vrdex_search result.
A separately installed, capability-qualified Cursor agent or cursor-agent
CLI can instead use pnpm smoke:mcp-cursor-agent to record structured tool
listing and completed-call evidence; the Cursor IDE executable does not count
as that headless client.
Record manual pass or fail results with the recorder command instead of hand-editing the JSON:
pnpm record:mcp-client-smoke -- \
--client mcp-inspector \
--check hosted-anonymous-read \
--status pass \
--environment "Windows 11 / MCP Inspector <version> / https://vrdex.net/mcp" \
--target-environment "production-like staging https://vrdex.net/mcp" \
--evidence "sanitized screenshot or PR evidence link"
Use --matrix <path> or VRDEX_MCP_CLIENT_MATRIX_PATH=<path> to rehearse an
update against a temporary copy before writing the canonical matrix. A pass
or fail entry requires an environment and evidence pointer; pending clears
run evidence; not_applicable requires notes and is allowed only for rows that
are not required for external readiness. Generated recorder commands are
templates: replace every <placeholder> value before running them. The
recorder and verifier reject placeholder evidence, environment, or target text
for pass/fail rows.
For required hosted rows, a pass also requires --target-environment naming
a same-branch Convex preview, staging, production-like, or production target.
The recorder and matrix verifier reject hosted pass rows that still describe
pending, skipped, unavailable, or non-data-backed evidence. This keeps
lightweight PR preview transport smokes separate from external-readiness
evidence, even if the JSON artifact is hand-edited. The
hosted-data-backed-anonymous-read pass row must also mention the stricter
--hosted-data evidence shape: anonymous vrdex_search,
OpenAI-compatible search, and fetch document text from the same target.
Record the top-level hosted MCP production-like evidence rows with
pnpm record:mcp-hosted-evidence after the corresponding hosted smoke passes:
pnpm record:mcp-hosted-evidence -- \
--check hosted-data-backed-anonymous-read \
--status pass \
--target-environment "production-like staging https://vrdex.net/mcp" \
--environment "GitHub Actions / hosted-mcp-smoke" \
--evidence "sanitized workflow link showing vrdex_search plus search and fetch"
The required hosted evidence rows are:
hosted-data-backed-anonymous-readhosted-dynamic-client-registrationhosted-client-id-metadata-document
Current PR #159 status: same-branch preview 8144d47 passes hosted data-backed
anonymous read, Dynamic Client Registration, public-client Client ID Metadata
Document persistence, and authenticated MCP Inspector OAuth. Deployed Health
Checks run 29288588007 generated a confidential smoke client, authenticated
bootstrap tools/list, and repeated authenticated tool listing through MCP
Inspector with the corrected credential mapping.
Shared staging promotion still waits on the
Terraform-owned Redis rate-limit variables; other client-specific hosted OAuth
rows remain pending until their matching real-client smokes succeed.
The deployed-health.yml hosted-mcp-smoke workflow can additionally run the
Inspector hosted OAuth smoke when dispatched with mcp_oauth=true. When the
same run has OPENAI_API_KEY plus generic client credentials, it also runs the
OpenAI Responses API OAuth smoke with gpt-5.6-luna; that remains API evidence,
not ChatGPT Apps/Connectors UI evidence. The workflow prefers repository secrets
that provide either VRDEX_MCP_OAUTH_CLIENT_ID plus
VRDEX_MCP_OAUTH_CLIENT_SECRET or VRDEX_MCP_INSPECTOR_OAUTH_TOKEN. If those
secrets are absent on a staging or same-branch target, the workflow can mint a
temporary reviewed smoke client through the same helper below when
VRDEX_HOSTED_E2E_AUTH_HELPERS=true,
VRDEX_HOSTED_E2E_DEVELOPER_CREDENTIALS=true, and
VRDEX_HOSTED_E2E_BROWSER_TOKEN is configured. The workflow leaves
anonymous/data/DCR/CIMD evidence runnable even when reviewed OAuth smoke
credentials and helper prerequisites are absent.
When those repository secrets have not yet been installed, mint a temporary
reviewed smoke client with pnpm ops:mcp-oauth-smoke-credentials. It creates
its account through the Clerk Backend API and signs in with a one-time ticket,
so it needs CLERK_SECRET_KEY and NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY for the
development instance backing the target, alongside
VRDEX_E2E_BROWSER_TOKEN. A production secret key is rejected outright.
Otherwise register a confidential OAuth app by hand with client_credentials
and mcp:read, then export its credentials as VRDEX_MCP_OAUTH_CLIENT_ID and
VRDEX_MCP_OAUTH_CLIENT_SECRET — or supply an already-issued bearer token as
VRDEX_MCP_INSPECTOR_OAUTH_TOKEN — before running the Claude Code and
Inspector hosted OAuth smokes and recording the two matrix rows.
Before dispatching the workflow for hosted OAuth evidence, audit the repository prerequisites:
pnpm ops:mcp-hosted-oauth-prereqs
That read-only check uses gh variable list and gh secret list for the
selected repository, then reports whether the hosted OAuth path can use
reviewed VRDEX_MCP_OAUTH_CLIENT_ID / VRDEX_MCP_OAUTH_CLIENT_SECRET
secrets or the temporary credential-generation gate
(VRDEX_HOSTED_E2E_AUTH_HELPERS=true,
VRDEX_HOSTED_E2E_DEVELOPER_CREDENTIALS=true, and
VRDEX_HOSTED_E2E_BROWSER_TOKEN). It prints only variable/secret names plus
boolean readiness, never secret values. Add --require-ready when the audit
should fail until one of those complete paths is configured.
Current PR #159 audit result from 2026-07-13: reviewed OAuth client secrets and
the Inspector token fallback remain absent, but temporary credential generation
through VRDEX_HOSTED_E2E_AUTH_HELPERS=true,
VRDEX_HOSTED_E2E_DEVELOPER_CREDENTIALS=true, and the
VRDEX_HOSTED_E2E_BROWSER_TOKEN secret passed against same-branch preview
8144d47. Deployed Health Checks run 29288588007 passed hosted data, DCR,
CIMD, authenticated bootstrap tools/list, and MCP Inspector OAuth with the
corrected credential mapping. Shared staging promotion still waits on the Terraform-owned
VRDEX_RATE_LIMIT_STORE, VRDEX_RATE_LIMIT_REDIS_REST_URL, and
VRDEX_RATE_LIMIT_REDIS_REST_TOKEN.
These rows are checked separately from manual client UI rows so a lightweight PR preview transport smoke cannot accidentally satisfy the production-like data-backed, DCR, and CIMD readiness gate.
A green PR is implementation-ready, not externally ready. Baseline Checks
enforces the API/MCP contract and local protocol suites only; it carries no
hosted evidence. Hosted preview evidence comes from the on-demand
Hosted MCP Preview Smoke, which runs only after someone requests a preview and
fails unless a Vercel preview is connected to a same-branch Convex preview for
data-backed reads, DCR, and CIMD. Neither converts pending major client UI
evidence into passes.
pnpm check:api-mcp-rollout is the advisory summary for current rollout state.
It reports pending and failed external evidence without requiring every manual
row to pass.
By default, the check reports nonblocking follow-up rows without failing. For external readiness, it requires every selected representative row to pass and enforces minimum client diversity for each transport/auth class:
pnpm check:mcp-client-matrix -- --require-ready
For the broader public API/MCP launch audit, run:
pnpm verify:api-mcp-rollout:external
That command verifies API contracts, MCP behavior, and docs before enforcing
the strict rollout audit. It fails while representative client rows or hosted
data/DCR/CIMD/OAuth evidence are not pass. The manual External API and MCP Readiness workflow is the authoritative CI launch gate and always uploads a
fresh client session pack. Baseline Checks deliberately does not create that
artifact on every PR. The workflow live-smokes the selected host with
data-backed reads, DCR, and CIMD, then requires the checked-in matrix target to
name both that host and an explicit deployed evidence_revision input. The
workflow checkout SHA is reported separately, avoiding an impossible
self-reference while preventing evidence from another deployment from
satisfying launch readiness.
To include a deployed hosted MCP endpoint, pass:
pnpm smoke:mcp-compat -- --hosted-url https://staging.vrdex.net/mcp
The hosted smoke covers anonymous Streamable HTTP initialization/tool listing, an
anonymous empty-query vrdex_search tool call, OAuth protected-resource
metadata, authorization-server metadata, and the OAuth protected-resource
challenge for invalid bearer tokens. Add --hosted-data when the target is
backed by same-branch or production-like Convex functions and indexes; that path
requires non-empty anonymous vrdex_search to return structured content instead
of a tool error. When a data-backed tool call fails, the smoke prints a
sanitized summary of the MCP error content to make backend, fixture, and tool
contract failures easier to distinguish. Add --hosted-only when you are
rechecking a remote target and do not need the local stdio profile sweep. Add
--continue-on-failure for production-like readiness diagnostics when you want
the data-backed read, DCR, and CIMD probes to keep running after one selected
subcheck fails; the command still exits non-zero if any selected probe fails.
Add --dcr when you want the smoke to register a
constrained public MCP client through Dynamic Client Registration. Add --cimd
when you want the smoke to exercise a URL-form public client id against
GET /oauth/authorize; the smoke uses
/.well-known/oauth-client/vrdex-mcp-public-client and expects the
unauthenticated sign-in redirect after metadata validation succeeds.
The equivalent environment variables remain supported for CI:
VRDEX_MCP_SMOKE_URL, VRDEX_MCP_SMOKE_DATA, VRDEX_MCP_SMOKE_DCR,
VRDEX_MCP_SMOKE_QUERY, VRDEX_MCP_SMOKE_CIMD, and
VRDEX_MCP_SMOKE_CONTINUE_ON_FAILURE. Set VRDEX_MCP_SMOKE_TOKEN only for a
local terminal run when you want to test an authenticated hosted tool list. Do
not commit real tokens or smoke output containing credentials.
GitHub also has a manual Deployed Health Checks workflow target named
hosted-mcp-smoke for production-like or same-branch Convex preview targets.
Use it for targeted production-like diagnostics or to collect hosted evidence
before the external launch gate. The on-demand Hosted MCP Preview Smoke
fails when CONVEX_DEPLOY_KEY_PREVIEW is unavailable; it no longer downgrades
coverage and reports green. The deployed-health workflow keeps selected hosted
diagnostics running after a subcheck failure so one run can distinguish
backend data, DCR, and CIMD blockers.
Day-One Client Matrix
| Client | Local stdio config | Hosted HTTP config | OAuth expectation | Current status |
|---|---|---|---|---|
| Claude Desktop | Uses mcpServers JSON with command, args, and optional env. | Remote setup should use Claude's current Custom Connector path. | Hosted /mcp should complete OAuth through protected-resource metadata. | Local stdio protocol smoke covered by pnpm smoke:mcp-compat; hosted manual smoke pending. |
| Claude Code | Supports stdio with claude mcp add --transport stdio. | Supports HTTP with claude mcp add --transport http. | Supports OAuth from /mcp or claude mcp login; reviewed-app client-credentials token acquisition and token-backed header auth are available as evidence paths. DCR and public-client CIMD are implemented. | Local stdio passes. The same-branch hosted anonymous rerun is blocked by stale local Claude authentication, not a VRDex transport or data failure; reauthenticate before the hosted anonymous and OAuth reruns. |
| Gemini CLI | Uses settings.json mcpServers entries with command for stdio. | Supports Streamable HTTP through httpUrl and SSE through url. | Supports OAuth 2.0 for remote MCP, automatic discovery, Dynamic Client Registration, /mcp auth, and secure token storage; token-backed fallback evidence is available through the Gemini smoke harness. | Local stdio and same-branch data-backed hosted anonymous read pass with Gemini CLI 0.50.0. Hosted OAuth remains pending. |
| VS Code | Uses .vscode/mcp.json or user MCP config with servers entries. | Supports type: "http" and url. | Avoid hardcoded secrets; use inputs or environment files. OAuth manual smoke pending. | VS Code 1.128.0 real-client sessions pass local stdio and hosted anonymous tool listing/calls. Hosted OAuth remains pending. |
| Cursor | Uses project .cursor/mcp.json; pnpm smoke:mcp-cursor-agent validates local stdio through the standalone Agent CLI. | Agent CLI discovers the same config and the smoke harness validates hosted anonymous HTTP with structured stream-json evidence. | Confirm current native OAuth login behavior during manual smoke. | Cursor IDE 3.11.13 accepts the generated MCP definitions. The standalone Agent CLI is not installed on the current Windows host, so local and hosted-anonymous real-client rows remain pending without claiming IDE launch success. |
| OpenAI and ChatGPT MCP-capable surfaces | Treat local stdio as unsupported until the current product surface says otherwise. | Use hosted remote MCP when ChatGPT Apps, deep research, or API integration setup supports custom MCP servers; hosted search and fetch compatibility aliases are available for OpenAI-required document search. | Current OpenAI docs recommend CIMD when the authorization server supports it and keep DCR as a supported path when configured; VRDex implements both DCR and public-client CIMD. Public read tools advertise _meta["securitySchemes"] with noauth plus optional oauth2. | OpenAI Responses API gpt-5.6-luna passes same-branch data-backed search and fetch at 0af8dbb. ChatGPT Apps/Connectors UI and hosted OAuth behavior remain pending. |
| Devin Desktop / Windsurf Cascade | Uses mcp_config.json with mcpServers. | Supports serverUrl or url for remote HTTP MCPs. | Docs state OAuth support for stdio, Streamable HTTP, and SSE. | Local stdio protocol smoke covered by pnpm smoke:mcp-compat; Windsurf 1.110.1 accepted all generated --add-mcp definitions on 2026-07-09; manual tool-call smoke pending. |
| MCP Inspector | Use as a protocol-level stdio debugger; local stdio vrdex_search is manually verified in the smoke matrix. | Connect directly to hosted /mcp for remote debugging; pnpm smoke:mcp-inspector validates hosted tool listing and auth metadata. | Use reviewed-app client credentials or VRDEX_MCP_INSPECTOR_OAUTH_TOKEN fallback to validate authenticated hosted tools/list; pair with the DCR/CIMD protocol smoke. | Local stdio, same-branch data-backed anonymous read, and generated-client hosted OAuth pass. Deployed Health Checks run 29288588007 authenticated bootstrap and Inspector tools/list requests against preview 8144d47. |
Shared Local Stdio Config
Most clients that accept the common MCP server JSON shape can use this local stdio configuration.
{
"mcpServers": {
"vrdex": {
"command": "pnpm",
"args": [
"--silent",
"--dir",
"<path-to-vrdex-checkout>",
"exec",
"tsx",
"packages/vrdex-mcp/src/stdio.ts"
],
"env": {
"VRDEX_API_BASE_URL": "https://vrdex.net",
"VRDEX_API_TOKEN": "<personal-api-token>"
}
}
}
}
For anonymous public reads, omit VRDEX_API_TOKEN. For self-hosted or staging
deployments, set VRDEX_API_BASE_URL to the deployment origin or explicit
/api/v0 path.
VS Code uses servers rather than mcpServers:
{
"servers": {
"vrdex": {
"type": "stdio",
"command": "pnpm",
"args": [
"--silent",
"--dir",
"<path-to-vrdex-checkout>",
"exec",
"tsx",
"packages/vrdex-mcp/src/stdio.ts"
],
"env": {
"VRDEX_API_BASE_URL": "https://vrdex.net"
}
}
}
}
Shared Hosted HTTP Config
Hosted endpoint:
https://vrdex.net/mcp
Anonymous public reads require no credential. OAuth-authenticated hosted reads
need an MCP-resource token with mcp:read. If a client is testing OAuth
discovery, remove static Authorization headers so it can follow protected
resource metadata.
Claude Code hosted anonymous command:
claude mcp add --transport http vrdex https://vrdex.net/mcp
Claude Code hosted header-token fallback:
claude mcp add --transport http vrdex https://vrdex.net/mcp \
--header "Authorization: Bearer <mcp-resource-token>"
Windsurf or Devin Desktop hosted config:
{
"mcpServers": {
"vrdex": {
"serverUrl": "https://vrdex.net/mcp"
}
}
}
VS Code hosted config:
{
"servers": {
"vrdex": {
"type": "http",
"url": "https://vrdex.net/mcp"
}
}
}
Manual Smoke Checklist
Start by generating the current plan:
pnpm ops:mcp-client-smokes -- \
--hosted-url <preview-or-production-like-/mcp-url> \
--hosted-query <known-public-query>
-
Run
pnpm smoke:mcp-compat; for hosted protocol coverage, add--hosted-url <preview-or-production-like-/mcp-url>. Use--hosted-onlyfor focused remote-target retries. Add--hosted-datawhen the deployed target has same-branch or production-like Convex functions and indexes. Add--dcrwhen the smoke should create a temporary dynamic public MCP client, and--cimdwhen the smoke should materialize the public client metadata document flow through/oauth/authorize. For GitHub-hosted evidence against a deployed target, run the manualDeployed Health Checksworkflow with targethosted-mcp-smoke,base_url=<target-/mcp-url>, and the matchingmcp_data/mcp_dcr/mcp_cimdtoggles. Addmcp_oauth=truewhen the run should use configured repository OAuth smoke secrets or mint temporary staging smoke credentials from the hosted E2E auth/developer helper path. PR #159's 2026-07-09 repository audit shows that OAuth subcheck remains gated until reviewed OAuth smoke secrets are installed orVRDEX_HOSTED_E2E_DEVELOPER_CREDENTIALS=trueis enabled alongside the already-present hosted auth-helper inputs. For local stdio rows, an anonymous session lists the six public read tools. A session configured with a bearer credential lists eight tools: those six reads plusvrdex_event_createandvrdex_event_update. -
Claude Desktop local stdio starts, lists six anonymous tools or eight credentialed tools as appropriate, and calls
vrdex_search. -
Claude Desktop hosted Custom Connector lists anonymous tools and completes OAuth for
mcp:readwhen protected tools are enabled. -
Claude Code local stdio and hosted HTTP anonymous reads pass through
pnpm smoke:mcp-claude-code; hosted anonymous readiness uses--hosted-datafor a data-backed non-empty search against the target backend. Hosted OAuth either completes interactively throughclaude mcp login, uses reviewed OAuth app client credentials, or usesVRDEX_CLAUDE_CODE_OAUTH_TOKENfallback for an authenticated smoke, paired with DCR and public-client CIMD protocol evidence. -
Gemini CLI local stdio lists six anonymous tools or eight credentialed tools through
/mcp, hosted anonymous reads work throughhttpUrl, and hosted OAuth succeeds through automatic discovery or a documented static OAuth fallback. -
VS Code local stdio lists six anonymous tools or eight credentialed tools and hosted HTTP anonymous reads work.
-
Cursor local stdio and hosted HTTP read tools work in the current release.
-
OpenAI or ChatGPT MCP-capable surfaces connect to hosted
/mcpif the current product supports custom remote MCP connectors. Responses API hosted anonymous-read evidence usespnpm smoke:mcp-openaiwithOPENAI_API_KEY; the smoke requires bothsearchandfetch, and now preflights the hosted MCP target before making an OpenAI request. PR #159 records a 2026-07-13 pass against same-branch preview7fe11e8:gpt-5.6-lunacalled hosted MCPsearchandfetchthrough the Responses API harness. Record whether ChatGPT Apps/Connectors accepts DCR, requires Client ID Metadata Documents, or follows a reviewed app submission path. Also record whether public read tools appear as anonymous/no-auth tools instead of forcing OAuth before a safe search. -
Devin Desktop or Windsurf Cascade local stdio and hosted HTTP read tools work; OAuth is tested when team MCP access allows it.
-
MCP Inspector local stdio and hosted anonymous read paths return expected tool lists, auth metadata, and data-backed search results. Use
pnpm smoke:mcp-inspector -- --hosted-datafor the hosted data-backed row; set reviewed OAuth app client credentials orVRDEX_MCP_INSPECTOR_OAUTH_TOKENfallback for the hosted OAuth row and pair it with the DCR/CIMD hosted protocol smoke.
For rows 4, 5, 6, and 8, start from pnpm ops:mcp-client-session-pack so
Gemini CLI, VS Code, Cursor, and Windsurf use the same generated local stdio
and hosted HTTP definitions, prompt, target URL, and recorder-command shape.
For each smoke, record client version, OS, transport, auth mode, result, exact config shape, whether the client distinguishes anonymous/no-auth tools from OAuth-required tools, and issue link if it fails. Keep real tokens out of docs, logs, and screenshots.
Record those results with pnpm record:mcp-client-smoke. The command updates
docs/developers/mcp-client-smoke-results.json and preserves the matrix shape
expected by pnpm check:mcp-client-matrix. Non-gating rows may remain
pending after external readiness, but only passing rows support a
client-specific compatibility claim.