Skip to content

langchain4j spring-ai mcp integration doesn't respect valid schema and wants parameters to be specified #490

@andreyborisovpt

Description

@andreyborisovpt

Spring AI MCP server tools is not exporting parameters as such

{
   "tools":[
      {
         "name":"get-weather",
         "description":"Function to get the weather forecast for a given city",
         "inputSchema":{
            "type":"object",
            "properties":{
               "city":{
                  "type":"string",
                  "description":"The city to get the weather forecast for"
               }
            },
            "required":[
               "city"
            ],
            "additionalProperties":false
         }
      }
   ]
}

Definition of tool in spring AI (1.1.0-M3 latest one)

@Service
    public static class WeatherToolService {
        @Tool(name = "get-weather", description = "Function to get the weather forecast for a given city")
        public static Map<String, Object> getWeather(@ToolParam(required = true, description = "The city to get the weather forecast for") String city) {
            return Map.of(
                    "city", city,
                    "forecast", "a beautiful and sunny weather",
                    "temperature", "from 10°C in the morning up to 24°C in the afternoon");
        }
    }

Export function

    @Configuration
    @EnableAutoConfiguration
    public static class SpringAiMSPServerContext {
        @Bean
        public WeatherToolService weatherToolService() {
            return new WeatherToolService();
        }
        @Bean
        public WebFluxSseServerTransportProvider sseServerTransportProvider(ObjectMapper mapper) {
            return WebFluxSseServerTransportProvider.builder()
                    .jsonMapper(new JacksonMcpJsonMapper(mapper))
                    .messageEndpoint("/mcp/message")
                    .build();
        }
        @Bean
        public RouterFunction<?> mcpRouterFunction(WebFluxSseServerTransportProvider transportProvider) {
            return transportProvider.getRouterFunction();
        }
        @Bean
        public McpSyncServer mcpServer(McpServerTransportProvider transportProvider, WeatherToolService tool) {
            var capabilities = McpSchema.ServerCapabilities.builder().tools(true).logging().build();
            return McpServer
                    .sync(transportProvider)
                    .serverInfo("MCP Server", "1.0.0")
                    .capabilities(capabilities)
                    .tools(McpToolUtils.toSyncToolSpecifications(ToolCallbacks.from(tool)))
                    .build();
        }
    }

finally the code fails in LangChain4j (Tool lacking parameters)

private List<ToolSpecification> toToolSpecifications(LlmRequest llmRequest) {
    List<ToolSpecification> toolSpecifications = new ArrayList<>();

    llmRequest
        .tools()
        .values()
        .forEach(
            baseTool -> {
              if (baseTool.declaration().isPresent()) {
                FunctionDeclaration functionDeclaration = baseTool.declaration().get();
                if (functionDeclaration.parameters().isPresent()) {
                  Schema schema = functionDeclaration.parameters().get();
                  ToolSpecification toolSpecification =
                      ToolSpecification.builder()
                          .name(baseTool.name())
                          .description(baseTool.description())
                          .parameters(toParameters(schema))
                          .build();
                  toolSpecifications.add(toolSpecification);
                } else {
                  // TODO exception or something else?
                  throw new IllegalStateException("Tool lacking parameters: " + baseTool);
                }
              } else {
                // TODO exception or something else?
                throw new IllegalStateException("Tool lacking declaration: " + baseTool);
              }
            });

    return toolSpecifications;
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions