Chapter 14: Model Context Protocol (MCP) & MCP Server Architecture
The Model Context Protocol (MCP) is an open standardized interaction protocol designed to seamlessly connect AI applications (hosts) with external tools, contextual data sources, and prompts. By decoupling deterministic execution environments (MCP Servers) from language model applications (MCP Clients), MCP solves the exponential integration overhead inherent in monolithic tool integration patterns.
1. The Status Quo: LLM Tool Augmentation
Large Language Models (LLMs) are strictly probabilistic text engines. While they excel at pattern recognition and natural language generation, they cannot natively execute deterministic operations such as:
- Fetching real-time external data (e.g., retrieving the current weather in New Delhi).
- Performing guaranteed accurate mathematical calculations.
- Executing arbitrary code or persisting records in external storage engines.
To overcome these constraints, modern GenAI applications attach Tools to the LLM. In an early-stage or single-service architecture, these tools are integrated directly inside the monolithic application server using framework annotations (e.g., @Tool in Spring AI, or native function declarations in OpenAI/LangChain).
The Structured Output Contract
Because deterministically programmed tools cannot process raw natural language, the LLM converts user intent into a rigid JSON structure conforming to the tool's input schema:
{
"name": "getWeather",
"parameters": {
"latitude": 28.6139,
"longitude": 77.2090,
"unit": "celsius"
}
}
While this monolithic approach functions well for a single application with isolated tools, it degrades quickly in enterprise microservice environments.
2. The Integration Bottleneck
As an organization's AI ecosystem expands beyond a single service to multiple specialized applications (e.g., App_1, App_2, App_3), each app often requires access to the same shared suite of capabilities (such as standard mathematical calculators, central code compilers, enterprise weather gateways, or database connectors).
The First-Principles Problem
If you have host applications and external tools:
For 5 microservices and 10 external AI tools, developers must write, test, and maintain 50 distinct adapter proxies.
The Solution: Decoupling Tools via a Common Layer
Applying first-principles engineering leads to a key insight: Deterministic tools do not require an LLM inside them to execute. They are standard software functions.
Extracting these tools into a standalone, centralized service allows multiple host applications to connect to a shared execution engine. However, doing so requires a universal, standardized communication protocol—which is where the Model Context Protocol (MCP) fits in.
3. Demystifying Model Context Protocol (MCP)
Model Context Protocol (MCP) is an open standard that dictates how AI applications (MCP Clients) securely discover, query, and execute capabilities hosted on external execution engines (MCP Servers).
Analogy: Just as HTTP standardized how web browsers request content from web servers regardless of the underlying hardware or language, MCP standardizes how AI applications discover and invoke capabilities on remote tool servers regardless of the underlying LLM framework (Spring AI, LangChain, LlamaIndex, Python, or TypeScript).
Architectural Roles
- Host (AI Application): The container process housing the primary application server, user security context, and the connection to the LLM model.
- MCP Client: A lightweight protocol engine running within the Host that maintains a connection to the MCP Server, auto-discovers available tools, and issues invocation commands.
- MCP Server: A standalone execution engine hosting tools, contextual resources, and prompt templates, exposing them over standard MCP endpoints.
4. The 3 Pillars of MCP: Tools, Resources, and Prompts
An MCP Server can expose three primary primitives to connected MCP Clients:
5. Dynamic Tool Discovery & Execution Flow
MCP eliminates the need to manually build microservice adapters by leveraging Dynamic Service Discovery. When an application boots, the MCP Client negotiates capabilities directly with the MCP Server.
Phase 1: Service Discovery (tools/list)
Upon initialization, the MCP Client calls the server's tools/list RPC endpoint. The MCP Server inspects its registered functions and returns a structured JSON Schema document detailing every available tool:
{
"tools": [
{
"name": "createTask",
"description": "Creates a new scheduled task in the system",
"inputSchema": {
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "The title of the task to perform"
}
},
"required": ["title"]
}
}
]
}
Phase 2: Runtime Execution (tools/call)
- User Prompt: The user submits: "Add Go To Gym as my task."
- LLM Evaluation: The host passes the prompt along with the auto-discovered tool schemas to the LLM. The LLM determines that
createTaskmatches the intent and returns a JSON schema requesting tool execution. - MCP Client Dispatch: The MCP Client wraps this parameter map and issues a
tools/callrequest to the MCP Server over the/mcptransport. - Server Execution: The MCP Server runs the native code function deterministically and returns the output string (e.g.,
"Task Created: Go To Gym"). - Final Generation: The LLM consumes the raw execution response and translates it into a polished natural language response for the user.
6. MCP Transports: STDIO vs. Streamable HTTP
MCP dictates how messages are structured, but relies on standardized lower-level transports to move data between Client and Server.
7. Step-by-Step Practical Implementation: AI Task Scheduler
To illustrate MCP in practice, we examine a complete implementation using Spring AI and Java, building a decoupled AI Task Scheduler consisting of:
task-server(MCP Server on port8081) holding tool logic.task-client(MCP Client & Host App on port8080) containing the LLM connection and user REST controller.
Part A: The MCP Server (task-server)
1. Configuration (application.properties)
server.port=8081
spring.main.banner-mode=off
# MCP Server Identification
spring.ai.mcp.server.name=task-server
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.protocol=streamable-http
2. Deterministic Tools Definition (TaskTools.java)
The server defines concrete Java business logic, using @McpTool and @McpToolParam annotations to automatically expose methods to the protocol engine:
package com.coderarmy.taskserver;
import org.springframework.ai.mcp.annotation.McpTool;
import org.springframework.ai.mcp.annotation.McpToolParam;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class TaskTools {
private final List<String> tasks = new ArrayList<>();
@McpTool(name = "createTask", description = "Creates a new task in the task scheduler")
public String createTask(
@McpToolParam(description = "Title of the task to perform", required = true) String title) {
tasks.add(title);
return "Task Created: " + title;
}
@McpTool(name = "listTasks", description = "Returns the complete list of scheduled tasks")
public List<String> listTasks() {
return List.copyOf(tasks);
}
@McpTool(name = "completeTask", description = "Marks a specific task as completed and removes it from the list")
public String completeTask(
@McpToolParam(description = "Exact title of the task to mark completed", required = true) String title) {
boolean removed = tasks.remove(title);
if (removed) {
return "Task Completed: " + title;
} else {
return "Task Not Found: " + title;
}
}
}
Part B: The MCP Client & Host Application (task-client)
1. Configuration (application.properties)
server.port=8080
spring.ai.openai.api-key=${OPENAI_API_KEY}
# Transport points to the remote MCP Server URL
spring.ai.mcp.client.streamable-http-connection.task-server.url=http://localhost:8081
Note: When using Spring AI's Streamable HTTP auto-configuration, the client targets
http://localhost:8081/mcpby default under the hood.
2. Chat Service Layer (ChatService.java)
The host integrates auto-discovered tools directly into its ChatClient using the framework's ToolCallbackProvider:
package com.coderarmy.taskclient;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.mcp.SyncMcpToolCallbackProvider;
import org.springframework.stereotype.Service;
@Service
public class ChatService {
private final ChatClient chatClient;
public ChatService(ChatClient.Builder builder, SyncMcpToolCallbackProvider mcpTools) {
// Automatically injects discovered tools from the connected MCP Server
this.chatClient = builder
.defaultTools(mcpTools)
.build();
}
public String processUserPrompt(String message) {
return this.chatClient.prompt()
.user(message)
.call()
.content();
}
}
3. Controller Layer (ChatController.java)
package com.coderarmy.taskclient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ChatController {
private final ChatService chatService;
public ChatController(ChatService chatService) {
this.chatService = chatService;
}
@GetMapping("/ask")
public String ask(@RequestParam("message") String message) {
return chatService.processUserPrompt(message);
}
}
8. REST APIs vs. MCP & Security Realities
Why Not Use Standard REST APIs Directly?
- Schema Standardization: With standard REST APIs, developers must manually parse Swagger/OpenAPI specifications, map JSON structures to LLM prompt wrappers, and write custom logic to trigger endpoints. MCP standardizes capability negotiation into a runtime protocol (
tools/listandtools/call). - Zero Host Code Updates for New Tools: If developers add a 4th tool (
clearAllTasks) to thetask-server, any connected host application automatically discovers and utilizes it on its next run without requiring application re-compilation or added client adapters.
Host Security & Authorization Governance
A common misconception is that offloading tools to an external MCP Server strips security control away from the Host. In practice, security governance remains the strict responsibility of the Host application.
The Host receives proposed tool executions before they are sent to the MCP Client. If an unauthenticated user asks an LLM to invoke a destructive command, the Host intercepts the proposed JSON schema and aborts execution prior to making the network call to the MCP Server.
9. Summary and Key Takeaways
- Monolithic Coupling Limits Scale: Embedding tool logic directly inside individual AI microservices creates an integration bottleneck where every app requires manual adapters for every tool.
- Model Context Protocol (MCP): An open standardized protocol enabling decoupled AI Applications (MCP Clients) to communicate dynamically with external tool execution engines (MCP Servers).
- The 3 Core Server Pillars: MCP Servers expose Tools (executable deterministic actions), Resources (passive context/data streams), and Prompts (reusable instruction templates).
- Automated Discovery (
tools/list): MCP Clients dynamically query servers at runtime to extract structural JSON schemas detailing capability names, descriptions, parameter types, and validation rules. - Automated Execution (
tools/call): When an LLM requests a tool call, the MCP Client serializes arguments and dispatches a standard execution payload to the server's/mcpendpoint. - Transport Modes: Supports local low-latency sub-process execution via STDIO and decoupled enterprise network execution over Streamable HTTP (HTTP POST + SSE).
- Rest Stays Intact: MCP does not replace REST; rather, MCP Servers frequently act as smart execution wrappers around lower-level internal REST microservices and third-party APIs.
- Host-Side Governance: The Host Application retains complete authority over authentication, authorization, and rate-limiting. It intercepts tool call proposals generated by LLMs before passing them along to the MCP Server.