""" šŸš€ MissionControlMCP - Gradio Web Interface Beautiful GUI demo for all 8 tools! Run: python demo_gui.py Then share the public URL on LinkedIn! """ import gradio as gr import sys import os import json import base64 from io import BytesIO from PIL import Image # Setup paths SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.append(SCRIPT_DIR) EXAMPLES_DIR = os.path.join(SCRIPT_DIR, "examples") # Import tools from tools.pdf_reader import read_pdf from tools.text_extractor import extract_text from tools.web_fetcher import fetch_web_content from tools.rag_search import search_documents from tools.data_visualizer import visualize_data from tools.file_converter import convert_file from tools.email_intent_classifier import classify_email_intent from tools.kpi_generator import generate_kpis # ============================================================================ # TOOL FUNCTIONS # ============================================================================ def tool_pdf_reader(pdf_file): """PDF Reader tool""" try: if pdf_file is None: return "āŒ Please upload a PDF file!", None result = read_pdf(pdf_file.name) output = f"""āœ… **PDF Analysis Complete!** šŸ“„ **Metadata:** - Pages: {result['pages']} - Characters: {len(result['text']):,} - Author: {result['metadata'].get('author', 'N/A')} - Title: {result['metadata'].get('title', 'N/A')} šŸ“ **Extracted Text (first 1000 chars):** {result['text'][:1000]}... """ # Extract keywords keywords = extract_text(result['text'], operation="keywords") output += f"\n\nšŸ”‘ **Keywords:** {keywords['result']}" return output, None except Exception as e: return f"āŒ Error: {str(e)}", None def tool_text_extractor(text, operation, max_length): """Text Extractor tool""" try: if not text.strip(): return "āŒ Please enter some text!" result = extract_text(text, operation=operation, max_length=max_length) output = f"""āœ… **Text Processing Complete!** šŸ“Š **Operation:** {operation.upper()} šŸ“ **Word Count:** {result['word_count']} šŸ“ **Result:** {result['result']} """ return output except Exception as e: return f"āŒ Error: {str(e)}" def tool_web_fetcher(url): """Web Fetcher tool""" try: if not url.strip(): return "āŒ Please enter a URL!" result = fetch_web_content(url) if result['status_code'] == 999: return f"""āš ļø **Status 999 - Bot Detection** The website is blocking automated requests. This is common for LinkedIn, Facebook, etc. Try a different website!""" output = f"""āœ… **Website Fetched Successfully!** 🌐 **URL:** {url} šŸ“Š **Status:** {result['status_code']} šŸ“„ **Title:** {result.get('title', 'N/A')} šŸ“ **Content Length:** {len(result['content']):,} characters šŸ”— **Links Found:** {len(result.get('links', []))} šŸ“ **Content Preview (first 1000 chars):** {result['content'][:1000]}... """ # Extract keywords if len(result['content']) > 50: keywords = extract_text(result['content'], operation="keywords") output += f"\n\nšŸ”‘ **Keywords:** {keywords['result']}" return output except Exception as e: return f"āŒ Error: {str(e)}" def tool_rag_search(query): """RAG Search tool""" try: if not query.strip(): return "āŒ Please enter a search query!" # Load sample documents docs_file = os.path.join(EXAMPLES_DIR, "sample_documents.txt") with open(docs_file, "r", encoding="utf-8") as f: content = f.read() documents = [doc.strip() for doc in content.split("##") if doc.strip()] result = search_documents(query, documents, top_k=3) output = f"""āœ… **Search Complete!** šŸ” **Query:** "{query}" šŸ“š **Documents Searched:** {len(documents)} šŸ“Š **Results Found:** {len(result['results'])} šŸŽÆ **Top Results:** """ for i, res in enumerate(result['results'], 1): preview = res['document'][:200].replace('\n', ' ') output += f""" **Result {i}** (Score: {res['score']:.4f}) {preview}... """ return output except Exception as e: return f"āŒ Error: {str(e)}" def tool_data_visualizer(csv_data, chart_type, x_col, y_col, title): """Data Visualizer tool""" try: if not csv_data.strip(): return "āŒ Please enter CSV data!", None result = visualize_data( data=csv_data, chart_type=chart_type, x_column=x_col, y_column=y_col, title=title ) # Convert base64 to image img_data = base64.b64decode(result['image_base64']) image = Image.open(BytesIO(img_data)) output = f"""āœ… **Chart Created!** šŸ“Š **Chart Type:** {chart_type.upper()} šŸ“ **Dimensions:** {result['dimensions']} šŸ“ˆ **Title:** {title} """ return output, image except Exception as e: return f"āŒ Error: {str(e)}", None def tool_email_classifier(email_text): """Email Intent Classifier tool""" try: if not email_text.strip(): return "āŒ Please enter email text!" result = classify_email_intent(email_text) output = f"""āœ… **Email Classified!** šŸŽÆ **Primary Intent:** {result['intent'].upper()} šŸ“Š **Confidence:** {result['confidence']:.2%} šŸ’¬ **Explanation:** {result['explanation']} """ if result['secondary_intents']: output += "\n\nšŸ“‹ **Secondary Intents:**\n" for intent in result['secondary_intents'][:3]: output += f"- {intent['intent']}: {intent['confidence']:.2%}\n" return output except Exception as e: return f"āŒ Error: {str(e)}" def tool_kpi_generator(business_json, metrics): """KPI Generator tool""" try: if not business_json.strip(): return "āŒ Please enter business data!" # Validate JSON json.loads(business_json) result = generate_kpis(business_json, metrics=metrics) output = f"""āœ… **KPIs Generated!** šŸ“Š **Total KPIs Calculated:** {len(result['kpis'])} šŸ“ˆ **Key Metrics:** """ # Display top 15 KPIs for i, (name, value) in enumerate(list(result['kpis'].items())[:15], 1): # Format based on metric type if 'percent' in name or 'rate' in name or 'margin' in name: formatted = f"{value:.1f}%" elif 'revenue' in name or 'profit' in name or 'cost' in name: formatted = f"${value:,.0f}" else: formatted = f"{value:,.2f}" display_name = name.replace('_', ' ').title() output += f"{i}. **{display_name}:** {formatted}\n" output += f"\n\nšŸ“ **Executive Summary:**\n{result['summary']}" if result.get('trends'): output += "\n\nšŸ“Š **Key Trends:**\n" for trend in result['trends'][:5]: output += f"- {trend}\n" return output except json.JSONDecodeError: return "āŒ Invalid JSON format! Please check your data." except Exception as e: return f"āŒ Error: {str(e)}" # ============================================================================ # LOAD SAMPLE DATA # ============================================================================ def load_sample_csv(): csv_file = os.path.join(EXAMPLES_DIR, "business_data.csv") with open(csv_file, "r") as f: return f.read() def load_sample_email(): email_file = os.path.join(EXAMPLES_DIR, "sample_email_complaint.txt") with open(email_file, "r", encoding="utf-8") as f: return f.read() def load_sample_json(): return """{ "revenue": 5500000, "costs": 3400000, "customers": 2700, "current_revenue": 5500000, "previous_revenue": 5400000, "current_customers": 2700, "previous_customers": 2650, "employees": 50, "marketing_spend": 500000, "sales": 5500000, "cogs": 2000000 }""" # ============================================================================ # GRADIO INTERFACE # ============================================================================ # Custom CSS for beautiful UI custom_css = """ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); /* Global mobile-first settings */ * { box-sizing: border-box !important; } html, body { overflow-x: hidden !important; width: 100% !important; } .gradio-container { font-family: 'Inter', sans-serif !important; max-width: 1400px !important; margin: 0 auto !important; padding: 10px !important; width: 100% !important; overflow-x: hidden !important; } /* Header styling */ .gradio-container h1 { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-size: 3em !important; font-weight: 700 !important; text-align: center; margin-bottom: 0.5em; } /* Mobile responsive header */ @media (max-width: 768px) { .gradio-container h1 { font-size: 2em !important; } .gradio-container h3 { font-size: 1.2em !important; } .gradio-container p { font-size: 0.9em !important; } } /* Tab styling */ .tab-nav { border-radius: 12px !important; background: linear-gradient(to right, #f8f9fa, #e9ecef) !important; padding: 8px !important; margin-bottom: 20px !important; } button.selected { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; color: white !important; border-radius: 8px !important; font-weight: 600 !important; box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4) !important; } /* Mobile tab styling */ @media (max-width: 768px) { .tab-nav button { font-size: 0.85em !important; padding: 8px 12px !important; } } /* Button styling */ .primary-btn { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; border: none !important; color: white !important; font-weight: 600 !important; border-radius: 10px !important; padding: 12px 24px !important; font-size: 16px !important; transition: all 0.3s ease !important; box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4) !important; } .primary-btn:hover { transform: translateY(-2px) !important; box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6) !important; } /* Mobile button styling */ @media (max-width: 768px) { .primary-btn { width: 100% !important; padding: 14px 20px !important; font-size: 15px !important; } } /* Input fields */ textarea, input[type="text"] { border-radius: 10px !important; border: 2px solid #e9ecef !important; padding: 12px !important; font-size: 15px !important; transition: border-color 0.3s ease !important; } textarea:focus, input[type="text"]:focus { border-color: #667eea !important; box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important; } /* Mobile input fields */ @media (max-width: 768px) { textarea, input[type="text"] { font-size: 16px !important; padding: 10px !important; } } /* Output boxes */ .output-class { background: linear-gradient(to bottom, #ffffff, #f8f9fa) !important; border-radius: 12px !important; padding: 20px !important; border: 2px solid #e9ecef !important; } /* Cards and containers */ .gr-box { border-radius: 12px !important; border: 1px solid #e9ecef !important; box-shadow: 0 2px 8px rgba(0,0,0,0.05) !important; } /* Labels */ label { font-weight: 600 !important; color: #495057 !important; font-size: 14px !important; margin-bottom: 8px !important; } /* Examples */ .gr-samples-table { border-radius: 10px !important; overflow: hidden !important; } /* Footer */ .footer { text-align: center; padding: 30px; background: linear-gradient(to right, #f8f9fa, #e9ecef); border-radius: 12px; margin-top: 30px; } /* Image display */ .gr-image { border-radius: 12px !important; border: 2px solid #e9ecef !important; box-shadow: 0 4px 15px rgba(0,0,0,0.1) !important; } /* Radio buttons and checkboxes */ .gr-radio, .gr-checkbox { padding: 10px !important; border-radius: 8px !important; } /* File upload */ .gr-file { border: 2px dashed #667eea !important; border-radius: 12px !important; background: linear-gradient(to bottom, #ffffff, #f8f9fa) !important; padding: 30px !important; } .gr-file:hover { border-color: #764ba2 !important; background: #f8f9fa !important; } /* Mobile responsive layout */ @media (max-width: 768px) { .gr-row { flex-direction: column !important; gap: 15px !important; } .gr-column { width: 100% !important; max-width: 100% !important; min-width: 0 !important; flex: 0 0 100% !important; } .gr-file { padding: 20px !important; } /* Stack columns vertically on mobile */ .gradio-container .gr-form { display: flex !important; flex-direction: column !important; } /* Prevent text overflow */ .gradio-container { word-wrap: break-word !important; overflow-wrap: break-word !important; } /* Better spacing on mobile */ .gr-box { margin: 10px 0 !important; } /* Tabs scrollable on mobile */ .tab-nav { overflow-x: auto !important; -webkit-overflow-scrolling: touch !important; white-space: nowrap !important; } } /* Improve touch targets for mobile */ @media (max-width: 768px) { button, a, input, textarea, select { min-height: 44px !important; -webkit-tap-highlight-color: rgba(102, 126, 234, 0.2) !important; } label { font-size: 15px !important; margin-bottom: 10px !important; } /* Better radio and checkbox sizing */ .gr-radio label, .gr-checkbox label { padding: 12px !important; min-height: 44px !important; display: flex !important; align-items: center !important; } /* Mobile-friendly sliders */ input[type="range"] { height: 44px !important; padding: 10px 0 !important; } /* Examples section */ .gr-samples-table { overflow-x: auto !important; -webkit-overflow-scrolling: touch !important; } } /* Footer responsive */ @media (max-width: 768px) { .footer { padding: 20px 10px !important; } .footer h2 { font-size: 1.5em !important; } .footer p { font-size: 0.9em !important; } } /* Smaller screens (phones in portrait) */ @media (max-width: 480px) { .gradio-container h1 { font-size: 1.5em !important; } .tab-nav button { font-size: 0.75em !important; padding: 6px 10px !important; } .primary-btn { font-size: 14px !important; padding: 12px 16px !important; } /* Reduce line count for better mobile UX */ textarea { min-height: 100px !important; } } /* Landscape mobile */ @media (max-width: 768px) and (orientation: landscape) { .gradio-container h1 { font-size: 1.8em !important; margin-bottom: 0.3em !important; } } """ # Create Gradio interface with gr.Blocks(theme=gr.themes.Soft(), css=custom_css, title="MissionControlMCP Demo") as demo: # Add viewport meta tag for proper mobile rendering gr.HTML("""""") gr.Markdown("# šŸš€ MissionControlMCP") gr.Markdown("### Enterprise Automation Tools - Powered by AI") gr.HTML("""

