Add mcp-client module: ChatClient calling tools from real external MCP servers over stdio

defaultToolCallbacks(ToolCallbackProvider) wires two real stdio MCP servers (the official
filesystem server and git server) into ChatClient, contrasted with defaultTools(Object) for a
local @Tool method. Every call -- MCP-sourced or local -- is logged through one Micrometer
ObservationHandler<ToolCallingObservationContext>; a first version wired that handler two ways
at once and every call logged twice, which is now a regression test. No real LLM is used
anywhere: every test builds an AssistantMessage.ToolCall by hand and drives it through the real
ToolCallingManager bean against real npx/uvx-launched MCP server processes.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01FtpJvZfg4nvLvtzgJTDWpB
This commit is contained in:
Claude
2026-09-23 14:44:10 +00:00
parent 9919da58a7
commit 60849f4319
25 changed files with 969 additions and 0 deletions
@@ -0,0 +1,6 @@
# Calling the git MCP server's git_log tool through the real ToolCallingManager
tool: git_log
arguments: {"repo_path":"/home/claude/work/spring-ai-clone/mcp-client/fixtures/demo-repo","max_count":5}
response: [{"text":"Commit history:\nCommit: 'b45115d1016791970e7827c8b2573a345c95f733'\nAuthor: <git.Actor \"Demo <[email protected]>\">\nDate: 2026-09-23 14:43:44+00:00\nMessage: 'Add a second line\\n'\n\nCommit: 'aa0f59aeba079fc5a4e9f85c07d357e593e184b0'\nAuthor: <git.Actor \"Demo <[email protected]>\">\nDate: 2026-09-23 14:43:44+00:00\nMessage: 'Initial commit\\n'\n"}]