Skip to content
AgentEnsemble AgentEnsemble
Get Started

MCP Bridge

The agentensemble-mcp module bridges the Model Context Protocol (MCP) ecosystem into AgentEnsemble. It adapts MCP server tools to the AgentTool interface so they can be used alongside Java-native tools in any agent’s tool list.


implementation("net.agentensemble:agentensemble-mcp:VERSION")

Use McpToolFactory.fromServer() to connect to any MCP-compatible server and obtain its tools as AgentTool instances. Wrap the transport in try-with-resources to ensure the subprocess is cleaned up:

import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
import net.agentensemble.mcp.McpToolFactory;
try (StdioMcpTransport transport = new StdioMcpTransport.Builder()
.command(List.of("npx", "--yes", "@modelcontextprotocol/server-filesystem", "/workspace"))
.build()) {
// Get all tools from the server
List<AgentTool> tools = McpToolFactory.fromServer(transport);
// Or filter to specific tools by name
List<AgentTool> filtered = McpToolFactory.fromServer(transport, "read_file", "write_file");
}

For managed lifecycle (recommended), prefer McpServerLifecycle via McpToolFactory.filesystem() or McpToolFactory.git() — see below.

Each tool’s parameter schema is passed through directly from the MCP server to the LLM — the LLM sees properly typed, named parameters just as with TypedAgentTool records.


McpToolFactory provides convenience methods for the well-known MCP reference servers:

import net.agentensemble.mcp.McpToolFactory;
import net.agentensemble.mcp.McpServerLifecycle;
// Filesystem server: read, write, search, list files
try (McpServerLifecycle fs = McpToolFactory.filesystem(Path.of("/workspace"))) {
fs.start();
List<AgentTool> fsTools = fs.tools();
var agent = Agent.builder()
.role("File Manager")
.tools(fsTools)
.llm(chatModel)
.build();
}
// Git server: status, diff, log, commit, branch
try (McpServerLifecycle git = McpToolFactory.git(Path.of("/repo"))) {
git.start();
List<AgentTool> gitTools = git.tools();
// ...
}

These methods require npx (Node.js) to be available on the system PATH. They spawn the MCP reference servers as subprocesses:

  • filesystem(Path) runs npx @modelcontextprotocol/server-filesystem <dir>
  • git(Path) runs npx @modelcontextprotocol/server-git --repository <dir>

McpServerLifecycle manages the MCP server subprocess lifecycle. It implements AutoCloseable for use with try-with-resources:

try (McpServerLifecycle server = McpToolFactory.filesystem(projectDir)) {
server.start(); // Spawn subprocess, initialize MCP protocol
List<AgentTool> tools = server.tools(); // List and cache tools
boolean alive = server.isAlive(); // Check health
// ... use tools ...
} // Automatically closes the server on exit

State machine:

CREATED --start()--> STARTED --close()--> CLOSED
^
CREATED --close()----> CLOSED -------+
  • start() spawns the server subprocess and performs a health check
  • tools() lists available tools (cached after first call)
  • close() shuts down the server; idempotent
  • isAlive() returns true when started and not yet closed

MCP tools and Java tools produce standard AgentTool instances. They can be freely mixed in a single agent’s tool list:

// MCP tools for filesystem operations
try (McpServerLifecycle fs = McpToolFactory.filesystem(workDir)) {
fs.start();
// Combine MCP tools with Java tools by name
List<Object> allTools = new ArrayList<>(fs.tools());
allTools.add(new CalculatorTool());
allTools.add(WebSearchTool.ofTavily(apiKey));
var agent = Agent.builder()
.role("Developer")
.tools(allTools)
.llm(chatModel)
.build();
}

MCP tools integrate naturally with the agentensemble-coding module. Start the filesystem and git servers, then combine their tools into a coding agent:

import net.agentensemble.coding.CodingTask;
import net.agentensemble.mcp.McpToolFactory;
import net.agentensemble.mcp.McpServerLifecycle;
try (McpServerLifecycle fs = McpToolFactory.filesystem(projectDir);
McpServerLifecycle git = McpToolFactory.git(projectDir)) {
fs.start();
git.start();
List<Object> mcpTools = new ArrayList<>();
mcpTools.addAll(fs.tools());
mcpTools.addAll(git.tools());
Agent agent = Agent.builder()
.role("Senior Software Engineer")
.goal("Implement, debug, and refactor code with precision")
.tools(mcpTools)
.llm(model)
.maxIterations(75)
.build();
Task task = CodingTask.fix("Fix the failing authentication test")
.toBuilder().agent(agent).build();
EnsembleOutput output = Ensemble.run(model, task);
}

For the full walkthrough, see the MCP Coding Example and the Coding Agents Guide.


import net.agentensemble.Agent;
import net.agentensemble.Ensemble;
import net.agentensemble.Task;
import net.agentensemble.mcp.McpToolFactory;
import net.agentensemble.mcp.McpServerLifecycle;
// Start MCP filesystem server scoped to the project directory
try (McpServerLifecycle fs = McpToolFactory.filesystem(Path.of("/my/project"))) {
fs.start();
Agent coder = Agent.builder()
.role("Software Engineer")
.goal("Read code and answer questions about it")
.tools(fs.tools())
.llm(chatModel)
.maxIterations(20)
.build();
Task task = Task.builder()
.description("Find the main entry point of the application and explain what it does")
.build();
var result = Ensemble.builder()
.agent(coder)
.task(task)
.build()
.run();
System.out.println(result.output());
}