flet-mcp-server 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
@@ -0,0 +1,29 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - name: Set up Python
16
+ uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.11"
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v4
22
+ with:
23
+ enable-cache: true
24
+
25
+ - name: Install dependencies
26
+ run: uv sync --dev
27
+
28
+ - name: Run tests
29
+ run: uv run pytest
@@ -0,0 +1,35 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ pypi-publish:
9
+ name: Upload release to PyPI
10
+ runs-on: ubuntu-latest
11
+ environment:
12
+ name: release
13
+ url: https://pypi.org/p/flet-mcp-server
14
+
15
+ # Required for PyPI Trusted Publisher authentication
16
+ permissions:
17
+ id-token: write
18
+ contents: read
19
+
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: "3.11"
27
+
28
+ - name: Install uv
29
+ uses: astral-sh/setup-uv@v4
30
+
31
+ - name: Build distributions
32
+ run: uv build
33
+
34
+ - name: Publish to PyPI
35
+ uses: pypa/gh-action-pypi-publish@release/v1
Binary file
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Onyeka Nwokike
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.4
2
+ Name: flet-mcp-server
3
+ Version: 0.1.0
4
+ Summary: Auto-updating MCP server for Flet documentation and packages
5
+ Project-URL: Homepage, https://github.com/Nwokike/flet-mcp-server
6
+ Project-URL: Repository, https://github.com/Nwokike/flet-mcp-server
7
+ Project-URL: Issues, https://github.com/Nwokike/flet-mcp-server/issues
8
+ Author-email: Onyeka Nwokike <nwokikeonyeka@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent,ai,documentation,flet,github-api,mcp
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: diskcache>=5.6.3
22
+ Requires-Dist: httpx>=0.28.1
23
+ Requires-Dist: mcp>=1.27.0
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest-asyncio>=1.3.0; extra == 'test'
26
+ Requires-Dist: pytest-cov>=7.1.0; extra == 'test'
27
+ Requires-Dist: pytest>=9.0.3; extra == 'test'
28
+ Requires-Dist: ruff>=0.15.12; extra == 'test'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # Flet MCP Server
32
+
33
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
34
+ [![Python: 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
35
+
36
+ An auto-updating Model Context Protocol (MCP) server that dynamically fetches, caches, and serves the official Flet documentation and ecosystem packages directly from GitHub and PyPI.
37
+
38
+ ## Features
39
+
40
+ * **GitHub Tree Sync**: Maps documentation in real-time.
41
+ * **Intelligent Caching**: Uses `diskcache` for fast responses.
42
+ * **Ecosystem Discovery**: Finds and verifies official and community Flet packages.
43
+ * **AI-Optimized**: Tool definitions designed for LLM understanding.
44
+
45
+ ## Tools Included
46
+
47
+ ### 1. `list_flet_controls`
48
+ List all available Flet UI controls.
49
+
50
+ ### 2. `search_flet_docs(query)`
51
+ Search the documentation index.
52
+
53
+ ### 3. `get_flet_doc(doc_path)`
54
+ Get raw Markdown for a specific doc.
55
+
56
+ ### 4. `list_official_packages()`
57
+ List official Flet extension packages.
58
+
59
+ ### 5. `search_flet_ecosystem(query)`
60
+ Search for verified community Flet components.
61
+
62
+ ### 6. `get_package_details(package_name)`
63
+ Fetch version and installation info from PyPI.
64
+
65
+ ## Client Configuration Examples
66
+
67
+ ### 🌌 Antigravity / Cascade
68
+ Add this to your `mcp_config.json`:
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "flet-mcp-server": {
74
+ "command": "uvx",
75
+ "args": ["flet-mcp-server"]
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ ### 🤖 Claude Desktop
82
+ Add this to your `claude_desktop_config.json`:
83
+
84
+ ```json
85
+ {
86
+ "mcpServers": {
87
+ "flet-mcp-server": {
88
+ "command": "uvx",
89
+ "args": ["flet-mcp-server"]
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ ### 💻 Cursor / Windsurf
96
+ In your IDE's MCP settings, add a new server:
97
+ - **Name**: Flet MCP
98
+ - **Type**: Command
99
+ - **Command**: `uvx flet-mcp-server`
100
+
101
+ ## Development
102
+
103
+ ### Install
104
+ ```bash
105
+ git clone https://github.com/Nwokike/flet-mcp-server.git
106
+ cd flet-mcp-server
107
+ uv sync
108
+ ```
109
+
110
+ ### Test
111
+ ```bash
112
+ uv run pytest
113
+ ```
114
+
115
+ ## License
116
+ MIT
@@ -0,0 +1,86 @@
1
+ # Flet MCP Server
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
4
+ [![Python: 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
5
+
6
+ An auto-updating Model Context Protocol (MCP) server that dynamically fetches, caches, and serves the official Flet documentation and ecosystem packages directly from GitHub and PyPI.
7
+
8
+ ## Features
9
+
10
+ * **GitHub Tree Sync**: Maps documentation in real-time.
11
+ * **Intelligent Caching**: Uses `diskcache` for fast responses.
12
+ * **Ecosystem Discovery**: Finds and verifies official and community Flet packages.
13
+ * **AI-Optimized**: Tool definitions designed for LLM understanding.
14
+
15
+ ## Tools Included
16
+
17
+ ### 1. `list_flet_controls`
18
+ List all available Flet UI controls.
19
+
20
+ ### 2. `search_flet_docs(query)`
21
+ Search the documentation index.
22
+
23
+ ### 3. `get_flet_doc(doc_path)`
24
+ Get raw Markdown for a specific doc.
25
+
26
+ ### 4. `list_official_packages()`
27
+ List official Flet extension packages.
28
+
29
+ ### 5. `search_flet_ecosystem(query)`
30
+ Search for verified community Flet components.
31
+
32
+ ### 6. `get_package_details(package_name)`
33
+ Fetch version and installation info from PyPI.
34
+
35
+ ## Client Configuration Examples
36
+
37
+ ### 🌌 Antigravity / Cascade
38
+ Add this to your `mcp_config.json`:
39
+
40
+ ```json
41
+ {
42
+ "mcpServers": {
43
+ "flet-mcp-server": {
44
+ "command": "uvx",
45
+ "args": ["flet-mcp-server"]
46
+ }
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### 🤖 Claude Desktop
52
+ Add this to your `claude_desktop_config.json`:
53
+
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "flet-mcp-server": {
58
+ "command": "uvx",
59
+ "args": ["flet-mcp-server"]
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### 💻 Cursor / Windsurf
66
+ In your IDE's MCP settings, add a new server:
67
+ - **Name**: Flet MCP
68
+ - **Type**: Command
69
+ - **Command**: `uvx flet-mcp-server`
70
+
71
+ ## Development
72
+
73
+ ### Install
74
+ ```bash
75
+ git clone https://github.com/Nwokike/flet-mcp-server.git
76
+ cd flet-mcp-server
77
+ uv sync
78
+ ```
79
+
80
+ ### Test
81
+ ```bash
82
+ uv run pytest
83
+ ```
84
+
85
+ ## License
86
+ MIT
@@ -0,0 +1,21 @@
1
+ # Architecture
2
+
3
+ The Flet MCP Server is built with a focus on speed, reliability, and real-time data.
4
+
5
+ ## Components
6
+
7
+ ### 1. `FastMCP` Interface
8
+ Uses the official Python SDK to expose tools via the Model Context Protocol.
9
+
10
+ ### 2. Documentation Service (`github_docs.py`)
11
+ * Uses the GitHub Git Tree API to fetch documentation structure.
12
+ * Caches content locally to minimize network latency.
13
+
14
+ ### 3. Package Service (`packages.py`)
15
+ * Scrapes official extensions from the Flet repository.
16
+ * Searches GitHub for community packages.
17
+ * **PyPI Verification**: Cross-references GitHub search results with PyPI metadata to ensure packages actually depend on `flet`.
18
+ * **Classification**: Automatically classifies packages as "UI Control" or "Service Integration" based on summary analysis.
19
+
20
+ ### 4. Caching Layer
21
+ Uses `diskcache` to store responses for 24 hours, ensuring near-instant tool execution for the AI agent.
@@ -0,0 +1,19 @@
1
+ # Contributing to Flet MCP Server
2
+
3
+ We welcome contributions!
4
+
5
+ ## How to Contribute
6
+
7
+ 1. **Fork the repository** on GitHub.
8
+ 2. **Clone your fork** locally.
9
+ 3. **Create a new branch** for your feature or bugfix.
10
+ 4. **Install dependencies** using `uv sync`.
11
+ 5. **Write tests** for your changes.
12
+ 6. **Run tests** with `uv run pytest`.
13
+ 7. **Submit a Pull Request**.
14
+
15
+ ## Standards
16
+
17
+ * Use `ruff` for linting.
18
+ * Ensure all tests pass.
19
+ * Keep documentation updated.
@@ -0,0 +1,79 @@
1
+ [project]
2
+ name = "flet-mcp-server"
3
+ version = "0.1.0"
4
+ description = "Auto-updating MCP server for Flet documentation and packages"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ license = { text = "MIT" }
8
+ authors = [
9
+ { name = "Onyeka Nwokike", email = "nwokikeonyeka@gmail.com" }
10
+ ]
11
+ keywords = ["flet", "mcp", "ai", "agent", "documentation", "github-api"]
12
+ classifiers = [
13
+ "Development Status :: 4 - Beta",
14
+ "Intended Audience :: Developers",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
21
+ ]
22
+
23
+ dependencies = [
24
+ "diskcache>=5.6.3",
25
+ "httpx>=0.28.1",
26
+ "mcp>=1.27.0",
27
+ ]
28
+
29
+ [project.optional-dependencies]
30
+ test = [
31
+ "pytest>=9.0.3",
32
+ "pytest-asyncio>=1.3.0",
33
+ "pytest-cov>=7.1.0",
34
+ "ruff>=0.15.12",
35
+ ]
36
+
37
+ [project.urls]
38
+ Homepage = "https://github.com/Nwokike/flet-mcp-server"
39
+ Repository = "https://github.com/Nwokike/flet-mcp-server"
40
+ Issues = "https://github.com/Nwokike/flet-mcp-server/issues"
41
+
42
+ [project.scripts]
43
+ flet-mcp-server = "flet_mcp.main:run_server"
44
+
45
+ [tool.hatch.build.targets.wheel]
46
+ packages = ["src/flet_mcp"]
47
+
48
+ [build-system]
49
+ requires = ["hatchling"]
50
+ build-backend = "hatchling.build"
51
+
52
+ [tool.pytest.ini_options]
53
+ asyncio_mode = "auto"
54
+ testpaths = ["tests"]
55
+
56
+ [tool.ruff]
57
+ line-length = 100
58
+ target-version = "py310"
59
+
60
+ [tool.coverage.run]
61
+ source = ["flet_mcp"]
62
+ omit = ["tests/*", "**/tests/*"]
63
+
64
+ [tool.coverage.report]
65
+ exclude_lines = [
66
+ "pragma: no cover",
67
+ "def __repr__",
68
+ "if __name__ == .__main__.",
69
+ "if TYPE_CHECKING:",
70
+ "raise NotImplementedError",
71
+ ]
72
+
73
+ [dependency-groups]
74
+ dev = [
75
+ "pytest>=9.0.3",
76
+ "pytest-asyncio>=1.3.0",
77
+ "pytest-cov>=7.1.0",
78
+ "ruff>=0.15.12",
79
+ ]
File without changes
@@ -0,0 +1,12 @@
1
+ from flet_mcp.server import mcp
2
+
3
+ def run_server():
4
+ """
5
+ Entry point for the uv script execution.
6
+ Runs the MCP server over standard input/output (stdio),
7
+ which is the communication protocol required by desktop AI agents.
8
+ """
9
+ mcp.run(transport='stdio')
10
+
11
+ if __name__ == "__main__":
12
+ run_server()
@@ -0,0 +1,72 @@
1
+ from mcp.server.fastmcp import FastMCP
2
+ from flet_mcp.services.github_docs import FletDocsFetcher
3
+ from flet_mcp.services.packages import FletPackageFetcher
4
+
5
+ # Initialize the FastMCP server
6
+ mcp = FastMCP("Flet MCP Server")
7
+ docs_fetcher = FletDocsFetcher()
8
+ pkg_fetcher = FletPackageFetcher()
9
+
10
+ # --- DOCUMENTATION TOOLS ---
11
+
12
+ @mcp.tool()
13
+ async def search_flet_docs(query: str) -> list[str]:
14
+ """
15
+ Search the official Flet documentation index for a specific topic or control.
16
+ Always use this first to find the correct file path before calling get_flet_doc.
17
+
18
+ Args:
19
+ query: The keyword to search for (e.g., 'dropdown', 'navigation', 'layout').
20
+ """
21
+ return await docs_fetcher.search_docs(query)
22
+
23
+ @mcp.tool()
24
+ async def get_flet_doc(doc_path: str) -> str:
25
+ """
26
+ Fetch the full Markdown documentation for a specific Flet control or topic.
27
+
28
+ Args:
29
+ doc_path: The exact path to the doc file, usually obtained from search_flet_docs
30
+ (e.g., 'website/docs/controls/dropdown/index.md').
31
+ """
32
+ return await docs_fetcher.get_doc_content(doc_path)
33
+
34
+ @mcp.tool()
35
+ async def list_flet_controls() -> list[str]:
36
+ """
37
+ Get a complete list of all available Flet UI controls.
38
+ Use this to discover what UI elements can be built in Flet.
39
+ """
40
+ return await docs_fetcher.list_flet_controls()
41
+
42
+ # --- ECOSYSTEM & PACKAGE TOOLS ---
43
+
44
+ @mcp.tool()
45
+ async def list_official_packages() -> list[str]:
46
+ """
47
+ Get a list of all official Flet extension packages (e.g. flet-audio, flet-video).
48
+ Use this to see what official extra capabilities Flet supports outside the core library.
49
+ """
50
+ return await pkg_fetcher.list_official_packages()
51
+
52
+ @mcp.tool()
53
+ async def search_flet_ecosystem(query: str) -> list[dict]:
54
+ """
55
+ Search the open-source community for third-party Flet packages and components.
56
+ Use this when the user wants to add a feature (e.g., 'calendar', 'table', 'auth')
57
+ that might not be in the core Flet library.
58
+
59
+ Args:
60
+ query: The keyword to search for (e.g., 'calendar').
61
+ """
62
+ return await pkg_fetcher.search_flet_ecosystem(query)
63
+
64
+ @mcp.tool()
65
+ async def get_package_details(package_name: str) -> str:
66
+ """
67
+ Fetch PyPI details, current version, and installation instructions for a specific Flet package.
68
+
69
+ Args:
70
+ package_name: The exact name of the package on PyPI (e.g., 'flet-audio').
71
+ """
72
+ return await pkg_fetcher.get_package_details(package_name)
@@ -0,0 +1,98 @@
1
+ import os
2
+ import httpx
3
+ import diskcache
4
+
5
+ # Set up a persistent local cache in the user's home directory
6
+ # This prevents us from getting rate-limited by GitHub when the AI asks multiple questions
7
+ CACHE_DIR = os.path.expanduser("~/.cache/flet-mcp")
8
+ cache = diskcache.Cache(CACHE_DIR)
9
+
10
+ class FletDocsFetcher:
11
+ """Fetches and caches Flet documentation from the official GitHub repo."""
12
+
13
+ def __init__(self):
14
+ self.client = httpx.AsyncClient(timeout=10.0)
15
+ self.headers = {
16
+ "Accept": "application/vnd.github.v3+json",
17
+ "User-Agent": "Flet-MCP-Server/0.1.0"
18
+ }
19
+ # If the user has a GITHUB_TOKEN, use it to vastly expand API limits
20
+ if token := os.getenv("GITHUB_TOKEN"):
21
+ self.headers["Authorization"] = f"Bearer {token}"
22
+
23
+ async def _fetch_json(self, url: str) -> dict | list | None:
24
+ """Helper to fetch and cache JSON responses (24-hour TTL)."""
25
+ if url in cache:
26
+ return cache[url]
27
+
28
+ response = await self.client.get(url, headers=self.headers)
29
+ if response.status_code == 200:
30
+ data = response.json()
31
+ cache.set(url, data, expire=86400) # 86400 seconds = 24 hours
32
+ return data
33
+ return None
34
+
35
+ async def _fetch_text(self, url: str) -> str | None:
36
+ """Helper to fetch and cache raw Markdown text (24-hour TTL)."""
37
+ if url in cache:
38
+ return cache[url]
39
+
40
+ response = await self.client.get(url)
41
+ if response.status_code == 200:
42
+ text = response.text
43
+ cache.set(url, text, expire=86400)
44
+ return text
45
+ return None
46
+
47
+ async def get_docs_tree(self) -> list[str]:
48
+ """Gets a flat list of all Markdown documentation paths in the Flet repo."""
49
+ # The Tree API is the most efficient way to get all files in a repo at once
50
+ repo_api_url = "https://api.github.com/repos/flet-dev/flet/git/trees/main?recursive=1"
51
+ data = await self._fetch_json(repo_api_url)
52
+
53
+ if not data or "tree" not in data:
54
+ return []
55
+
56
+ # Filter out everything except markdown files in the docs folder
57
+ doc_paths = [
58
+ item["path"] for item in data["tree"]
59
+ if item["path"].startswith("website/docs/") and item["path"].endswith(".md")
60
+ ]
61
+ return doc_paths
62
+
63
+ async def get_doc_content(self, file_path: str) -> str:
64
+ """Fetches the raw Markdown content for a specific Flet doc file."""
65
+ # Use raw.githubusercontent for fast, quota-free raw file fetching
66
+ raw_url = f"https://raw.githubusercontent.com/flet-dev/flet/main/{file_path}"
67
+ content = await self._fetch_text(raw_url)
68
+
69
+ if content:
70
+ return content
71
+ return f"Error: Could not fetch documentation for {file_path}. Ensure the path is correct."
72
+
73
+ async def search_docs(self, query: str) -> list[str]:
74
+ """A keyword search over the available document paths."""
75
+ all_docs = await self.get_docs_tree()
76
+ query_lower = query.lower()
77
+
78
+ # Filter paths that contain the query string
79
+ # e.g., querying "dropdown" will match "docs/docs/controls/dropdown.md"
80
+ matches = [path for path in all_docs if query_lower in path.lower()]
81
+ return matches
82
+
83
+ async def list_flet_controls(self) -> list[str]:
84
+ """Returns a list of all available Flet UI controls."""
85
+ all_docs = await self.get_docs_tree()
86
+
87
+ # Filter only the files that live in the controls directory
88
+ controls = []
89
+ for path in all_docs:
90
+ if "website/docs/controls/" in path:
91
+ # Extract just the control name from the path (e.g., 'dropdown/index.md' -> 'dropdown')
92
+ parts = path.split("website/docs/controls/")
93
+ if len(parts) > 1:
94
+ clean_name = parts[1].split("/")[0].replace(".md", "")
95
+ if clean_name not in controls:
96
+ controls.append(clean_name)
97
+
98
+ return sorted(controls)