001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.examples.mcp.spring;
018
019import org.springframework.boot.*;
020import org.springframework.boot.autoconfigure.*;
021import org.springframework.boot.web.servlet.*;
022import org.springframework.context.annotation.*;
023
024/**
025 * A minimal Spring Boot application that serves {@link SpringExampleMcpServer} on embedded Tomcat.
026 *
027 * <p>
028 * Run {@link #main(String[]) main} and the MCP endpoint is available at {@code http://localhost:8080/mcp}
029 * (default Spring Boot port). Point {@link org.apache.juneau.examples.mcp.ExampleClient ExampleClient} at
030 * that URL, or drive it with any MCP client. The three {@code @Bean} methods are the entire integration:
031 *
032 * <ul>
033 *    <li>the {@link GreetingService} the MCP tool resolves via Spring DI;
034 *    <li>the {@link SpringExampleMcpServer} servlet itself; and
035 *    <li>a {@link ServletRegistrationBean} mounting it at {@code /*} (so the MCP operation lands at {@code /mcp}).
036 * </ul>
037 */
038@SpringBootApplication
039public class SpringExampleApplication {
040
041   /**
042    * The Spring-managed service injected into the MCP {@code greet} tool.
043    *
044    * @return A new {@link GreetingService}.
045    */
046   @Bean
047   public GreetingService greetingService() {
048      return new GreetingService();
049   }
050
051   /**
052    * The MCP servlet bean (constructed by Spring so it participates in the application context).
053    *
054    * @return A new {@link SpringExampleMcpServer}.
055    */
056   @Bean
057   public SpringExampleMcpServer springExampleMcpServer() {
058      return new SpringExampleMcpServer();
059   }
060
061   /**
062    * Mounts the MCP servlet on the embedded container.
063    *
064    * @param servlet The MCP servlet bean.
065    * @return The registration mapping the servlet at {@code /*}.
066    */
067   @Bean
068   public ServletRegistrationBean<SpringExampleMcpServer> mcpServletRegistration(SpringExampleMcpServer servlet) {
069      return new ServletRegistrationBean<>(servlet, "/*");
070   }
071
072   /**
073    * Boots the application.
074    *
075    * @param args Standard Spring Boot arguments.
076    */
077   @SuppressWarnings({
078      "resource" // the returned application context intentionally lives for the app's lifetime.
079   })
080   public static void main(String[] args) {
081      SpringApplication.run(SpringExampleApplication.class, args);
082   }
083}