The server-side error handling only checked for SseError instances
when detecting 401 responses from MCP servers. StreamableHTTPClientTransport
throws a different error type (generic Error with "HTTP 401" message)
when there's no authProvider configured.
This caused the proxy to return 500 instead of 401 to the client,
preventing the OAuth discovery and redirect flow from triggering.
Added is401Error() helper that checks for:
- SseError with code 401
- StreamableHTTPError with code 401
- Generic Error with "HTTP 401" or "(401)" in message
Fixes#960🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Clarify in contribution guidelines that during V2 development, V1
contributions should focus on bug fixes and MCP spec compliance.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Align tests with new form-first rendering and UI behavior:
- Labels prefer schema `title` over property key.
- Descriptions shown for boolean checkboxes and select fields.
- Explicit mode switching between Form/JSON when needed.
- Add comprehensive coverage for enum schema variants:
- Titled single-select via `oneOf`/`anyOf` with `{ const, title }`.
- Untitled single-select via `enum` (with legacy `enumNames` labels).
- Untitled multi-select via `items.enum` with `minItems`/`maxItems` helper text.
- Titled multi-select via `items.anyOf`/`oneOf` with `{ const, title }`.
- Adjust complex/JSON-mode tests to click “Switch to JSON” before asserting textarea and clipboard interactions.
- Fix debounced JSON update expectations to assert parsed objects rather than raw text.
Files updated:
- `client/src/components/__tests__/DynamicJsonForm.test.tsx`
- `client/src/components/__tests__/DynamicJsonForm.array.test.tsx`
In DynamicJsonForm.tsx,
- Support all five enum shapes used by MCP SDK:
- Titled single-select via `oneOf`/`anyOf` with `{ const, title }`
- Untitled single-select via `enum`
- Titled legacy single-select with optional `enumNames` for labels
- Titled multi-select via `items.anyOf`/`oneOf`
- Untitled multi-select via `items.enum`
- Show field descriptions for string select fields and boolean checkboxes (consistent help text above inputs).
- Prefer schema property `title` for object field labels; fall back to the JSON key when missing.
- Allow top‑level form rendering for objects with properties, arrays with items, and primitive types (was overly strict before).
- Multi-select UI: sensible list size and `minItems`/`maxItems` helper text when present.
- JSON editor fallback, copy/format controls, and debounced parsing preserved.
- apply defaults for optional fields during form init
In schemaUtils.ts
- `generateDefaultValue` now includes optional properties that declare a `default`, ensuring fields like strings show their defaults on first render.
In jsonUtils.ts
- Add legacy `enumNames?: string[]` and array constraints `minItems?`/`maxItems?`.
1. createWebReadableStream: Add closed flag and cancel() callback to
prevent double-close crashes when SSE streams end. This fixes the
"Controller is already closed" error that occurs when the SDK calls
response.body.cancel() on 202 responses.
2. DELETE handler: Call serverTransport.close() after terminateSession()
to properly cleanup the transport and cancel pending reconnections.
- terminateSession() notifies the server (sends DELETE request)
- close() cleans up client-side resources (abort controller, timeouts)
- Both are needed for a complete disconnect
Guard against calling controller.close() when the stream has already
been closed by an external cancellation. This can happen when the SDK
cancels the stream before the underlying Node stream emits its 'end'
event.
- Add `closed` flag to track controller state
- Guard all controller operations with closed check
- Add `cancel()` callback to handle external cancellation
- Properly destroy the Node stream on cancellation