Skip to main content
Glama
openai-apps-sdk-compatibility.md37.7 kB
# OpenAI Apps SDK Compatibility Specification **Status**: Planning **Created**: November 10, 2025 **Estimated Effort**: 12-18 hours (LLM-assisted implementation) **Timeline**: 1 week (casual pace) or 1-2 days (sprint) **Priority**: Medium (Apps SDK is 1 month old, directory not yet open) ## Overview This specification outlines the enhancement of the Reddit Research MCP server to be compatible with the OpenAI Apps SDK, enabling Reddit research capabilities directly within ChatGPT conversations for 800+ million users. ### What is OpenAI Apps SDK? The OpenAI Apps SDK (launched October 6, 2025) allows developers to build applications that run directly inside ChatGPT conversations. Key characteristics: - **Conversational Discovery**: Apps surface automatically based on conversation context - **Custom UI**: Apps can render HTML/CSS/JavaScript widgets in chat - **MCP Foundation**: Built on Model Context Protocol (open standard) - **OAuth 2.1**: Secure user authentication - **Massive Distribution**: Access to 800M+ ChatGPT users **Current Status**: Preview/Beta (as of Nov 2025) - Developers can build and test in Developer Mode - App directory opens "later 2025" for public submissions - Not available in EU/UK/Switzerland due to regulatory considerations ### Why This Matters Our Reddit Research MCP server is already well-positioned for Apps SDK compatibility: - ✅ Built with FastMCP (supports HTTP transport) - ✅ OAuth already implemented (Descope provider) - ✅ Clean three-layer architecture - ✅ Well-structured tools and data models - ✅ Existing React frontend with reusable components **Opportunity**: First-mover advantage in Reddit research tools for ChatGPT platform. --- ## Current State Analysis ### What We Have (Advantages) #### 1. **Solid MCP Server Foundation** - **Location**: `/reddit-research-mcp/src/server.py` - **Framework**: FastMCP with Descope OAuth - **Transport**: stdio (for desktop AI assistants) - **Architecture**: Three-layer (discover → schema → execute) #### 2. **Five Core Reddit Operations** ```python operations = { "discover_subreddits": discover_subreddits, # Semantic search "search_subreddit": search_in_subreddit, # Search within subreddit "fetch_posts": fetch_subreddit_posts, # Get posts from subreddit "fetch_multiple": fetch_multiple_subreddits, # Batch fetch (70% fewer API calls) "fetch_comments": fetch_submission_with_comments # Complete comment trees } ``` #### 3. **Existing React UI Components** (Reusable!) - **Location**: `/frontend-reddit-research-mcp/frontend/src/components/` - **Key Components**: - `SubredditCard.tsx` - Displays subreddit with confidence score, subscriber count - `SubredditGrid.tsx` - Grid layout with select all/none controls - `RedditQuote.tsx` - Formatted Reddit quote with author/subreddit - `SentimentGauge.tsx` - Visual sentiment indicator with color-coded bar - `MetricBadge.tsx` - Metric display badge - **Styling**: Tailwind CSS with custom brand colors - **Data Types**: Already match MCP server responses (`SubredditOption`, etc.) #### 4. **OAuth Infrastructure** - **Provider**: Descope - **Endpoints**: `/health`, `/server-info` (public), OAuth flows configured - **Status**: Working for HTTP mode ### What Needs Work #### 1. **Transport Layer** (Low Complexity - 2-4 hours) - **Current**: stdio only - **Needed**: HTTP with SSE support - **Change Required**: Minimal (FastMCP supports both) ```python # Current mcp.run() # defaults to stdio # Needed mcp.run(transport="http", host="0.0.0.0", port=8000) ``` #### 2. **Widget/Resource System** (Medium Complexity - 7-10 hours with component reuse) - **Current**: Returns text/JSON only - **Needed**: HTML/CSS/JavaScript widgets for visual display - **Solution**: Convert React components to HTML templates #### 3. **CSP Configuration** (Low Complexity - 2-3 hours) - **Current**: None - **Needed**: Content Security Policy for widget sandboxing - **Domains**: Reddit thumbnails (`i.redd.it`, `external-preview.redd.it`) #### 4. **Metadata Optimization** (Low Complexity - 2-3 hours) - **Current**: Tool descriptions exist but not optimized - **Needed**: "Use this when..." format for discovery - **Testing**: Requires iteration in ChatGPT Developer Mode #### 5. **Deployment** (Medium Complexity - 3-4 hours) - **Current**: Local development only - **Needed**: Cloud deployment with HTTPS - **Platforms**: Render, Railway, or Fly.io --- ## Requirements & Architecture ### 1. HTTP Transport Configuration **Objective**: Switch from stdio to HTTP transport for Apps SDK compatibility. **Implementation**: ```python # src/server.py modifications from fastmcp import FastMCP from starlette.middleware.cors import CORSMiddleware mcp = FastMCP( "Reddit MCP", auth=auth, instructions="""...""" ) # Add CORS for ChatGPT app.add_middleware( CORSMiddleware, allow_origins=["https://chatgpt.com", "https://chat.openai.com"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) if __name__ == "__main__": # Support both stdio (desktop) and HTTP (Apps SDK) import sys if "--http" in sys.argv: mcp.run(transport="http", host="0.0.0.0", port=8000) else: mcp.run() # stdio ``` **Files to Modify**: - `src/server.py` - Add HTTP mode support - `package.json` - Add HTTP start script **Effort**: 0.5-1 hour (with LLM) --- ### 2. Widget/Resource System **Objective**: Create visual widgets for Reddit data display. #### Widget Architecture ``` src/ ├── widgets/ │ ├── __init__.py │ ├── templates.py # HTML templates │ ├── subreddit_widgets.py # Subreddit display widgets │ ├── post_widgets.py # Post/comment widgets │ └── research_widgets.py # Research report widgets └── resources.py # Register widgets as MCP resources ``` #### Key Widgets to Create ##### 1. Subreddit Discovery Card **Purpose**: Display discovered subreddits with confidence scores **Source**: Convert from `SubredditCard.tsx` **Effort**: 1-2 hours **Features**: - Confidence score badge (color-coded: green >0.8, orange >0.6, gray <0.6) - Subscriber count with formatted display (1.2M, 350K, etc.) - Subreddit description (truncated to 2 lines) - Hover effects **Template Structure**: ```html <div class="subreddit-card"> <div class="confidence-badge confidence-{{tier}}"> {{confidence_percent}}% match </div> <div class="subscribers"> <svg class="icon"><!-- users icon --></svg> <span>{{subscribers_formatted}}</span> </div> <div class="content"> <h3>r/{{name}}</h3> <p>{{description}}</p> </div> </div> ``` ##### 2. Subreddit Grid **Purpose**: Display multiple subreddits in responsive grid **Source**: Convert from `SubredditGrid.tsx` **Effort**: 1-2 hours **Features**: - Responsive grid (1-3 columns based on width) - Selection count display - Select all/none buttons (if interactive features supported) ##### 3. Reddit Quote Block **Purpose**: Display quoted Reddit comments with attribution **Source**: Convert from `RedditQuote.tsx` **Effort**: 0.5-1 hour **Template**: ```html <div class="reddit-quote"> <blockquote>"{{text}}"</blockquote> <div class="attribution"> <span class="author">u/{{author}}</span> <span>in</span> <a href="{{url}}" target="_blank">{{subreddit}}</a> </div> </div> ``` ##### 4. Sentiment Gauge **Purpose**: Visual sentiment indicator **Source**: Convert from `SentimentGauge.tsx` **Effort**: 0.5-1 hour **Features**: - Color-coded based on sentiment (green/red/gray) - Progress bar showing score - Percentage display ##### 5. Post Card **Purpose**: Display Reddit posts with metadata **Effort**: 1-2 hours **Features**: - Post title and content preview - Score, comments, subreddit - Author and timestamp - Link to full post ##### 6. Research Report Widget **Purpose**: Formatted research output with sections **Effort**: 2-3 hours **Features**: - Executive summary - Community breakdown table - Key findings sections - Data quality metrics - Collapsible sections #### Widget Registration Pattern ```python # src/widgets/__init__.py from typing import Dict, Any from .templates import WIDGET_STYLES def register_widgets(mcp): """Register all widgets as MCP resources""" @mcp.resource(uri="ui://widget/subreddit_card") def subreddit_card_widget(): return { "mimeType": "text/html+skybridge", "description": "Card displaying subreddit with confidence score" } @mcp.resource(uri="ui://widget/subreddit_grid") def subreddit_grid_widget(): return { "mimeType": "text/html+skybridge", "description": "Grid of subreddit cards" } # ... additional widgets ``` #### Widget Rendering Pattern ```python # src/widgets/subreddit_widgets.py from typing import Dict, Any, List def render_subreddit_card(subreddit: Dict[str, Any]) -> str: """Render single subreddit card""" # Calculate confidence tier confidence = subreddit.get('confidence_score', 0) tier = 'high' if confidence >= 0.8 else 'medium' if confidence >= 0.6 else 'low' # Format subscribers subs = subreddit.get('subscribers', 0) if subs >= 1_000_000: subs_formatted = f"{subs / 1_000_000:.1f}M" elif subs >= 1_000: subs_formatted = f"{subs / 1_000:.1f}K" else: subs_formatted = str(subs) return f""" <div class="subreddit-card"> <div class="confidence-badge confidence-{tier}"> {int(confidence * 100)}% match </div> <div class="subscribers"> <svg class="icon" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/> </svg> <span>{subs_formatted}</span> </div> <div class="content"> <h3>r/{subreddit['name']}</h3> <p>{subreddit.get('description', 'No description available')}</p> </div> </div> """ def render_subreddit_grid(subreddits: List[Dict[str, Any]]) -> str: """Render grid of subreddit cards""" cards = ''.join(render_subreddit_card(sr) for sr in subreddits) return f""" <div class="subreddit-grid"> <div class="grid-header"> <span>{len(subreddits)} communities found</span> </div> <div class="grid-container"> {cards} </div> </div> <style> {SUBREDDIT_GRID_STYLES} </style> """ ``` #### Tool Response Updates Modify `execute_operation` to return widget references: ```python # src/server.py - Updated execute_operation @mcp.tool(description="Execute a Reddit operation with validated parameters") async def execute_operation( operation_id: str, parameters: Dict[str, Any], ctx: Context = None ) -> Dict[str, Any]: """Execute operation and return data with optional widget""" operations = { "discover_subreddits": discover_subreddits, # ... other operations } if operation_id not in operations: return {"success": False, "error": f"Unknown operation: {operation_id}"} try: # Execute operation if operation_id in ["search_subreddit", "fetch_posts", "fetch_multiple", "fetch_comments"]: params = {**parameters, "reddit": reddit, "ctx": ctx} else: params = {**parameters, "ctx": ctx} if operation_id in ["discover_subreddits", "fetch_multiple", "fetch_comments"]: result = await operations[operation_id](**params) else: result = operations[operation_id](**params) # Add widget rendering for visual display widget = None if operation_id == "discover_subreddits": from src.widgets.subreddit_widgets import render_subreddit_grid subreddits = result.get('subreddits', []) widget = { "uri": "ui://widget/subreddit_grid", "mimeType": "text/html+skybridge", "content": render_subreddit_grid(subreddits) } return { "success": True, "data": result, "widget": widget # Optional widget for visual display } except Exception as e: return { "success": False, "error": str(e), "recovery": suggest_recovery(operation_id, e) } ``` **Total Widget Development Effort**: 7-10 hours (with component reuse) --- ### 3. CSP Configuration **Objective**: Configure Content Security Policy for widget sandboxing. **Implementation**: ```python # src/config.py - Add CSP configuration CSP_CONFIG = { "widget_domains": [ "i.redd.it", # Reddit images "external-preview.redd.it", # Reddit previews "www.redditstatic.com" # Reddit static assets ], "csp": { "script-src": ["'self'", "'unsafe-inline'"], # Allow inline scripts "style-src": ["'self'", "'unsafe-inline'"], # Allow inline styles "img-src": ["'self'", "data:", "https:"], # Allow all HTTPS images "connect-src": ["'self'"], # Only same-origin requests "font-src": ["'self'", "data:"], # Allow fonts "frame-src": ["'none'"], # No iframes "object-src": ["'none'"] # No plugins } } # Add to server manifest MANIFEST = { "name": "reddit-research-mcp", "version": "1.0.0", "display_name": "Reddit Research", "description": "Use this when the user wants to research topics on Reddit, discover relevant communities, or analyze Reddit discussions", "oauth": { "client_id": os.getenv("DESCOPE_PROJECT_ID"), "authorization_url": f"{os.getenv('SERVER_URL')}/oauth/authorize", "token_url": f"{os.getenv('SERVER_URL')}/oauth/token", "scopes": ["read:reddit"] }, "widget_domains": CSP_CONFIG["widget_domains"], "csp": CSP_CONFIG["csp"] } ``` **Effort**: 0.5-1 hour (with LLM) --- ### 4. Metadata Optimization for Discovery **Objective**: Optimize tool descriptions for ChatGPT's discovery algorithm. **Current vs. Optimized**: ```python # BEFORE @mcp.tool( description="Discover available Reddit operations and recommended workflows" ) def discover_operations(ctx: Context) -> Dict[str, Any]: ... # AFTER @mcp.tool( description="Use this when the user wants to find Reddit communities, research topics on Reddit, or discover relevant subreddits for any subject or question" ) def discover_operations(ctx: Context) -> Dict[str, Any]: ... ``` **Optimization Guidelines**: 1. **Start with "Use this when..."** - Helps ChatGPT understand context 2. **Include synonyms** - "communities", "subreddits", "Reddit forums" 3. **Be specific but not narrow** - Cover related use cases 4. **Avoid generic terms** - Don't say "research" without "Reddit" **Updated Tool Descriptions**: ```python # src/server.py - Optimized metadata @mcp.tool( description="Use this when the user wants to discover relevant Reddit communities, find subreddits for research, or identify where people discuss specific topics on Reddit", annotations={"readOnlyHint": True} ) def discover_operations(ctx: Context) -> Dict[str, Any]: """Layer 1: Discover Reddit operations""" ... @mcp.tool( description="Use this when the user wants to understand the parameters needed for Reddit operations, or needs examples of how to search communities or fetch posts", annotations={"readOnlyHint": True} ) def get_operation_schema( operation_id: str, include_examples: bool = True, ctx: Context = None ) -> Dict[str, Any]: """Layer 2: Get operation schema""" ... @mcp.tool( description="Use this when the user wants to actually perform Reddit research, search subreddits, fetch posts, analyze comments, or gather community data" ) async def execute_operation( operation_id: str, parameters: Dict[str, Any], ctx: Context = None ) -> Dict[str, Any]: """Layer 3: Execute Reddit operation""" ... ``` **Testing Strategy**: Test with various conversation patterns to ensure app surfaces appropriately: - "What do people on Reddit think about electric vehicles?" - "Find me communities discussing machine learning" - "Show me Reddit discussions about remote work" - "Research Python frameworks on Reddit" - "Where can I find people talking about investing on Reddit?" **Effort**: 1-2 hours (testing requires iteration) --- ### 5. Deployment Configuration **Objective**: Deploy server to cloud platform with HTTPS. #### Option A: Render (Recommended) **Why Render**: - ✅ Free tier available - ✅ Automatic HTTPS - ✅ Simple environment variable management - ✅ PostgreSQL and Redis available if needed later - ✅ Good Python support **Configuration**: ```yaml # render.yaml services: - type: web name: reddit-research-mcp env: python region: oregon plan: free buildCommand: "pip install -r requirements.txt" startCommand: "python src/server.py --http" envVars: - key: REDDIT_CLIENT_ID sync: false - key: REDDIT_CLIENT_SECRET sync: false - key: REDDIT_USER_AGENT value: "RedditMCP:v1.0:reddit-research-mcp" - key: DESCOPE_PROJECT_ID sync: false - key: DESCOPE_BASE_URL value: "https://api.descope.com" - key: SERVER_URL value: "https://reddit-research-mcp.onrender.com" - key: CHROMA_PROXY_URL sync: false - key: CHROMA_PROXY_API_KEY sync: false healthCheckPath: /health ``` **Deployment Steps**: 1. Create Render account 2. Connect GitHub repository 3. Create new Web Service 4. Upload `render.yaml` 5. Configure environment variables in dashboard 6. Deploy #### Option B: Railway **Why Railway**: - ✅ Excellent developer experience - ✅ Automatic HTTPS - ✅ Simple pricing ($5/month after free tier) - ✅ Fast deployments **Configuration**: ```toml # railway.toml [build] builder = "NIXPACKS" buildCommand = "pip install -r requirements.txt" [deploy] startCommand = "python src/server.py --http" restartPolicyType = "ON_FAILURE" healthcheckPath = "/health" healthcheckTimeout = 30 [env] PORT = "8000" ``` #### Environment Variables Needed ```bash # Reddit API REDDIT_CLIENT_ID=your_client_id REDDIT_CLIENT_SECRET=your_client_secret REDDIT_USER_AGENT=RedditMCP:v1.0:reddit-research-mcp # Descope OAuth DESCOPE_PROJECT_ID=your_project_id DESCOPE_BASE_URL=https://api.descope.com # Server Configuration SERVER_URL=https://your-app.onrender.com # or railway.app NODE_ENV=production # ChromaDB (optional) CHROMA_PROXY_URL=https://reddit-mcp-vector-db.onrender.com CHROMA_PROXY_API_KEY=your_proxy_api_key ``` **Effort**: 3-4 hours (including environment setup and testing) --- ## Component Reuse Strategy ### React → Widget Conversion Our existing frontend has 5 key components that can be directly converted to widgets: | React Component | Widget Purpose | Conversion Effort | Time Savings | |----------------|----------------|-------------------|--------------| | SubredditCard | Display subreddit with confidence | 1-2 hrs | 15-20 hrs | | SubredditGrid | Grid of subreddit cards | 1-2 hrs | 10-15 hrs | | RedditQuote | Formatted quote with attribution | 0.5-1 hr | 5-8 hrs | | SentimentGauge | Visual sentiment indicator | 0.5-1 hr | 5-8 hrs | | MetricBadge | Metric display badge | 0.5 hr | 2-4 hrs | **Total Savings**: 37-55 hours → 7-10 hours conversion work ### Conversion Process #### 1. Extract Styles ```bash # Option A: Manual conversion (Tailwind → CSS) # Convert className="p-3 rounded-lg" to style="padding: 0.75rem; border-radius: 0.5rem;" # Option B: Use Tailwind JIT (recommended) # Create widget HTML with Tailwind classes # Run: npx tailwindcss -o widget-styles.css --minify # Include generated CSS in widget <style> block ``` #### 2. Replace React Logic with Templates ```html <!-- React (JSX) --> <h3 className="text-base font-semibold"> r/{subreddit.name} </h3> <!-- Widget (HTML template) --> <h3 class="text-base font-semibold"> r/{{name}} </h3> ``` #### 3. Convert Functions to Server-Side ```typescript // React (client-side) const formatSubscribers = (count: number): string => { if (count >= 1000000) return `${(count / 1000000).toFixed(1)}M`; if (count >= 1000) return `${(count / 1000).toFixed(1)}K`; return count.toString(); }; // Python (server-side) def format_subscribers(count: int) -> str: if count >= 1_000_000: return f"{count / 1_000_000:.1f}M" if count >= 1_000: return f"{count / 1_000:.1f}K" return str(count) ``` ### Example: SubredditCard Conversion **Original React Component** (102 lines): ```tsx // frontend/src/components/subreddit/SubredditCard.tsx export const SubredditCard: React.FC<SubredditCardProps> = ({ subreddit, isSelected, onToggle, }) => { const confidenceColor = (score: number) => { if (score >= 0.8) return 'bg-success-primary/20 text-success-primary border-success-primary'; if (score >= 0.6) return 'bg-brand-primary-primary/20 text-brand-primary-primary border-brand-primary-primary'; return 'bg-grey-tertiary/20 text-grey-secondary border-grey-tertiary'; }; // ... component logic return ( <div className={`relative p-3 rounded-lg shadow-md transition-all duration-200 ...`}> {/* ... JSX structure ... */} </div> ); }; ``` **Converted Widget** (~50 lines): ```python # src/widgets/subreddit_widgets.py def render_subreddit_card(subreddit: Dict[str, Any]) -> str: """Render subreddit card widget""" # Server-side logic confidence = subreddit.get('confidence_score', 0) tier = 'high' if confidence >= 0.8 else 'medium' if confidence >= 0.6 else 'low' subs = subreddit.get('subscribers', 0) subs_formatted = ( f"{subs / 1_000_000:.1f}M" if subs >= 1_000_000 else f"{subs / 1_000:.1f}K" if subs >= 1_000 else str(subs) ) # HTML template with inline CSS return f""" <div class="subreddit-card"> <div class="confidence-badge confidence-{tier}"> {int(confidence * 100)}% match </div> <div class="subscribers"> <svg class="icon" viewBox="0 0 24 24"><!-- SVG path --></svg> <span>{subs_formatted}</span> </div> <div class="content"> <h3>r/{subreddit['name']}</h3> <p>{subreddit.get('description', 'No description available')}</p> </div> </div> <style> .subreddit-card {{ position: relative; padding: 12px; border-radius: 8px; background: #1a1a1a; border: 1px solid #333; transition: all 0.2s; }} .confidence-high {{ background: rgba(34,197,94,0.2); color: #22c55e; border: 1px solid #22c55e; }} /* ... more styles ... */ </style> """ ``` **Key Changes**: - React props → Python function parameters - JSX → HTML string with f-string interpolation - Tailwind classes → Inline CSS (or extracted CSS) - Client logic → Server-side Python functions - Interactive elements removed (checkboxes, onClick) --- ## Implementation Timeline ### LLM-Assisted Implementation Estimates With LLM (Claude Code) doing the coding, human time is dramatically reduced: | Task | Human Manual | LLM-Assisted | Savings | |------|--------------|--------------|---------| | HTTP Transport | 2-4 hrs | 0.5-1 hr | 75% | | Widget Conversion | 7-10 hrs | 1-2 hrs | 85% | | OAuth Verification | 4-8 hrs | 2-3 hrs | 50% | | CSP Configuration | 2-3 hrs | 0.5-1 hr | 67% | | Server Integration | 3-4 hrs | 0.5-1 hr | 80% | | Deployment | 4-6 hrs | 3-4 hrs | 33% | | Testing/Iteration | 3-4 hrs | 3-4 hrs | 0% | | Bug Fixes | 2-3 hrs | 0.5-1 hr | 75% | | Metadata Optimization | 2 hrs | 1-2 hrs | 25% | | Documentation | 1 hr | 0.25 hr | 75% | | **TOTAL** | **27-43 hrs** | **12-18 hrs** | **58%** | ### Week-Long Implementation Plan (Casual Pace) **Day 1 (2-3 hours): Core Implementation** - [ ] LLM generates HTTP transport code - [ ] LLM converts all 5 React components to widgets - [ ] Human reviews and approves code - [ ] Local testing of widgets - [ ] Fix any rendering issues **Day 2 (2-3 hours): Integration & Deployment** - [ ] LLM updates `execute_operation` to return widgets - [ ] LLM creates deployment configuration (render.yaml) - [ ] Human deploys to Render/Railway - [ ] Human configures environment variables - [ ] Verify deployment health check **Day 3 (2-3 hours): ChatGPT Integration** - [ ] Human enables ChatGPT Developer Mode - [ ] Human registers app with staging URL - [ ] Test basic conversation flows - [ ] Verify widgets render in ChatGPT sandbox - [ ] Debug CSP/424 errors if they appear **Day 4 (2-3 hours): Testing & Iteration** - [ ] Test all 5 Reddit operations in ChatGPT - [ ] Try various conversation patterns for discovery - [ ] LLM optimizes metadata based on what works - [ ] Human verifies improvements - [ ] Additional bug fixes **Day 5 (2 hours): Polish & Documentation** - [ ] LLM generates final fixes - [ ] Human deploys to production - [ ] LLM creates documentation - [ ] Final verification - [ ] Ready for users (when directory opens) **Total Human Time: 10-14 hours over 5 days** ### Weekend Sprint (Intensive) **Saturday (6-8 hours)** - Morning (3-4 hrs): Complete implementation & local testing - Afternoon (3-4 hrs): Deployment & ChatGPT integration **Sunday (6-8 hours)** - Morning (3-4 hrs): Comprehensive testing & bug fixes - Afternoon (3-4 hrs): Optimization & final polish **Total: 12-16 hours over 2 days** ### Single-Day MVP (Sprint Mode) If you can dedicate one full day (8-10 hours): - **Hours 1-2**: Implementation (all code generated by LLM) - **Hours 3-4**: Deployment & ChatGPT setup - **Hours 5-6**: Testing & iteration - **Hours 7-8**: Bug fixes & optimization - **Hours 9-10**: Polish & documentation --- ## Technical Specifications ### Directory Structure Changes ``` reddit-research-mcp/ ├── src/ │ ├── widgets/ │ │ ├── __init__.py │ │ ├── templates.py # NEW: HTML templates │ │ ├── subreddit_widgets.py # NEW: Subreddit display widgets │ │ ├── post_widgets.py # NEW: Post/comment widgets │ │ └── research_widgets.py # NEW: Research report widgets │ ├── config.py # MODIFIED: Add CSP config │ ├── server.py # MODIFIED: HTTP mode, widgets │ └── ... (existing files) ├── render.yaml # NEW: Render deployment config ├── railway.toml # NEW: Railway deployment config (optional) └── requirements.txt # MODIFIED: Add any new dependencies ``` ### Dependencies to Add ```txt # requirements.txt additions starlette>=0.27.0 # For CORS middleware (may already be included) uvicorn>=0.23.0 # HTTP server (may already be included with FastMCP) ``` ### Environment Variables ```bash # .env.production (for deployment) REDDIT_CLIENT_ID=your_client_id REDDIT_CLIENT_SECRET=your_client_secret REDDIT_USER_AGENT=RedditMCP:v1.0:reddit-research-mcp DESCOPE_PROJECT_ID=your_descope_project_id DESCOPE_BASE_URL=https://api.descope.com SERVER_URL=https://reddit-research-mcp.onrender.com CHROMA_PROXY_URL=https://reddit-mcp-vector-db.onrender.com CHROMA_PROXY_API_KEY=your_chroma_api_key NODE_ENV=production PORT=8000 ``` ### Testing Checklist #### Local Testing (Before Deployment) - [ ] HTTP server starts successfully on port 8000 - [ ] Health check endpoint returns 200: `curl http://localhost:8000/health` - [ ] Server info endpoint returns correct data: `curl http://localhost:8000/server-info` - [ ] OAuth endpoints are accessible - [ ] All widgets render without errors - [ ] Tool execution returns widget data #### Deployment Testing - [ ] App deploys successfully to hosting platform - [ ] HTTPS certificate is active - [ ] Health check passes in production - [ ] Environment variables are configured correctly - [ ] OAuth flow works with production URL - [ ] Logs show no errors #### ChatGPT Integration Testing - [ ] App registers in ChatGPT Developer Mode - [ ] Discovery triggers on relevant conversations - [ ] All 5 operations execute successfully - [ ] Widgets render in ChatGPT sandbox (no CSP errors) - [ ] Images load (Reddit thumbnails) - [ ] Links work (external navigation) - [ ] OAuth prompts correctly when needed #### Discovery Testing (Conversation Patterns) Test these phrases to verify app surfaces appropriately: - [ ] "What do people on Reddit think about [topic]?" - [ ] "Find me Reddit communities about [topic]" - [ ] "Show me discussions about [topic] on Reddit" - [ ] "Research [topic] on Reddit" - [ ] "Where can I find people talking about [topic] on Reddit?" --- ## Decision Points & Considerations ### 1. Styling Approach **Decision**: How to convert Tailwind CSS to widget CSS? **Options**: - **A. Manual Conversion** (inline styles) - Pros: Full control, no build step - Cons: Time-consuming, verbose - Best for: Quick MVP - **B. Tailwind JIT Extraction** (generate CSS file) - Pros: Clean, maintainable, familiar - Cons: Requires build step - Best for: Production-ready widgets - **C. Hybrid** (Tailwind for complex, inline for simple) - Pros: Balanced approach - Cons: Inconsistent patterns - Best for: Iterative development **Recommendation**: Start with **Option A** for MVP, migrate to **Option B** for production. ### 2. Widget Interactivity **Decision**: Should widgets have interactive elements? **Constraints**: - ChatGPT widgets run in sandboxed iframes - Limited JavaScript execution - Must use `window.parent.postMessage()` for tool calls **Options**: - **A. Static Widgets Only** - Pros: Simple, reliable, fast to build - Cons: Less engaging - Best for: MVP - **B. Basic Interactivity** (expand/collapse, tooltips) - Pros: Better UX - Cons: More complex, potential CSP issues - Best for: Production **Recommendation**: **Option A** for initial release, add interactivity in Phase 2. ### 3. OAuth Requirement **Decision**: Should all operations require OAuth? **Current State**: OAuth is configured but may not be strictly required for read-only Reddit operations. **Options**: - **A. No OAuth Required** - Pros: Frictionless user experience - Cons: Rate limits may affect users - **B. Optional OAuth** (prompt when rate limited) - Pros: Best of both worlds - Cons: Complex logic - **C. Always Require OAuth** - Pros: Consistent experience, higher rate limits - Cons: Friction for new users **Recommendation**: **Option B** - Allow anonymous use until rate limited, then prompt for OAuth. ### 4. Deployment Platform **Decision**: Which cloud platform? **Options Comparison**: | Feature | Render | Railway | Fly.io | |---------|--------|---------|--------| | Free Tier | ✅ Yes | ✅ Yes ($5 credit) | ✅ Yes (limited) | | Pricing | $7/mo after free | $5/mo | Usage-based | | Ease of Use | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | | Python Support | ✅ Native | ✅ Native | ✅ Dockerfile | | HTTPS | ✅ Automatic | ✅ Automatic | ✅ Automatic | | Environment Vars | ✅ Simple | ✅ Simple | ✅ Simple | | Databases | ✅ PostgreSQL | ✅ PostgreSQL | ✅ PostgreSQL | **Recommendation**: **Render** for simplicity and free tier, **Railway** for best DX. ### 5. Phased Rollout **Decision**: Should we implement all features at once or in phases? **Phase 1: MVP** (Week 1) - HTTP transport - Basic widgets (SubredditCard, RedditQuote) - Simple deployment - Basic discovery metadata **Phase 2: Enhanced Widgets** (Week 2-3) - All 5 widgets fully polished - Interactive elements - Optimized CSS - Comprehensive testing **Phase 3: Production Ready** (Week 4) - Advanced features (if needed) - Performance optimization - Monitoring and analytics - Documentation for app directory submission **Recommendation**: **Phase 1 → Test → Phase 2** approach to validate concept quickly. --- ## Success Criteria ### MVP Success Metrics - [ ] App deploys successfully with HTTPS - [ ] All 5 Reddit operations work in ChatGPT - [ ] At least 2 widgets render correctly (SubredditCard, RedditQuote) - [ ] App surfaces in 3+ conversation patterns - [ ] No critical bugs or CSP errors - [ ] OAuth flow works (if implemented) ### Production Ready Metrics - [ ] All 5 widgets fully implemented and polished - [ ] App surfaces reliably in target conversations - [ ] Widget rendering performance < 2 seconds - [ ] Zero CSP/424 errors in testing - [ ] Comprehensive documentation complete - [ ] Ready for app directory submission ### User Experience Goals - [ ] Users can discover Reddit communities through conversation - [ ] Widgets provide clear, actionable information - [ ] Visual design is clean and professional - [ ] App feels integrated with ChatGPT (not jarring) - [ ] Operations complete in < 5 seconds --- ## Risk Assessment ### High Risk (Requires Mitigation) **1. CSP/424 Errors During Widget Rendering** - **Likelihood**: Medium-High - **Impact**: High (breaks user experience) - **Mitigation**: - Test widgets in isolation first - Start with simple widgets, add complexity gradually - Keep detailed logs of CSP issues - Reference Apps SDK guide for troubleshooting **2. Discovery Not Surfacing App** - **Likelihood**: Medium - **Impact**: High (users can't find app) - **Mitigation**: - Test 15+ conversation patterns - Iterate on metadata descriptions - Use "Use this when..." format consistently - Monitor which patterns work best **3. Apps SDK Changes During Development** - **Likelihood**: Medium (SDK is 1 month old) - **Impact**: Medium (may require rework) - **Mitigation**: - Monitor OpenAI announcements - Join developer community/forums - Keep architecture flexible ### Medium Risk **4. OAuth Configuration Issues** - **Likelihood**: Low-Medium - **Impact**: Medium - **Mitigation**: - Test OAuth flow early - Use existing Descope configuration - Have fallback to anonymous mode **5. Widget Performance in ChatGPT Sandbox** - **Likelihood**: Low - **Impact**: Medium - **Mitigation**: - Keep widgets lightweight - Optimize CSS - Minimize external dependencies ### Low Risk **6. Deployment Platform Issues** - **Likelihood**: Low - **Impact**: Low-Medium - **Mitigation**: - Use well-documented platforms (Render/Railway) - Have backup platform ready - Test deployment early --- ## Next Steps ### Immediate Actions (When Ready to Start) 1. **Review OpenAI Apps SDK Guide** - Location: `/ai-docs/openai-apps-sdk-comprehensive-guide.md` - Read sections on widget development and CSP configuration - Review real-world examples 2. **Set Up Development Environment** - Ensure FastMCP is up to date - Test HTTP mode locally: `python src/server.py --http` - Verify all dependencies are installed 3. **Choose Deployment Platform** - Create account on Render or Railway - Set up GitHub repository connection - Prepare environment variables 4. **Begin Implementation** - Start with HTTP transport (fastest win) - Convert SubredditCard widget first (most visible) - Test locally before deploying ### Questions to Resolve 1. **OAuth Strategy**: Do we require OAuth for all operations or make it optional? 2. **Styling Approach**: Manual CSS conversion or Tailwind extraction? 3. **Deployment Platform**: Render vs. Railway? 4. **Interactive Widgets**: MVP static or add basic interactivity? 5. **Phased Rollout**: All features at once or MVP → iterate? ### Resources Created 1. **OpenAI Apps SDK Guide**: `/ai-docs/openai-apps-sdk-comprehensive-guide.md` 2. **This Specification**: `/specs/openai-apps-sdk-compatibility.md` 3. **Existing React Components**: `/frontend/src/components/` 4. **MCP Server**: `/src/server.py` --- ## Appendix ### Useful Links - **OpenAI Apps SDK Docs**: `developers.openai.com/apps-sdk` - **MCP Specification**: `modelcontextprotocol.io` - **FastMCP Documentation**: `github.com/jlowin/fastmcp` - **Render Documentation**: `render.com/docs` - **Railway Documentation**: `docs.railway.app` ### File Paths Reference **MCP Server**: - Main server: `/src/server.py` - Config: `/src/config.py` - Tools: `/src/tools/*.py` - Resources: `/src/resources.py` **Frontend Components** (for conversion): - SubredditCard: `/frontend/src/components/subreddit/SubredditCard.tsx` - SubredditGrid: `/frontend/src/components/subreddit/SubredditGrid.tsx` - RedditQuote: `/frontend/src/components/visualization/RedditQuote.tsx` - SentimentGauge: `/frontend/src/components/visualization/SentimentGauge.tsx` - MetricBadge: `/frontend/src/components/visualization/MetricBadge.tsx` **Types** (shared): - `/shared/types.ts` - Contains `SubredditOption`, `RedditPost`, etc. ### Contact Points for Implementation When ready to implement: 1. Resume conversation with Claude Code 2. Reference this spec file 3. Provide decision answers for questions listed above 4. Begin with Day 1 implementation plan --- **End of Specification** *Last Updated: November 10, 2025* *Status: Ready for Implementation* *Estimated Effort: 12-18 hours (LLM-assisted)*

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/king-of-the-grackles/dialog-reddit-tools'

If you have feedback or need assistance with the MCP directory API, please join our Discord server