MCP Server
The `McpServer` exposes TnsAI tools, resources, and prompts to MCP clients.
Building a Server
To create an MCP server, use the builder to register your tool, resource, and prompt providers, then call start(). By default the server communicates over stdio, making it easy to launch as a subprocess from any MCP client.
McpServer server = McpServer.builder()
.serverName("My-TnsAI-Server")
.serverVersion("1.0.0")
.addToolProvider(myToolProvider)
.addResourceProvider(myResourceProvider)
.addPromptProvider(myPromptProvider)
.build();
server.start(); // Stdio transport (blocking)Expose TnsAI Tools via MCP
If you already have TnsAI tools registered through the SPI mechanism, you can expose all of them to MCP clients with a single line. The TnsAIToolProvider.fromRegistry() call discovers all tools on the classpath automatically.
McpServer server = McpServer.builder()
.serverName("TnsAI-Tools")
.addToolProvider(TnsAIToolProvider.fromRegistry()) // All SPI-discovered tools
.build();
server.start(); // Listens on stdioCustom Tool Provider
To expose your own custom tools via MCP, implement the ToolProvider interface. You define which tools are available and how each one executes when called by a client.
public class MyToolProvider implements ToolProvider {
@Override
public List<McpToolDefinition> listTools() {
return List.of(
McpToolDefinition.builder()
.name("analyze")
.description("Analyze text for sentiment")
.inputSchema(schemaNode)
.build()
);
}
@Override
public ToolResult executeTool(String name, JsonNode args) {
if ("analyze".equals(name)) {
String text = args.get("text").asText();
return ToolResult.text(analyzeSentiment(text));
}
return ToolResult.error("Unknown tool: " + name);
}
}HTTP Server
For production deployments where clients connect over the network, use HttpMcpServer. It serves MCP over Streamable HTTP transport, supporting JSON-RPC requests via POST, server-sent event notifications via GET, and session termination via DELETE.
HttpMcpServer httpServer = HttpMcpServer.builder()
.port(8080)
.path("/mcp")
.addToolProvider(myProvider)
.build();
httpServer.start();
// POST /mcp — JSON-RPC requests
// GET /mcp — SSE notifications
// DELETE /mcp — Session terminationError Handling
Structured error events emitted when MCP tool execution fails. Register a ToolErrorListener to receive notifications and decide on recovery strategy.
ToolErrorCategory
Each error is classified into a category that tells clients whether they should retry the operation or fix the request. This prevents pointless retries for permanent failures like invalid parameters.
| Category | Code | Retriable | Guidance |
|---|---|---|---|
INVALID_PARAMS | invalid_params | No | Request malformed, do not retry with same params |
TOOL_NOT_FOUND | tool_not_found | No | Tool does not exist, check tool registry |
TIMEOUT | timeout | Yes | Execution timed out, may retry |
PERMISSION_DENIED | permission_denied | No | Access denied, do not retry |
INTERNAL | internal | Yes | Unexpected error, may retry |
ToolErrorEvent
A ToolErrorEvent is a structured record emitted whenever a tool execution fails. It contains the tool name, error category, a safe error message (no stack traces), a timestamp, and an optional request ID for correlation.
// Factory methods
ToolErrorEvent event = ToolErrorEvent.of("my_tool", ToolErrorCategory.TIMEOUT, "Timed out after 30s");
ToolErrorEvent event = ToolErrorEvent.of("my_tool", ToolErrorCategory.INTERNAL, "Unexpected error", requestId);
// Check retriability (delegates to category)
if (event.isRetriable()) {
// retry logic
}ToolErrorListener
Register a ToolErrorListener to get notified whenever a tool call fails. This is useful for logging, metrics, or implementing retry logic based on the error category.
// Lambda listener
server.getRequestHandler().addToolErrorListener(event -> {
logger.warn("Tool '{}' failed: {} [{}]",
event.toolName(), event.message(), event.category().code());
if (event.isRetriable()) {
retryQueue.add(event);
}
});MCP Registry
The MCP module provides a unified registry that aggregates MCP server entries from 4 public sources, with deduplication, caching, and protocol version filtering. It also includes a testing toolkit for MCP server development.
MCP Transports
The MCP module provides 5 transport implementations plus an OAuth decorator and an auto-detection utility for connecting to MCP servers over stdio, HTTP, SSE, and bidirectional streaming.