✨ Try all 8 powerful tools in your browser - No installation needed! ✨

Built for HuggingFace Gradio Hackathon | Claude MCP Integration

""") with gr.Tabs(): # ====== TAB 1: PDF READER ====== with gr.Tab("šŸ“„ PDF Reader"): gr.Markdown(""" ### šŸ“„ Extract Text and Metadata from PDF Documents Upload any PDF file to extract its content, metadata, and keywords instantly. """) with gr.Row(): with gr.Column(scale=1): pdf_input = gr.File( label="šŸ“Ž Upload PDF File", file_types=[".pdf"], elem_classes=["file-upload"] ) pdf_btn = gr.Button( "šŸ” Extract Text from PDF", variant="primary", size="lg", elem_classes=["primary-btn"] ) gr.Markdown(""" **šŸ’” Tips:** - Supports multi-page PDFs - Extracts metadata (author, title) - Automatically generates keywords **āš ļø Limitations:** - Max file size: 200 MB (HuggingFace limit) - Text-based PDFs only (scanned images need OCR) - Processing time: ~2-5 seconds per page """) with gr.Column(scale=2): pdf_output = gr.Textbox( label="šŸ“Š Extraction Results", lines=20, elem_classes=["output-class"] ) pdf_img = gr.Image(label="Preview", visible=False) pdf_btn.click(tool_pdf_reader, inputs=[pdf_input], outputs=[pdf_output, pdf_img]) gr.Markdown("*šŸ’” Try uploading your resume, research paper, or any PDF document!*") # ====== TAB 2: TEXT EXTRACTOR ====== with gr.Tab("šŸ“ Text Extractor"): gr.Markdown(""" ### šŸ“ AI-Powered Text Analysis Extract keywords, generate summaries, clean text, or split into chunks. **āš ļø Limitations:** - Max input: ~50,000 characters - Summary length: 100-1000 characters (adjustable) - Processing time: ~1-3 seconds """) with gr.Row(): with gr.Column(scale=1): text_input = gr.Textbox( label="āœļø Enter Your Text", lines=10, placeholder="Paste any text here - articles, reports, emails, etc...", elem_classes=["input-field"] ) text_operation = gr.Radio( ["keywords", "summarize", "clean", "chunk"], label="šŸ› ļø Select Operation", value="keywords", info="Choose what to do with your text" ) text_length = gr.Slider( 100, 1000, 300, label="šŸ“ Max Length (for summarize/chunk)", info="Adjust output length" ) text_btn = gr.Button( "✨ Process Text", variant="primary", size="lg", elem_classes=["primary-btn"] ) with gr.Column(scale=2): text_output = gr.Textbox( label="šŸ“Š Processing Results", lines=20, elem_classes=["output-class"] ) text_btn.click( tool_text_extractor, inputs=[text_input, text_operation, text_length], outputs=[text_output] ) gr.Examples([ ["Artificial Intelligence is transforming businesses worldwide. Companies are leveraging AI for automation, decision-making, and customer service. Machine learning models can now process vast amounts of data and provide actionable insights.", "keywords", 300], ["Climate change is one of the most pressing challenges of our time. Rising temperatures, extreme weather events, and environmental degradation require urgent action.", "summarize", 300] ], inputs=[text_input, text_operation, text_length], label="šŸ“š Try These Examples") # ====== TAB 3: WEB FETCHER ====== with gr.Tab("🌐 Web Fetcher"): gr.Markdown(""" ### 🌐 Scrape and Analyze Web Content Fetch content from any website, extract clean text, and analyze it. **āš ļø Limitations:** - Timeout: 30 seconds per request - Some sites block automated access (LinkedIn, Facebook, etc.) - JavaScript-heavy sites may not render fully - Rate limits apply to prevent abuse """) with gr.Row(): with gr.Column(scale=1): web_input = gr.Textbox( label="šŸ”— Website URL", placeholder="https://example.com", value="https://example.com", info="Enter any public website URL" ) web_btn = gr.Button( "🌐 Fetch Website", variant="primary", size="lg", elem_classes=["primary-btn"] ) gr.Markdown(""" **šŸ’” Tips:** - Works with most public websites - Extracts clean text (no HTML) - Finds all page links - Some sites block bots (e.g., LinkedIn) """) with gr.Column(scale=2): web_output = gr.Textbox( label="šŸ“Š Website Content", lines=20, elem_classes=["output-class"] ) web_btn.click(tool_web_fetcher, inputs=[web_input], outputs=[web_output]) gr.Examples([ ["https://example.com"], ["https://python.org"], ["https://github.com"] ], inputs=[web_input], label="šŸ“š Try These Examples") # ====== TAB 4: RAG SEARCH ====== with gr.Tab("šŸ” RAG Search"): gr.Markdown(""" ### šŸ” Semantic Document Search with AI Search through documents using AI-powered semantic understanding (RAG - Retrieval Augmented Generation). **āš ļø Limitations:** - Currently searches 5 pre-loaded sample documents - First search: ~5-10 seconds (loads AI model) - Subsequent searches: ~1-2 seconds - Max 1000 documents supported """) with gr.Row(): with gr.Column(scale=1): rag_input = gr.Textbox( label="šŸ”Ž Search Query", placeholder="What are you looking for?", value="What is machine learning?", lines=3, info="Ask questions in natural language" ) rag_btn = gr.Button( "šŸ” Search Documents", variant="primary", size="lg", elem_classes=["primary-btn"] ) gr.Markdown(""" **šŸ’” How it works:** - Uses AI embeddings (FAISS) - Understands meaning, not just keywords - Searches 5 sample documents - Returns relevance scores """) with gr.Column(scale=2): rag_output = gr.Textbox( label="šŸ“Š Search Results", lines=20, elem_classes=["output-class"] ) rag_btn.click(tool_rag_search, inputs=[rag_input], outputs=[rag_output]) gr.Examples([ ["What is machine learning?"], ["How to reduce carbon emissions?"], ["What are modern web frameworks?"], ["Digital marketing strategies"] ], inputs=[rag_input], label="šŸ“š Try These Searches") # ====== TAB 5: DATA VISUALIZER ====== with gr.Tab("šŸ“Š Data Visualizer"): gr.Markdown(""" ### šŸ“Š Create Beautiful Charts from Your Data Transform CSV data into stunning visualizations - line charts, bar charts, pie charts, and scatter plots. **āš ļø Limitations:** - Max 10,000 rows of data - CSV format only (comma-separated) - Generated as PNG images (800x600px) - Numeric columns required for pie/scatter charts """) with gr.Row(): with gr.Column(scale=1): viz_csv = gr.Textbox( label="šŸ“‹ CSV Data", lines=10, value=load_sample_csv(), placeholder="month,revenue,costs\nJan,100000,60000", info="Paste your CSV data here" ) viz_chart = gr.Radio( ["line", "bar", "pie", "scatter"], label="šŸ“ˆ Chart Type", value="line", info="Select visualization style" ) viz_x = gr.Textbox(label="šŸ“ X-Axis Column", value="month") viz_y = gr.Textbox(label="šŸ“ Y-Axis Column", value="revenue") viz_title = gr.Textbox(label="šŸ“ Chart Title", value="Monthly Revenue") viz_btn = gr.Button( "šŸ“Š Create Chart", variant="primary", size="lg", elem_classes=["primary-btn"] ) with gr.Column(scale=2): viz_output = gr.Textbox( label="šŸ“Š Chart Status", lines=5, elem_classes=["output-class"] ) viz_img = gr.Image(label="šŸ“ˆ Generated Chart", elem_classes=["chart-output"]) viz_btn.click( tool_data_visualizer, inputs=[viz_csv, viz_chart, viz_x, viz_y, viz_title], outputs=[viz_output, viz_img] ) gr.Markdown("*šŸ’” Sample data is already loaded! Just click 'Create Chart' to see it in action.*") # ====== TAB 6: EMAIL CLASSIFIER ====== with gr.Tab("šŸ“§ Email Classifier"): gr.Markdown(""" ### šŸ“§ AI-Powered Email Intent Detection Automatically classify email intent and detect sentiment - complaint, inquiry, urgent, etc. **āš ļø Limitations:** - Rule-based classification (not deep learning) - Max 10,000 characters per email - English language optimized - 10 intent categories supported """) with gr.Row(): with gr.Column(scale=1): email_input = gr.Textbox( label="āœ‰ļø Email Content", lines=12, value=load_sample_email(), placeholder="Paste email content here...", info="Paste any email text for analysis" ) email_btn = gr.Button( "šŸŽÆ Classify Email", variant="primary", size="lg", elem_classes=["primary-btn"] ) gr.Markdown(""" **šŸ’” Detects 10 intents:** - Complaint - Inquiry - Request - Feedback - Order - Meeting - Urgent - Application - Sales - Other """) with gr.Column(scale=2): email_output = gr.Textbox( label="šŸ“Š Classification Results", lines=20, elem_classes=["output-class"] ) email_btn.click(tool_email_classifier, inputs=[email_input], outputs=[email_output]) gr.Examples([ ["I am writing to complain about the poor service I received at your store yesterday."], ["Could you please send me more information about your pricing plans?"], ["URGENT: The server is down and customers cannot access the website!"] ], inputs=[email_input], label="šŸ“š Try These Examples") # ====== TAB 7: KPI GENERATOR ====== with gr.Tab("šŸ“ˆ KPI Generator"): gr.Markdown(""" ### šŸ“ˆ Business KPI & Analytics Dashboard Generate comprehensive business metrics and KPIs from your data automatically. **āš ļø Limitations:** - JSON format required - Max 50 KPIs calculated per request - Numeric data only for calculations - Processing time: ~1-2 seconds """) with gr.Row(): with gr.Column(scale=1): kpi_json = gr.Textbox( label="šŸ“Š Business Data (JSON Format)", lines=14, value=load_sample_json(), placeholder='{"revenue": 1000000, "costs": 600000}', info="Enter your business metrics in JSON" ) kpi_metrics = gr.CheckboxGroup( ["revenue", "growth", "efficiency", "customer", "operational"], label="šŸ“‹ Metrics to Calculate", value=["revenue", "growth", "efficiency"], info="Select which KPI categories to generate" ) kpi_btn = gr.Button( "šŸ“ˆ Generate KPIs", variant="primary", size="lg", elem_classes=["primary-btn"] ) gr.Markdown(""" **šŸ’” Generates:** - Revenue metrics - Growth rates - Efficiency ratios - Customer metrics - Operational KPIs - Executive summary """) with gr.Column(scale=2): kpi_output = gr.Textbox( label="šŸ“Š KPI Report", lines=25, elem_classes=["output-class"] ) kpi_btn.click( tool_kpi_generator, inputs=[kpi_json, kpi_metrics], outputs=[kpi_output] ) gr.Markdown("*šŸ’” Sample business data is already loaded! Just click 'Generate KPIs' to see results.*") # Footer gr.HTML(""" """) # ============================================================================ # LAUNCH # ============================================================================ if __name__ == "__main__": print("\n" + "="*80) print("šŸš€ Launching MissionControlMCP Web Interface...") print("="*80) # Launch with public sharing enabled demo.launch( share=True, # Creates public URL! server_name="0.0.0.0", server_port=7860, show_error=True )