
Model Context Protocol (MCP)
I would like to make a point regarding the Model Context Protocol (MCP)…
While the Model Context Protocol (MCP) is currently discussed primarily in terms of tool integration, its context management capabilities represent an equally important — if not more fundamental — aspect of the protocol.
Context management in MCP addresses several critical challenges:
- Context window limitations, LLMs have finite context windows. MCP provides a standardised way to manage, prioritise, and compress conversation history to maximise the effective use of this limited space.
- Stateful conversations, by maintaining conversation state outside the model, MCP enables longer, more coherent interactions that persist beyond a single exchange.
- Memory management, MCP allows for selective retention of important information while discarding less relevant context, creating a more efficient “working memory” for the AI system.

Context sharing across sessions, with proper implementation, MCP can maintain context across different sessions or even different models, providing continuity for users.
Structured knowledge representation, rather than treating all context as a flat sequence of tokens, MCP enables more structured representations of knowledge within the context.
Retrieval augmentation, MCP provides a framework for dynamically retrieving relevant information from external sources and integrating it into the context.
The tool connection aspect gets more attention perhaps because it’s more visibly transformative — enabling LLMs to take actions.
But context management capabilities are equally revolutionary, as they address fundamental limitations in how LLMs interact with information over time.
In fact, effective context management is a prerequisite for meaningful tool use — the model needs to understand what tools were used previously, what information they returned, and how that information relates to the current state of the conversation.
MCP & Context
MCP Server
Below is a practical example of a MCP server and client managing context. You can run this MCP configuration locally on your MacBook…here is how…
Using a terminal window, create a file called mcp_context_server.py
and copy the code window below into the file and save it.
# mcp_context_server.py
import json
import uuid
import time
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import parse_qs, urlparse
# In-memory storage for context/sessions
context_store = {}
# Simple weather database
WEATHER_DATA = {
"New York": {"temperature": 72, "condition": "Sunny", "humidity": 65},
"London": {"temperature": 60, "condition": "Rainy", "humidity": 80},
"Tokyo": {"temperature": 75, "condition": "Partly Cloudy", "humidity": 70},
"Sydney": {"temperature": 80, "condition": "Clear", "humidity": 55},
"Paris": {"temperature": 68, "condition": "Cloudy", "humidity": 75}
}
class SessionContext:
"""Represents a user session with context data"""
def __init__(self, session_id):
self.session_id = session_id
self.created_at = time.time()
self.last_accessed = time.time()
self.data = {
"recent_searches": [],
"preferred_unit": "celsius",
"visits": 0
}
def update_access(self):
self.last_accessed = time.time()
self.data["visits"] += 1
def add_search(self, city):
# Keep only the 5 most recent searches
if city not in self.data["recent_searches"]:
self.data["recent_searches"].insert(0, city)
self.data["recent_searches"] = self.data["recent_searches"][:5]
def set_preference(self, key, value):
self.data[key] = value
def to_dict(self):
return {
"session_id": self.session_id,
"created_at": self.created_at,
"last_accessed": self.last_accessed,
"data": self.data
}
class MCPRequestHandler(BaseHTTPRequestHandler):
def _set_headers(self, content_type='application/json'):
self.send_response(200)
self.send_header('Content-type', content_type)
# Now set the cookie if needed
if hasattr(self, 'should_set_cookie') and self.should_set_cookie:
self.send_header('Set-Cookie', f'session_id={self.new_session_id}; Path=/')
self.end_headers()
def _get_or_create_session(self):
# Check if client sent a session cookie
session_id = None
if 'Cookie' in self.headers:
cookies = self.headers['Cookie'].split('; ')
for cookie in cookies:
if cookie.startswith('session_id='):
session_id = cookie.split('=')[1]
break
# Create new session if none exists or if it's expired
if not session_id or session_id not in context_store:
session_id = str(uuid.uuid4())
context_store[session_id] = SessionContext(session_id)
# Don't set the cookie header here - it's too early!
self.should_set_cookie = True # Flag to set cookie when sending headers
self.new_session_id = session_id
else:
self.should_set_cookie = False
# Update last accessed time
context_store[session_id].update_access()
return context_store[session_id]
def _clean_expired_sessions(self, max_age=3600): # 1 hour
"""Remove sessions that haven't been used for max_age seconds"""
current_time = time.time()
expired_keys = []
for key, session in context_store.items():
if current_time - session.last_accessed > max_age:
expired_keys.append(key)
for key in expired_keys:
del context_store[key]
def do_GET(self):
self._clean_expired_sessions()
parsed_url = urlparse(self.path)
path = parsed_url.path
query = parse_qs(parsed_url.query)
session = self._get_or_create_session()
# Get user's temperature preference
unit = query.get('unit', [session.data.get('preferred_unit')])[0]
# Set temperature unit preference if specified
if 'unit' in query:
session.set_preference('preferred_unit', unit)
if path == '/api/weather':
self._set_headers()
# Get city from query parameters
if 'city' in query:
city = query['city'][0]
session.add_search(city)
if city in WEATHER_DATA:
data = WEATHER_DATA[city].copy()
# Convert temperature based on user preference
if unit == 'fahrenheit' and 'temperature' in data:
# Data is stored in Fahrenheit
pass
elif unit == 'celsius' and 'temperature' in data:
# Convert Fahrenheit to Celsius
data['temperature'] = round((data['temperature'] - 32) * 5/9, 1)
response = {
"city": city,
"weather": data,
"unit": unit
}
else:
response = {"error": f"City '{city}' not found"}
else:
response = {"cities": list(WEATHER_DATA.keys())}
# Include session context data in response
response["context"] = session.to_dict()
self.wfile.write(json.dumps(response).encode())
elif path == '/api/context':
self._set_headers()
response = {"context": session.to_dict()}
self.wfile.write(json.dumps(response).encode())
else:
# Serve a simple HTML interface for manual testing
self._set_headers('text/html')
html = f"""
<!DOCTYPE html>
<html>
<head>
<title>MCP Weather Service</title>
<style>
body {{ font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }}
.card {{ border: 1px solid #ddd; border-radius: 8px; padding: 15px; margin-bottom: 15px; }}
.recent {{ color: #666; font-size: 0.9em; }}
</style>
</head>
<body>
<h1>MCP Weather Service</h1>
<div class="card">
<h2>Your Session</h2>
<p>Session ID: {session.session_id}</p>
<p>Number of visits: {session.data["visits"]}</p>
<p>Temperature unit preference: {session.data["preferred_unit"]}</p>
<form>
<label>
Change temperature unit:
<select name="unit" onchange="this.form.submit()">
<option value="celsius" {"selected" if session.data["preferred_unit"] == "celsius" else ""}>Celsius</option>
<option value="fahrenheit" {"selected" if session.data["preferred_unit"] == "fahrenheit" else ""}>Fahrenheit</option>
</select>
</label>
</form>
</div>
<div class="card">
<h2>Get Weather</h2>
<form action="/" method="get">
<select name="city">
{' '.join([f'<option value="{city}">{city}</option>' for city in WEATHER_DATA.keys()])}
</select>
<button type="submit">Get Weather</button>
</form>
</div>
{"<div class='card'><h2>Your Recent Searches</h2><ul>" +
''.join([f'<li><a href="/?city={city}">{city}</a></li>' for city in session.data["recent_searches"]]) +
"</ul></div>" if session.data["recent_searches"] else ""}
{"<div class='card'><h2>Weather Result</h2>" +
f"<h3>Weather in {query['city'][0]}</h3>" +
f"<p>Temperature: {WEATHER_DATA[query['city'][0]]['temperature']}°F " +
f"({round((WEATHER_DATA[query['city'][0]]['temperature'] - 32) * 5/9, 1)}°C)</p>" +
f"<p>Condition: {WEATHER_DATA[query['city'][0]]['condition']}</p>" +
f"<p>Humidity: {WEATHER_DATA[query['city'][0]]['humidity']}%</p></div>"
if 'city' in query and query['city'][0] in WEATHER_DATA else ""}
</body>
</html>
"""
self.wfile.write(html.encode())
def do_POST(self):
self._clean_expired_sessions()
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
request_json = json.loads(post_data.decode('utf-8'))
session = self._get_or_create_session()
if self.path == '/api/preferences':
# Update user preferences
for key, value in request_json.items():
session.set_preference(key, value)
self._set_headers()
response = {
"status": "success",
"message": "Preferences updated",
"context": session.to_dict()
}
self.wfile.write(json.dumps(response).encode())
else:
self.send_response(404)
self.end_headers()
self.wfile.write(json.dumps({"error": "Not found"}).encode())
def run_server(port=8000):
server_address = ('', port)
httpd = HTTPServer(server_address, MCPRequestHandler)
print(f"Starting MCP context-aware server on port {port}...")
httpd.serve_forever()
if __name__ == "__main__":
run_server()
Then run the following command to run the server: python3 mcp_context_server.py
from your terminal window.
Below is a screenshot of the terminal window when the server is running…the fact that the command prompt is not returning, but is show as below, indicates that the server is running.
Remember, this is all running locally on your machine.

