Skip to content

Commit d8570c3

Browse files
committed
feat(i18n): Add i18n support for MCP server component description
- Introduce ResourceBundle for handling localized descriptions - Add descriptionI18nKey field to relevant annotations - Update factory classes to use localized descriptions - Modify getDescription method to handle both localized and default descriptions
1 parent 2d65932 commit d8570c3

File tree

11 files changed

+53
-15
lines changed

11 files changed

+53
-15
lines changed

src/main/java/com/github/codeboyzhou/mcp/declarative/annotation/McpJsonSchemaDefinitionProperty.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
public @interface McpJsonSchemaDefinitionProperty {
1313
String name() default StringHelper.EMPTY;
1414

15-
String description();
15+
String description() default StringHelper.EMPTY;
16+
17+
String descriptionI18nKey() default StringHelper.EMPTY;
1618

1719
boolean required() default false;
20+
1821
}

src/main/java/com/github/codeboyzhou/mcp/declarative/annotation/McpPrompt.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@
1313

1414
String name() default StringHelper.EMPTY;
1515

16-
String description();
16+
String description() default StringHelper.EMPTY;
17+
18+
String descriptionI18nKey() default StringHelper.EMPTY;
19+
1720
}

src/main/java/com/github/codeboyzhou/mcp/declarative/annotation/McpPromptParam.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.github.codeboyzhou.mcp.declarative.annotation;
22

3+
import com.github.codeboyzhou.mcp.declarative.util.StringHelper;
4+
35
import java.lang.annotation.ElementType;
46
import java.lang.annotation.Retention;
57
import java.lang.annotation.RetentionPolicy;
@@ -11,7 +13,10 @@
1113

1214
String name();
1315

14-
String description();
16+
String description() default StringHelper.EMPTY;
17+
18+
String descriptionI18nKey() default StringHelper.EMPTY;
1519

1620
boolean required() default false;
21+
1722
}

src/main/java/com/github/codeboyzhou/mcp/declarative/annotation/McpResource.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@
1515

1616
String name() default StringHelper.EMPTY;
1717

18-
String description();
18+
String description() default StringHelper.EMPTY;
19+
20+
String descriptionI18nKey() default StringHelper.EMPTY;
1921

2022
String mimeType() default "text/plain";
2123

2224
McpSchema.Role[] roles() default {McpSchema.Role.ASSISTANT, McpSchema.Role.USER};
2325

2426
double priority() default 1.0;
27+
2528
}

src/main/java/com/github/codeboyzhou/mcp/declarative/annotation/McpTool.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@
1313

1414
String name() default StringHelper.EMPTY;
1515

16-
String description();
16+
String description() default StringHelper.EMPTY;
17+
18+
String descriptionI18nKey() default StringHelper.EMPTY;
19+
1720
}

src/main/java/com/github/codeboyzhou/mcp/declarative/annotation/McpToolParam.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.github.codeboyzhou.mcp.declarative.annotation;
22

3+
import com.github.codeboyzhou.mcp.declarative.util.StringHelper;
4+
35
import java.lang.annotation.ElementType;
46
import java.lang.annotation.Retention;
57
import java.lang.annotation.RetentionPolicy;
@@ -10,7 +12,10 @@
1012
public @interface McpToolParam {
1113
String name();
1214

13-
String description();
15+
String description() default StringHelper.EMPTY;
16+
17+
String descriptionI18nKey() default StringHelper.EMPTY;
1418

1519
boolean required() default false;
20+
1621
}

src/main/java/com/github/codeboyzhou/mcp/declarative/server/factory/AbstractMcpServerComponentFactory.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,28 @@
22

33
import com.google.inject.Injector;
44

5+
import java.util.Locale;
6+
import java.util.ResourceBundle;
7+
58
public abstract class AbstractMcpServerComponentFactory<T> implements McpServerComponentFactory<T> {
69

710
protected final Injector injector;
811

12+
private final ResourceBundle bundle;
13+
914
protected AbstractMcpServerComponentFactory(Injector injector) {
1015
this.injector = injector;
16+
this.bundle = ResourceBundle.getBundle("i18n/mcp_server_component_descriptions", Locale.getDefault());
17+
}
18+
19+
protected String getDescription(String descriptionI18nKey, String description) {
20+
if (!descriptionI18nKey.isBlank() && bundle.containsKey(descriptionI18nKey)) {
21+
bundle.getString(descriptionI18nKey);
22+
}
23+
if (!description.isBlank()) {
24+
return description;
25+
}
26+
return "No description provided.";
1127
}
1228

1329
}

