preflight-mcp 0.1.0 → 0.1.1
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.
- package/LICENSE +21 -0
- package/README.md +195 -27
- package/README.zh-CN.md +277 -308
- package/dist/bundle/deepwiki.js +1 -1
- package/dist/bundle/github.js +100 -15
- package/dist/bundle/githubArchive.js +82 -0
- package/dist/bundle/ingest.js +2 -2
- package/dist/bundle/paths.js +23 -0
- package/dist/bundle/service.js +701 -25
- package/dist/config.js +1 -0
- package/dist/context7/client.js +1 -1
- package/dist/core/concurrency-limiter.js +100 -0
- package/dist/core/scheduler.js +4 -1
- package/dist/jobs/tmp-cleanup-job.js +71 -0
- package/dist/mcp/errorKinds.js +54 -0
- package/dist/mcp/uris.js +28 -8
- package/dist/search/sqliteFts.js +68 -36
- package/dist/server/optimized-server.js +4 -0
- package/dist/server.js +455 -279
- package/dist/tools/searchByTags.js +80 -0
- package/package.json +26 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 preflight-mcp contributors
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,42 +1,121 @@
|
|
|
1
1
|
# preflight-mcp
|
|
2
2
|
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://nodejs.org/)
|
|
5
|
+
[](https://modelcontextprotocol.io/)
|
|
6
|
+
|
|
3
7
|
> **English** | [中文](./README.zh-CN.md)
|
|
4
8
|
|
|
5
|
-
An MCP (Model Context Protocol) **stdio** server
|
|
9
|
+
An MCP (Model Context Protocol) **stdio** server that creates evidence-based preflight bundles for GitHub repositories and library documentation.
|
|
6
10
|
|
|
7
11
|
Each bundle contains:
|
|
8
12
|
- A local copy of repo docs + code (normalized text)
|
|
9
13
|
- A lightweight **full-text search index** (SQLite FTS5)
|
|
10
14
|
- Agent-facing entry files: `START_HERE.md`, `AGENTS.md`, and `OVERVIEW.md` (factual-only, with evidence pointers)
|
|
11
15
|
|
|
12
|
-
##
|
|
13
|
-
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- **12 MCP tools** to create/update/repair/search/verify/read bundles (plus resources)
|
|
19
|
+
- **De-duplication**: prevent repeated indexing of the same normalized inputs
|
|
20
|
+
- **Resilient GitHub fetching**: configurable git clone timeout + GitHub archive (zipball) fallback
|
|
21
|
+
- **Offline repair**: rebuild missing/empty derived artifacts (index/guides/overview) without re-fetching
|
|
14
22
|
- **Static facts extraction** via `analysis/FACTS.json` (non-LLM)
|
|
15
23
|
- **Evidence-based verification** to reduce hallucinations
|
|
16
24
|
- **Resources** to read bundle files via `preflight://...` URIs
|
|
17
25
|
- **Multi-path mirror backup** for cloud storage redundancy
|
|
18
26
|
- **Resilient storage** with automatic failover when mounts are unavailable
|
|
19
27
|
|
|
28
|
+
## Table of Contents
|
|
29
|
+
|
|
30
|
+
- [Requirements](#requirements)
|
|
31
|
+
- [Installation](#installation)
|
|
32
|
+
- [Quick Start](#quick-start)
|
|
33
|
+
- [Tools](#tools-12-total)
|
|
34
|
+
- [Environment Variables](#environment-variables)
|
|
35
|
+
- [Contributing](#contributing)
|
|
36
|
+
- [License](#license)
|
|
37
|
+
|
|
20
38
|
## Requirements
|
|
39
|
+
|
|
21
40
|
- Node.js >= 18
|
|
22
41
|
- `git` available on PATH
|
|
23
42
|
|
|
24
|
-
##
|
|
25
|
-
Local dev:
|
|
26
|
-
- `npm install`
|
|
27
|
-
- `npm run build`
|
|
43
|
+
## Installation
|
|
28
44
|
|
|
29
|
-
|
|
30
|
-
- `npm install -g preflight-mcp`
|
|
45
|
+
### From npm (after published)
|
|
31
46
|
|
|
32
|
-
|
|
33
|
-
|
|
47
|
+
```bash
|
|
48
|
+
npm install -g preflight-mcp
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Local Development
|
|
34
52
|
|
|
35
|
-
|
|
36
|
-
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/jonnyhoo/preflight-mcp.git
|
|
55
|
+
cd preflight-mcp
|
|
56
|
+
npm install
|
|
57
|
+
npm run build
|
|
58
|
+
```
|
|
37
59
|
|
|
38
|
-
|
|
39
|
-
|
|
60
|
+
## Quick Start
|
|
61
|
+
|
|
62
|
+
### 1. Configure MCP Host (e.g., Claude Desktop)
|
|
63
|
+
|
|
64
|
+
Add to your MCP configuration file:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"mcpServers": {
|
|
69
|
+
"preflight": {
|
|
70
|
+
"command": "npx",
|
|
71
|
+
"args": ["preflight-mcp"]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Or for local development:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"preflight": {
|
|
83
|
+
"command": "node",
|
|
84
|
+
"args": ["path/to/preflight-mcp/dist/index.js"]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. Create Your First Bundle
|
|
91
|
+
|
|
92
|
+
Ask your AI assistant:
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
"Create a bundle for the repository octocat/Hello-World"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This will:
|
|
99
|
+
- Clone the repository
|
|
100
|
+
- Index all docs and code
|
|
101
|
+
- Generate searchable SQLite FTS5 index
|
|
102
|
+
- Create `START_HERE.md`, `AGENTS.md`, and `OVERVIEW.md`
|
|
103
|
+
|
|
104
|
+
### 3. Search the Bundle
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
"Search for 'GitHub' in the bundle"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 4. Test Locally (Optional)
|
|
111
|
+
|
|
112
|
+
Run end-to-end smoke test:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npm run smoke
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This will test bundle creation, search, and update operations.
|
|
40
119
|
|
|
41
120
|
## Smoke test
|
|
42
121
|
Runs an end-to-end stdio client that:
|
|
@@ -51,7 +130,7 @@ Command:
|
|
|
51
130
|
|
|
52
131
|
Note: the smoke test clones `octocat/Hello-World` from GitHub, so it needs internet access.
|
|
53
132
|
|
|
54
|
-
## Tools (
|
|
133
|
+
## Tools (12 total)
|
|
55
134
|
|
|
56
135
|
### `preflight_list_bundles`
|
|
57
136
|
List bundle IDs in storage.
|
|
@@ -61,10 +140,21 @@ List bundle IDs in storage.
|
|
|
61
140
|
Create a new bundle from one or more inputs.
|
|
62
141
|
- Triggers: "index this repo", "学习这个项目", "创建bundle"
|
|
63
142
|
|
|
143
|
+
Key semantics:
|
|
144
|
+
- **De-dup by default**: if a bundle already exists for the same normalized inputs, creation is rejected.
|
|
145
|
+
- Use `ifExists` to control behavior:
|
|
146
|
+
- `error` (default): reject duplicate
|
|
147
|
+
- `returnExisting`: return the existing bundle without fetching
|
|
148
|
+
- `updateExisting`: update the existing bundle then return it
|
|
149
|
+
- `createNew`: bypass de-duplication
|
|
150
|
+
- GitHub ingest uses **shallow clone**; if `git clone` fails, it will fall back to **GitHub archive (zipball)**.
|
|
151
|
+
- Supports `repos.kind: "local"` to ingest from a local directory (e.g. an extracted zip).
|
|
152
|
+
|
|
64
153
|
Input (example):
|
|
65
|
-
- `repos`: `[{ kind: "github", repo: "owner/repo" }, { kind: "deepwiki", url: "https://deepwiki.com/owner/repo" }]`
|
|
154
|
+
- `repos`: `[{ kind: "github", repo: "owner/repo" }, { kind: "local", repo: "owner/repo", path: "/path/to/dir" }, { kind: "deepwiki", url: "https://deepwiki.com/owner/repo" }]`
|
|
66
155
|
- `libraries`: `["nextjs", "react"]` (Context7; optional)
|
|
67
156
|
- `topics`: `["routing", "api"]` (Context7 topic filter; optional)
|
|
157
|
+
- `ifExists`: `"error" | "returnExisting" | "updateExisting" | "createNew"`
|
|
68
158
|
|
|
69
159
|
### `preflight_read_file`
|
|
70
160
|
Read a file from bundle (OVERVIEW.md, START_HERE.md, AGENTS.md, or any repo file).
|
|
@@ -90,30 +180,49 @@ Optional parameters:
|
|
|
90
180
|
Batch update all bundles at once.
|
|
91
181
|
- Triggers: "批量更新", "全部刷新"
|
|
92
182
|
|
|
183
|
+
### `preflight_find_bundle`
|
|
184
|
+
Check whether a bundle already exists for the given inputs (no fetching, no changes).
|
|
185
|
+
- Use when your UI/agent wants to decide whether to create/update.
|
|
186
|
+
|
|
187
|
+
### `preflight_repair_bundle`
|
|
188
|
+
Offline repair for a bundle (no fetching): rebuild missing/empty derived artifacts.
|
|
189
|
+
- Rebuilds `indexes/search.sqlite3`, `START_HERE.md`, `AGENTS.md`, `OVERVIEW.md` when missing/empty.
|
|
190
|
+
- Use when: search fails due to index corruption, bundle files were partially deleted, etc.
|
|
191
|
+
|
|
93
192
|
### `preflight_search_bundle`
|
|
94
193
|
Full-text search across ingested docs/code (line-based SQLite FTS5).
|
|
95
194
|
- Triggers: "搜索bundle", "在仓库中查找", "搜代码"
|
|
96
195
|
|
|
97
|
-
|
|
98
|
-
- `ensureFresh
|
|
99
|
-
-
|
|
196
|
+
Important: **this tool is strictly read-only**.
|
|
197
|
+
- `ensureFresh` / `maxAgeHours` are **deprecated** and will error if provided.
|
|
198
|
+
- To update: call `preflight_update_bundle`, then search again.
|
|
199
|
+
- To repair: call `preflight_repair_bundle`, then search again.
|
|
100
200
|
|
|
101
201
|
### `preflight_search_by_tags`
|
|
102
202
|
Search across multiple bundles filtered by tags (line-based SQLite FTS5).
|
|
103
203
|
- Triggers: "search in MCP bundles", "search in all bundles", "在MCP项目中搜索", "搜索所有agent"
|
|
104
204
|
|
|
205
|
+
Notes:
|
|
206
|
+
- This tool is read-only and **does not auto-repair**.
|
|
207
|
+
- If some bundles fail to search (e.g. missing/corrupt index), they will be reported in `warnings`.
|
|
208
|
+
|
|
105
209
|
Optional parameters:
|
|
106
210
|
- `tags`: Filter bundles by tags (e.g., `["mcp", "agents"]`)
|
|
107
211
|
- `scope`: Search scope (`docs`, `code`, or `all`)
|
|
108
212
|
- `limit`: Max total hits across all bundles
|
|
109
213
|
|
|
214
|
+
Output additions:
|
|
215
|
+
- `warnings?: [{ bundleId, kind, message }]` (non-fatal per-bundle errors)
|
|
216
|
+
- `warningsTruncated?: true` if warnings were capped
|
|
217
|
+
|
|
110
218
|
### `preflight_verify_claim`
|
|
111
219
|
Find evidence for a claim/statement in bundle.
|
|
112
220
|
- Triggers: "验证说法", "找证据", "这个对吗"
|
|
113
221
|
|
|
114
|
-
|
|
115
|
-
- `ensureFresh
|
|
116
|
-
-
|
|
222
|
+
Important: **this tool is strictly read-only**.
|
|
223
|
+
- `ensureFresh` / `maxAgeHours` are **deprecated** and will error if provided.
|
|
224
|
+
- To update: call `preflight_update_bundle`, then verify again.
|
|
225
|
+
- To repair: call `preflight_repair_bundle`, then verify again.
|
|
117
226
|
|
|
118
227
|
## Resources
|
|
119
228
|
### `preflight://bundles`
|
|
@@ -126,6 +235,24 @@ Examples:
|
|
|
126
235
|
- `preflight://bundle/<id>/file/START_HERE.md`
|
|
127
236
|
- `preflight://bundle/<id>/file/repos%2Fowner%2Frepo%2Fnorm%2FREADME.md`
|
|
128
237
|
|
|
238
|
+
## Error semantics (stable, UI-friendly)
|
|
239
|
+
Most tool errors are wrapped with a stable, machine-parseable prefix:
|
|
240
|
+
- `[preflight_error kind=<kind>] <message>`
|
|
241
|
+
|
|
242
|
+
Common kinds:
|
|
243
|
+
- `bundle_not_found`
|
|
244
|
+
- `file_not_found`
|
|
245
|
+
- `invalid_path` (unsafe path traversal attempt)
|
|
246
|
+
- `permission_denied`
|
|
247
|
+
- `index_missing_or_corrupt`
|
|
248
|
+
- `deprecated_parameter`
|
|
249
|
+
- `unknown`
|
|
250
|
+
|
|
251
|
+
This is designed so UIs/agents can reliably decide whether to:
|
|
252
|
+
- call `preflight_update_bundle`
|
|
253
|
+
- call `preflight_repair_bundle`
|
|
254
|
+
- prompt the user for a different bundleId/path
|
|
255
|
+
|
|
129
256
|
## Environment variables
|
|
130
257
|
### Storage
|
|
131
258
|
- `PREFLIGHT_STORAGE_DIR`: bundle storage dir (default: `~/.preflight-mcp/bundles`)
|
|
@@ -138,20 +265,21 @@ Examples:
|
|
|
138
265
|
- `PREFLIGHT_ANALYSIS_MODE`: Static analysis mode - `none` or `quick` (default: `quick`). Generates `analysis/FACTS.json`.
|
|
139
266
|
|
|
140
267
|
### GitHub & Context7
|
|
141
|
-
- `GITHUB_TOKEN`: optional; used for GitHub API/auth patterns
|
|
268
|
+
- `GITHUB_TOKEN`: optional; used for GitHub API/auth patterns and GitHub archive fallback (public repos usually work without it)
|
|
269
|
+
- `PREFLIGHT_GIT_CLONE_TIMEOUT_MS`: optional; max time to allow `git clone` before failing over to archive (default: 5 minutes)
|
|
142
270
|
- `CONTEXT7_API_KEY`: optional; enables higher Context7 limits (runs without a key but may be rate-limited)
|
|
143
271
|
- `CONTEXT7_MCP_URL`: optional; defaults to Context7 MCP endpoint
|
|
144
272
|
|
|
145
273
|
## Bundle layout (on disk)
|
|
146
274
|
Inside a bundle directory:
|
|
147
|
-
- `manifest.json`
|
|
275
|
+
- `manifest.json` (includes `fingerprint`, `displayName`, `tags`, and per-repo `source`)
|
|
148
276
|
- `START_HERE.md`
|
|
149
277
|
- `AGENTS.md`
|
|
150
278
|
- `OVERVIEW.md`
|
|
151
279
|
- `indexes/search.sqlite3`
|
|
152
280
|
- **`analysis/FACTS.json`** (static analysis)
|
|
153
281
|
- `repos/<owner>/<repo>/raw/...`
|
|
154
|
-
- `repos/<owner>/<repo>/norm/...`
|
|
282
|
+
- `repos/<owner>/<repo>/norm/...` (GitHub/local snapshots)
|
|
155
283
|
- `deepwiki/<owner>/<repo>/norm/index.md` (DeepWiki sources)
|
|
156
284
|
- `deepwiki/<owner>/<repo>/meta.json`
|
|
157
285
|
- `libraries/context7/<...>/meta.json`
|
|
@@ -179,7 +307,7 @@ $env:PREFLIGHT_STORAGE_DIRS = "D:\OneDrive\preflight;E:\GoogleDrive\preflight"
|
|
|
179
307
|
```
|
|
180
308
|
```bash
|
|
181
309
|
# macOS/Linux
|
|
182
|
-
export PREFLIGHT_STORAGE_DIRS="$HOME/OneDrive/preflight
|
|
310
|
+
export PREFLIGHT_STORAGE_DIRS="$HOME/OneDrive/preflight;$HOME/Dropbox/preflight"
|
|
183
311
|
```
|
|
184
312
|
|
|
185
313
|
### MCP host config (Claude Desktop)
|
|
@@ -206,3 +334,43 @@ export PREFLIGHT_STORAGE_DIRS="$HOME/OneDrive/preflight:$HOME/Dropbox/preflight"
|
|
|
206
334
|
### Important notes
|
|
207
335
|
- **Avoid concurrent access**: Only use on one machine at a time (SQLite conflicts)
|
|
208
336
|
- **Wait for sync**: After updates, wait for cloud sync before switching machines
|
|
337
|
+
|
|
338
|
+
## Contributing
|
|
339
|
+
|
|
340
|
+
We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details on:
|
|
341
|
+
|
|
342
|
+
- Development setup
|
|
343
|
+
- Code style guidelines
|
|
344
|
+
- Testing requirements
|
|
345
|
+
- Pull request process
|
|
346
|
+
|
|
347
|
+
Please also read our [Code of Conduct](./CODE_OF_CONDUCT.md) before contributing.
|
|
348
|
+
|
|
349
|
+
## Support
|
|
350
|
+
|
|
351
|
+
If you encounter any issues or have questions:
|
|
352
|
+
|
|
353
|
+
- **Issues**: [GitHub Issues](https://github.com/jonnyhoo/preflight-mcp/issues)
|
|
354
|
+
- **Discussions**: [GitHub Discussions](https://github.com/jonnyhoo/preflight-mcp/discussions)
|
|
355
|
+
|
|
356
|
+
## License
|
|
357
|
+
|
|
358
|
+
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
359
|
+
|
|
360
|
+
The MIT License allows you to:
|
|
361
|
+
- Use commercially
|
|
362
|
+
- Modify
|
|
363
|
+
- Distribute
|
|
364
|
+
- Use privately
|
|
365
|
+
|
|
366
|
+
With the only requirement being to include the original copyright and license notice.
|
|
367
|
+
|
|
368
|
+
## Acknowledgments
|
|
369
|
+
|
|
370
|
+
- Built on the [Model Context Protocol](https://modelcontextprotocol.io/)
|
|
371
|
+
- Uses SQLite FTS5 for efficient full-text search
|
|
372
|
+
- Inspired by the need for evidence-based AI assistance
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
Made with ❤️ for the AI developer community
|