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

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions