Skip to content
AgentEnsemble AgentEnsemble
Get Started

MCP Coding Example

Demonstrates a coding agent that uses MCP (Model Context Protocol) reference servers for filesystem and git operations instead of Java-native tools.


  1. Accepts a git-tracked project directory as a command-line argument
  2. Starts MCP filesystem and git reference servers scoped to the project
  3. Combines all MCP tools into a single coding agent
  4. Runs a bug-fix task using the MCP tools for file reading, editing, and git operations
  5. Shuts down the MCP servers automatically when complete
// Use the first CLI argument as the project directory, or default to "."
Path projectDir = args.length > 0 ? Path.of(args[0]) : Path.of(".");
ChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o")
.build();
// Start MCP filesystem and git servers (AutoCloseable)
try (McpServerLifecycle fs = McpToolFactory.filesystem(projectDir);
McpServerLifecycle git = McpToolFactory.git(projectDir)) {
fs.start();
git.start();
// Combine filesystem and git tools
List<Object> mcpTools = new ArrayList<>();
mcpTools.addAll(fs.tools());
mcpTools.addAll(git.tools());
// Build a coding agent with MCP 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("Find and fix any compilation errors")
.toBuilder()
.agent(agent)
.build();
EnsembleOutput output = Ensemble.run(model, task);
System.out.println(output.getRaw());
}
Terminal window
export OPENAI_API_KEY=sk-...
./gradlew :agentensemble-examples:runMcpCoding --args="/path/to/git/project"

If no path argument is provided, the current directory is used.

Prerequisites: Node.js must be installed (npx available on the system PATH). The MCP reference servers are installed automatically via npx --yes on first run.

  • MCP servers: McpToolFactory.filesystem() and McpToolFactory.git() start the official MCP reference server subprocesses. Each exposes a standard set of tools (file read/write/search, git status/diff/commit, etc.).
  • Lifecycle management: McpServerLifecycle implements AutoCloseable. Use try-with-resources to ensure servers are shut down cleanly.
  • Tool composition: MCP tools produce standard AgentTool instances that can be freely mixed with Java-native tools in any agent’s tool list.
  • CodingTask: The CodingTask.fix() convenience method provides a pre-configured task description and expected output for bug-fix workflows.

The try-with-resources around Ensemble.run() shown above is correct for a one-shot invocation. Do not transplant it into a long-running process that calls run() more than once — each iteration would spawn a new npx subprocess and pay the cold-start cost.

For loops, request handlers, or long-running ensembles with scheduled tasks, bind the lifecycle to the ensemble instead:

McpServerLifecycle fs = McpToolFactory.filesystem(projectDir);
Ensemble ensemble = Ensemble.builder()
.chatLanguageModel(model)
.managedResource(fs) // started here; closed by ensemble.stop()
.agent(Agent.builder().tools(fs.tools()).build())
.task(task)
.build();
// One-shot: fs stays up across many run() calls
for (var input : inputs) ensemble.run(input);
// Or long-running with scheduled tasks: fs is closed on ensemble.stop()
ensemble.start(7329);

See the Binding the Lifecycle to an Ensemble section of the MCP guide for the full pattern.

The exact tool names are defined by the MCP reference servers. You can discover them at runtime via fs.tools() and git.tools(). Typical tools include:

read_file, write_file, edit_file, search_files, list_directory, directory_tree, get_file_info

git_status, git_diff_unstaged, git_diff_staged, git_diff, git_commit, git_add, git_log, git_branch, git_create_branch, git_checkout, git_show, git_reset