Component authorization now applies after transforms, denied resources cannot fall through matching templates, and OAuth client credentials providers support issuer binding across fresh and cached-token flows. Existing configurations remain compatible, but users of ClientCredentialsOAuthProvider or PrivateKeyJWTOAuthProvider must set issuer to enable this protection; upgrading alone is insufficient. Thanks to our 18 contributors, including 9 first-time contributors.
What's Changed
Security 🔒
- Authorize transformed components and prevent denied-resource template fallback by @zzstoatzz and @rishid in #5933
- Bind OAuth client credentials to a configured issuer, including cached-token renewal, by @zzstoatzz and @LHMisme420 in #5933
Enhancements ✨
- Add SEP-2640 Skills extension foundation by @strawgate in #5057
- Write down triage and merge norms in docs/development by @zzstoatzz in #5872
- Add experimental Skills discovery to SkillsDirectoryProvider by @zzstoatzz in #5704
Fixes 🐞
- Do not require websockets for the OAuth callback server by @asasemahmed in #5693
- Keep fastmcp.json resolvable when deployment.cwd changes the working directory by @asasemahmed in #5700
- Fix ctx.log() failing when extra contains LogRecord attribute names by @asasemahmed in #5688
- Use a monotonic clock in the rate limiters by @asasemahmed in #5689
- Escape server metadata in the fastmcp inspect text summary by @asasemahmed in #5701
- Respect an explicit is_binary=False on FileResource by @asasemahmed in #5696
- Follow pagination in the MCP format of fastmcp inspect by @asasemahmed in #5691
- Visit each reference once when finding access-restricted properties by @AarnavNoble in #5751
- Run sync resource templates in the threadpool by @hardness1020 in #5742
- Require openapi-pydantic 0.6.0 so OpenAPI 3.1.2 specs load by @jsphbtst in #5647
- Scope FileUpload and session visibility to a stable client on MCP 2026-07-28 by @zzstoatzz in #5651
- fix(auth): accept private_key_jwt without form client_id by @HootRock and @imranq2 in #5832
- fix(cli): honor explicit URL transport by @mikamikasuki in #5529
- Remove legacy logging state when HTTP sessions close by @mikamikasuki in #5539
- Name data-backed File resources consistently with their MIME subtype by @nandanadileep in #5568
- fix(client): run Python stdio children in UTF-8 mode by @ningmao-hlyz in #5642
- Report an unbindable OAuth callback port instead of SystemExit by @asasemahmed in #5692
- Accept ES256 and other RSA/EC algorithms for CIMD private_key_jwt assertions by @asasemahmed in #5695
- Preserve icons on transformed tools by @asasemahmed in #5702
- Hydrate valid schema defaults while preserving invalid defaults by @nandanadileep in #5738
- fix(resources): preserve public metadata in built-in read contents by @HootRock in #5778
- Preserve shared dependency scopes without optional task dependencies by @HootRock and @BlueX888 in #5817
- fix: treat non-string skill frontmatter descriptions as absent by @BlueX888 in #5823
- fix(resources): preserve component meta for list[ResourceContent] returns by @BlueX888 in #5843
- Fall back to the client timeout when resolving claimed results by @marcinbelczewski in #5190
- Discover Goose Streamable HTTP extensions by @jiuyueQ and @ch-z-hc in #5582
- Raise ToolError when a tool with an output schema returns an unserializable value by @massimiliano1991 in #5063
- Stop deploy tests from spawning PowerShell on every state access by @zzstoatzz in #5874
- Give the timeout-override test headroom for the follow-up tools/list by @zzstoatzz in #5875
- Keep disabled resources from being served by matching templates by @zzstoatzz in #5876
Docs 📚
- Fix codespell typo in v4.1.1 changelog by @zzstoatzz in #5818
- context: stop documenting session_id as a cross-request key by @zzstoatzz in #5862
Examples & Contrib 💡
- fix(contrib): preserve BulkToolCaller tool prefixes by @mikamikasuki in #5555
Other Changes 🦾
- chore(deps): Update github actions by @prefect-renovate[bot] in #5707
New Contributors
-
@AarnavNoble made their first contribution in #5751
-
@hardness1020 made their first contribution in #5742
-
@marcinbelczewski made their first contribution in #5190
-
@massimiliano1991 made their first contribution in #5063
-
@LHMisme420 made their first contribution in #5933
Full Changelog: v4.1.1...v4.1.2