Skip to content

Implemented SSL Verification Disable#3450

Open
strunker wants to merge 15 commits intoPrefectHQ:mainfrom
strunker:main
Open

Implemented SSL Verification Disable#3450
strunker wants to merge 15 commits intoPrefectHQ:mainfrom
strunker:main

Conversation

@strunker
Copy link

Description

No AI was used in this code.

I have implemented SSL cert verification into the client.py so that it can be optionally disabled. This new param by default it is set to True, and not a required argument when the Client class is instantiated. It is my belief that the omission of this likely wasn't intentional, and this flag and capability exists in the underlying httpx transport protocol lib. This is also commonly available in libraries like requests, so it seemed logical to extend to this project. I implemented this with the same argument "verify" as requests lib uses, so most will likely be familiar and think to try it on their own. SSL cert verification disable is entirely valid while testing, and still affords encryption. And I think generally it should be up to developers and implementers to decide for themselves whether the authentication that a legitimate cert affords is required for their own use cases, it isn't a maintainers/creators role to decide that for them. There have been a few requests for this, and it required very minor tweaking to implement. Sadly there was a singular dependent function within the core MCP library, it just builds a simple object and I cant imagine it changes much from the source lib. I removed the import from the base MCP lib and moved it into http.py to finish implementing the SSL verification fix. The only reason to do this is it removes the need to file another separate PR into the core MCP lib just for a very simple function change. I will leave to you to decide if this acceptable or not. This code is fully tested and does work.

Quick example below:

  1. client = Client(url,verify=False) - This will disable ssl verification.
  2. client = Client(url,verify=True) or client = Client(url) - Setting to true or simply not including will leave SSL verification on and enforce a True bool.

There are no samples for client code in the readme on github so I didnt make any modifications to the readme. If this PR is approved we would likely want to update the documentation on the main site outside of GitHub.

Thanks!

Contributors Checklist

Review Checklist

  • I have self-reviewed my changes
  • My Pull Request is ready for review

strunker added 3 commits March 9, 2026 20:52
SSL Verification fix.
Fixed SSL verification.
Removed extra space.
@marvin-context-protocol marvin-context-protocol bot added enhancement Improvement to existing functionality. For issues and smaller PR improvements. client Related to the FastMCP client SDK or client-side functionality. http Related to HTTP transport, networking, or web server functionality. labels Mar 10, 2026
@marvin-context-protocol
Copy link
Contributor

marvin-context-protocol bot commented Mar 10, 2026

Test Failure Analysis

✏️ Updated to reflect latest CI run (workflow 22885470414)

Failure 1 — Tests: Python 3.13 on ubuntu-latest

Summary: TestEndToEndFunctionality.test_optional_parameter_handling times out on Python 3.13 due to a real DNS lookup blocking inside the test.

Root Cause: The test at tests/server/providers/openapi/test_end_to_end_compatibility.py:195 creates an httpx.AsyncClient(base_url="https://api.example.com") and then calls an OpenAPI-backed tool, expecting the call to fail with an HTTP-level error. In this CI run the DNS lookup for api.example.com blocked in a thread-pool executor for >5 s, triggering pytest-timeout before any HTTP error was returned. This is a pre-existing flaky test that makes real network calls — it is not caused by this PR's changes.

Suggested Solution: Mock the HTTP transport in the test so it never makes a real network call:

# In test_optional_parameter_handling, replace the real httpx.AsyncClient
# with a respx mock (or any httpx transport mock) so DNS/TCP are never touched.
import respx, httpx

@respx.mock
async def test_optional_parameter_handling(self, simple_spec):
    respx.get(url__regex=r".*").mock(side_effect=httpx.ConnectError("mocked"))
    async with httpx.AsyncClient(base_url="https://api.example.com") as client:
        ...

Or, if the intent is just to confirm the error type (not a schema error), use httpx.MockTransport / respx to return a deterministic connection error immediately.


Failure 2 — Tests with lowest-direct dependencies (previous run)

Summary: The Tests with lowest-direct dependencies job fails because the minimum supported mcp version (1.24.0) does not honor per-call timeout overrides.

Root Cause: test_timeout_tool_call_overrides_client_timeout_even_if_lower fails because in mcp==1.24.0 the per-call read_timeout_seconds passed to session.call_tool() does not override the session-level timeout. The regular jobs use mcp==1.26.0 from the lock file where this works correctly. This is also pre-existing and unrelated to this PR's SSL verification changes.

Suggested Solution:

  1. Raise the minimum mcp version in pyproject.toml to a version where per-call timeout override works correctly (>1.24.0).
  2. Or skip the test for low mcp versions with a pytest.mark.skipif.

Both fixes belong in a separate commit on main, not in this PR.

Detailed Analysis — Failure 1 (DNS timeout)

Failing test:

FAILED tests/server/providers/openapi/test_end_to_end_compatibility.py::TestEndToEndFunctionality::test_optional_parameter_handling

Error from logs:

E    Failed: Timeout (>5.0s) from pytest-timeout.

Timeout stack trace (asyncio_0 thread):

concurrent/futures/thread.py:59: result = self.fn(*self.args, **self.kwargs)
socket.py:977: for res in _socket.getaddrinfo(host, port, family, type, proto, flags):

The event loop is blocked waiting for socket.getaddrinfo — the OS-level DNS lookup for api.example.com — in a thread-pool executor. This exceeds the 5 s pytest-timeout limit.

This PR's changes only add a verify: bool | None parameter to Client, StreamableHttpTransport, and infer_transport. The failing test connects via FastMCPTransport (passes a FastMCP instance, not a URL) and the OpenAPI provider uses its own httpx.AsyncClient created inside the test.

Detailed Analysis — Failure 2 (mcp version compat)

Failing test:

FAILED tests/client/client/test_timeout.py::TestTimeout::test_timeout_tool_call_overrides_client_timeout_even_if_lower
E    mcp.shared.exceptions.McpError: Timed out while waiting for response to ClientRequest. Waited 0.01 seconds.

src/fastmcp/client/mixins/tools.py:157 passes a per-call read_timeout_seconds override; in mcp==1.24.0 this override is ignored.

Related Files
  • tests/server/providers/openapi/test_end_to_end_compatibility.py:195 — flaky test making real DNS/network calls
  • tests/client/client/test_timeout.py — timeout override test
  • src/fastmcp/client/mixins/tools.py:157 — per-call timeout passed to MCP session
  • pyproject.tomlmcp>=1.24.0,<2.0 constraint

🤖 Analysis by marvin, powered by Claude

strunker added 11 commits March 9, 2026 21:33
Implemented fixes from the original Marvin analysis.
Updated client code after test failure.
Updated as per test failure.
Updated overloads as per prek.
More Prek fixes.
More Prek fixes.
@strunker strunker changed the title Implemented SSL Verification Implemented SSL Verification Disable Mar 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client Related to the FastMCP client SDK or client-side functionality. enhancement Improvement to existing functionality. For issues and smaller PR improvements. http Related to HTTP transport, networking, or web server functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant