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.rest.server.mcp.v20250618;
018
019import org.apache.juneau.bean.mcp.v20250618.*;
020
021/**
022 * Abstract MCP servlet bound to protocol revision {@code 2025-06-18}.
023 *
024 * <p>
025 * Subclass this (rather than {@link McpRestServlet}) to expose a {@code 2025-06-18} endpoint; the
026 * revision binding is a compile-time choice made by which class you extend.
027 *
028 * <h5 class='section'>Example:</h5>
029 * <pre>
030 * @Rest(path="/mcp")
031 * public class MyMcpServlet extends McpRestServlet {
032 *     @Override
033 *     protected McpServerConfig createMcpConfig() {
034 *         return new McpServerConfig().setName("my-server").setVersion("1.0.0").addTool(new MyEchoTool());
035 *     }
036 * }
037 * </pre>
038 *
039 * @serial exclude
040 */
041@SuppressWarnings({
042   "java:S110" // Inherent to extending the RestServlet hierarchy.
043})
044public abstract class McpRestServlet extends org.apache.juneau.rest.server.mcp.AbstractMcpRestServlet {
045   private static final long serialVersionUID = 1L;
046
047   @Override /* AbstractMcpRestServlet */
048   protected McpRevision revision() {
049      return new McpRevision(capabilities());
050   }
051
052   /**
053    * Optional explicit capabilities advertisement for {@code initialize}.
054    *
055    * <p>
056    * Returning <jk>null</jk> (the default) leaves capabilities auto-derived from the registered
057    * tool / prompt / resource lists. Returning a non-<jk>null</jk> value bypasses auto-derivation
058    * entirely and advertises exactly what is returned — the way to advertise
059    * {@code resources.subscribe}, {@code logging}, {@code listChanged}, or {@code experimental},
060    * none of which are derivable from a handler registry.
061    *
062    * <p>
063    * This hook is typed against this revision's wire beans on purpose: capabilities diverge between
064    * MCP revisions, so a neutral carrier in the core would accept data that is nonsense for the
065    * bound revision and fail only at serialization time.
066    *
067    * <p>
068    * Stays {@code protected} (Correction C8): {@link #revision()} above is the only caller, and it
069    * lives in this same class, so there is never a need to reach this hook from outside this
070    * class's own hierarchy — in particular, {@code McpRevision} never calls back into it.
071    *
072    * @return The explicit capabilities, or <jk>null</jk> to auto-derive.
073    */
074   protected ServerCapabilities capabilities() {
075      return null;
076   }
077}