Skip to content

feat: add SSE client demo example #598

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Python SDK Examples
# SSE Client Demo

This folders aims to provide simple examples of using the Python SDK. Please refer to the
[servers repository](https://github.com/modelcontextprotocol/servers)
for real-world servers.
## Description
This example demonstrates how to use the Model Context Protocol (MCP) Python SDK with Server-Sent Events (SSE) transport.

It sets up a local mock MCP server using Flask and connects a simple SSE client to receive streamed events.

## How to Run
Install required packages:
```bash
pip install flask requests

Start the server and client:
python mcp_server_client_demo.py
Alternatively, you can:

Run mock_mcp_server.py separately to start the server.

Then run sse_client_demo.py to connect the client.

You should see three streamed messages printed from the server to the client.
Binary file added examples/images/demo_screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
184 changes: 184 additions & 0 deletions examples/python mcp_server_client_demo.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"id": "8f0351de-69f9-40c3-9298-5d6321f33a1d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: flask in c:\\users\\vinis\\anaconda3\\lib\\site-packages (2.2.5)\n",
"Requirement already satisfied: requests in c:\\users\\vinis\\anaconda3\\lib\\site-packages (2.31.0)\n",
"Requirement already satisfied: Werkzeug>=2.2.2 in c:\\users\\vinis\\anaconda3\\lib\\site-packages (from flask) (2.2.3)\n",
"Requirement already satisfied: Jinja2>=3.0 in c:\\users\\vinis\\anaconda3\\lib\\site-packages (from flask) (3.1.3)\n",
"Requirement already satisfied: itsdangerous>=2.0 in c:\\users\\vinis\\anaconda3\\lib\\site-packages (from flask) (2.0.1)\n",
"Requirement already satisfied: click>=8.0 in c:\\users\\vinis\\anaconda3\\lib\\site-packages (from flask) (8.1.7)\n",
"Requirement already satisfied: charset-normalizer<4,>=2 in c:\\users\\vinis\\anaconda3\\lib\\site-packages (from requests) (2.0.4)\n",
"Requirement already satisfied: idna<4,>=2.5 in c:\\users\\vinis\\anaconda3\\lib\\site-packages (from requests) (3.4)\n",
"Requirement already satisfied: urllib3<3,>=1.21.1 in c:\\users\\vinis\\anaconda3\\lib\\site-packages (from requests) (2.0.7)\n",
"Requirement already satisfied: certifi>=2017.4.17 in c:\\users\\vinis\\anaconda3\\lib\\site-packages (from requests) (2024.8.30)\n",
"Requirement already satisfied: colorama in c:\\users\\vinis\\anaconda3\\lib\\site-packages (from click>=8.0->flask) (0.4.6)\n",
"Requirement already satisfied: MarkupSafe>=2.0 in c:\\users\\vinis\\anaconda3\\lib\\site-packages (from Jinja2>=3.0->flask) (2.1.3)\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"pip install flask requests\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "564f36a1-de43-4eb8-b0f4-b3e259f980c2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * Serving Flask app '__main__'\n",
" * Debug mode: off\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.\n",
" * Running on http://127.0.0.1:5000\n",
"Press CTRL+C to quit\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"✅ Server started at http://127.0.0.1:5000\n",
"\n",
"📥 Received request: {'tool': 'example_tool', 'input': {'message': 'Hello via SSE!'}}\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"127.0.0.1 - - [28/Apr/2025 17:31:39] \"POST /mcp HTTP/1.1\" 200 -\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"🚀 Connecting to SSE Server...\n",
"\n",
"data: {\"message\": \"Update 1\"}\n",
": keep-alive\n",
"data: {\"message\": \"Update 2\"}\n",
"\n",
"🎯 Successfully received all SSE events!\n"
]
}
],
"source": [
"import threading\n",
"import time\n",
"from flask import Flask, Response, request\n",
"import requests\n",
"\n",
"# --- 1. SETUP FLASK MOCK SERVER ---\n",
"\n",
"app = Flask(__name__)\n",
"\n",
"@app.route('/mcp', methods=['POST'])\n",
"def mcp_handler():\n",
" data = request.json\n",
" print(\"\\n📥 Received request:\", data)\n",
"\n",
" def stream():\n",
" for i in range(3):\n",
" time.sleep(1)\n",
" yield f\"data: {{\\\"message\\\": \\\"Update {i+1}\\\"}}\\n\\n\"\n",
" yield \": keep-alive\\n\\n\" # Force immediate flush\n",
"\n",
" return Response(stream(), mimetype='text/event-stream')\n",
"\n",
"@app.route('/')\n",
"def home():\n",
" return \"🏠 MCP Mock Server Running!\"\n",
"\n",
"def start_server():\n",
" app.run(port=5000)\n",
"\n",
"# --- 2. START SERVER IN BACKGROUND THREAD ---\n",
"server_thread = threading.Thread(target=start_server)\n",
"server_thread.daemon = True\n",
"server_thread.start()\n",
"\n",
"# --- 3. WAIT FOR SERVER TO BE READY ---\n",
"time.sleep(3) # Give Flask server a few seconds to boot\n",
"\n",
"print(\"\\n✅ Server started at http://127.0.0.1:5000\")\n",
"\n",
"# --- 4. CLIENT CODE: CONNECT TO SERVER ---\n",
"\n",
"try:\n",
" SERVER_URL = \"http://127.0.0.1:5000\"\n",
"\n",
" response = requests.post(f\"{SERVER_URL}/mcp\", stream=True, json={\n",
" \"tool\": \"example_tool\",\n",
" \"input\": {\"message\": \"Hello via SSE!\"}\n",
" })\n",
"\n",
" print(\"\\n🚀 Connecting to SSE Server...\\n\")\n",
" event_count = 0\n",
" for line in response.iter_lines():\n",
" if line:\n",
" decoded_line = line.decode('utf-8')\n",
" print(decoded_line)\n",
" event_count += 1\n",
" if event_count >= 3:\n",
" break # Stop after 3 messages\n",
"\n",
" print(\"\\n🎯 Successfully received all SSE events!\")\n",
"\n",
"except Exception as e:\n",
" print(\"❌ Connection failed:\", e)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9f9497e8-4354-44e7-b79a-105091ee479b",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading