Skip to content

feat(security): collect credentials via elicitation for createAccessibilityAuthConfig and createLCASteps - #361

Merged
ruturaj-browserstack merged 1 commit into
browserstack:mainfrom
SavioBS629:elicitation-support
Aug 6, 2026
Merged

feat(security): collect credentials via elicitation for createAccessibilityAuthConfig and createLCASteps#361
ruturaj-browserstack merged 1 commit into
browserstack:mainfrom
SavioBS629:elicitation-support

Conversation

@SavioBS629

Copy link
Copy Markdown
Collaborator

Both tools previously accepted credentials as tool arguments, so the values transited the model context. They now prefer MCP elicitation: when the connected client advertises elicitation support, missing credentials are requested directly from the user via the client — the value flows user -> client -> server and never enters the LLM's tool-call arguments, context, or logs.

A shared, capability-gated helper (elicitCredentialsIfSupported) drives this. When the client can't elicit, the user declines, or the request errors, it falls back to the existing argument-based flow — so behavior is unchanged for clients without elicitation and it is safe to ship to remote MCP (degrades gracefully).

  • createAccessibilityAuthConfig: username/password are now optional; elicited when absent and supported, otherwise the tool errors asking for them.
  • createLCASteps: adds a requires_authentication flag so credentials are only elicited when the test case actually needs login; the credentials arg remains a fallback.

Backward-compatible (no argument removed). Tests cover the helper's branches and the elicit / no-capability / decline / error paths for both tools.

…bilityAuthConfig and createLCASteps

Both tools previously accepted credentials as tool arguments, so the values
transited the model context. They now prefer MCP elicitation: when the connected
client advertises elicitation support, missing credentials are requested directly
from the user via the client — the value flows user -> client -> server and never
enters the LLM's tool-call arguments, context, or logs.

A shared, capability-gated helper (elicitCredentialsIfSupported) drives this. When
the client can't elicit, the user declines, or the request errors, it falls back
to the existing argument-based flow — so behavior is unchanged for clients without
elicitation and it is safe to ship to remote MCP (degrades gracefully).

- createAccessibilityAuthConfig: username/password are now optional; elicited when
  absent and supported, otherwise the tool errors asking for them.
- createLCASteps: adds a `requires_authentication` flag so credentials are only
  elicited when the test case actually needs login; the credentials arg remains a
  fallback.

Backward-compatible (no argument removed). Tests cover the helper's branches and
the elicit / no-capability / decline / error paths for both tools.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@SavioBS629

Copy link
Copy Markdown
Collaborator Author

Elicitation for credential tools — behavior & rationale

createAccessibilityAuthConfig

┌────────────────────────────────────┬───────────────────────────────────────┐
│             Condition              │                Result                 │
├────────────────────────────────────┼───────────────────────────────────────┤
│ Credentials passed as args         │ Used directly — no prompt             │
│                                    │ (backward-compat)                     │
├────────────────────────────────────┼───────────────────────────────────────┤
│ Credentials omitted + client       │ Server prompts the user via the       │
│ supports elicitation               │ client form; entered values are used  │
├────────────────────────────────────┼───────────────────────────────────────┤
│ Credentials omitted + client does  │ Returns error "Username and password  │
│ not support elicitation            │ are required…" (graceful fallback)    │
├────────────────────────────────────┼───────────────────────────────────────┤
│ Credentials omitted + client       │ Returns the same "required" error     │
│ supports it, but user              │ (creds still missing)                 │
│ declines/cancels                   │                                       │
└────────────────────────────────────┴───────────────────────────────────────┘

createLCASteps

┌───────────────────────────────────────┬────────────────────────────────────┐
│               Condition               │               Result               │
├───────────────────────────────────────┼────────────────────────────────────┤
│ requires_authentication false/unset   │ No prompt — most test cases don't  │
│                                       │ need login; proceeds normally      │
├───────────────────────────────────────┼────────────────────────────────────┤
│ Credentials passed as args            │ Used directly — no prompt          │
│                                       │ (backward-compat)                  │
├───────────────────────────────────────┼────────────────────────────────────┤
│ requires_authentication: true + creds │ Server prompts for the test case's │
│  omitted + client supports            │  login; entered values are used    │
│ elicitation                           │                                    │
├───────────────────────────────────────┼────────────────────────────────────┤
│ requires_authentication: true + creds │ Falls back to the existing arg     │
│  omitted + client does not support    │ path (proceeds without creds,      │
│ elicitation                           │ unchanged behavior — no error)     │
└───────────────────────────────────────┴────────────────────────────────────┘

Why we implemented it this way (arg path kept as fallback)

  1. Backward compatible — no argument removed; existing callers that pass credentials work unchanged. Zero breaking change.
  2. Uneven client support — elicitation is newer; not all clients (nor the Remote MCP wrapper yet) support it. Capability-gating means we prompt only where supported and degrade gracefully elsewhere.
  3. Safe for Remote MCP — gated on client capability, so deploying can't break the hosted server; elicitation just stays dormant there until the wrapper forwards it.
  4. Incremental, low-risk — ships the security win now (creds out of model context on capable clients) without forcing a breaking change; we watch for issues before tightening.

Note — new requires_authentication flag (LCA only): Unlike the accessibility tool (creds always required), most LCA test cases don't need a login, so there's no reliable way to know when to prompt. The flag is an explicit "this test case needs login" signal — the agent sets it instead of passing credentials, and the tool then elicits them. Additive and optional (defaults false), so it changes nothing for existing calls.

@ruturaj-browserstack
ruturaj-browserstack merged commit b069ad2 into browserstack:main Aug 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants