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.
Installation¶
Connecting to Any MCP Server¶
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.
Convenience: Filesystem and Git Servers¶
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)runsnpx @modelcontextprotocol/server-filesystem <dir>git(Path)runsnpx @modelcontextprotocol/server-git --repository <dir>
Lifecycle Management¶
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:
start()spawns the server subprocess and performs a health checktools()lists available tools (cached after first call)close()shuts down the server; idempotentisAlive()returns true when started and not yet closed
Mixing MCP Tools with Java Tools¶
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();
}
Coding Agents with MCP¶
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.
Complete Example¶
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());
}