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.v20260728; 018 019import java.net.*; 020import java.util.*; 021 022import org.apache.juneau.commons.bean.BeanType; 023import org.apache.juneau.commons.bean.PropertyNamerULC; 024 025/** 026 * Server-side representation of an <a class="doclink" href="https://datatracker.ietf.org/doc/html/rfc9728">RFC 9728</a> 027 * Protected Resource Metadata (PRM) document, emitted by the {@code 2026-07-28} MCP resource server from its 028 * {@code .well-known/oauth-protected-resource} endpoint so a client can discover which authorization server(s) protect 029 * this MCP server. 030 * 031 * <p> 032 * The {@link BeanType#propertyNamer() property namer} maps the camel-case Java properties to the snake-case wire field 033 * names RFC 9728 mandates ({@code resource}, {@code authorization_servers}, {@code scopes_supported}, 034 * {@code bearer_methods_supported}), so Juneau bean serialization produces JSON that parses cleanly on the client side 035 * via {@code org.apache.juneau.rest.client.mcp.auth.McpProtectedResourceMetadata} / 036 * {@code McpProtectedResourceMetadataClient}. 037 * 038 * <h5 class='section'>Client/server split:</h5> 039 * <p> 040 * This intentionally duplicates the shape of the client-side 041 * {@code org.apache.juneau.rest.client.mcp.auth.McpProtectedResourceMetadata} record; the 042 * two live in different modules with different dependency footprints (the client parses via Nimbus; the server emits via 043 * Juneau marshalling). A shared, dependency-neutral bean may replace both later. 044 * 045 * @since 10.0.0 046 */ 047@BeanType(propertyNamer = PropertyNamerULC.class) 048public class McpProtectedResourceMetadata { 049 050 private URI resource; 051 private List<URI> authorizationServers; 052 private Set<String> scopesSupported; 053 private Set<String> bearerMethodsSupported; 054 055 /** 056 * The {@code resource} field — this server's canonical resource identifier (RFC 9728 §2). 057 * 058 * @return The resource identifier, or <jk>null</jk> if not set. 059 */ 060 public URI getResource() { 061 return resource; 062 } 063 064 /** 065 * Sets the {@code resource} identifier. 066 * 067 * @param value The new value. Can be <jk>null</jk> to unset. 068 * @return This object (for method chaining). 069 */ 070 public McpProtectedResourceMetadata setResource(URI value) { 071 resource = value; 072 return this; 073 } 074 075 /** 076 * The {@code authorization_servers} field — the issuer URIs of the authorization servers that mint tokens for 077 * this resource (RFC 9728 §2). 078 * 079 * @return The authorization-server issuer URIs, or <jk>null</jk> if not set. 080 */ 081 public List<URI> getAuthorizationServers() { 082 return authorizationServers; 083 } 084 085 /** 086 * Sets the {@code authorization_servers} list. 087 * 088 * @param value The new value. Can be <jk>null</jk> to unset. 089 * @return This object (for method chaining). 090 */ 091 public McpProtectedResourceMetadata setAuthorizationServers(List<URI> value) { 092 authorizationServers = value; 093 return this; 094 } 095 096 /** 097 * The {@code scopes_supported} field — the OAuth scopes this resource understands (RFC 9728 §2). 098 * 099 * @return The supported scopes, or <jk>null</jk> if not set. 100 */ 101 public Set<String> getScopesSupported() { 102 return scopesSupported; 103 } 104 105 /** 106 * Sets the {@code scopes_supported} set. 107 * 108 * @param value The new value. Can be <jk>null</jk> to unset. 109 * @return This object (for method chaining). 110 */ 111 public McpProtectedResourceMetadata setScopesSupported(Set<String> value) { 112 scopesSupported = value; 113 return this; 114 } 115 116 /** 117 * The {@code bearer_methods_supported} field — the RFC 6750 methods by which a bearer token may be presented 118 * (RFC 9728 §2). This server accepts the {@code header} method only. 119 * 120 * @return The supported bearer methods, or <jk>null</jk> if not set. 121 */ 122 public Set<String> getBearerMethodsSupported() { 123 return bearerMethodsSupported; 124 } 125 126 /** 127 * Sets the {@code bearer_methods_supported} set. 128 * 129 * @param value The new value. Can be <jk>null</jk> to unset. 130 * @return This object (for method chaining). 131 */ 132 public McpProtectedResourceMetadata setBearerMethodsSupported(Set<String> value) { 133 bearerMethodsSupported = value; 134 return this; 135 } 136}