Skip to content

Live MCP client QA

This guide separates real-client manual QA from the protocol checks that are safe to automate. Never commit a token, PAT, client log, or client configuration containing a literal credential.

Supported client paths

ClientSupported transport used hereCredential handling
Codex CLIremote Streamable HTTPbearer from an inherited environment variable
Claude Desktoplocal stdio adapterrestricted token file read by openface-mcp-stdio
VS Coderemote Streamable HTTPpassword input in the official mcp.json schema

Codex can register the remote endpoint without putting the credential on its command line:

powershell
$env:OPENFACE_MCP_TOKEN = (Get-Content $env:OPENFACE_MCP_TOKEN_FILE -Raw).Trim()
codex mcp add openface --url https://openface.example/mcp `
  --bearer-token-env-var OPENFACE_MCP_TOKEN

Claude Desktop's remote custom connectors use authless or OAuth authorization; they do not provide a static bearer field. Install the verified host package before using the local stdio command (from this checkout: python -m pip install --upgrade ./openface-mcp, or install the verified wheel), validate its non-secret configuration, and register the local stdio adapter in %APPDATA%\Claude\claude_desktop_config.json instead:

json
{
  "mcpServers": {
    "openface": {
      "command": "openface-mcp-stdio",
      "env": {
        "OPENFACE_MCP_REMOTE_URL": "https://openface.example/mcp",
        "OPENFACE_MCP_CLIENT_TOKEN_FILE": "C:\\restricted\\openface.token"
      }
    }
  }
}

Fully quit and restart Claude Desktop after changing the file. For packaged Windows installs, confirm the effective roaming path under the app package's LocalCache rather than assuming the unpackaged path.

For VS Code, copy openface-mcp/examples/vscode-mcp.json to .vscode/mcp.json or the user-profile MCP configuration, then replace only the <OPENFACE_HOST> host placeholder; keep the template's /mcp path. Keep the password input and do not replace it with a literal token.

These examples were checked against the official Codex MCP guide, VS Code MCP configuration reference, Claude Desktop local-server guide, and Claude remote connector guide.

Manual checklist

  1. Provision a different short-lived service credential for each client.
  2. Record client, OS, server revision, and execution time without recording the token value or token-file contents.
  3. Confirm initialize/capability negotiation, Tools, Resources, and one bounded read. A client-native resource browser is preferable to an AI chat prompt.
  4. Repeat protocol checks with valid, insufficient-scope, expired, revoked, and invalid credentials. Expect 401 before initialization for invalid lifecycle states. For insufficient scope, call a tool already allowed by governance so the request reaches scope authorization; the versioned QA uses a repository-only credential against the allowed search_catalog tool and expects a missing-catalog:read denial.
  5. In the two-instance deployment, remove one healthy instance, wait for the gateway resolver interval, repeat the read, restore it, and repeat with the other instance. The client configuration must remain unchanged.
  6. Scan the sanitized summary for credential material before committing it.
  7. Snapshot raw native logs outside Git, scan them against every QA credential, and commit only source labels, byte counts, SHA-256 values, and sanitized state records. A blocked native run must remain blocked, even when its protocol identity passes.

The helper scripts are intentionally separate from the desktop QA:

bash
bash openface-mcp/scripts/provision_live_client_qa.sh
python openface-mcp/scripts/run_live_client_protocol.py --help

The provisioner writes root-only credentials outside Git and prints only a secret-free count. The protocol runner reads one token file, supports expected authentication failures, and fails if the credential appears in its summary. CI may exercise these scripts and protocol behavior; CI must not claim desktop UI or screenshot coverage.

Versioned result for issue #130

The 2026-08-02 JST run against the two-replica public endpoint produced these results:

ClientNative resultRemaining limitation
Codex CLI 0.146.026 tools, 1 resource, and 9 resource templates enumerated; OpenAPI resource and bounded catalog read passed; scope and invalid states passednone for the documented read-only path
Claude Desktop 1.19367.0.0initialize plus Tools, Prompts, and Resources passed; invalid startup rejection passedrepresentative native read pending; no Claude prompt was sent
VS Code 1.129.1native manager ran, discovered tools, opened the OpenAPI resource read-only, and passed scope/invalid state switchesnone for the documented read-only path

For HA evidence, each replica was made the sole backend in turn. The same configuration fingerprint was used without session headers or sticky cookies; initialize, Tools, Resources, and the representative read returned only the expected replica in both phases. Both replicas were restored healthy afterward.

Raw artifacts stay in a restricted directory outside Git. To reproduce the evidence boundary:

  1. Save native output without token values and retain the original bytes.
  2. Scan every raw artifact for every unique QA credential before revocation.
  3. Record only the source label, byte count, SHA-256, and sanitized state row in Git; do not commit paths, logs, screenshots, tokens, or client configuration.
  4. Revoke the temporary credentials, confirm zero active QA credentials, restore client configuration, and verify both replicas are healthy.

The sanitized records, exact HA phase identities, and raw hashes are in docs/evidence/issues/130/.

Released under the MIT License. Third-party components retain their own licenses.