cloudsync-fte / src /mcp_server.py
Asma-yaseen's picture
feat: complete CloudSync Pro AI Customer Support FTE
07c1369
Raw
History Blame Contribute Delete
3.19 kB
"""
MCP Server — src/mcp_server.py
Stage 1 incubation: 5 tools mirroring production @function_tool signatures.
Run with Claude Code via stdio transport.
"""
from __future__ import annotations
from enum import Enum
from mcp.server import Server
from mcp.types import TextContent, Tool
from src.agent.prototype import (
_conversations,
detect_escalation,
process_message,
search_docs,
)
server = Server("customer-success-fte")
class Channel(str, Enum):
EMAIL = "email"
WHATSAPP = "whatsapp"
WEB_FORM = "web_form"
# ---------------------------------------------------------------------------
# Tools — 1:1 mapping to production @function_tool functions
# ---------------------------------------------------------------------------
@server.tool("search_knowledge_base")
async def search_knowledge_base(query: str, max_results: int = 5) -> str:
"""Search CloudSync Pro product documentation for relevant information.
Use this when the customer asks questions about product features,
how to use something, or needs technical information.
"""
results = search_docs(query)
return results if results else "No relevant documentation found."
@server.tool("create_ticket")
async def create_ticket(customer_id: str, issue: str,
priority: str = "medium", channel: str = "web_form") -> str:
"""Create a support ticket for tracking. ALWAYS call this first."""
import uuid
ticket_id = f"TICKET-{str(uuid.uuid4())[:8].upper()}"
_conversations.setdefault(customer_id, {
"messages": [], "sentiment_scores": [], "status": "open",
"original_channel": channel, "topics": [],
})
_conversations[customer_id]["ticket_id"] = ticket_id
return f"Ticket created: {ticket_id} | Channel: {channel} | Priority: {priority}"
@server.tool("get_customer_history")
async def get_customer_history(customer_id: str) -> str:
"""Get customer interaction history across ALL channels."""
conv = _conversations.get(customer_id)
if not conv:
return "No prior interaction history found for this customer."
messages = conv.get("messages", [])
if not messages:
return "No messages in history."
summary = [f"[{m['channel']}] {m['role']}: {m['content'][:100]}" for m in messages[-10:]]
return "\n".join(summary)
@server.tool("escalate_to_human")
async def escalate_to_human(ticket_id: str, reason: str, urgency: str = "normal") -> str:
"""Escalate conversation to human support.
Use when: pricing/refund inquiry, legal language, negative sentiment,
explicit human request, or knowledge not found after 2 searches.
"""
return f"Escalated {ticket_id} to human support. Reason: {reason} | Urgency: {urgency}"
@server.tool("send_response")
async def send_response(ticket_id: str, message: str, channel: str) -> str:
"""Send formatted response to customer via their channel.
Always call this LAST. Response will be formatted for the channel.
"""
# In incubation, just return confirmation
return f"Response sent via {channel} | Ticket: {ticket_id} | Status: delivered"
if __name__ == "__main__":
server.run()