Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

TypeMismatchError unrecoverable when server response doesn't round-trip through CallTool.Result codable

Aperta
#220 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 7 giorni

@EhsanAzish80 ci sta già lavorando.

Dal 24/9/2026.

  • #250 di @systemblueio — chiusa senza merge
  • #292 di @EhsanAzish80 — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
swift

Direzione di ricerca

Start in Sources/MCP/Base/PendingRequest.swift at PendingRequest.AnyPendingRequest._resume and trace how the decoded Value is discarded when decoding CallTool.Result fails. Reproduce against @adeze/raindrop-mcp and inspect TypeMismatchError handling. Done should provide clients with enough underlying decoding or raw-response information to diagnose and recover from incompatible tools/call responses.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

PendingRequest.AnyPendingRequest._resume (in Sources/MCP/Base/PendingRequest.swift) throws TypeMismatchError() whenever the Value returned by the server can be encoded as JSON but the subsequent JSONDecoder().decode(T.self, from: ...) fails. When this happens with CallTool.Result, there is no way for client code to recover the raw response — the decoded Value is discarded before it reaches the client, and TypeMismatchError() carries no diagnostics (not even the underlying DecodingError, not even which key/path was missing).

This breaks interoperability with real MCP servers in the wild whose tools/call responses are "codable-close but not strictly compliant" with the Swift CallTool.Result shape (extra fields, slightly different casing, optional wrapping, etc.).

Reproduction

Client: swift-sdk 0.12.0 on macOS 26.

Server: @adeze/raindrop-mcp (stdio transport, npx -y @adeze/raindrop-mcp).

Request:

{ "method": "tools/call",
  "params": { "name": "list_raindrops",
              "arguments": {"collectionId": 0, "perPage": 3} } }

Every response decodes to TypeMismatchError(). Because the SDK doesn't surface the underlying DecodingError, downstream consumers cannot tell whether the issue is a missing content key, an unexpected extra field, a union-type mismatch inside Tool.Content, or something else entirely. We see only the opaque error string TypeMismatchError().

We tried several tools on the same server (list_raindrops, bookmark_search, collection_list) and all fail identically — the server is simply using a response shape the SDK rejects.

Why this matters

MCP is meant to be a cross-language/cross-vendor protocol. A Python server and a Swift client should be able to talk even when the server's Zod schema and the client's Codable model don't line up perfectly — at minimum the client should have enough information to recover, log, or surface the raw payload.

Today the Swift SDK is materially harder to use than the TypeScript or Python SDKs in these cases.

Proposed fix (any of)

  1. Leak the DecodingError: change TypeMismatchError from a marker to an error that wraps DecodingError and the raw Value. This alone would unblock debugging.

    struct TypeMismatchError: Error {
        let expected: Any.Type
        let underlying: Error
        let rawValue: Value
    }
    
  2. Expose a raw-response escape hatch on Client: func callToolRaw(...) async throws -> Value that returns the protocol-level Value without attempting to decode into CallTool.Result. Downstream clients can implement lenient parsing themselves.

  3. Use decodeIfPresent-style lenient decoding for CallTool.Result so extra fields are ignored and optional fields can be missing. This is the TypeScript SDK behavior.

Option 1 is the cheapest and unblocks the most users — it's a couple of lines in PendingRequest.swift. Option 2 is the most flexible. Option 3 is the most user-friendly.

Workaround we're using

We catch the error by type name (errorType.contains(\"TypeMismatchError\")) and surface a generic "tool call decode failed" string to the end user. This is obviously fragile and hides the real bug.

Environment

  • swift-sdk: 0.12.0
  • Swift: 6.0, strict concurrency
  • macOS: Tahoe 26.4
  • Xcode: 26.4.1
  • Project: trapias/EasyChat, see Data/Services/MCP/MCPManager.swift
Lingua principale
Swift
Stelle
1.5k
Fork
249
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di modelcontextprotocol/swift-sdk

Tutte le issue di modelcontextprotocol/swift-sdk

Issue simili

Altre issue su Swift

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.