Tool calling lets one app's model use that app's tools. MCP (Model Context Protocol) standardises this across processes — so any MCP client can use your tools, and your app can consume any MCP server. Spring AI ships starters for both sides.
MCP in one picture
Instead of wiring every tool into every app, you build/consume standard servers. One integration, many clients.
Exposing tools (MCP server)
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
Your @Tool beans become MCP tools any client can discover:
@Bean
ToolCallbackProvider tools(OrderTools orderTools) {
return MethodToolCallbackProvider.builder().toolObjects(orderTools).build();
}
Consuming tools (MCP client)
Add the client starter, point it at one or more servers (stdio or SSE/HTTP), and the discovered tools become available to your ChatClient just like local @Tools.
From tools to agents
An agent is the model in a loop: reason → call a tool → observe → repeat → answer. With Spring AI you give the ChatClient tools and let it iterate. The discipline is in the controls around it:
- Termination: cap iterations and define stop conditions in code (never rely on the model to stop).
- Approval gates: require human/confirmation before irreversible actions.
- Idempotency: make tool actions safe to retry.
- Scoped context & tools per agent: smaller choice space → better selection. For complex goals, use an orchestrator that routes sub-tasks to specialist agents.
Best practices & anti-patterns
- ✅ Publish a deliberate, well-described tool set from your MCP server; authenticate and rate-limit it like any API.
- ✅ Validate all tool inputs server-side — the model (and other clients) are untrusted.
- ❌ One agent with 25 tools → split into specialists or trim.
- ❌ Unbounded agent loops with no cap → runaway cost and behaviour.
Next: pick the right model and integrate any provider → Choosing & Integrating LLMs →