initial mcp server setup

This commit is contained in:
OwusuBlessing
2025-09-11 23:13:58 +01:00
commit 20f96c0f30
141 changed files with 14444 additions and 0 deletions
+179
View File
@@ -0,0 +1,179 @@
#!/usr/bin/env python3
"""
MCP Template Demo Client
Demonstrates how to connect to and interact with MCP servers
"""
import asyncio
import sys
import os
# Add src to path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
from clients.client_factory import AIClientFactory
from transport.transport_manager import TransportManager
from core.types import TransportType
class MCPDemoClient:
"""Demo client for interacting with MCP servers"""
def __init__(self, ai_provider="openai", model="gpt-4o"):
self.ai_provider = ai_provider
self.model = model
self.ai_client = None
self.transport_manager = TransportManager()
async def initialize(self):
"""Initialize the demo client"""
print(f"🤖 Initializing {self.ai_provider} client with {self.model}...")
# Initialize AI client
self.ai_client = AIClientFactory.create_client(
provider=self.ai_provider,
model_name=self.model
)
await self.ai_client.initialize()
print("✅ AI client initialized")
async def demo_stdio_interaction(self):
"""Demo direct STDIO interaction with MCP server"""
print("\n🔧 Demo: Direct STDIO Interaction")
print("This demonstrates direct tool calls without AI involvement")
# For this demo, we'll simulate MCP server responses
# In a real scenario, you'd connect to an actual MCP server
print("📋 Available tools (simulated):")
print(" • add: Add two numbers together")
print(" • multiply: Multiply two numbers")
print(" • greet_user: Generate personalized greeting")
print(" • calculate_bmi: Calculate BMI and health category")
# Simulate some tool calls
print("\n🧮 Simulating tool calls:")
# Simulate add tool
print(" add(5, 3) = 8")
# Simulate greet tool
print(" greet_user('Alice', 'casual') = 'Hey Alice! Welcome aboard! 🎉'")
# Simulate BMI tool
print(" calculate_bmi(70, 1.75) = 'Your BMI is 22.9 (Normal weight)'")
async def demo_ai_with_tools(self):
"""Demo AI client with MCP tool integration"""
print("\n🧠 Demo: AI Client with MCP Tools")
print("This demonstrates how AI can use MCP tools to perform tasks")
# Sample queries that would benefit from MCP tools
queries = [
"What is 15 + 27?",
"Can you greet Sarah in a professional manner?",
"What's the BMI for someone who weighs 80kg and is 1.8m tall?",
"Calculate 12 * 8 for me"
]
print("💭 Sample queries for AI + MCP integration:")
for i, query in enumerate(queries, 1):
print(f" {i}. {query}")
print("\n📝 Note: To run actual AI+MCP integration, you need:")
print(" 1. A running MCP server (see demo_server.py)")
print(" 2. Proper API keys in environment variables")
print(" 3. Network connection for AI provider")
async def demo_transport_switching(self):
"""Demo transport layer switching capabilities"""
print("\n🔄 Demo: Transport Layer Switching")
print("The MCP template supports easy switching between transports:")
print("📡 SSE (Server-Sent Events):")
print(" • Best for: Web applications, remote connections")
print(" • Protocol: HTTP-based, real-time communication")
print(" • Use case: Browser-based MCP clients")
print("\n💻 STDIO (Standard Input/Output):")
print(" • Best for: Local applications, direct process communication")
print(" • Protocol: Direct pipes between processes")
print(" • Use case: CLI tools, local development")
print("\n🔧 Easy switching example:")
print(" # Switch to SSE transport")
print(" transport_manager.switch_transport('sse', host='localhost', port=8050)")
print(" ")
print(" # Switch to STDIO transport")
print(" transport_manager.switch_transport('stdio')")
async def demo_configuration(self):
"""Demo configuration management"""
print("\n⚙️ Demo: Configuration Management")
print("The MCP template supports flexible configuration:")
print("📄 Configuration sources (in order of priority):")
print(" 1. Environment variables")
print(" 2. JSON configuration files")
print(" 3. Default values")
print("\n🌍 Environment variables example:")
print(" MCP_SERVER_NAME=MyServer")
print(" MCP_TRANSPORT=sse")
print(" MCP_AI_PROVIDER=openai")
print(" OPENAI_API_KEY=your_key_here")
print("\n📋 JSON config example:")
print(" {")
print(' "server": {"name": "MyServer", "port": 8080},')
print(' "client": {"provider": "openai", "model": "gpt-4o"}')
print(" }")
async def run_demo(self):
"""Run the complete demo"""
print("🎭 MCP Template Demo Client")
print("=" * 50)
await self.initialize()
await self.demo_stdio_interaction()
await self.demo_ai_with_tools()
await self.demo_transport_switching()
await self.demo_configuration()
print("\n🎉 Demo completed!")
print("\n📚 Next steps:")
print(" • Run 'python examples/demo_server.py calculator' for a calculator server")
print(" • Run 'python examples/demo_server.py knowledge' for a knowledge base server")
print(" • Check the tests/ directory for comprehensive test examples")
print(" • Read docs in README.md for detailed usage instructions")
async def main():
"""Main demo function"""
if len(sys.argv) > 1:
ai_provider = sys.argv[1]
model = sys.argv[2] if len(sys.argv) > 2 else None
else:
ai_provider = "openai"
model = "gpt-4o"
print(f"🤖 Using AI provider: {ai_provider}")
if model:
print(f"🧠 Using model: {model}")
client = MCPDemoClient(ai_provider, model)
try:
await client.run_demo()
except KeyboardInterrupt:
print("\n👋 Demo interrupted by user")
except Exception as e:
print(f"❌ Error running demo: {e}")
print("💡 Make sure you have the required dependencies installed:")
print(" pip install openai aiohttp python-dotenv")
sys.exit(1)
if __name__ == "__main__":
asyncio.run(main())
+180
View File
@@ -0,0 +1,180 @@
#!/usr/bin/env python3
"""
MCP Template Demo Server
Demonstrates how to create and run different types of MCP servers
"""
import asyncio
import sys
import os
# Add src to path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
from server.server_factory import MCPServerFactory
async def demo_calculator_server():
"""Demo: Create and run a calculator server with SSE transport"""
print("🚀 Starting Calculator Server with SSE transport...")
server = MCPServerFactory.create_basic_calculator_server(
name="Demo Calculator Server",
transport="sse",
host="localhost",
port=8050
)
print("📊 Available tools:")
tools = await server.list_tools()
for tool in tools:
print(f"{tool['name']}: {tool['description']}")
print("🌐 Server will be available at: http://localhost:8050/sse")
print("💡 To test: Run 'python examples/demo_client.py' in another terminal")
await server.start()
async def demo_knowledge_base_server():
"""Demo: Create and run a knowledge base server with STDIO transport"""
print("🚀 Starting Knowledge Base Server with STDIO transport...")
# Custom knowledge base data
kb_data = {
"company_info": "TechCorp is a leading AI solutions provider founded in 2020.",
"mission": "Our mission is to democratize AI through open-source tools and education.",
"values": "Innovation, transparency, collaboration, and ethical AI development.",
"contact": "Email: info@techcorp.com | Phone: (555) 123-4567"
}
server = MCPServerFactory.create_knowledge_base_server(
name="Demo Knowledge Base Server",
transport="stdio",
kb_data=kb_data
)
print("📚 Available tools:")
tools = await server.list_tools()
for tool in tools:
print(f"{tool['name']}: {tool['description']}")
print("💻 Server running in STDIO mode")
print("💡 To test: Run 'python examples/demo_client.py' in another terminal")
await server.start()
async def demo_custom_server():
"""Demo: Create a custom server with mixed tools and resources"""
print("🚀 Starting Custom Server with mixed capabilities...")
# Custom tools
async def greet_user(name: str, style: str = "formal") -> str:
"""Generate a personalized greeting"""
if style == "casual":
return f"Hey {name}! Welcome aboard! 🎉"
elif style == "professional":
return f"Good day, {name}. Welcome to our platform."
else:
return f"Hello, {name}. Welcome!"
async def calculate_bmi(weight_kg: float, height_m: float) -> str:
"""Calculate BMI and provide health category"""
bmi = weight_kg / (height_m ** 2)
if bmi < 18.5:
category = "Underweight"
elif bmi < 25:
category = "Normal weight"
elif bmi < 30:
category = "Overweight"
else:
category = "Obese"
return f"Your BMI is {bmi:.1f} ({category})"
from core.types import MCPTool
tools = [
MCPTool(
name="greet_user",
description="Generate a personalized greeting with different styles",
input_schema={
"type": "object",
"properties": {
"name": {"type": "string", "description": "User's name"},
"style": {
"type": "string",
"enum": ["casual", "formal", "professional"],
"description": "Greeting style"
}
},
"required": ["name"]
},
handler=greet_user
),
MCPTool(
name="calculate_bmi",
description="Calculate BMI and provide health assessment",
input_schema={
"type": "object",
"properties": {
"weight_kg": {"type": "number", "description": "Weight in kilograms"},
"height_m": {"type": "number", "description": "Height in meters"}
},
"required": ["weight_kg", "height_m"]
},
handler=calculate_bmi
)
]
server = MCPServerFactory.create_server(
name="Demo Custom Server",
transport="stdio",
tools=tools
)
print("🛠️ Available tools:")
tools_list = await server.list_tools()
for tool in tools_list:
print(f"{tool['name']}: {tool['description']}")
print("💻 Server running in STDIO mode")
print("💡 To test: Run 'python examples/demo_client.py' in another terminal")
await server.start()
async def main():
"""Main demo function"""
if len(sys.argv) != 2:
print("Usage: python demo_server.py <server_type>")
print("Available server types:")
print(" calculator - Basic calculator with math operations")
print(" knowledge - Knowledge base with searchable content")
print(" custom - Custom server with mixed capabilities")
sys.exit(1)
server_type = sys.argv[1].lower()
try:
if server_type == "calculator":
await demo_calculator_server()
elif server_type == "knowledge":
await demo_knowledge_base_server()
elif server_type == "custom":
await demo_custom_server()
else:
print(f"Unknown server type: {server_type}")
sys.exit(1)
except KeyboardInterrupt:
print("\n👋 Server stopped by user")
except Exception as e:
print(f"❌ Error running server: {e}")
sys.exit(1)
if __name__ == "__main__":
asyncio.run(main())
+195
View File
@@ -0,0 +1,195 @@
#!/usr/bin/env python3
"""
Modular MCP Template Demo
Demonstrates the new modular architecture with separate tool, prompt, and resource folders
"""
import asyncio
import sys
import os
# Add src to path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
from server.server_factory import MCPServerFactory
from tools.tool_registry import ToolRegistry
from resources.data_resources import DataResources
from clients.client_factory import AIClientFactory
async def demo_modular_server_creation():
"""Demo: Creating servers using the modular architecture"""
print("🏗️ Modular MCP Server Creation Demo")
print("=" * 50)
# 1. Using Tool Registry for category-based tool selection
print("\n1️⃣ Tool Registry - Category-based Tool Selection")
registry = ToolRegistry()
print("Available tool categories:")
categories = registry.get_available_categories()
for category in categories:
tools = registry.get_tools_by_category(category)
print(f"{category}: {len(tools)} tools")
# Create a math-focused server
math_tools = registry.get_tools_by_category('math')
math_server = MCPServerFactory.create_server(
name="Math Server",
tools=math_tools,
transport="stdio"
)
print(f"\n✅ Created Math Server with {len(math_tools)} tools")
# 2. Using Server Factory with categories
print("\n2️⃣ Server Factory - Direct Category Selection")
dev_server = MCPServerFactory.create_server_from_categories(
name="Developer Server",
categories=["math", "text", "system"],
transport="stdio"
)
print("✅ Created Developer Server with math, text, and system tools")
# 3. Adding custom tools to registry
print("\n3️⃣ Custom Tools - Extending the Registry")
async def generate_password(length: int = 12) -> str:
"""Generate a secure random password"""
import secrets
import string
chars = string.ascii_letters + string.digits + "!@#$%^&*"
return ''.join(secrets.choice(chars) for _ in range(length))
from core.types import MCPTool
custom_tool = MCPTool(
name="generate_password",
description="Generate a secure random password",
input_schema={
"type": "object",
"properties": {
"length": {"type": "integer", "description": "Password length", "default": 12}
}
},
handler=generate_password,
)
registry.add_custom_tool(custom_tool)
print("✅ Added custom password generation tool")
# 4. Resources integration
print("\n4️⃣ Resources - Static Data Integration")
resources = DataResources.get_resources()
print(f"Available data resources: {len(resources)}")
for resource in resources:
print(f"{resource.name}: {resource.uri}")
# Create server with resources
resource_server = MCPServerFactory.create_server(
name="Resource Server",
tools=math_tools,
resources=resources,
transport="stdio"
)
print("✅ Created server with both tools and resources")
# 5. Test the servers
print("\n5️⃣ Server Testing")
print("Testing Math Server:")
# List tools
tools = await math_server.list_tools()
print(f" 📋 Available tools: {[t['name'] for t in tools]}")
# Test a tool
try:
result = await math_server.call_tool("add", {"a": 15, "b": 27})
print(f" 🧮 add(15, 27) = {result}")
except Exception as e:
print(f" ❌ Tool test failed: {e}")
# Test resources
print("\nTesting Resource Server:")
resources_list = await resource_server.list_resources()
print(f" 📄 Available resources: {len(resources_list)}")
if resources_list:
# Read a resource
resource_content = await resource_server.read_resource(resources_list[0]["uri"])
print(f" 📖 Read resource: {resources_list[0]['name']} ({len(resource_content)} chars)")
print("\n✅ Modular server creation demo completed!")
async def demo_ai_client_integration():
"""Demo: AI client integration with modular servers"""
print("\n🤖 AI Client Integration Demo")
print("=" * 40)
try:
# Note: This demo requires API keys to be set
print("Note: This demo requires OPENAI_API_KEY environment variable")
# Create AI client (would work with proper API key)
ai_client = AIClientFactory.create_openai_client(
model_name="gpt-4o",
api_key=os.getenv("OPENAI_API_KEY", "demo-key")
)
print("✅ Created OpenAI client (requires valid API key for actual use)")
# Create a server for AI integration
registry = ToolRegistry()
tools = registry.get_tools_by_categories(["math", "text"])
server = MCPServerFactory.create_server(
name="AI Integration Server",
tools=tools,
transport="stdio"
)
print(f"✅ Created server with {len(tools)} tools for AI integration")
print("\nExample AI queries that would work:")
print("'What is 25 * 18?'")
print("'Count the words in: The quick brown fox jumps over the lazy dog'")
print("'Convert this to uppercase: hello world'")
print("'Calculate BMI for 70kg and 1.75m height'")
except Exception as e:
print(f"❌ AI Client demo setup failed: {e}")
print("This is expected without proper API key configuration")
async def main():
"""Main demo function"""
print("🎭 Modular MCP Template Demo")
print("Demonstrating the new modular architecture with separate folders")
print("=" * 70)
try:
await demo_modular_server_creation()
await demo_ai_client_integration()
print("\n🎉 All demos completed successfully!")
print("\n📚 Key Features Demonstrated:")
print(" • 🔧 Modular tool organization by category")
print(" • 📄 Separate resource management")
print(" • 🏗️ Flexible server creation with tool registry")
print(" • 🤖 AI client abstraction and integration")
print(" • ⚙️ Easy configuration and customization")
print("\n🚀 Next Steps:")
print(" • Add your API keys to .env file")
print(" • Create custom tools in src/tools/")
print(" • Add custom resources in src/resources/")
print(" • Create custom prompts in src/prompts/")
print(" • Run the examples with: python examples/modular_demo.py")
except KeyboardInterrupt:
print("\n👋 Demo interrupted by user")
except Exception as e:
print(f"❌ Error running demo: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
asyncio.run(main())
+47
View File
@@ -0,0 +1,47 @@
"""
Modular Server Example
"""
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
from mcp_template.server.modular_server import ModularMCPServer
def main():
"""Run the modular server example"""
# Create a modular server
server = ModularMCPServer(
name="Modular Demo Server",
host="0.0.0.0",
port=8050,
stateless_http=True
)
# Print server info
print("Server Information:")
print("=" * 50)
info = server.get_server_info()
print(f"Name: {info['name']}")
print(f"Host: {info['host']}:{info['port']}")
print(f"Tools: {info['tools']['count']} ({', '.join(info['tools']['names'])})")
print(f"Prompts: {info['prompts']['count']} ({', '.join(info['prompts']['names'])})")
print(f"Resources: {info['resources']['count']} ({', '.join(info['resources']['uris'])})")
print("=" * 50)
# Choose transport
transport = "stdio" # Change to "sse" for HTTP transport
if transport == "stdio":
print("Running server with STDIO transport")
print("Connect using MCP client with stdio transport")
elif transport == "sse":
print(f"Running server with SSE transport on http://{server.host}:{server.port}")
print("Connect using MCP client with SSE transport")
# Run the server
server.run(transport=transport)
if __name__ == "__main__":
main()
+94
View File
@@ -0,0 +1,94 @@
#!/usr/bin/env python3
"""
Simple test script for LLM clients using config.py
"""
import asyncio
import sys
import os
# Add the src directory to the path so we can import our modules
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
from config import Config
from llm_client.client_factory import AIClientFactory
async def test_openai_client():
"""Test OpenAI client with config.py"""
print("Testing OpenAI client with config.py...")
if not Config.OPENAI_API_KEY:
print("⚠️ OPENAI_API_KEY not found in environment variables")
return
try:
# Create OpenAI client using the factory (API key automatically loaded from config)
client = AIClientFactory.create_openai_client(
model_name="gpt-3.5-turbo" # Use cheaper model for testing
)
# Test basic chat completion
messages = [{"role": "user", "content": "Hello! Please respond with just 'Hello from OpenAI!'"}]
response = await client.chat_completion(messages)
print("✅ OpenAI client test successful!")
print(f"Response: {response['choices'][0]['message']['content']}")
await client.cleanup()
except Exception as e:
print(f"❌ OpenAI client test failed: {e}")
async def test_client_factory():
"""Test client factory functionality"""
print("\nTesting client factory...")
# Test available providers
providers = AIClientFactory.get_available_providers()
print(f"Available providers: {providers}")
# Test provider validation
print(f"OpenAI valid: {AIClientFactory.validate_provider('openai')}")
print(f"Invalid provider valid: {AIClientFactory.validate_provider('invalid')}")
# Test creating client by provider (API key loaded automatically)
if Config.OPENAI_API_KEY:
try:
client = AIClientFactory.create_client("openai", "gpt-3.5-turbo")
print("✅ Client creation by provider successful!")
await client.cleanup()
except Exception as e:
print(f"❌ Client creation by provider failed: {e}")
else:
print("⚠️ Skipping client creation test - no OpenAI API key")
print("✅ Client factory test completed!")
async def test_config_loading():
"""Test config.py loading"""
print("\nTesting config.py loading...")
print(f"OpenAI API Key loaded: {'Yes' if Config.OPENAI_API_KEY else 'No'}")
print(f"Claude API Key loaded: {'Yes' if Config.CLAUDE_API_KEY else 'No'}")
print(f"Grok API Key loaded: {'Yes' if Config.GROK_API_KEY else 'No'}")
print("✅ Config loading test completed!")
async def main():
"""Run all tests"""
print("🚀 Starting LLM Client Tests with config.py")
print("=" * 50)
await test_config_loading()
await test_client_factory()
await test_openai_client()
print("\n" + "=" * 50)
print("🏁 All tests completed!")
if __name__ == "__main__":
asyncio.run(main())