Skip to content

Conversation

@roterski
Copy link
Contributor

@roterski roterski commented Mar 16, 2025

Motivation and Context

MCP specification defines includeContext enum values as none, allServers and thisServer, while java-sdk used none, all_server and this_server. This mismatch caused tool calls with sampling (e.g. server-everything's sampleLLM) to fail with:

; Execution error (McpError) at io.modelcontextprotocol.spec.DefaultMcpSession/lambda$sendRequest$12 (DefaultMcpSession.java:241).
; MCP error -32603: Cannot deserialize value of type `io.modelcontextprotocol.spec.McpSchema$CreateMessageRequest$ContextInclusionStrategy` from String "thisServer": not one of the values accepted for Enum class: [none, all_server, this_server]
;  at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: io.modelcontextprotocol.spec.McpSchema$CreateMessageRequest["includeContext"])

Other sdks (python-sdk, typescript-sdk) also use camelCased values so it looks like sdk-java is in the wrong.

How Has This Been Tested?

I used java-sdk through clojure interop:

`->client` and `call-tool` implementation
(ns example
  (:require [jsonista.core :as j])
  (:import
   [io.modelcontextprotocol.spec
    McpTransport
    McpSchema$ClientCapabilities
    McpSchema$CallToolRequest
    McpSchema$CreateMessageResult]
   [io.modelcontextprotocol.client.transport ServerParameters StdioClientTransport]
   [io.modelcontextprotocol.client McpClient McpSyncClient]
   com.fasterxml.jackson.databind.ObjectMapper
   java.time.Duration))

(def McpClientSchema
  [:fn
   {:error/message "should be an instance of McpSyncClient"}
   #(instance? McpSyncClient %)])

(defn obj->clj
  [obj]
  (-> (.writeValueAsString (ObjectMapper.) obj)
      (j/read-value j/keyword-keys-object-mapper)))

(defn stringify-keywords
  [m]
  (->> m
       (j/write-value-as-bytes)
       j/read-value))

(defn ->client
  {:malli/schema [:=>
                  [:cat
                   [:map
                    [:command :string]
                    [:args [:vector :string]]]]
                  McpClientSchema]}
  ^McpSyncClient
  [{:keys [command args]}]
  (let [^ServerParameters params (-> (ServerParameters/builder command)
                                     (.args args)
                                     (.build))
        ^McpTransport transport (StdioClientTransport. params)
        ^McpSyncClient client (-> (McpClient/sync transport)
                                  (.requestTimeout (Duration/ofSeconds 10))
                                  (.capabilities (-> (McpSchema$ClientCapabilities/builder)
                                                     (.roots true)
                                                     (.sampling)
                                                     (.build)))
                                  (.sampling (fn [request]
                                               (tap> request)
                                               (-> (McpSchema$CreateMessageResult/builder)
                                                   (.model "claude")
                                                   (.message "test")
                                                   .build)))
                                  (.build))]
    (doto client
      .initialize)))

(defn call-tool
  [client tool-name & [args]]
  (->> args
       stringify-keywords
       (McpSchema$CallToolRequest. tool-name)
       (.callTool client)
       obj->clj))
  ;; BEFORE THE FIX:
  (-> (->client {:command "npx"
                 :args ["-y" "@modelcontextprotocol/server-everything"]})
      (call-tool "sampleLLM" {:prompt "hello"}))
  ;;=> Execution error (McpError) at io.modelcontextprotocol.spec.DefaultMcpSession/lambda$sendRequest$12 (DefaultMcpSession.java:241).
  ;;   MCP error -32603: Cannot deserialize value of type `io.modelcontextprotocol.spec.McpSchema$CreateMessageRequest$ContextInclusionStrategy` from String "thisServer": not one of the values accepted for Enum class: [none, all_server, this_server]
  ;;    at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: io.modelcontextprotocol.spec.McpSchema$CreateMessageRequest["includeContext"])
  ;;

  ;; AFTER THE FIX:
  (-> (->client {:command "npx"
                 :args ["-y" "@modelcontextprotocol/server-everything"]})
      (call-tool "sampleLLM" {:prompt "hello"}))
  ;;=> {:content [{:type "text", :text "LLM sampling result: test"}]}
  

Breaking Changes

It might break server implementations (if there're any) relying on java-sdk enum values, but nevertheless, those would be incompatible with specification, server-everything and other sdks.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

@tzolov
Copy link
Contributor

tzolov commented Mar 20, 2025

@roterski thanks for catching and fixing this

@tzolov tzolov added this to the 0.8.0 milestone Mar 20, 2025
@tzolov tzolov merged commit 7046249 into modelcontextprotocol:main Mar 20, 2025
@tzolov tzolov added bug Something isn't working area/mcp-schema labels Mar 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/mcp-schema bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants