44# This source code is licensed under the MIT license found in the
55# LICENSE file in the root directory of this source tree.
66
7- """Simplified demo server that combines health and SSE endpoints in one FastAPI app ."""
7+ """Simplified demo server with FastMCP integration ."""
88
9- import asyncio
109import logging
1110import os
1211import tempfile
13- import time
1412
1513import uvicorn
1614from dotenv import load_dotenv
17- from fastapi import FastAPI , Query
15+ from fastapi import FastAPI
1816from fastapi .middleware .cors import CORSMiddleware
19- from fastapi .responses import StreamingResponse
2017from fastmcp import FastMCP
2118
2219from api_tools import create_webcat_functions , setup_webcat_tools
23- from demo_utils import (
24- format_sse_message ,
25- get_server_info ,
26- handle_health_operation ,
27- handle_search_operation ,
28- )
2920from health import setup_health_endpoints
3021
3122# Load environment variables
4435logger .setLevel (getattr (logging , LOG_LEVEL ))
4536
4637
47- async def _generate_webcat_stream (
48- webcat_functions , operation : str , query : str , max_results : int
49- ):
50- """Generate SSE stream for WebCat operations.
51-
52- Args:
53- webcat_functions: Dictionary of WebCat functions
54- operation: Operation to perform
55- query: Search query
56- max_results: Maximum results
57-
58- Yields:
59- SSE formatted messages
60- """
61- try :
62- # Send connection message
63- yield format_sse_message (
64- "connection" ,
65- status = "connected" ,
66- message = "WebCat stream started" ,
67- operation = operation ,
68- )
69-
70- if operation == "search" and query :
71- search_func = webcat_functions .get ("search" )
72- if search_func :
73- async for msg in handle_search_operation (
74- search_func , query , max_results
75- ):
76- yield msg
77- else :
78- yield format_sse_message (
79- "error" , message = "Search function not available"
80- )
81-
82- elif operation == "health" :
83- health_func = webcat_functions .get ("health_check" )
84- async for msg in handle_health_operation (health_func ):
85- yield msg
86-
87- else :
88- # Just connection - send server info
89- yield format_sse_message ("data" , data = get_server_info ())
90- yield format_sse_message ("complete" , message = "Connection established" )
91-
92- # Keep alive with heartbeat
93- heartbeat_count = 0
94- while True :
95- await asyncio .sleep (30 )
96- heartbeat_count += 1
97- yield format_sse_message (
98- "heartbeat" , timestamp = time .time (), count = heartbeat_count
99- )
100-
101- except Exception as e :
102- logger .error (f"Error in SSE stream: { str (e )} " )
103- yield format_sse_message ("error" , message = str (e ))
104-
105-
10638def create_demo_app ():
10739 """Create a single FastAPI app with all endpoints."""
10840
10941 # Create FastAPI app with CORS middleware
11042 app = FastAPI (
111- title = "WebCat MCP Demo Server" ,
112- description = "WebCat server with FastMCP integration and SSE streaming demo " ,
113- version = "2.2.0 " ,
43+ title = "WebCat MCP Server" ,
44+ description = "WebCat server with FastMCP integration" ,
45+ version = "2.3.1 " ,
11446 )
11547
11648 app .add_middleware (
@@ -131,31 +63,10 @@ def create_demo_app():
13163 webcat_functions = create_webcat_functions ()
13264 setup_webcat_tools (mcp_server , webcat_functions )
13365
134- # Add custom SSE endpoint for demo
135- @app .get ("/sse" )
136- async def webcat_stream (
137- operation : str = Query (
138- "connect" , description = "Operation to perform: connect, search, health"
139- ),
140- query : str = Query ("" , description = "Search query for search operations" ),
141- max_results : int = Query (5 , description = "Maximum number of search results" ),
142- ):
143- """Stream WebCat functionality via SSE"""
144- return StreamingResponse (
145- _generate_webcat_stream (webcat_functions , operation , query , max_results ),
146- media_type = "text/event-stream" ,
147- headers = {
148- "Cache-Control" : "no-cache" ,
149- "Connection" : "keep-alive" ,
150- "Access-Control-Allow-Origin" : "*" ,
151- "Access-Control-Allow-Headers" : "*" ,
152- },
153- )
154-
155- # Mount FastMCP server as a sub-application (like Clima project)
66+ # Mount FastMCP server
15667 app .mount ("/mcp" , mcp_server .sse_app ())
15768
158- logger .info ("FastAPI app configured with SSE and FastMCP integration" )
69+ logger .info ("FastAPI app configured with FastMCP integration" )
15970 return app
16071
16172
@@ -166,20 +77,18 @@ def run_simple_demo(host: str = "0.0.0.0", port: int = 8000):
16677 app = create_demo_app ()
16778
16879 # Log endpoints
169- logger .info (f"WebCat Demo Server: http://{ host } :{ port } " )
170- logger .info (f"SSE Demo Endpoint: http://{ host } :{ port } /sse" )
80+ logger .info (f"WebCat MCP Server: http://{ host } :{ port } " )
17181 logger .info (f"FastMCP Endpoint: http://{ host } :{ port } /mcp" )
17282 logger .info (f"Health Check: http://{ host } :{ port } /health" )
17383 logger .info (f"Demo Client: http://{ host } :{ port } /demo" )
17484 logger .info (f"Server Status: http://{ host } :{ port } /status" )
17585
176- print ("\n 🐱 WebCat MCP Demo Server Starting..." )
86+ print ("\n 🐱 WebCat MCP Server Starting..." )
17787 print (f"📡 Server: http://{ host } :{ port } " )
178- print (f"🔗 SSE Demo: http://{ host } :{ port } /sse" )
179- print (f"🛠️ FastMCP: http://{ host } :{ port } /mcp" )
88+ print (f"🛠️ MCP Endpoint: http://{ host } :{ port } /mcp" )
18089 print (f"💗 Health: http://{ host } :{ port } /health" )
18190 print (f"🎨 Demo UI: http://{ host } :{ port } /demo" )
182- print (f"📊 Server Status: http://{ host } :{ port } /status" )
91+ print (f"📊 Status: http://{ host } :{ port } /status" )
18392 print ("\n ✨ Ready for connections!" )
18493
18594 # Run the server
0 commit comments