Skip to main content
Glama

Flutter MCP

by adamsmaka
initial-vision.mdβ€’19.9 kB
# Building an MCP Server for Flutter/Dart Documentation in 2025 The Model Context Protocol (MCP) has become the "USB-C of AI applications" with adoption by OpenAI, Microsoft, and Google DeepMind in 2025. This comprehensive guide provides everything you need to build a Flutter/Dart documentation MCP server similar to Context7, leveraging the latest Python SDK and best practices for deployment and distribution. ## MCP fundamentals and current state The Model Context Protocol provides a standardized way to connect AI models with external data sources and tools. **Major platforms including OpenAI's ChatGPT Desktop, Microsoft VS Code, and Google DeepMind adopted MCP between November 2024 and March 2025**, establishing it as the de facto standard for AI-tool integration. The protocol operates through three core primitives: tools (model-controlled functions), resources (application-controlled data), and prompts (user-controlled templates). Official documentation lives at modelcontextprotocol.io, with the specification at github.com/modelcontextprotocol/specification. The current protocol revision is 2024-11-05 with active updates through June 2025. MCP servers communicate via multiple transport mechanisms including STDIO for local processes, HTTP Server-Sent Events for remote connections, and WebSockets for real-time bidirectional communication. **The Python SDK has emerged as the most popular implementation with 14.8k GitHub stars**, offering both a high-level FastMCP framework and low-level protocol access. The ecosystem now includes over 1,000 open-source connectors and pre-built servers for everything from GitHub and Docker to PostgreSQL and Stripe. ## Python SDK implementation guide The Python MCP SDK offers two approaches: FastMCP for rapid development and the low-level SDK for maximum control. **FastMCP's decorator-based API makes creating an MCP server remarkably simple**, requiring just a few lines of code to expose Python functions as AI-accessible tools. Installation uses the modern `uv` package manager (recommended) or traditional pip: ```bash # Using uv (recommended) curl -LsSf https://astral.sh/uv/install.sh | sh uv init mcp-server-flutter-docs cd mcp-server-flutter-docs uv add "mcp[cli]" # Alternative with pip pip install "mcp[cli]" ``` Here's a minimal FastMCP server structure: ```python from mcp.server.fastmcp import FastMCP mcp = FastMCP("Flutter Docs Server") @mcp.tool() def search_flutter_docs(query: str, topic: str = None) -> str: """Search Flutter documentation for specific topics""" # Implementation here return search_results @mcp.resource("flutter://{class_name}") def get_flutter_class_docs(class_name: str) -> str: """Get documentation for a Flutter class""" # Fetch and return class documentation return class_documentation if __name__ == "__main__": mcp.run() ``` **The MCP Inspector tool provides instant visual testing** during development: ```bash mcp dev server.py ``` For production deployments, the SDK supports context management, lifecycle hooks, and advanced features like image handling and async operations. Integration with Claude Desktop requires adding your server to the configuration file at `~/Library/Application Support/Claude/claude_desktop_config.json`: ```json { "mcpServers": { "flutter-docs": { "command": "uv", "args": ["--directory", "/path/to/project", "run", "server.py"] } } } ``` ## Learning from Context7's architecture Context7, developed by Upstash, demonstrates best practices for building documentation MCP servers. **Their architecture employs a sophisticated multi-stage pipeline**: ingestion (indexing from GitHub), processing (parsing, enriching with LLMs, cleaning, vectorizing), ranking and filtering (proprietary relevance algorithm), and caching (Redis for sub-second responses). The technical implementation uses TypeScript with the official MCP SDK, supports multiple transport protocols (stdio, HTTP, SSE), and distributes via npm as `@upstash/context7-mcp`. **Key innovations include leveraging the llms.txt standard for AI-optimized documentation**, implementing semantic search with vector embeddings, and maintaining version-specific documentation for accuracy. Context7's success stems from recognizing that raw documentation isn't sufficient for LLMs - it requires processing, enrichment, and intelligent serving. Their stateless design enables horizontal scaling, while aggressive caching ensures performance. The system strips noise to focus on code examples and essential information, providing exactly what LLMs need for effective code generation. ## Accessing Flutter and Dart documentation Flutter and Dart documentation presents unique challenges as **neither api.flutter.dev nor api.dart.dev offers official programmatic APIs**. Following Context7's proven approach, we'll implement on-demand web scraping to fetch documentation in real-time, ensuring users always get the most current information. **Pub.dev provides the only official API endpoints** for package information: ```python import httpx import gzip async def get_all_packages(): """Fetch all package names from pub.dev""" packages = [] url = "https://pub.dev/api/package-names" async with httpx.AsyncClient() as client: while url: response = await client.get(url) data = response.json() packages.extend(data["packages"]) url = data.get("nextUrl") return packages async def get_package_info(package_name: str): """Get detailed package information""" url = f"https://pub.dev/api/packages/{package_name}" async with httpx.AsyncClient() as client: response = await client.get(url) return response.json() ``` **Documentation sources for on-demand fetching**: - **api.flutter.dev**: Official Flutter API reference with predictable URL patterns - **api.dart.dev**: Core Dart library documentation - **Flutter cookbook**: Examples and best practices **Context7-inspired processing pipeline**: 1. **Parse**: Extract code snippets and examples from HTML 2. **Enrich**: Add explanations using LLMs for better context 3. **Clean**: Remove navigation, ads, and irrelevant content 4. **Cache**: Store in Redis for sub-second subsequent responses This on-demand approach allows us to claim "supports ALL pub.dev packages" - a powerful marketing message that resonates with developers. ## Building your documentation MCP server Following Context7's successful architecture, we'll build an on-demand documentation server that fetches and processes documentation in real-time. ### Core MCP Server Implementation ```python from mcp.server.fastmcp import FastMCP import httpx import redis from bs4 import BeautifulSoup import asyncio from typing import Optional, Dict import structlog import re mcp = FastMCP("Flutter Docs Server", dependencies=["httpx", "redis", "beautifulsoup4", "structlog"]) # Redis for caching - Context7 style redis_client = redis.Redis(decode_responses=True, host='localhost', port=6379) logger = structlog.get_logger() # Rate limiter for respectful scraping class RateLimiter: def __init__(self, calls_per_second: float = 2.0): self.semaphore = asyncio.Semaphore(1) self.min_interval = 1.0 / calls_per_second self.last_call = 0 async def acquire(self): async with self.semaphore: elapsed = asyncio.get_event_loop().time() - self.last_call if elapsed < self.min_interval: await asyncio.sleep(self.min_interval - elapsed) self.last_call = asyncio.get_event_loop().time() rate_limiter = RateLimiter() @mcp.tool() async def get_flutter_docs(class_name: str, library: str = "widgets") -> Dict: """Get Flutter class documentation on-demand""" # Check cache first cache_key = f"flutter:{library}:{class_name}" cached = redis_client.get(cache_key) if cached: logger.info("cache_hit", class_name=class_name, library=library) return {"source": "cache", "content": cached} # Rate-limited fetch from Flutter docs await rate_limiter.acquire() url = f"https://api.flutter.dev/flutter/{library}/{class_name}-class.html" try: async with httpx.AsyncClient() as client: response = await client.get( url, headers={"User-Agent": "Flutter-MCP-Docs/1.0 (github.com/yourname/flutter-mcp)"} ) response.raise_for_status() # Process HTML - Context7 style pipeline content = await process_documentation(response.text, class_name) # Cache for 24 hours redis_client.setex(cache_key, 86400, content) logger.info("docs_fetched", class_name=class_name, library=library) return {"source": "live", "content": content} except httpx.HTTPError as e: logger.error("fetch_error", class_name=class_name, error=str(e)) return {"error": f"Could not fetch docs for {class_name}: {str(e)}"} @mcp.tool() async def get_pub_package_docs(package_name: str) -> Dict: """Get any pub.dev package documentation on-demand""" cache_key = f"pub:{package_name}" cached = redis_client.get(cache_key) if cached: return {"source": "cache", "content": cached} # Use official pub.dev API async with httpx.AsyncClient() as client: response = await client.get(f"https://pub.dev/api/packages/{package_name}") if response.status_code == 200: package_data = response.json() # Process and enrich package documentation content = format_package_docs(package_data) redis_client.setex(cache_key, 86400, content) return {"source": "live", "content": content} return {"error": f"Package {package_name} not found"} async def process_documentation(html: str, class_name: str) -> str: """Context7-style documentation processing pipeline""" soup = BeautifulSoup(html, 'html.parser') # 1. Parse - Extract key sections description = soup.find('section', class_='desc') constructors = soup.find_all('section', class_='constructor') properties = soup.find_all('dl', class_='properties') methods = soup.find_all('section', class_='method') # 2. Clean - Remove navigation, scripts, styles for element in soup.find_all(['script', 'style', 'nav', 'header', 'footer']): element.decompose() # 3. Enrich - Format for AI consumption markdown = f"""# {class_name} ## Description {clean_text(description) if description else 'No description available'} ## Constructors {format_constructors(constructors)} ## Properties {format_properties(properties)} ## Methods {format_methods(methods)} ## Code Examples {extract_code_examples(soup)} """ return markdown ``` ### Key Implementation Features **1. Smart Caching Strategy**: Like Context7, cache processed documentation: ```python def get_cache_key(doc_type: str, identifier: str, version: str = None) -> str: """Generate cache keys for different documentation types""" if version: return f"{doc_type}:{identifier}:{version}" return f"{doc_type}:{identifier}" # Cache TTL strategy CACHE_DURATIONS = { "flutter_api": 86400, # 24 hours for stable APIs "pub_package": 43200, # 12 hours for packages (may update more frequently) "cookbook": 604800, # 7 days for examples "stackoverflow": 3600, # 1 hour for community content } ``` **2. Intelligent URL Pattern Detection**: ```python def resolve_flutter_url(query: str) -> Optional[str]: """Intelligently resolve documentation URLs from queries""" # Common Flutter class patterns patterns = { r"^(\w+)$": "https://api.flutter.dev/flutter/widgets/{0}-class.html", r"^material\.(\w+)$": "https://api.flutter.dev/flutter/material/{0}-class.html", r"^cupertino\.(\w+)$": "https://api.flutter.dev/flutter/cupertino/{0}-class.html", r"^dart:(\w+)\.(\w+)$": "https://api.dart.dev/stable/dart-{0}/{1}-class.html", } for pattern, url_template in patterns.items(): if match := re.match(pattern, query, re.IGNORECASE): return url_template.format(*match.groups()) return None ``` **3. Fallback Search When Direct URL Fails**: ```python @mcp.tool() async def search_flutter_docs(query: str) -> Dict: """Search across all Flutter/Dart documentation sources""" results = [] # Try direct URL resolution first if url := resolve_flutter_url(query): if doc := await fetch_and_process(url): results.append(doc) # Search pub.dev packages pub_results = await search_pub_packages(query) results.extend(pub_results[:5]) # Top 5 packages # Search Flutter cookbook cookbook_results = await search_cookbook(query) results.extend(cookbook_results[:3]) return { "query": query, "results": results, "total": len(results) } ``` ## Implementation Timeline **MVP - 4 Hours (Context7-style):** 1. Basic FastMCP server with Redis caching 2. On-demand Flutter API documentation fetching 3. Simple HTML to Markdown processing 4. Test with Claude Desktop **Week 1 - Core Features:** - Add pub.dev package support ("supports ALL packages!") - Implement smart URL resolution - Add rate limiting and error handling - Create search functionality **Week 2 - Polish & Launch:** - Add Flutter cookbook integration - Implement Context7-style enrichment - Write comprehensive documentation - Package for npm/pip distribution - Launch on r/FlutterDev **Future Enhancements:** - Stack Overflow integration - Version-specific documentation - Example code extraction - Performance metrics dashboard ## Deployment and distribution strategies Package your MCP server for easy distribution across multiple platforms. **Like Context7, the server is lightweight and fetches documentation on-demand**, ensuring fast installation and minimal disk usage. ### Distribution Methods Create a lightweight Python package: ```toml # pyproject.toml [project] name = "mcp-flutter-docs" version = "1.0.0" dependencies = [ "mcp[cli]", "httpx", "beautifulsoup4", "aiofiles" ] [project.scripts] mcp-flutter-docs = "mcp_flutter_docs.server:main" ``` Docker image with Redis: ```dockerfile FROM python:3.11-slim WORKDIR /app # Install Redis (or use external Redis service) RUN apt-get update && apt-get install -y redis-server COPY requirements.txt . RUN pip install -r requirements.txt COPY . . # Start Redis and the MCP server CMD redis-server --daemonize yes && python server.py ``` **Provide multiple installation methods** in your documentation: ```json // Claude Desktop configuration { "mcpServers": { "flutter-docs": { "command": "npx", "args": ["-y", "@yourorg/mcp-flutter-docs"] } } } // Docker alternative { "mcpServers": { "flutter-docs": { "command": "docker", "args": ["run", "-i", "--rm", "ghcr.io/yourorg/mcp-flutter-docs:latest"] } } } ``` Use semantic versioning strictly: MAJOR for breaking changes, MINOR for new features, PATCH for bug fixes. Automate releases with GitHub Actions and maintain comprehensive documentation including installation instructions, tool descriptions, and troubleshooting guides. ## Marketing on Reddit effectively Reddit marketing requires patience and authentic community participation. **The Flutter community on r/FlutterDev (154k members) values technical depth, open-source contributions, and genuine problem-solving** over promotional content. Follow the 80/20 rule religiously: 80% genuine community participation, 20% promotion. Build credibility over 6-8 weeks before launching: - Weeks 1-2: Join communities, start answering technical questions - Weeks 3-4: Share expertise without mentioning your project - Weeks 5-6: Subtle mentions in relevant contexts - Weeks 7+: Direct promotion with established credibility **Technical founders posting personally outperform marketing teams consistently**. Frame your launch as a learning experience: ``` Title: "Built an MCP server to integrate Claude with Flutter development - lessons from 6 months of daily use" Body: - Personal intro as Flutter developer - Problem statement (AI coding limitations) - Technical approach with architecture decisions - Real usage examples with screenshots - GitHub link and documentation - Request for feedback and contributions ``` Avoid common mistakes: new accounts with no karma, obvious marketing language, copy-paste promotion across subreddits, and ignoring community norms. Target r/FlutterDev for primary launch, r/programming for technical deep-dive, and r/SideProject for direct promotion. ## Common pitfalls and debugging strategies MCP server development presents unique challenges. **Transport mismatches cause the most common issues** - ensure your server supports the transport your client expects. Debug with MCP Inspector first before testing with actual clients. Handle errors gracefully in FastMCP: ```python @mcp.tool() def risky_operation(data: str) -> str: try: if not data: raise ValueError("Data cannot be empty") # Process data return result except ValueError as e: # FastMCP converts to proper MCP error response raise e except Exception as e: # Log for debugging logger.error(f"Unexpected error: {e}") raise Exception("Operation failed") ``` **Common debugging issues include**: - Permission errors: Ensure proper file access and API keys - Transport conflicts: Match server and client transport types - Serialization problems: Validate JSON schema compliance - Memory leaks: Implement proper cleanup in lifecycle hooks - Rate limiting: Add retry logic with exponential backoff Monitor your server with structured logging: ```python import structlog logger = structlog.get_logger() @mcp.tool() async def fetch_docs(query: str) -> str: logger.info("fetch_docs.start", query=query) try: result = await process_query(query) logger.info("fetch_docs.success", query=query, result_length=len(result)) return result except Exception as e: logger.error("fetch_docs.error", query=query, error=str(e)) raise ``` ## Conclusion Building an MCP server for Flutter/Dart documentation following Context7's proven approach combines simplicity with effectiveness. The on-demand web scraping architecture provides the best of both worlds - always up-to-date documentation with fast cached responses. **Key Advantages of the Context7-Style Approach**: - **Always Current**: Real-time fetching ensures documentation is never outdated - **Lightweight**: Small package size with minimal dependencies - **Marketing Power**: "Supports ALL pub.dev packages" - no limitations - **Fast Responses**: Redis caching provides sub-second performance after first fetch - **Simple Architecture**: No complex ingestion pipelines or database management By following Context7's successful model and adapting it for the Flutter ecosystem, we can deliver immediate value to developers. The 4-hour MVP timeline demonstrates that effective tools don't require months of development - they require understanding real developer needs and implementing proven patterns. Focus on solving the core problem: making Flutter documentation instantly accessible within AI coding assistants. Start with the basic on-demand fetching, add intelligent caching, and ship quickly. The Flutter community's enthusiasm for developer tools combined with the MCP ecosystem's rapid growth creates the perfect opportunity for this project.

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/adamsmaka/flutter-mcp'

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