src/main/java/com/github/codeboyzhou/mcp/declarative/server/factory/McpServerPromptFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ protected McpServerPromptFactory(Injector injector) {
3838
public McpServerFeatures.AsyncPromptSpecification create(Class<?> clazz, Method method) {
3939
McpPrompt promptMethod = method.getAnnotation(McpPrompt.class);
4040
final String name = promptMethod.name().isBlank() ? method.getName() : promptMethod.name();
41-
final String description = promptMethod.description();
41+
final String description = getDescription(promptMethod.descriptionI18nKey(), promptMethod.description());
4242
List<McpSchema.PromptArgument> promptArguments = createPromptArguments(method);
4343
McpSchema.Prompt prompt = new McpSchema.Prompt(name, description, promptArguments);
4444
logger.debug("Registering prompt: {}", JsonHelper.toJson(prompt));
@@ -83,7 +83,7 @@ private List<McpSchema.PromptArgument> createPromptArguments(Method method) {
8383
for (Parameter param : params) {
8484
McpPromptParam promptParam = param.getAnnotation(McpPromptParam.class);
8585
final String name = promptParam.name();
86-
final String description = promptParam.description();
86+
final String description = getDescription(promptParam.descriptionI18nKey(), promptParam.description());
8787
final boolean required = promptParam.required();
8888
McpSchema.PromptArgument promptArgument = new McpSchema.PromptArgument(name, description, required);
8989
promptArguments.add(promptArgument);

src/main/java/com/github/codeboyzhou/mcp/declarative/server/factory/McpServerResourceFactory.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,9 @@ protected McpServerResourceFactory(Injector injector) {
3131
public McpServerFeatures.AsyncResourceSpecification create(Class<?> clazz, Method method) {
3232
McpResource res = method.getAnnotation(McpResource.class);
3333
final String name = res.name().isBlank() ? method.getName() : res.name();
34-
McpSchema.Resource resource = new McpSchema.Resource(
35-
res.uri(), name, res.description(), res.mimeType(),
36-
new McpSchema.Annotations(List.of(res.roles()), res.priority())
37-
);
34+
final String description = getDescription(res.descriptionI18nKey(), res.description());
35+
McpSchema.Annotations annotations = new McpSchema.Annotations(List.of(res.roles()), res.priority());
36+
McpSchema.Resource resource = new McpSchema.Resource(res.uri(), name, description, res.mimeType(), annotations);
3837
logger.debug("Registering resource: {}", JsonHelper.toJson(resource));
3938
return new McpServerFeatures.AsyncResourceSpecification(resource, (exchange, request) ->
4039
Mono.fromSupplier(() -> {

src/main/java/com/github/codeboyzhou/mcp/declarative/server/factory/McpServerToolFactory.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public McpServerFeatures.AsyncToolSpecification create(Class<?> clazz, Method me
4545
McpTool toolMethod = method.getAnnotation(McpTool.class);
4646
McpSchema.JsonSchema paramSchema = createJsonSchema(method);
4747
final String name = toolMethod.name().isBlank() ? method.getName() : toolMethod.name();
48-
McpSchema.Tool tool = new McpSchema.Tool(name, toolMethod.description(), paramSchema);
48+
final String description = getDescription(toolMethod.descriptionI18nKey(), toolMethod.description());
49+
McpSchema.Tool tool = new McpSchema.Tool(name, description, paramSchema);
4950
logger.debug("Registering tool: {}", JsonHelper.toJson(tool));
5051
return new McpServerFeatures.AsyncToolSpecification(tool, (exchange, params) ->
5152
Mono.fromSupplier(() -> {
@@ -98,7 +99,7 @@ private McpSchema.JsonSchema createJsonSchema(Method method) {
9899

99100
if (parameterType.getAnnotation(McpJsonSchemaDefinition.class) == null) {
100101
property.put("type", parameterType.getSimpleName().toLowerCase());
101-
property.put("description", toolParam.description());
102+
property.put("description", getDescription(toolParam.descriptionI18nKey(), toolParam.description()));
102103
} else {
103104
final String parameterTypeSimpleName = parameterType.getSimpleName();
104105
property.put("$ref", "#/definitions/" + parameterTypeSimpleName);
@@ -135,7 +136,7 @@ private Map<String, Object> createJsonSchemaDefinition(Class<?> definitionClass)
135136

136137
Map<String, Object> fieldProperties = new HashMap<>();
137138
fieldProperties.put("type", field.getType().getSimpleName().toLowerCase());
138-
fieldProperties.put("description", property.description());
139+
fieldProperties.put("description", getDescription(property.descriptionI18nKey(), property.description()));
139140

140141
final String fieldName = property.name().isBlank() ? field.getName() : property.name();
141142
properties.put(fieldName, fieldProperties);

0 commit comments

Comments
 (0)