Conversation
jundot
left a comment
There was a problem hiding this comment.
Thanks for adding streamable HTTP support! Found a few things to address before merging.
Resource leak in disconnect()
_connect_streamable_http() creates self._http_client (httpx.AsyncClient), but disconnect() never cleans it up. Needs something like:
if hasattr(self, "_http_client") and self._http_client:
await self._http_client.__aexit__(None, None, None)
self._http_client = NoneAlso, if the streamable_http or session init fails midway, already-opened resources from earlier steps won't get cleaned up either. A try/except with cleanup would help here.
Please remove uv.lock
This repo doesn't track uv.lock — looks like it got included by accident.
Minor things
getattr(self.config, "headers", {})can beself.config.headers or {}sinceheadersis now a field onMCPServerConfig- The
raw_resulttype branching (isinstance(raw_result, (list, tuple))) differs from how stdio/SSE handle it (direct tuple unpacking). Matching the existing pattern would be more consistent - A few formatting-only changes (quote styles, blank lines) are mixed into the feature commit — separating those would make the diff cleaner
- Could use a couple more tests:
_http_clientcleanup, error scenarios,headersfield validation
|
I left a review above. Please address those items and i'll take another look. Closing #285 for now since it's tracked by this PR. |
Thank you for your review. I will follow up on this matter and take time to address it. It will likely take about a week. |
f6faf2f to
c2beead
Compare
171cbbb to
b4a21e6
Compare
|
Hi, @jundot . I have revised the code submission, retaining only the necessary parts and test code, and it has passed the pytest test. Please review it again. |
bef2aeb to
86720d8
Compare
dbd699f to
63ff98a
Compare
|
Reviewed the latest revision ( 1. Resource leak on partial connect failure In async def _connect_streamable_http(self):
try:
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client
import httpx
except ImportError:
raise ImportError("MCP SDK required for MCP support. Install with: pip install mcp")
headers = self.config.headers or {}
self._http_client = httpx.AsyncClient(headers=headers)
await self._http_client.__aenter__()
try:
self._streamable_http_client = streamable_http_client(
url=self.config.url, http_client=self._http_client
)
self._read, self._write, _ = await self._streamable_http_client.__aenter__()
self._session = ClientSession(self._read, self._write)
await self._session.__aenter__()
except Exception:
# Clean up already-opened resources before re-raising
if hasattr(self, '_streamable_http_client') and self._streamable_http_client:
await self._streamable_http_client.__aexit__(None, None, None)
self._streamable_http_client = None
await self._http_client.__aexit__(None, None, None)
self._http_client = None
raise2. Typo in error message raise ValueError(f"MCP server '{self.name}': streamable-http transport requires 'url''")
# ^^ extra quoteShould be Everything else looks good. The disconnect cleanup, |
|
Looks good, merging this now. Thanks for the contribution @tianfeng98! There are two small things i'll fix in a follow-up commit:
|
|
@tianfeng98 v0.3.0rc1 is out with your MCP Streamable HTTP included. https://github.com/jundot/omlx/releases/tag/v0.3.0rc1 — if you get a chance, please give it a test and let me know if anything looks off. thanks! |
Thank you very much for your suggestion. These issues were indeed due to my negligence, and I will exercise caution in subsequent submissions. |
@jundot Thank you for accepting it. It seems to be fine. |

For #285