-
Notifications
You must be signed in to change notification settings - Fork 73
Fix client parsing #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Summary: I noticed we are not converting value associated with response to the strong types requests recorded This change will help to decode the value type later once we support the rest of plumbing (next commit)
Summary: Looks like there were multiple issues with parsing response: 1. It appears that we would mistakenly pass response both for response and request arguments in the private func handleResponse(_ response: Response<AnyMethod>, for request: Any) 2. Later I couldn't figure out how to win against swift type system, so ended up creating a type-erased request to store in the pendingRequests instead of original type under Any (that wouldn't allow to downcast original type later) Test Plan: 1. Standup iMCP client from https://github.com/loopwork-ai/iMCP 2. Create a dummy project setting up MCP client against "/private/var/folders/26/8gncz37x7slbfrr95d9jcr400000gn/T/AppTranslocation/62ADEC4D-3545-4E98-A612-0E6DF52CE525/d/iMCP.app/Contents/MacOS/imcp-server" and call initialize Note response is being parsed correctly and client.initialize() does not hang indefinitely
Just so you don't feel alone... I just now ran into the same thing and trying to discern the best resolution |
@zats and can confirm your branch fixes it. Again, no clue if it adheres to matttttttt's intentions but it most certainly unblocks me. Thank you! |
ay thanks Stephen, glad it works for you 🙂 |
Ran into the same issue + patched in a similar way! |
I no longer think this fix is correct. It appears to fix one thing and break another. Still trying to discern the intention.... |
@mattt its related to using client.callTool. The tool is returning a successful response (Which works in the MCP Inspector), but its failing a typecast here during attempting to process the result: private struct AnyPendingRequest {
|
@mattt best i can tell with my bad eyes.. the spot i pointed to above, the .success(value) is an MCP.Value and in the pending request is expecting MCP.CallTool.Result |
hey folks, catching up on he conversation, thanks for digging depper |
@mattt give me a few min to finish lunch and i'll pull and give it a go. and have more deets if its not. |
* Allow decoding Decodable type directly from Value Summary: I noticed we are not converting value associated with response to the strong types requests recorded This change will help to decode the value type later once we support the rest of plumbing (next commit) * Store and pass original request when response arrives Summary: Looks like there were multiple issues with parsing response: 1. It appears that we would mistakenly pass response both for response and request arguments in the private func handleResponse(_ response: Response<AnyMethod>, for request: Any) 2. Later I couldn't figure out how to win against swift type system, so ended up creating a type-erased request to store in the pendingRequests instead of original type under Any (that wouldn't allow to downcast original type later) Test Plan: 1. Standup iMCP client from https://github.com/loopwork-ai/iMCP 2. Create a dummy project setting up MCP client against "/private/var/folders/26/8gncz37x7slbfrr95d9jcr400000gn/T/AppTranslocation/62ADEC4D-3545-4E98-A612-0E6DF52CE525/d/iMCP.app/Contents/MacOS/imcp-server" and call initialize Note response is being parsed correctly and client.initialize() does not hang indefinitely * Fix warning: 'Cast from Client.AnyPendingRequest to unrelated type Client.PendingRequest<Any> always fails' * Fix warning: 'Conditional cast from NWError to NWError always succeeds' * Uncomment code in RoundtripTests * Formatting * Reorganize declarations * Inline JSONDecoder extension * Expand roundtrip tests --------- Co-authored-by: Sash Zats sash@zats.io <> Co-authored-by: Mattt Zmuda <mattt@loopwork.com>
This addressed issue #7, tldr looks like client had no way of parsing response due to
Value
instead of strong type associated with request<Any>
seem to constantly fail for me, introducing type-erased wrapper seem to fix it for meThere is a good chance I am not aware of the original thinking and missing something obvious to make it work 🙂
Original Issue Description:
I will prephrase my question by saying I am not sure at all that any of my findings are accurate.
I think I am seeing consistent failure of the client to handle responses due to 2 issues:
First of all it appears that we are passing response twice under
https://github.com/loopwork-ai/mcp-swift-sdk/blob/main/Sources/MCP/Client/Client.swift#L132-L133
Where instead we should be getting appropriate request from pandingRequests like so
Even fixing that locally downcast here https://github.com/loopwork-ai/mcp-swift-sdk/blob/main/Sources/MCP/Client/Client.swift#L329 fails
Not sure if there is a way to tell Swift "don't worry about generic the original value was created with", it seem to consistently fail. Specifically I am debugging initialize sequence and so when I fix passing pending request,
$ po request
printsMCP.Client.PendingRequest<MCP.Initialize.Result>)
, thoguard let typedRequest = request as? PendingRequest<Any> else { return }
failsAny ideas if I am holding it wrong? or we might need to store type-erased pending requests instead of Any?