MCP Client
Create a file called mcp_context_client.py
, the MCP Client will run using this code.
Copy the code below into the file…
# mcp_context_client.py
import json
import requests
import sys
import os
class WeatherClient:
def __init__(self, server_url="http://localhost:8000"):
self.server_url = server_url
self.session = requests.Session() # Use a session to maintain cookies
self.context = None
# Try to load saved session ID from file
self.session_file = "session.json"
if os.path.exists(self.session_file):
try:
with open(self.session_file, "r") as f:
saved_data = json.load(f)
if "session_id" in saved_data:
self.session.cookies.set("session_id", saved_data["session_id"])
if "context" in saved_data:
self.context = saved_data["context"]
print("Restored previous session")
except Exception as e:
print(f"Error loading session: {e}")
def save_session(self):
"""Save the session ID and context to a file"""
if "session_id" in self.session.cookies:
session_data = {
"session_id": self.session.cookies.get("session_id"),
"context": self.context
}
with open(self.session_file, "w") as f:
json.dump(session_data, f)
def get_cities(self):
"""Get list of available cities"""
response = self.session.get(f"{self.server_url}/api/weather")
data = response.json()
# Update context if available
if "context" in data:
self.context = data["context"]
self.save_session()
return data["cities"]
def get_weather(self, city, unit=None):
"""Get weather for a specific city"""
url = f"{self.server_url}/api/weather?city={city}"
# Use stored preference or provided unit
if unit:
url += f"&unit={unit}"
elif self.context and "data" in self.context and "preferred_unit" in self.context["data"]:
url += f"&unit={self.context['data']['preferred_unit']}"
response = self.session.get(url)
data = response.json()
# Update context if available
if "context" in data:
self.context = data["context"]
self.save_session()
return data
def update_preferences(self, preferences):
"""Update user preferences"""
response = self.session.post(
f"{self.server_url}/api/preferences",
json=preferences
)
data = response.json()
# Update context if available
if "context" in data:
self.context = data["context"]
self.save_session()
return data
def get_context(self):
"""Get current session context"""
if not self.context:
response = self.session.get(f"{self.server_url}/api/context")
data = response.json()
self.context = data["context"]
self.save_session()
return self.context
def display_weather(self, weather_data):
"""Display weather information nicely"""
if "error" in weather_data:
print(f"\nError: {weather_data['error']}")
return
city = weather_data["city"]
weather = weather_data["weather"]
unit = weather_data.get("unit", "celsius")
unit_symbol = "°F" if unit == "fahrenheit" else "°C"
print(f"\nWeather for {city}:")
print(f"Temperature: {weather['temperature']}{unit_symbol}")
print(f"Condition: {weather['condition']}")
print(f"Humidity: {weather['humidity']}%")
def display_context(self):
"""Display current context information"""
context = self.get_context()
if not context:
print("\nNo context available")
return
print("\n=== Your Session Context ===")
print(f"Session ID: {context['session_id']}")
print(f"Created: {context['created_at']}")
print(f"Last accessed: {context['last_accessed']}")
print("\nPreferences:")
print(f"Temperature unit: {context['data']['preferred_unit']}")
print(f"Total visits: {context['data']['visits']}")
if context['data']['recent_searches']:
print("\nRecent searches:")
for i, city in enumerate(context['data']['recent_searches'], 1):
print(f"{i}. {city}")
def run_client():
client = WeatherClient()
while True:
print("\n--- MCP Weather Client with Context ---")
print("1. List all cities")
print("2. Get weather for a city")
print("3. Change temperature unit preference")
print("4. View session context")
print("5. Exit")
choice = input("Enter your choice (1-5): ")
if choice == "1":
cities = client.get_cities()
print("\nAvailable cities:")
for city in cities:
print(f"- {city}")
elif choice == "2":
city = input("Enter city name: ")
try:
weather_data = client.get_weather(city)
client.display_weather(weather_data)
except Exception as e:
print(f"Error getting weather: {e}")
elif choice == "3":
unit = input("Choose temperature unit (celsius/fahrenheit): ").lower()
if unit in ["celsius", "fahrenheit"]:
try:
result = client.update_preferences({"preferred_unit": unit})
print(f"Temperature unit updated to {unit}")
except Exception as e:
print(f"Error updating preferences: {e}")
else:
print("Invalid unit. Please enter 'celsius' or 'fahrenheit'.")
elif choice == "4":
client.display_context()
elif choice == "5":
print("Exiting weather client.")
sys.exit(0)
else:
print("Invalid choice. Please try again.")
if __name__ == "__main__":
run_client()
Now run the server with the command below from the command prompt in the terminal window:
python3 mcp_context_client.py
Below is a screen shot of the the UI, which you can interact with via the command line, which also shows how context is managed.

Key Context Management Features
- The server creates a unique session ID for each client
- Sessions are maintained using cookies
- Context data persists across multiple requests
Context Data Elements:
- User preferences (temperature unit: Celsius/Fahrenheit)
- Usage history (recent searches)
- Session statistics (visit count, creation time)
This demonstrates how context can be managed in a client-server MCP architecture, maintaining user preferences and history across multiple interactions.

Chief Evangelist @ Kore.ai | I’m passionate about exploring the intersection of AI and language. From Language Models, AI Agents to Agentic Applications, Development Frameworks & Data-Centric Productivity Tools, I share insights and ideas on how these technologies are shaping the future.
