diff --git a/.gitignore b/.gitignore
index c4cc698..9d6d3db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,7 @@ target/
!**/src/test/**/target/
### IntelliJ IDEA ###
-.idea/*
+.idea/
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
@@ -36,4 +36,4 @@ build/
.vscode/
### Mac OS ###
-.DS_Store
\ No newline at end of file
+.DS_Store
diff --git a/mcp-example/pom.xml b/mcp-example/pom.xml
new file mode 100644
index 0000000..60a2f8b
--- /dev/null
+++ b/mcp-example/pom.xml
@@ -0,0 +1,57 @@
+
+
+ 4.0.0
+
+ dev.langchain4j
+ mcp-example
+ 0.36.1
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+
+ dev.langchain4j
+ langchain4j
+ 0.37.0
+
+
+
+ dev.langchain4j
+ langchain4j-open-ai
+ 0.37.0
+
+
+
+ dev.langchain4j
+ langchain4j-mcp
+ 0.37.0
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.10.0
+
+
+
+ org.assertj
+ assertj-core
+ 3.25.3
+
+
+
+ ch.qos.logback
+ logback-classic
+ 1.5.12
+
+
+
+
+
diff --git a/mcp-example/src/main/java/dev/langchain4j/example/mcp/Bot.java b/mcp-example/src/main/java/dev/langchain4j/example/mcp/Bot.java
new file mode 100644
index 0000000..398b89e
--- /dev/null
+++ b/mcp-example/src/main/java/dev/langchain4j/example/mcp/Bot.java
@@ -0,0 +1,9 @@
+package dev.langchain4j.example.mcp;
+
+import dev.langchain4j.service.UserMessage;
+
+public interface Bot {
+
+ String chat(@UserMessage String prompt);
+
+}
diff --git a/mcp-example/src/main/java/dev/langchain4j/example/mcp/McpToolsExampleOverHttp.java b/mcp-example/src/main/java/dev/langchain4j/example/mcp/McpToolsExampleOverHttp.java
new file mode 100644
index 0000000..fd0eb62
--- /dev/null
+++ b/mcp-example/src/main/java/dev/langchain4j/example/mcp/McpToolsExampleOverHttp.java
@@ -0,0 +1,63 @@
+package dev.langchain4j.example.mcp;
+
+import dev.langchain4j.mcp.McpToolProvider;
+import dev.langchain4j.mcp.client.DefaultMcpClient;
+import dev.langchain4j.mcp.client.McpClient;
+import dev.langchain4j.mcp.client.transport.http.HttpMcpTransport;
+import dev.langchain4j.mcp.client.transport.McpTransport;
+import dev.langchain4j.model.chat.ChatLanguageModel;
+import dev.langchain4j.model.openai.OpenAiChatModel;
+import dev.langchain4j.service.AiServices;
+import dev.langchain4j.service.tool.ToolProvider;
+
+import java.time.Duration;
+import java.util.List;
+
+public class McpToolsExampleOverHttp {
+
+ /**
+ * This example uses the `server-everything` MCP server that showcases some aspects of the MCP protocol.
+ * In particular, we use its 'add' tool that adds two numbers.
+ *
+ * Before running this example, you need to start the `everything` server in SSE mode on localhost:3001.
+ * Check out https://github.com/modelcontextprotocol/servers/tree/main/src/everything
+ * and run `npm install` and `node dist/sse.js`.
+ *
+ * Of course, feel free to swap out the server with any other MCP server.
+ *
+ * Run the example and check the logs to verify that the model used the tool.
+ */
+ public static void main(String[] args) throws Exception {
+ ChatLanguageModel model = OpenAiChatModel.builder()
+ .modelName("gpt-4o")
+ .apiKey(System.getenv("OPENAI_API_KEY"))
+ .logRequests(true)
+ .logResponses(true)
+ .build();
+ McpTransport transport = new HttpMcpTransport.Builder()
+ .sseUrl("http://localhost:3001/sse")
+ .timeout(Duration.ofSeconds(60))
+ .logRequests(true)
+ .logResponses(true)
+ .build();
+ McpClient mcpClient = new DefaultMcpClient.Builder()
+ .transport(transport)
+ .build();
+ ToolProvider toolProvider = McpToolProvider.builder()
+ .mcpClients(List.of(mcpClient))
+ .build();
+ Bot bot = AiServices.builder(Bot.class)
+ .chatLanguageModel(model)
+ .toolProvider(toolProvider)
+ .build();
+ try {
+ String response = bot.chat("What is 5+12? Use the provided tool to answer " +
+ "and always assume that the tool is correct.");
+ System.out.println(response);
+ } finally {
+ mcpClient.close();
+ }
+ }
+
+
+}
diff --git a/mcp-example/src/main/java/dev/langchain4j/example/mcp/McpToolsExampleOverStdio.java b/mcp-example/src/main/java/dev/langchain4j/example/mcp/McpToolsExampleOverStdio.java
new file mode 100644
index 0000000..d89bf1e
--- /dev/null
+++ b/mcp-example/src/main/java/dev/langchain4j/example/mcp/McpToolsExampleOverStdio.java
@@ -0,0 +1,74 @@
+package dev.langchain4j.example.mcp;
+
+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.stdio.StdioMcpTransport;
+import dev.langchain4j.model.chat.ChatLanguageModel;
+import dev.langchain4j.model.openai.OpenAiChatModel;
+import dev.langchain4j.service.AiServices;
+import dev.langchain4j.service.tool.ToolProvider;
+
+import java.io.File;
+import java.util.List;
+
+public class McpToolsExampleOverStdio {
+
+ // We will let the AI read the contents of this file
+ public static final String FILE_TO_BE_READ = "src/main/resources/file.txt";
+
+ /**
+ * This example uses the `server-filesystem` MCP server to showcase how
+ * to allow an LLM to interact with the local filesystem.
+ *
+ * Running this example requires npm to be installed on your machine,
+ * because it spawns the `server-filesystem` as a subprocess via npm:
+ * `npm exec @modelcontextprotocol/server-filesystem@0.6.2`.
+ *
+ * Of course, feel free to swap out the server with any other MCP server.
+ *
+ * The communication with the server is done directly via stdin/stdout.
+ *
+ * IMPORTANT: when executing this, make sure that the working directory is
+ * equal to the root directory of the project
+ * (`langchain4j-examples/mcp-example`), otherwise the program won't be able to find
+ * the proper file to read. If you're working from another directory,
+ * adjust the path inside the StdioMcpTransport.Builder() usage in the main method.
+ */
+ public static void main(String[] args) throws Exception {
+ ChatLanguageModel model = OpenAiChatModel.builder()
+ .modelName("gpt-4o")
+ .apiKey(System.getenv("OPENAI_API_KEY"))
+// .logRequests(true)
+// .logResponses(true)
+ .build();
+ McpTransport transport = new StdioMcpTransport.Builder()
+ .command(List.of("/usr/bin/npm", "exec",
+ "@modelcontextprotocol/server-filesystem@0.6.2",
+ // allowed directory for the server to interact with
+ new File("src/main/resources").getAbsolutePath()
+ ))
+ .logEvents(true)
+ .build();
+ McpClient mcpClient = new DefaultMcpClient.Builder()
+ .transport(transport)
+ .build();
+ ToolProvider toolProvider = McpToolProvider.builder()
+ .mcpClients(List.of(mcpClient))
+ .build();
+ Bot bot = AiServices.builder(Bot.class)
+ .chatLanguageModel(model)
+ .toolProvider(toolProvider)
+ .build();
+ try {
+ File file = new File(FILE_TO_BE_READ);
+ String response = bot.chat("Read the contents of the file " + file.getAbsolutePath());
+ System.out.println("RESPONSE: " + response);
+ } finally {
+ mcpClient.close();
+ }
+ }
+
+
+}
diff --git a/mcp-example/src/main/resources/file.txt b/mcp-example/src/main/resources/file.txt
new file mode 100644
index 0000000..2414524
--- /dev/null
+++ b/mcp-example/src/main/resources/file.txt
@@ -0,0 +1 @@
+Kaboom!
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index acd80a7..5bc3e83 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,6 +22,7 @@
infinispan-example
jakartaee-microprofile-example
jlama-examples
+ mcp-example
milvus-example
mistral-ai-examples
neo4j-example