Support for MCP (Model Context Protocol)
From, https://modelcontextprotocol.io/introduction
MCP is an open protocol that standardizes how applications provide context to LLMs. Think of MCP like a USB-C port for AI applications. Just as USB-C provides a standardized way to connect your devices to various peripherals and accessories, MCP provides a standardized way to connect AI models to different data sources and tools.
This protocol is relatively new and there is a lot of hype around it. I think there is value in creating an experimental module to add MCP support in Armeria. I think it can boost the project's popularity as well.
For example, Http4k added it recently: https://www.http4k.org/news/http4k_mcp_has_landed/ And Spring boot: https://docs.spring.io/spring-ai-mcp/reference/overview.html
As current implementation of MCP uses SSE, it should be relatively easy to abstract out the MCP protocol as a separate HttpService.
If you find value in this project, I am willing to pair-up to help. I have recently went ahead and helped a relatively new CLI tools for interacting MCPs to add HTTP support, so I am kinda familiar with the protocol now.
I am also interested in MCP. It would be awesome if we could support MCP in Armeria.
I am also interested in MCP. It would be awesome if we could support MCP in Armeria.
Here are some suggestions.
public class MyMcpService implements McpService {
@Override
public Set<McpTool> tools() { ... }
@Override
public Set<McpResource> resources() { ... }
@Override
public Set<McpPrompt> prompts() { ... }
}
public class TellAgeTool implements McpTool {
@Override public String name = "tell-age";
@Override public String description = "Tells the age of a person";
@Override
public McpParams params() {
return McpParams.of(
McpParams.string("name"),
McpParams.int("age").withDescription("Age of the person"),
);
}
@Override
public ToolResponse handle(McpParams params) {
String name = params.string("name");
Int age = params.int("age").orDefault(0);
return ToolResponse.ofText("Hello " + name ", you are " + age + " years old.");
}
}
public class PersonResource implements McpResource {
@Override public String name = "person";
@Override public String uri = "uri://person";
@Override
public ResourceResponse handle(params: McpParams) {
URI uri = params.uri("uri");
return ResourceResponse.ofImage(Images.get(uri).toBase64());
}
}
public class SamplePrompt implements McpPrompt {
@Override public String name = "person";
@Override
public ResourceResponse handle(params: McpParams) {
URI uri = params.uri("uri");
return ResourceResponse.ofImage(Images.get(uri).toBase64());
}
}
sb.serviceUnder("/mcp", MyMcpService())
For registering the entities, we can also use annotations,
@McpService
public class MyMcpService {
// Auto-register schema from parameters
@Tool(name = "tellAge", description = "...")
public tellAge(
String name,
Int age,
) ToolResponse {
return ToolResponse.ofText("Hello " + name ", you are " + age + " years old.);
}
@Resource(uri = "file://person", name = "person", description = "...")
public person(ResourceParams params) ResourceResponse {
return ResourceResponse.ofImage(Images.get(params.uri).toBase64());
}
@Prompt()
public prompt(
String code
) PromptResponse {
return PromptResponse.ofResource("uri://...");
}
}
sb.mcpService("/mcp", MyMcpService())
// Or
sb.annotatedService("/mcp", MyMcpService())
I would like this, even though it is an interesting challenge for trace propagation. Suggest we support stdio mode as well, even though that isn't typical for armeria. Rationale is well engineered i/o is a win even if using stdio.
Furthermore it can be extended to Google's recently released protocol A2A
https://github.com/google/A2A
Should we implement JSON RPC first to implement MCP?
sg. Also if you want a reference, this uses stdio in spring-ai. I think the integrations could be far cleaner in armeria https://github.com/elastic/observability-examples/pull/61
also here's a nice read of the latest non-stdio protocol "streamable" https://www.claudemcp.com/blog/mcp-streamable-http
Should we implement JSON RPC first to implement MCP?
Yes, I think it should be the first step. Should we create a separate issue for that @trustin ?
Hi @Dogacel , I'm interested in the JSON RPC implementation mentioned in that issue, if you don't mind, would you mind if I work on it?
fyi I proposed a clarification on MCP spec about how to encode trace identifiers in MCP's JSON-RPC requests (which I think would end up implemented here decoupled from MCP) https://github.com/modelcontextprotocol/modelcontextprotocol/pull/414 cc also also other armeria tracing friends @anuraaga and @kojilin