diff --git a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/Tool.java b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/Tool.java index 0fadc55c4..e60413949 100644 --- a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/Tool.java +++ b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/Tool.java @@ -22,5 +22,6 @@ String description() default ""; - ToolAnnotation[] value(); + ToolAnnotation[] annotations() default {}; + } \ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/ToolAnnotation.java b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/ToolAnnotation.java index c7689e6cf..cb0b8ac96 100644 --- a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/ToolAnnotation.java +++ b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/ToolAnnotation.java @@ -11,7 +11,7 @@ * (draft as of 5/18/2025) located here */ -@Repeatable(Tool.class) +@Repeatable(ToolAnnotations.class) @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ToolAnnotation { @@ -24,6 +24,5 @@ boolean readOnlyHint() default false; String title() default ""; - -} +} diff --git a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolGroup.java b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/ToolAnnotations.java similarity index 55% rename from framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolGroup.java rename to framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/ToolAnnotations.java index bcebcdeaa..6a4218e00 100644 --- a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolGroup.java +++ b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/annotation/ToolAnnotations.java @@ -7,11 +7,15 @@ * * SPDX-License-Identifier: EPL-2.0 *****************************************************************************/ -package org.eclipse.ecf.ai.mcp.tools.service; +package org.eclipse.ecf.ai.mcp.tools.annotation; -import java.util.List; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; -public interface ToolGroup { - - List getToolDescriptions(String interfaceClassName); +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ToolAnnotations { + ToolAnnotation[] value() default {}; } diff --git a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/AbstractToolGroup.java b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolGroupService.java similarity index 76% rename from framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/AbstractToolGroup.java rename to framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolGroupService.java index 581b1aad0..1d24603e8 100644 --- a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/AbstractToolGroup.java +++ b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolGroupService.java @@ -11,11 +11,11 @@ import java.util.List; -public class AbstractToolGroup implements ToolGroup { +import org.eclipse.ecf.ai.mcp.tools.util.ToolDescription; - @Override - public List getToolDescriptions(String interfaceClassName) { +public interface ToolGroupService { + + default List getToolDescriptions(String interfaceClassName) { return ToolDescription.fromService(this, interfaceClassName); } - } diff --git a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolAnnotationDescription.java b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolAnnotationDescription.java similarity index 75% rename from framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolAnnotationDescription.java rename to framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolAnnotationDescription.java index f787bfdf1..c6fd4ecb1 100644 --- a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolAnnotationDescription.java +++ b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolAnnotationDescription.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 *****************************************************************************/ -package org.eclipse.ecf.ai.mcp.tools.service; +package org.eclipse.ecf.ai.mcp.tools.util; import java.util.Arrays; import java.util.Collections; @@ -25,10 +25,13 @@ public record ToolAnnotationDescription(boolean destructiveHint, boolean idempot boolean readOnlyHint, String title) { public static List fromAnnotations(ToolAnnotation[] annotations) { - return (annotations != null) ? Arrays.asList(annotations).stream().map(a -> { - return new ToolAnnotationDescription(a.destructiveHint(), a.idempotentHint(), a.openWorldHint(), - a.readOnlyHint(), a.title()); - }).collect(Collectors.toList()) : Collections.emptyList(); - + if (annotations != null) { + return Arrays.asList(annotations).stream().map(a -> { + return new ToolAnnotationDescription(a.destructiveHint(), a.idempotentHint(), a.openWorldHint(), + a.readOnlyHint(), a.title()); + }).collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } } } diff --git a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolDescription.java b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolDescription.java similarity index 61% rename from framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolDescription.java rename to framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolDescription.java index c831b27e9..1b0a50038 100644 --- a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolDescription.java +++ b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolDescription.java @@ -7,8 +7,9 @@ * * SPDX-License-Identifier: EPL-2.0 *****************************************************************************/ -package org.eclipse.ecf.ai.mcp.tools.service; +package org.eclipse.ecf.ai.mcp.tools.util; +import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -17,19 +18,26 @@ import java.util.stream.Collectors; import org.eclipse.ecf.ai.mcp.tools.annotation.Tool; +import org.eclipse.ecf.ai.mcp.tools.annotation.ToolAnnotations; public record ToolDescription(String name, String description, List toolParamDescriptions, - ToolResultDescription resultDesc, List annotations) { + ToolResultDescription resultDescriptions, List toolAnnotationDescriptions) { public static List fromClass(Class clazz) { return Arrays.asList(clazz.getMethods()).stream().map(m -> { - Tool ma = m.getAnnotation(Tool.class); - return (ma != null) - ? new ToolDescription(m.getName(), ma.description(), - ToolParamDescription.fromParameters(m.getParameters()), - ToolResultDescription.fromMethod(m), - ToolAnnotationDescription.fromAnnotations(ma.value())) - : null; + // skip static methods + if (!Modifier.isStatic(m.getModifiers())) { + // Look for Tool annotation + Tool ma = m.getAnnotation(Tool.class); + if (ma != null) { + // Look for ToolAnnotations method annotation + ToolAnnotations tas = m.getAnnotation(ToolAnnotations.class); + return new ToolDescription(m.getName(), ma.description(), + ToolParamDescription.fromParameters(m.getParameters()), ToolResultDescription.fromMethod(m), + ToolAnnotationDescription.fromAnnotations(tas != null ? tas.value() : null)); + } + } + return null; }).filter(Objects::nonNull).collect(Collectors.toList()); } diff --git a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolParamDescription.java b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolParamDescription.java similarity index 96% rename from framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolParamDescription.java rename to framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolParamDescription.java index f9629cff1..423819245 100644 --- a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolParamDescription.java +++ b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolParamDescription.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 *****************************************************************************/ -package org.eclipse.ecf.ai.mcp.tools.service; +package org.eclipse.ecf.ai.mcp.tools.util; import java.lang.reflect.Parameter; import java.util.Arrays; diff --git a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolResultDescription.java b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolResultDescription.java similarity index 95% rename from framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolResultDescription.java rename to framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolResultDescription.java index af181b60a..b271a9c98 100644 --- a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/service/ToolResultDescription.java +++ b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/ToolResultDescription.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 *****************************************************************************/ -package org.eclipse.ecf.ai.mcp.tools.service; +package org.eclipse.ecf.ai.mcp.tools.util; import java.lang.reflect.Method; diff --git a/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/package-info.java b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/package-info.java new file mode 100644 index 000000000..dcf707e6e --- /dev/null +++ b/framework/bundles/org.eclipse.ecf.ai.mcp.tools/src/org/eclipse/ecf/ai/mcp/tools/util/package-info.java @@ -0,0 +1 @@ +package org.eclipse.ecf.ai.mcp.tools.util; \ No newline at end of file