import json from collections import Counter import gradio as gr # --- same logic as server.py --- STOP_WORDS = {'the','a','an','and','or','but','in','on','at','to','for', 'of','with','by','from','up','about','into','over','after', 'is','are','was','were','be','been','being','have','has', 'had','do','does','did','will','would','can','could','shall', 'should','may','might','i','you','he','she','it','we','they', 'me','him','her','us','them','my','your','his','its','our', 'their','this','that','these','those','not','no','nor','so'} def analyze_text(text: str) -> str: words = text.split() sentences = [s.strip() for s in text.replace('!', '.').replace('?', '.').split('.') if s.strip()] return json.dumps({ "total_characters": len(text), "total_words": len(words), "total_sentences": len(sentences), "avg_word_length": round(sum(len(w) for w in words) / len(words), 2) if words else 0, "avg_sentence_length": round(len(words) / len(sentences), 2) if sentences else 0, "unique_words": len(set(w.lower() for w in words)) }, indent=2) def extract_keywords(text: str, count: int = 5) -> str: words = [w.lower().strip('.,!?;:\'"()[]{}') for w in text.split()] words = [w for w in words if w and w not in STOP_WORDS and len(w) > 2] keywords = Counter(words).most_common(count) return json.dumps({"keywords": [{"word": w, "frequency": c} for w, c in keywords]}, indent=2) def check_reading_level(text: str) -> str: words = text.split() sentences = [s.strip() for s in text.replace('!', '.').replace('?', '.').split('.') if s.strip()] if not sentences or not words: return json.dumps({"error": "Text too short"}, indent=2) syllables = sum(sum(1 for c in w if c.lower() in 'aeiou') for w in words) grade = 0.39 * (len(words) / len(sentences)) + 11.8 * (syllables / len(words)) - 15.59 grade = max(0, min(grade, 20)) if grade < 5: level = "Elementary School" elif grade < 8: level = "Middle School" elif grade < 12: level = "High School" else: level = "College" return json.dumps({"grade_level": round(grade, 1), "reading_level": level}, indent=2) def reverse_text(text: str) -> str: return text[::-1] # --- UI --- with gr.Blocks(title="Text Processor") as demo: gr.Markdown("# Text Processor MCP Server") with gr.Tab("Analyze Text"): text_input = gr.Textbox(label="Text", lines=5) analyze_btn = gr.Button("Analyze") output = gr.Textbox(label="Results") analyze_btn.click(fn=analyze_text, inputs=text_input, outputs=output) with gr.Tab("Extract Keywords"): kw_input = gr.Textbox(label="Text", lines=5) kw_count = gr.Slider(1, 20, value=5, step=1, label="Keyword count") kw_btn = gr.Button("Extract") kw_output = gr.Textbox(label="Keywords") kw_btn.click(fn=extract_keywords, inputs=[kw_input, kw_count], outputs=kw_output) with gr.Tab("Reading Level"): rl_input = gr.Textbox(label="Text", lines=5) rl_btn = gr.Button("Check") rl_output = gr.Textbox(label="Reading Level") rl_btn.click(fn=check_reading_level, inputs=rl_input, outputs=rl_output) with gr.Tab("Reverse Text"): rev_input = gr.Textbox(label="Text", lines=5) rev_btn = gr.Button("Reverse") rev_output = gr.Textbox(label="Reversed") rev_btn.click(fn=reverse_text, inputs=rev_input, outputs=rev_output) if __name__ == "__main__": demo.launch(mcp_server=True)