mobile-docs-mcp 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.
@@ -0,0 +1,25 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ venv/
10
+ env/
11
+
12
+ # Crawled index output (regenerate via ingest; keep only the seed in git)
13
+ data/android/
14
+ data/apple/
15
+ *.index
16
+
17
+ # Tooling
18
+ .pytest_cache/
19
+ .mypy_cache/
20
+ .ruff_cache/
21
+ .DS_Store
22
+
23
+ # Secrets / local config
24
+ .env
25
+ .env.*
@@ -0,0 +1,78 @@
1
+ # Open-core architecture
2
+
3
+ `mobile-docs-mcp` is designed to live two lives from one codebase — the same
4
+ split Context7 uses (MIT client, proprietary backend).
5
+
6
+ ```
7
+ ┌─────────────────────────────┐ ┌──────────────────────────────┐
8
+ │ PUBLIC (this repo, MIT) │ │ HOSTED (yours, private) │
9
+ │ │ │ │
10
+ │ mobile_docs_mcp/ │ │ hosted/app.py │
11
+ │ server.py (MCP tools) │ HTTP │ FastAPI over the SAME │
12
+ │ store.py (retrieval) │ ─────▶ │ Store, but serving the │
13
+ │ ingest/ (crawlers) │ │ full crawled index │
14
+ │ + bundled SEED corpus │ │ + API keys + rate limits │
15
+ │ │ │ + freshness pipeline │
16
+ │ → the funnel & credibility │ │ → the paid product │
17
+ └─────────────────────────────┘ └──────────────────────────────┘
18
+ ```
19
+
20
+ The public half is fully usable on its own (`uvx mobile-docs-mcp` against the
21
+ seed corpus). That's what goes on GitHub and into interviews. The hosted half is
22
+ what you'd run as a service if you commercialize: it serves a large, continuously
23
+ refreshed, version-tagged index that isn't practical to bundle or self-host — the
24
+ same thing that makes Context7's backend defensible.
25
+
26
+ Open-sourcing the client does **not** give away the moat. The moat is index
27
+ breadth + freshness, which lives in the deployment, not the code.
28
+
29
+ ## What stays public vs. private
30
+
31
+ | Public (MIT) | Private (if you monetize) |
32
+ |---|---|
33
+ | MCP server + tool surface | Full crawled index (all androidx + SwiftUI symbols/versions) |
34
+ | Retrieval logic (`store.py`) | Freshness pipeline (scheduled re-crawl + diff) |
35
+ | Ingestion framework (`ingest/`) | Hosted API auth, billing, rate limiting |
36
+ | Seed corpus (demo) | Enterprise mode: index a customer's **private** SDK docs |
37
+
38
+ ## Run the hosted backend locally
39
+
40
+ ```bash
41
+ pip install fastapi uvicorn
42
+ uvicorn hosted.app:app --host 0.0.0.0 --port 8000
43
+
44
+ curl "http://localhost:8000/verify?name=scrollTargetBehavior&target_version=16.0&platform=apple"
45
+ # {"status":"unavailable","detail":"scrollTargetBehavior was introduced in 17.0 ..."}
46
+ ```
47
+
48
+ Env vars:
49
+
50
+ ```bash
51
+ MOBILE_DOCS_DATA=data/android,data/apple # serve a real crawled index, not the seed
52
+ MOBILE_DOCS_REQUIRE_KEY=1 # enforce API keys
53
+ MOBILE_DOCS_API_KEYS=key_abc,key_def # (stub — replace with a real key store)
54
+ ```
55
+
56
+ ## Deploy on Replit (fast MVP / demo)
57
+
58
+ 1. Create a Replit from your GitHub repo (or the private fork holding a real index).
59
+ 2. Set the run command:
60
+ ```
61
+ uvicorn hosted.app:app --host 0.0.0.0 --port 8000
62
+ ```
63
+ 3. Add `fastapi` and `uvicorn` to the environment (Replit auto-detects from
64
+ `pip install`, or add a `requirements-hosted.txt`).
65
+ 4. Replit exposes it at a public URL — point a landing page at `/search` and
66
+ `/verify`, collect usage, validate willingness-to-pay before investing in the
67
+ full crawl + freshness pipeline.
68
+
69
+ Replit is right for the demo endpoint and validation. If real pull appears, move
70
+ the crawl pipeline + vector store to durable infra; keep Replit as the front door.
71
+
72
+ ## Next step: remote-index mode for the MCP server
73
+
74
+ To let the public MCP server call your hosted index instead of the local seed,
75
+ add a `RemoteStore` that implements `search()` / `find_symbols()` over HTTP and
76
+ select it in `server.py` when `MOBILE_DOCS_REMOTE` is set. That turns the same
77
+ `uvx mobile-docs-mcp` install into a thin client of your paid backend — the
78
+ Context7 distribution model exactly.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Asif
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,246 @@
1
+ Metadata-Version: 2.4
2
+ Name: mobile-docs-mcp
3
+ Version: 0.1.0
4
+ Summary: Version-aware mobile docs MCP server for Android (Jetpack/Compose) and Apple (SwiftUI/UIKit)
5
+ Project-URL: Homepage, https://github.com/asif786ka/mobile-docs-mcp
6
+ Project-URL: Repository, https://github.com/asif786ka/mobile-docs-mcp
7
+ Project-URL: Issues, https://github.com/asif786ka/mobile-docs-mcp/issues
8
+ Author: Asif
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: android,documentation,ios,jetpack-compose,mcp,rag,swiftui
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Documentation
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: mcp>=1.2.0
23
+ Requires-Dist: rank-bm25>=0.2.2
24
+ Provides-Extra: hosted
25
+ Requires-Dist: fastapi>=0.110.0; extra == 'hosted'
26
+ Requires-Dist: uvicorn>=0.29.0; extra == 'hosted'
27
+ Provides-Extra: openai
28
+ Requires-Dist: openai>=1.40.0; extra == 'openai'
29
+ Provides-Extra: vector
30
+ Requires-Dist: sentence-transformers>=3.0.0; extra == 'vector'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # mobile-docs-mcp
34
+
35
+ A version-aware documentation MCP server for mobile development — the context7
36
+ idea, but specialized for the thing generic doc proxies get wrong: **which
37
+ version of an API you can actually use.**
38
+
39
+ It indexes Android (Jetpack / androidx / Compose) and Apple (SwiftUI / UIKit)
40
+ documentation with `since` / `deprecated` / `removed` metadata on every symbol,
41
+ so an agent can *verify an API exists on the version the project targets* before
42
+ writing code against it.
43
+
44
+ ## Why it's different from a doc proxy
45
+
46
+ Most "Apple docs" / "Android docs" MCP servers live-fetch and parse the current
47
+ doc site. They answer "what is `scrollTargetBehavior`?" but not "can I use it on
48
+ iOS 16?" — and that second question is where coding agents hallucinate. Every
49
+ result here is filtered and annotated against a target version.
50
+
51
+ ## Tools
52
+
53
+ | Tool | Purpose |
54
+ |------|---------|
55
+ | `search_mobile_docs` | Hybrid (BM25 + optional vector) retrieval, filtered by platform + target version |
56
+ | `get_api_reference` | Full symbol card: signature, availability, deprecation/migration pointer |
57
+ | `verify_api_exists` | Anti-hallucination check — real AND usable on a given version? |
58
+ | `list_api_versions` | since / deprecated / removed timeline + migration lineage |
59
+ | `get_release_notes` | What changed in a library/version |
60
+
61
+ Example verdict:
62
+
63
+ ```
64
+ verify_api_exists("scrollTargetBehavior", "16.0", "apple")
65
+ → ❌ NOT AVAILABLE — introduced in 17.0, newer than 16.0. Will not compile there.
66
+ ```
67
+
68
+ ## Run
69
+
70
+ ```bash
71
+ # From source
72
+ pip install -e .
73
+ python -m mobile_docs_mcp.server # stdio transport
74
+
75
+ # Once published
76
+ uvx mobile-docs-mcp
77
+ ```
78
+
79
+ Ships with a seed corpus, so it works immediately with no crawl.
80
+
81
+ ## Editor & IDE setup (iOS + Android)
82
+
83
+ The server speaks MCP over stdio, so any MCP-capable editor can use it. All the
84
+ tools work for **both** platforms — you'll lean on the SwiftUI entries in an iOS
85
+ project and the Compose/androidx entries in an Android one, but nothing is
86
+ editor-specific. Two ways to launch it:
87
+
88
+ - **From source (this repo):** `command: "python"`, `args: ["-m", "mobile_docs_mcp.server"]`, with `cwd` set to the repo path.
89
+ - **Once published:** `command: "uvx"`, `args: ["mobile-docs-mcp"]` (no `cwd` needed).
90
+
91
+ Set `MOBILE_DOCS_DATA` in `env` to layer in any corpora you've crawled with the
92
+ ingesters (see "Growing the index").
93
+
94
+ ### Claude Code (CLI)
95
+
96
+ ```bash
97
+ # from source, shared with the repo via .mcp.json (project scope)
98
+ claude mcp add mobile-docs-mcp --scope project -- python -m mobile_docs_mcp.server
99
+ # or, once published
100
+ claude mcp add mobile-docs-mcp -- uvx mobile-docs-mcp
101
+ ```
102
+
103
+ Verify with `claude mcp list`, or `/mcp` inside a session.
104
+
105
+ ### Claude Desktop
106
+
107
+ Edit `claude_desktop_config.json` (Settings → Developer → Edit Config), then
108
+ restart the app:
109
+
110
+ ```json
111
+ {
112
+ "mcpServers": {
113
+ "mobile-docs-mcp": {
114
+ "command": "python",
115
+ "args": ["-m", "mobile_docs_mcp.server"],
116
+ "cwd": "/absolute/path/to/mobile-docs-mcp",
117
+ "env": { "MOBILE_DOCS_DATA": "data/android,data/apple" }
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ ### Cursor
124
+
125
+ Create `.cursor/mcp.json` in the project root (or `~/.cursor/mcp.json` for all
126
+ projects) — same `mcpServers` shape as above:
127
+
128
+ ```json
129
+ {
130
+ "mcpServers": {
131
+ "mobile-docs-mcp": {
132
+ "command": "python",
133
+ "args": ["-m", "mobile_docs_mcp.server"],
134
+ "cwd": "${workspaceFolder}"
135
+ }
136
+ }
137
+ }
138
+ ```
139
+
140
+ Then enable it under Settings → MCP.
141
+
142
+ ### Windsurf
143
+
144
+ Edit `~/.codeium/windsurf/mcp_config.json` (Cascade panel → MCP icon →
145
+ Configure). Same `mcpServers` shape; Windsurf supports `${env:VAR}` interpolation
146
+ so you can keep paths/secrets out of the file:
147
+
148
+ ```json
149
+ {
150
+ "mcpServers": {
151
+ "mobile-docs-mcp": {
152
+ "command": "python",
153
+ "args": ["-m", "mobile_docs_mcp.server"],
154
+ "cwd": "/absolute/path/to/mobile-docs-mcp"
155
+ }
156
+ }
157
+ }
158
+ ```
159
+
160
+ ### Android Studio
161
+
162
+ Gemini in Android Studio is an MCP client. Go to **Settings → Tools → AI → MCP
163
+ Servers**, tick **Enable MCP Servers**, and paste the same `mcpServers` JSON
164
+ block shown for Claude Desktop. Confirm with the "Successfully connected"
165
+ notification, then type `/mcp` in the chat to see the tools. Great for checking
166
+ `androidx`/Compose availability against your module's `compileSdk` / library
167
+ versions without leaving the IDE.
168
+
169
+ ### VS Code
170
+
171
+ VS Code's key is `servers` (not `mcpServers`) and wants an explicit `type`.
172
+ Create `.vscode/mcp.json` (commit it to share with the team):
173
+
174
+ ```json
175
+ {
176
+ "servers": {
177
+ "mobile-docs-mcp": {
178
+ "type": "stdio",
179
+ "command": "python",
180
+ "args": ["-m", "mobile_docs_mcp.server"],
181
+ "cwd": "${workspaceFolder}",
182
+ "env": { "MOBILE_DOCS_DATA": "data/android,data/apple" }
183
+ }
184
+ }
185
+ }
186
+ ```
187
+
188
+ Open the file and click **Start**, or run *MCP: List Servers* from the Command
189
+ Palette. Copilot Chat's Agent mode will then surface the tools.
190
+
191
+ ### Xcode
192
+
193
+ Xcode 26.3+ is itself an **MCP server** (it exposes build / test / preview /
194
+ Apple-doc-search tools) rather than an MCP client — so you don't register
195
+ `mobile-docs-mcp` *inside* Xcode. Instead, run an agent that consumes both: point
196
+ Claude Code (or Cursor / Codex) at `mobile-docs-mcp` using the steps above while
197
+ it's also connected to Xcode's server. The agent then gets Xcode's build/preview
198
+ tools **and** this server's `verify_api_exists` version checks in one session —
199
+ e.g. it can confirm `scrollTargetBehavior` needs iOS 17 before writing it against
200
+ your iOS 16 deployment target, then build the project to check.
201
+
202
+ ## Architecture
203
+
204
+ ```
205
+ ingest/ (batch, offline) server.py (runtime)
206
+ android.py developer.android.com FastMCP
207
+ apple.py Apple JSON doc API │
208
+ │ ▼
209
+ ▼ store.py — hybrid, version-aware
210
+ symbols.json + chunks.json 1. BM25 lexical recall
211
+ (version-tagged) 2. vector recall (optional)
212
+ 3. RRF fusion
213
+ 4. VERSION FILTER ← the differentiator
214
+ 5. cross-encoder rerank (optional)
215
+ ```
216
+
217
+ Retrieval is provider-agnostic (`embeddings.py`), same shape as a multi-provider
218
+ model gateway: BM25 works fully offline; vector recall and rerank switch on via
219
+ env var with no code change and degrade gracefully if a provider is missing.
220
+
221
+ ```bash
222
+ MOBILE_DOCS_EMBEDDINGS=local # or openai ; default none (BM25-only)
223
+ MOBILE_DOCS_RERANK=local # default none
224
+ MOBILE_DOCS_DATA=data/android,data/apple # layer in crawled corpora
225
+ ```
226
+
227
+ ## Growing the index
228
+
229
+ ```bash
230
+ python -m mobile_docs_mcp.ingest.android --out data/android \
231
+ --refs androidx.compose.foundation.lazy.LazyColumn \
232
+ --release-notes compose-foundation navigation
233
+
234
+ python -m mobile_docs_mcp.ingest.apple --out data/apple \
235
+ --paths swiftui/navigationstack swiftui/view/scrolltargetbehavior
236
+ ```
237
+
238
+ Then point the server at the output with `MOBILE_DOCS_DATA`.
239
+
240
+ ## Status
241
+
242
+ MVP. The protocol layer, version logic, hybrid store, and tool surface are
243
+ production-shaped; the ingestion coverage is a seed. The real work — and the moat
244
+ — is breadth and freshness of the version-tagged index.
245
+
246
+ MIT.
@@ -0,0 +1,214 @@
1
+ # mobile-docs-mcp
2
+
3
+ A version-aware documentation MCP server for mobile development — the context7
4
+ idea, but specialized for the thing generic doc proxies get wrong: **which
5
+ version of an API you can actually use.**
6
+
7
+ It indexes Android (Jetpack / androidx / Compose) and Apple (SwiftUI / UIKit)
8
+ documentation with `since` / `deprecated` / `removed` metadata on every symbol,
9
+ so an agent can *verify an API exists on the version the project targets* before
10
+ writing code against it.
11
+
12
+ ## Why it's different from a doc proxy
13
+
14
+ Most "Apple docs" / "Android docs" MCP servers live-fetch and parse the current
15
+ doc site. They answer "what is `scrollTargetBehavior`?" but not "can I use it on
16
+ iOS 16?" — and that second question is where coding agents hallucinate. Every
17
+ result here is filtered and annotated against a target version.
18
+
19
+ ## Tools
20
+
21
+ | Tool | Purpose |
22
+ |------|---------|
23
+ | `search_mobile_docs` | Hybrid (BM25 + optional vector) retrieval, filtered by platform + target version |
24
+ | `get_api_reference` | Full symbol card: signature, availability, deprecation/migration pointer |
25
+ | `verify_api_exists` | Anti-hallucination check — real AND usable on a given version? |
26
+ | `list_api_versions` | since / deprecated / removed timeline + migration lineage |
27
+ | `get_release_notes` | What changed in a library/version |
28
+
29
+ Example verdict:
30
+
31
+ ```
32
+ verify_api_exists("scrollTargetBehavior", "16.0", "apple")
33
+ → ❌ NOT AVAILABLE — introduced in 17.0, newer than 16.0. Will not compile there.
34
+ ```
35
+
36
+ ## Run
37
+
38
+ ```bash
39
+ # From source
40
+ pip install -e .
41
+ python -m mobile_docs_mcp.server # stdio transport
42
+
43
+ # Once published
44
+ uvx mobile-docs-mcp
45
+ ```
46
+
47
+ Ships with a seed corpus, so it works immediately with no crawl.
48
+
49
+ ## Editor & IDE setup (iOS + Android)
50
+
51
+ The server speaks MCP over stdio, so any MCP-capable editor can use it. All the
52
+ tools work for **both** platforms — you'll lean on the SwiftUI entries in an iOS
53
+ project and the Compose/androidx entries in an Android one, but nothing is
54
+ editor-specific. Two ways to launch it:
55
+
56
+ - **From source (this repo):** `command: "python"`, `args: ["-m", "mobile_docs_mcp.server"]`, with `cwd` set to the repo path.
57
+ - **Once published:** `command: "uvx"`, `args: ["mobile-docs-mcp"]` (no `cwd` needed).
58
+
59
+ Set `MOBILE_DOCS_DATA` in `env` to layer in any corpora you've crawled with the
60
+ ingesters (see "Growing the index").
61
+
62
+ ### Claude Code (CLI)
63
+
64
+ ```bash
65
+ # from source, shared with the repo via .mcp.json (project scope)
66
+ claude mcp add mobile-docs-mcp --scope project -- python -m mobile_docs_mcp.server
67
+ # or, once published
68
+ claude mcp add mobile-docs-mcp -- uvx mobile-docs-mcp
69
+ ```
70
+
71
+ Verify with `claude mcp list`, or `/mcp` inside a session.
72
+
73
+ ### Claude Desktop
74
+
75
+ Edit `claude_desktop_config.json` (Settings → Developer → Edit Config), then
76
+ restart the app:
77
+
78
+ ```json
79
+ {
80
+ "mcpServers": {
81
+ "mobile-docs-mcp": {
82
+ "command": "python",
83
+ "args": ["-m", "mobile_docs_mcp.server"],
84
+ "cwd": "/absolute/path/to/mobile-docs-mcp",
85
+ "env": { "MOBILE_DOCS_DATA": "data/android,data/apple" }
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### Cursor
92
+
93
+ Create `.cursor/mcp.json` in the project root (or `~/.cursor/mcp.json` for all
94
+ projects) — same `mcpServers` shape as above:
95
+
96
+ ```json
97
+ {
98
+ "mcpServers": {
99
+ "mobile-docs-mcp": {
100
+ "command": "python",
101
+ "args": ["-m", "mobile_docs_mcp.server"],
102
+ "cwd": "${workspaceFolder}"
103
+ }
104
+ }
105
+ }
106
+ ```
107
+
108
+ Then enable it under Settings → MCP.
109
+
110
+ ### Windsurf
111
+
112
+ Edit `~/.codeium/windsurf/mcp_config.json` (Cascade panel → MCP icon →
113
+ Configure). Same `mcpServers` shape; Windsurf supports `${env:VAR}` interpolation
114
+ so you can keep paths/secrets out of the file:
115
+
116
+ ```json
117
+ {
118
+ "mcpServers": {
119
+ "mobile-docs-mcp": {
120
+ "command": "python",
121
+ "args": ["-m", "mobile_docs_mcp.server"],
122
+ "cwd": "/absolute/path/to/mobile-docs-mcp"
123
+ }
124
+ }
125
+ }
126
+ ```
127
+
128
+ ### Android Studio
129
+
130
+ Gemini in Android Studio is an MCP client. Go to **Settings → Tools → AI → MCP
131
+ Servers**, tick **Enable MCP Servers**, and paste the same `mcpServers` JSON
132
+ block shown for Claude Desktop. Confirm with the "Successfully connected"
133
+ notification, then type `/mcp` in the chat to see the tools. Great for checking
134
+ `androidx`/Compose availability against your module's `compileSdk` / library
135
+ versions without leaving the IDE.
136
+
137
+ ### VS Code
138
+
139
+ VS Code's key is `servers` (not `mcpServers`) and wants an explicit `type`.
140
+ Create `.vscode/mcp.json` (commit it to share with the team):
141
+
142
+ ```json
143
+ {
144
+ "servers": {
145
+ "mobile-docs-mcp": {
146
+ "type": "stdio",
147
+ "command": "python",
148
+ "args": ["-m", "mobile_docs_mcp.server"],
149
+ "cwd": "${workspaceFolder}",
150
+ "env": { "MOBILE_DOCS_DATA": "data/android,data/apple" }
151
+ }
152
+ }
153
+ }
154
+ ```
155
+
156
+ Open the file and click **Start**, or run *MCP: List Servers* from the Command
157
+ Palette. Copilot Chat's Agent mode will then surface the tools.
158
+
159
+ ### Xcode
160
+
161
+ Xcode 26.3+ is itself an **MCP server** (it exposes build / test / preview /
162
+ Apple-doc-search tools) rather than an MCP client — so you don't register
163
+ `mobile-docs-mcp` *inside* Xcode. Instead, run an agent that consumes both: point
164
+ Claude Code (or Cursor / Codex) at `mobile-docs-mcp` using the steps above while
165
+ it's also connected to Xcode's server. The agent then gets Xcode's build/preview
166
+ tools **and** this server's `verify_api_exists` version checks in one session —
167
+ e.g. it can confirm `scrollTargetBehavior` needs iOS 17 before writing it against
168
+ your iOS 16 deployment target, then build the project to check.
169
+
170
+ ## Architecture
171
+
172
+ ```
173
+ ingest/ (batch, offline) server.py (runtime)
174
+ android.py developer.android.com FastMCP
175
+ apple.py Apple JSON doc API │
176
+ │ ▼
177
+ ▼ store.py — hybrid, version-aware
178
+ symbols.json + chunks.json 1. BM25 lexical recall
179
+ (version-tagged) 2. vector recall (optional)
180
+ 3. RRF fusion
181
+ 4. VERSION FILTER ← the differentiator
182
+ 5. cross-encoder rerank (optional)
183
+ ```
184
+
185
+ Retrieval is provider-agnostic (`embeddings.py`), same shape as a multi-provider
186
+ model gateway: BM25 works fully offline; vector recall and rerank switch on via
187
+ env var with no code change and degrade gracefully if a provider is missing.
188
+
189
+ ```bash
190
+ MOBILE_DOCS_EMBEDDINGS=local # or openai ; default none (BM25-only)
191
+ MOBILE_DOCS_RERANK=local # default none
192
+ MOBILE_DOCS_DATA=data/android,data/apple # layer in crawled corpora
193
+ ```
194
+
195
+ ## Growing the index
196
+
197
+ ```bash
198
+ python -m mobile_docs_mcp.ingest.android --out data/android \
199
+ --refs androidx.compose.foundation.lazy.LazyColumn \
200
+ --release-notes compose-foundation navigation
201
+
202
+ python -m mobile_docs_mcp.ingest.apple --out data/apple \
203
+ --paths swiftui/navigationstack swiftui/view/scrolltargetbehavior
204
+ ```
205
+
206
+ Then point the server at the output with `MOBILE_DOCS_DATA`.
207
+
208
+ ## Status
209
+
210
+ MVP. The protocol layer, version logic, hybrid store, and tool surface are
211
+ production-shaped; the ingestion coverage is a seed. The real work — and the moat
212
+ — is breadth and freshness of the version-tagged index.
213
+
214
+ MIT.