Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*/
package org.springaicommunity.mcp.adapter;

import java.util.List;

import io.modelcontextprotocol.spec.McpSchema;
import org.springaicommunity.mcp.annotation.McpResource;

Expand All @@ -14,17 +16,31 @@ public class ResourceAdapter {
private ResourceAdapter() {
}

public static McpSchema.Resource asResource(McpResource mcpResource) {
String name = mcpResource.name();
public static McpSchema.Resource asResource(McpResource mcpResourceAnnotation) {
String name = mcpResourceAnnotation.name();
if (name == null || name.isEmpty()) {
name = "resource"; // Default name when not specified
}
return McpSchema.Resource.builder()
.uri(mcpResource.uri())

var resourceBuilder = McpSchema.Resource.builder()
.uri(mcpResourceAnnotation.uri())
.name(name)
.description(mcpResource.description())
.mimeType(mcpResource.mimeType())
.build();
.title(mcpResourceAnnotation.title())
.description(mcpResourceAnnotation.description())
.mimeType(mcpResourceAnnotation.mimeType());

// Only set annotations if not default value is provided
// This is a workaround since Java annotations do not support null default values
// and we want to avoid setting empty annotations.
// The default annotations value is ignored.
// The user must explicitly set the annotations to get them included.
var annotations = mcpResourceAnnotation.annotations();
if (annotations != null && annotations.lastModified() != null && !annotations.lastModified().isEmpty()) {
resourceBuilder
.annotations(new McpSchema.Annotations(List.of(annotations.audience()), annotations.priority()));
}

return resourceBuilder.build();
}

public static McpSchema.ResourceTemplate asResourceTemplate(McpResource mcpResource) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import io.modelcontextprotocol.spec.McpSchema.Role;

/**
* Marks a method as a MCP Resource.
*
Expand All @@ -21,11 +23,16 @@
public @interface McpResource {

/**
* A human-readable name for this resource. This can be used by clients to populate UI
* elements.
* Intended for programmatic or logical use, but used as a display name in past specs
* or fallback (if title isn’t present).
*/
String name() default "";

/**
* Optional human-readable name of the prompt for display purposes.
*/
String title() default "";

/**
* the URI of the resource.
*/
Expand All @@ -43,4 +50,37 @@
*/
String mimeType() default "text/plain";

/**
* Optional annotations for the client. Note: The default annotations value is
* ignored.
*/
McpAnnotations annotations() default @McpAnnotations(audience = { Role.USER }, lastModified = "", priority = 0.5);

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface McpAnnotations {

/**
* Describes who the intended customer of this object or data is. It can include
* multiple entries to indicate content useful for multiple audiences (e.g.,
* [“user”, “assistant”]).
*/
Role[] audience();

/**
* The date and time (in ISO 8601 format) when the resource was last modified.
*/
String lastModified() default "";

/**
* Describes how important this data is for operating the server.
*
* A value of 1 means “most important,” and indicates that the data is effectively
* required, while 0 means “least important,” and indicates that the data is
* entirely optional.
*/
double priority();

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.modelcontextprotocol.spec.McpSchema.ReadResourceRequest;
import io.modelcontextprotocol.spec.McpSchema.ReadResourceResult;
import io.modelcontextprotocol.spec.McpSchema.ResourceContents;
import io.modelcontextprotocol.spec.McpSchema.Role;
import io.modelcontextprotocol.spec.McpSchema.TextResourceContents;
import io.modelcontextprotocol.util.McpUriTemplateManager;
import io.modelcontextprotocol.util.McpUriTemplateManagerFactory;
Expand Down Expand Up @@ -252,6 +253,11 @@ public String name() {
return "";
}

@Override
public String title() {
return "";
}

@Override
public String description() {
return "";
Expand All @@ -262,6 +268,30 @@ public String mimeType() {
return "text/plain";
}

@Override
public McpAnnotations annotations() {
return new McpAnnotations() {
@Override
public Class<? extends java.lang.annotation.Annotation> annotationType() {
return McpAnnotations.class;
}

@Override
public Role[] audience() {
return new Role[] { Role.USER };
}

@Override
public String lastModified() {
return "";
}

@Override
public double priority() {
return 0.5;
}
};
}
};
}

Expand Down Expand Up @@ -562,6 +592,11 @@ public String name() {
return "";
}

@Override
public String title() {
return "";
}

@Override
public String description() {
return "";
Expand All @@ -572,6 +607,30 @@ public String mimeType() {
return "";
}

@Override
public McpAnnotations annotations() {
return new McpAnnotations() {
@Override
public Class<? extends java.lang.annotation.Annotation> annotationType() {
return McpAnnotations.class;
}

@Override
public Role[] audience() {
return new Role[] { Role.USER };
}

@Override
public String lastModified() {
return "";
}

@Override
public double priority() {
return 0.5;
}
};
}
};

assertThatThrownBy(() -> AsyncMcpResourceMethodCallback.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.modelcontextprotocol.spec.McpSchema.ReadResourceRequest;
import io.modelcontextprotocol.spec.McpSchema.ReadResourceResult;
import io.modelcontextprotocol.spec.McpSchema.ResourceContents;
import io.modelcontextprotocol.spec.McpSchema.Role;
import io.modelcontextprotocol.spec.McpSchema.TextResourceContents;
import io.modelcontextprotocol.util.McpUriTemplateManager;
import io.modelcontextprotocol.util.McpUriTemplateManagerFactory;
Expand Down Expand Up @@ -207,6 +208,11 @@ public String name() {
return "";
}

@Override
public String title() {
return "";
}

@Override
public String description() {
return "";
Expand All @@ -217,6 +223,30 @@ public String mimeType() {
return "text/plain";
}

@Override
public McpAnnotations annotations() {
return new McpAnnotations() {
@Override
public Class<? extends java.lang.annotation.Annotation> annotationType() {
return McpAnnotations.class;
}

@Override
public Role[] audience() {
return new Role[] { Role.USER };
}

@Override
public String lastModified() {
return "";
}

@Override
public double priority() {
return 0.5;
}
};
}
};
}

Expand Down Expand Up @@ -523,6 +553,11 @@ public String name() {
return "";
}

@Override
public String title() {
return "";
}

@Override
public String description() {
return "";
Expand All @@ -533,6 +568,30 @@ public String mimeType() {
return "";
}

@Override
public McpAnnotations annotations() {
return new McpAnnotations() {
@Override
public Class<? extends java.lang.annotation.Annotation> annotationType() {
return McpAnnotations.class;
}

@Override
public Role[] audience() {
return new Role[] { Role.USER };
}

@Override
public String lastModified() {
return "";
}

@Override
public double priority() {
return 0.5;
}
};
}
};

assertThatThrownBy(() -> AsyncStatelessMcpResourceMethodCallback.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import io.modelcontextprotocol.spec.McpSchema.ReadResourceRequest;
import io.modelcontextprotocol.spec.McpSchema.ReadResourceResult;
import io.modelcontextprotocol.spec.McpSchema.Role;
import org.springaicommunity.mcp.adapter.ResourceAdapter;
import org.springaicommunity.mcp.annotation.McpResource;

Expand Down Expand Up @@ -50,6 +51,11 @@ public String name() {
return "";
}

@Override
public String title() {
return "";
}

@Override
public String description() {
return "";
Expand All @@ -59,6 +65,31 @@ public String description() {
public String mimeType() {
return "";
}

@Override
public McpAnnotations annotations() {
return new McpAnnotations() {
@Override
public Class<? extends java.lang.annotation.Annotation> annotationType() {
return McpAnnotations.class;
}

@Override
public Role[] audience() {
return new Role[] { Role.USER };
}

@Override
public String lastModified() {
return "";
}

@Override
public double priority() {
return 0.5;
}
};
}
};
}

Expand All @@ -80,6 +111,11 @@ public String name() {
return "";
}

@Override
public String title() {
return "";
}

@Override
public String description() {
return "";
Expand All @@ -90,6 +126,30 @@ public String mimeType() {
return "";
}

@Override
public McpAnnotations annotations() {
return new McpAnnotations() {
@Override
public Class<? extends java.lang.annotation.Annotation> annotationType() {
return McpAnnotations.class;
}

@Override
public Role[] audience() {
return new Role[] { Role.USER };
}

@Override
public String lastModified() {
return "";
}

@Override
public double priority() {
return 0.5;
}
};
}
};
}

Expand Down
Loading