* fix(mcp): handle 400 auth errors, clear auth mode after OAuth, trim tokens
Three bugs prevented MCP server authentication (e.g. GitHub MCP) from
working correctly:
1. **400 treated as auth-required**: GitHub's MCP endpoint returns 400
"Authorization header is badly formatted" instead of 401 when auth
is missing. Broadened auth detection in activate_mcp, send_request,
and discover_via_401 to also match 400+authorization errors.
2. **Auth mode not cleared after OAuth callback**: The OAuth callback
handler and setup submit handler did not call clear_auth_mode(),
leaving pending_auth on the thread. The next user message was
intercepted as a token instead of triggering an LLM turn.
3. **Token trimming**: Tokens with leading/trailing whitespace or
newlines produced malformed Authorization headers. Now trimmed
before storage (configure) and before use (build_request_headers).
Adds E2E tests with a mock MCP server (JSON-RPC + OAuth discovery +
DCR + token exchange) covering install -> activate -> OAuth callback ->
LLM turn lifecycle, plus a GitHub-style 400 error variant.
[skip-regression-check]
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix(mcp): add TTL to PendingAuth and clear auth mode on all failure paths
Auth mode (pending_auth on a Thread) had no timeout and several code
paths that failed to clear it, causing user messages to be swallowed
indefinitely. This adds defense-in-depth:
- Add created_at + 5-minute TTL to PendingAuth; auto-clear on next
message if expired (safety net for edge cases like user closing
browser mid-OAuth)
- Clear auth mode on OAuth callback failure paths (unknown/consumed
state, expired flow)
- Move clear_auth_mode before configure() match in setup_submit so
it runs on failure too (addresses Copilot review feedback)
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix(ci): exclude test hunks from unwrap/assert pre-commit check
The pre-commit safety script only excluded files in tests/ but not
#[cfg(test)] mod tests blocks inside src/ files. Use the git diff @@
hunk header context (which includes the enclosing function name) to
detect and skip test hunks.
Also removes unnecessary // safety: comments from test assertions.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: restore formatting in test assertions
The replace_all edit that removed // safety: comments collapsed
newlines. Restore proper line breaks.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: address Copilot review - tighten pre-commit filter, document TTL sync
- pre-commit-safety.sh: only exclude `mod tests` hunks (not `fn test_*`)
to avoid hiding unwrap/assert in production functions like test_server()
- session.rs: extract AUTH_MODE_TTL_SECS constant and add doc comment
linking to OAUTH_FLOW_EXPIRY to prevent silent drift
[skip-regression-check]
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix(mcp): return error on expired auth input, clear auth on all OAuth paths
- When auth mode TTL expires and the user sends a message (possibly a
pasted token), return an explicit "expired, please retry" response
instead of forwarding the content to the LLM/history
- Add clear_auth_mode() to all early-return paths in oauth_callback_handler
(provider error, missing state/code, no extension manager)
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>