What's Changed
- ci: drop the redundant PR-head checkout from claude.yml by @cliffhall in #2070
- feat(apps): negotiated app-rendered form elicitations by @cliffhall in #2083
- feat(auth): file-backed and in-memory SecretStore for hosts with no keychain by @cliffhall in #2076
- chore(lint): fail lint on warnings (--max-warnings 0) by @cliffhall in #2090
- fix(web): roll a failed settings write back to what actually landed by @cliffhall in #2091
- chore: three small cleanups flagged in the v2.2.0 merge review by @cliffhall in #2092
- feat(auth): give the secrets file a real cross-process lock by @cliffhall in #2088
- feat: allow complex JSON values in request _meta by @cliffhall in #2094
- fix(web): surface a failed post-write server-list reload by @cliffhall in #2087
- fix(web): read MCP App UI resource metadata from _meta.ui by @cliffhall in #2098
- chore: remove the Claude Code GitHub Actions workflow by @cliffhall in #2103
- fix(proxy): route through undici's own fetch and keep undici external by @cliffhall in #2099
- fix(auth): don't answer
token_expiredfrom an unknowable local expiry by @cliffhall in #2105 - fix(web): state the expected shape when dropping a CSP source (#2064) by @cliffhall in #2106
- fix(web): honor _meta.ui.domain with a dedicated app origin by @cliffhall in #2100
- chore(ci): render an MCP App from the installed tarball in pack:verify (#2003) by @cliffhall in #2107
- fix(web): let tool string arguments be typed as multiline by @cliffhall in #2109
- fix(cli): apply a server's persisted mcp.json metadata by @cliffhall in #2112
- chore: pin esbuild past the GHSA-g7r4-m6w7-qqqr range in web/cli/tui by @cliffhall in #2116
- fix(auth): pass the challenge's resource_metadata URL to SDK auth() by @cliffhall in #2113
- fix(web): open the monitoring sidebar when a connect fails during OAuth by @cliffhall in #2115
- feat(oauth): make the refresh_token grant opt-out per server by @cliffhall in #2114
- chore(scripts): build test-servers unconditionally from one shared helper (#2111) by @cliffhall in #2120
- feat: flag unportable tool schemas in all three clients by @cliffhall in #2121
- fix(oauth): persist the requested scope when the token response omits it by @cliffhall in #2118
- fix(web): carry a landed stdio env/cwd onto the config it connects with by @cliffhall in #2119
- fix: keep the pagination toggle on the last write across a server switch by @cliffhall in #2131
- fix(core): carry the in-progress SSE frame across chunk boundaries by @cliffhall in #2135
- fix(oauth): keep the server's path in the fallback authorization-server URL (#2110) by @cliffhall in #2136
- fix(web): take the enlarge button out of the tab order by @cliffhall in #2139
- chore: bump version to 2.4.0 by @cliffhall in #2142
- chore: merge v2/main for the v2.4.0 milestone release by @cliffhall in #2145
Full Changelog: 2.3.0...2.4.0
Smoke test ledger for milestone branch: v2/chore/milestone-merge-v2.4.0