001/* 002 * Copyright 2022-2026 Revetware LLC. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.soklet; 018 019import org.jspecify.annotations.NonNull; 020import org.jspecify.annotations.Nullable; 021 022import javax.annotation.concurrent.Immutable; 023 024import static java.util.Objects.requireNonNull; 025 026/** 027 * Resource-list entry exposed by v1 MCP endpoints. 028 * 029 * @author <a href="https://www.revetkn.com">Mark Allen</a> 030 */ 031@Immutable 032public record McpListedResource( 033 @NonNull String uri, 034 @NonNull String name, 035 @NonNull String mimeType, 036 @Nullable String title, 037 @Nullable String description, 038 @Nullable Long sizeBytes 039) { 040 public McpListedResource { 041 requireNonNull(uri); 042 requireNonNull(name); 043 requireNonNull(mimeType); 044 045 if (sizeBytes != null && sizeBytes < 0L) 046 throw new IllegalArgumentException("Resource size metadata must be non-negative."); 047 } 048 049 /** 050 * Creates a minimal resource-list entry without optional metadata. 051 * 052 * @param uri the resource URI 053 * @param name the resource name 054 * @param mimeType the resource MIME type 055 * @return a minimal listed-resource entry 056 */ 057 @NonNull 058 public static McpListedResource fromComponents(@NonNull String uri, 059 @NonNull String name, 060 @NonNull String mimeType) { 061 requireNonNull(uri); 062 requireNonNull(name); 063 requireNonNull(mimeType); 064 return new McpListedResource(uri, name, mimeType, null, null, null); 065 } 066 067 /** 068 * Returns a copy of this resource entry with a title. 069 * 070 * @param title the title to apply 071 * @return a new resource entry with the given title 072 */ 073 @NonNull 074 public McpListedResource withTitle(@NonNull String title) { 075 requireNonNull(title); 076 return new McpListedResource(uri(), name(), mimeType(), title, description(), sizeBytes()); 077 } 078 079 /** 080 * Returns a copy of this resource entry with a description. 081 * 082 * @param description the description to apply 083 * @return a new resource entry with the given description 084 */ 085 @NonNull 086 public McpListedResource withDescription(@NonNull String description) { 087 requireNonNull(description); 088 return new McpListedResource(uri(), name(), mimeType(), title(), description, sizeBytes()); 089 } 090 091 /** 092 * Returns a copy of this resource entry with a size metadata value. 093 * 094 * @param sizeBytes the non-negative size in bytes 095 * @return a new resource entry with the given size 096 */ 097 @NonNull 098 public McpListedResource withSizeBytes(@NonNull Long sizeBytes) { 099 requireNonNull(sizeBytes); 100 return new McpListedResource(uri(), name(), mimeType(), title(), description(), sizeBytes); 101 } 102}