Background
Armeria gained MCP server support in #6513 — the ai/mcp module provides Armeria transports
(ArmeriaStreamableServerTransportProvider, ArmeriaStatelessServerTransport) for the
MCP Java SDK, built on top of JsonRpcService (#6504).
(Related: #6179)
However, defining tools, resources and prompts still goes through the SDK's programmatic APIs
(McpServerFeatures.SyncToolSpecification and friends), which are fairly verbose — input JSON schemas
are hand-written strings and every handler is registered manually.
Proposal
Provide an annotation-based programming model for MCP services, in the same spirit as Armeria's
annotated HTTP services and
Spring AI's MCP server annotations.
A strawman sketch:
final class MyMcpService {
@McpTool(description = "Adds two numbers")
public int add(@McpToolParam(description = "The first number") int a,
@McpToolParam(description = "The second number") int b) {
return a + b;
}
@McpResource(uri = "config://{key}", description = "Returns a configuration value")
public String config(String key) {
return configs.get(key);
}
@McpPrompt(description = "Generates a greeting message")
public String greeting(@McpArg(description = "The user's name") String name) {
return "Hello, " + name + '!';
}
}
Server.builder()
.service("/mcp", McpService.builder()
.annotatedService(new MyMcpService())
.build())
.build()
.start();
- Input JSON schemas are generated automatically from the method signature instead of hand-written
schema strings.
- Async support the Armeria way:
CompletableFuture<T> and Publisher<T> return types.
- Reuses the existing
ai/mcp transports underneath, so both streamable (stateful) and stateless
modes work as-is.
Notes
- Spring AI's annotations originate from the framework-agnostic
spring-ai-community/mcp-annotations, but that
project has graduated into Spring AI 2.x and is no longer maintained standalone — so implementing our
own annotations (reusing Armeria's annotated-service machinery where it makes sense) looks like the
better long-term fit.
DocService integration (browsing tools/resources/prompts, debug form) would be a nice follow-up,
similar to gRPC/Thrift support.
- Client-side annotations (sampling / elicitation / progress handlers) are out of scope here and could
follow later.
Background
Armeria gained MCP server support in #6513 — the
ai/mcpmodule provides Armeria transports(
ArmeriaStreamableServerTransportProvider,ArmeriaStatelessServerTransport) for theMCP Java SDK, built on top of
JsonRpcService(#6504).(Related: #6179)
However, defining tools, resources and prompts still goes through the SDK's programmatic APIs
(
McpServerFeatures.SyncToolSpecificationand friends), which are fairly verbose — input JSON schemasare hand-written strings and every handler is registered manually.
Proposal
Provide an annotation-based programming model for MCP services, in the same spirit as Armeria's
annotated HTTP services and
Spring AI's MCP server annotations.
A strawman sketch:
schema strings.
CompletableFuture<T>andPublisher<T>return types.ai/mcptransports underneath, so both streamable (stateful) and statelessmodes work as-is.
Notes
spring-ai-community/mcp-annotations, but that
project has graduated into Spring AI 2.x and is no longer maintained standalone — so implementing our
own annotations (reusing Armeria's annotated-service machinery where it makes sense) looks like the
better long-term fit.
DocServiceintegration (browsing tools/resources/prompts, debug form) would be a nice follow-up,similar to gRPC/Thrift support.
follow later.