Skip to content

Instantly share code, notes, and snippets.

@glaforge
Created April 2, 2025 20:39
Show Gist options
  • Save glaforge/e1b75653aaeb4742a7fe74dead3ee52f to your computer and use it in GitHub Desktop.
Save glaforge/e1b75653aaeb4742a7fe74dead3ee52f to your computer and use it in GitHub Desktop.
Raw MCP client / server example with the MCP JAVA SDK and LangChain4j's MCP client module
import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.http.HttpMcpTransport;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.tool.ToolProvider;
import java.io.IOException;
import java.util.List;
import static ai.patterns.utils.Ansi.blue;
import static ai.patterns.utils.Ansi.green;
public class CustomMcpClient {
public static void main(String[] args) throws IOException {
try (
VertexAiGeminiChatModel model = VertexAiGeminiChatModel.builder()
.project("genai-playground24")
.location("us-central1")
.modelName("gemini-2.0-flash-001")
.build();
McpTransport transport = new HttpMcpTransport.Builder()
.sseUrl("http://0.0.0.0:45450/sse")
.logRequests(true)
.logResponses(true)
.build()) {
McpClient mcpClient = new DefaultMcpClient.Builder()
.transport(transport)
.build();
ToolProvider toolProvider = McpToolProvider.builder()
.mcpClients(List.of(mcpClient))
.build();
System.out.println(blue("LIST TOOLS"));
mcpClient.listTools().forEach(System.out::println);
record WeatherForecast(String location, String forecast) {}
interface WeatherAssistant {
@SystemMessage("""
If the user asks about the weather forecast for a particular location,
use the `weather-forecast` tool.
Otherwise, respond with your internal knowledge.
""")
WeatherForecast request(String message);
}
WeatherAssistant meteo = AiServices.builder(WeatherAssistant.class)
.chatLanguageModel(model)
.toolProvider(toolProvider)
.build();
System.out.println(blue("WEATHER"));
var response = meteo.request("What is the weather in Paris?");
System.out.println(green(response.toString()));
}
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.server.McpSyncServer;
import io.modelcontextprotocol.server.transport.HttpServletSseServerTransportProvider;
import io.modelcontextprotocol.spec.McpSchema;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import java.util.Map;
import java.util.List;
import static ai.patterns.utils.Ansi.blue;
public class CustomMcpServer {
public static void main(String[] args) throws Exception {
HttpServletSseServerTransportProvider transportProvider =
new HttpServletSseServerTransportProvider(new ObjectMapper(), "/", "/sse");
McpSyncServer syncServer = McpServer.sync(transportProvider)
.serverInfo("custom-server", "0.0.1")
.capabilities(McpSchema.ServerCapabilities.builder()
.tools(true)
.resources(false, false)
.prompts(false)
.build())
.build();
McpServerFeatures.SyncToolSpecification syncToolSpecification =
new McpServerFeatures.SyncToolSpecification(
new McpSchema.Tool("weather-forecast", "gives today's weather forecast for a given location",
new McpSchema.JsonSchema("object", Map.of(
"location", new McpSchema.JsonSchema("string", null, null, false),
"forecast", new McpSchema.JsonSchema("string", null, null, false)
), List.of("location", "forecast"), false)
/*
"""
{
"type": "object",
"properties": {
"location": {
"type": "string"
},
"forecast": {
"type": "string"
}
},
"required": ["location", "forecast"]
}
"""
*/
),
(mcpSyncServerExchange, stringObjectMap) -> {
System.out.println(blue("Incoming request: ") + stringObjectMap);
return new McpSchema.CallToolResult(List.of(new McpSchema.TextContent("""
{"location": "Paris", "forecast": "sunny"}
"""
)), false);
}
);
syncServer.addTool(syncToolSpecification);
QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.setName("server");
Server server = new Server(threadPool);
ServerConnector connector = new ServerConnector(server);
connector.setPort(45450);
server.addConnector(connector);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
context.addServlet(new ServletHolder(transportProvider), "/*");
server.setHandler(context);
server.start();
// syncServer.close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment