@groundtruth-mcp/gt-mcp 2.2.0
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 +80 -0
- package/README.md +417 -0
- package/dist/constants.d.ts +15 -0
- package/dist/constants.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/services/cache.d.ts +29 -0
- package/dist/services/cache.js +1 -0
- package/dist/services/fetcher.d.ts +16 -0
- package/dist/services/fetcher.js +1 -0
- package/dist/sources/registry.d.ts +16 -0
- package/dist/sources/registry.js +1 -0
- package/dist/tools/audit.d.ts +25 -0
- package/dist/tools/audit.js +1 -0
- package/dist/tools/auto-scan.d.ts +7 -0
- package/dist/tools/auto-scan.js +1 -0
- package/dist/tools/best-practices.d.ts +2 -0
- package/dist/tools/best-practices.js +1 -0
- package/dist/tools/changelog.d.ts +2 -0
- package/dist/tools/changelog.js +1 -0
- package/dist/tools/compare.d.ts +2 -0
- package/dist/tools/compare.js +1 -0
- package/dist/tools/compat.d.ts +2 -0
- package/dist/tools/compat.js +1 -0
- package/dist/tools/docs.d.ts +2 -0
- package/dist/tools/docs.js +1 -0
- package/dist/tools/resolve.d.ts +2 -0
- package/dist/tools/resolve.js +1 -0
- package/dist/tools/search.d.ts +6 -0
- package/dist/tools/search.js +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.js +1 -0
- package/dist/utils/extract.d.ts +9 -0
- package/dist/utils/extract.js +1 -0
- package/dist/utils/guard.d.ts +26 -0
- package/dist/utils/guard.js +1 -0
- package/dist/utils/sanitize.d.ts +9 -0
- package/dist/utils/sanitize.js +1 -0
- package/dist/utils/watermark.d.ts +62 -0
- package/dist/utils/watermark.js +1 -0
- package/package.json +65 -0
- package/postinstall.mjs +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
Elastic License 2.0
|
|
2
|
+
|
|
3
|
+
URL: https://www.elastic.co/licensing/elastic-license
|
|
4
|
+
|
|
5
|
+
## Acceptance
|
|
6
|
+
|
|
7
|
+
By using the software, you agree to all of the terms and conditions below.
|
|
8
|
+
|
|
9
|
+
## Copyright License
|
|
10
|
+
|
|
11
|
+
The licensor grants you a non-exclusive, royalty-free, worldwide,
|
|
12
|
+
non-sublicensable, non-transferable license to use, copy, distribute, make
|
|
13
|
+
available, and prepare derivative works of the software, in each case subject to
|
|
14
|
+
the limitations and conditions below.
|
|
15
|
+
|
|
16
|
+
## Limitations
|
|
17
|
+
|
|
18
|
+
You may not provide the software to third parties as a hosted or managed
|
|
19
|
+
service, where the service provides users with access to any substantial set of
|
|
20
|
+
the features or functionality of the software.
|
|
21
|
+
|
|
22
|
+
You may not move, change, disable, or circumvent the license key functionality
|
|
23
|
+
in the software, and you may not remove or obscure any functionality in the
|
|
24
|
+
software that is protected by the license key.
|
|
25
|
+
|
|
26
|
+
You may not alter, remove, or obscure any licensing, copyright, or other notices
|
|
27
|
+
of the licensor in the software. Any use of the licensor's trademarks is subject
|
|
28
|
+
to applicable law.
|
|
29
|
+
|
|
30
|
+
## Patents
|
|
31
|
+
|
|
32
|
+
The licensor grants you a license, under any patent claims the licensor can
|
|
33
|
+
license, or becomes able to license, to make, have made, use, sell, offer for
|
|
34
|
+
sale, import and have imported the software, in each case subject to the
|
|
35
|
+
limitations and conditions in this license. This license does not cover any
|
|
36
|
+
patent claims that you cause to be infringed by modifications or additions to
|
|
37
|
+
the software. If you or your company make any written claim that the software
|
|
38
|
+
infringes or contributes to infringement of any patent, your patent license for
|
|
39
|
+
the software granted under these terms ends immediately.
|
|
40
|
+
|
|
41
|
+
## Notices
|
|
42
|
+
|
|
43
|
+
You must ensure that anyone who gets a copy of any part of the software from you
|
|
44
|
+
also gets a copy of these terms.
|
|
45
|
+
|
|
46
|
+
If you modify the software, you must include in any modified copies of the
|
|
47
|
+
software a prominent notice stating that you have modified the software.
|
|
48
|
+
|
|
49
|
+
## No Other Rights
|
|
50
|
+
|
|
51
|
+
These terms do not imply any licenses other than those expressly granted in
|
|
52
|
+
these terms.
|
|
53
|
+
|
|
54
|
+
## Termination
|
|
55
|
+
|
|
56
|
+
If you use the software in violation of these terms, such use is not licensed,
|
|
57
|
+
and your licenses will automatically terminate. If the licensor provides you
|
|
58
|
+
with a notice of your violation, and you cease all violation of this license no
|
|
59
|
+
later than 30 days after you receive that notice, your licenses will be
|
|
60
|
+
reinstated retroactively. However, if you violate these terms after such
|
|
61
|
+
reinstatement, any additional violation of these terms will cause your licenses
|
|
62
|
+
to terminate automatically and permanently.
|
|
63
|
+
|
|
64
|
+
## No Liability
|
|
65
|
+
|
|
66
|
+
As far as the law allows, the software comes as is, without any warranty or
|
|
67
|
+
condition, and the licensor will not be liable to you for any damages arising
|
|
68
|
+
out of these terms or the use or nature of the software, under any kind of
|
|
69
|
+
legal claim.
|
|
70
|
+
|
|
71
|
+
## Definitions
|
|
72
|
+
|
|
73
|
+
The _licensor_ is the entity offering these terms.
|
|
74
|
+
|
|
75
|
+
The _software_ is the software the licensor makes available under these terms.
|
|
76
|
+
|
|
77
|
+
A _service_ is a hosted or cloud service that makes the software available to
|
|
78
|
+
third parties.
|
|
79
|
+
|
|
80
|
+
_You_ refers to the individual or entity agreeing to these terms.
|
package/README.md
ADDED
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./banner.webp" alt="GroundTruth — self-hosted MCP server for live documentation and code audits" width="100%" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">GroundTruth</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
Your AI assistant just confidently wrote deprecated code again.<br/>
|
|
9
|
+
This fixes that.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/@groundtruth-mcp/gt-mcp"><img src="https://img.shields.io/npm/v/@groundtruth-mcp/gt-mcp?color=00d4aa&label=npm" alt="npm version" /></a>
|
|
14
|
+
<a href="https://github.com/rm-rf-prod/GroundTruth-MCP/actions/workflows/ci.yml"><img src="https://github.com/rm-rf-prod/GroundTruth-MCP/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
15
|
+
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-ELv2-orange" alt="Elastic License 2.0" /></a>
|
|
16
|
+
<img src="https://img.shields.io/badge/libraries-363%2B-teal" alt="363+ libraries" />
|
|
17
|
+
<img src="https://img.shields.io/badge/audit_patterns-100%2B-red" alt="100+ audit patterns" />
|
|
18
|
+
<img src="https://img.shields.io/badge/tests-565-brightgreen" alt="565 tests" />
|
|
19
|
+
<img src="https://img.shields.io/badge/node-%3E%3D24-green" alt="Node 24+" />
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## The problem with AI coding assistants
|
|
25
|
+
|
|
26
|
+
They hallucinate APIs. Not because the models are bad — because documentation moves faster than training data does. A library ships a major version, deprecates half its API, and the model keeps generating the old patterns for the next six months. You catch it in review if you're lucky. In production if you're not.
|
|
27
|
+
|
|
28
|
+
There's also the security problem nobody talks about enough. AI assistants produce insecure patterns without knowing they're doing it: SQL built with template literals, `innerHTML` fed user input, `any` scattered through TypeScript like confetti, `cookies()` called without `await` in Next.js 16. The model isn't malicious — it just learned from code that predates the rule change, and now it's your problem.
|
|
29
|
+
|
|
30
|
+
Context7 helps with the first problem. But it has rate limits, lives in the cloud, and covers around 130 libraries. Hit the quota mid-session and you get nothing. I did that enough times that I built the thing I actually wanted.
|
|
31
|
+
|
|
32
|
+
**GroundTruth runs on your machine.** It fetches docs directly from the source at query time — `llms.txt` files first (purpose-built for LLMs by the maintainers themselves), then Jina Reader for JS-rendered pages, then GitHub. No quota. No cold start. No cache from six months ago. 363+ libraries across the Python AI/ML stack, Go, Rust, and web standards including OWASP, MDN, and WebAssembly.
|
|
33
|
+
|
|
34
|
+
The audit tool scans your actual source files at `file:line` level and fetches current fix guidance from the real spec. Not a linting rule someone wrote in 2019. The actual spec.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<img src="./diagram.webp" alt="GroundTruth architecture — library nodes connected to a central hub, code audit panel, live documentation fetch" width="100%" />
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
### Claude Code
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
claude mcp add gt -- npx -y @groundtruth-mcp/gt-mcp@latest
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Cursor / Claude Desktop / VS Code
|
|
53
|
+
|
|
54
|
+
Add to your MCP config (`claude_desktop_config.json`, `.cursor/mcp.json`, or `.vscode/mcp.json`):
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"gt": {
|
|
60
|
+
"command": "npx",
|
|
61
|
+
"args": ["-y", "@groundtruth-mcp/gt-mcp@latest"]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
No build step. No config file. Node.js 24+. npx pulls the latest version on every session start automatically.
|
|
68
|
+
|
|
69
|
+
### Optional: GitHub token
|
|
70
|
+
|
|
71
|
+
GroundTruth fetches README files, release notes, and migration guides from GitHub. Unauthenticated requests are rate-limited to 60/hr. If you build anything with more than a couple dependencies, you'll hit that by lunch.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Claude Code
|
|
75
|
+
claude mcp add gt -e GT_GITHUB_TOKEN=ghp_yourtoken -- npx -y @groundtruth-mcp/gt-mcp@latest
|
|
76
|
+
|
|
77
|
+
# Cursor / Claude Desktop / VS Code
|
|
78
|
+
{
|
|
79
|
+
"mcpServers": {
|
|
80
|
+
"gt": {
|
|
81
|
+
"command": "npx",
|
|
82
|
+
"args": ["-y", "@groundtruth-mcp/gt-mcp@latest"],
|
|
83
|
+
"env": { "GT_GITHUB_TOKEN": "ghp_yourtoken" }
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
A token with no extra scopes (public repo read) is enough. Takes the limit from 60 to 5000 requests/hr. Takes about 30 seconds to set up. Worth it.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Tools
|
|
94
|
+
|
|
95
|
+
Nine tools. Each does one thing and stops there.
|
|
96
|
+
|
|
97
|
+
| Tool | What it does |
|
|
98
|
+
|---|---|
|
|
99
|
+
| `gt_resolve_library` | Find a library by name — gets the registry entry and docs URL |
|
|
100
|
+
| `gt_get_docs` | Fetch live docs for a specific topic (not whatever was cached six months ago) |
|
|
101
|
+
| `gt_best_practices` | Get patterns, anti-patterns, and config guidance for any library |
|
|
102
|
+
| `gt_auto_scan` | Read `package.json` / `requirements.txt`, fetch best practices for everything in it |
|
|
103
|
+
| `gt_search` | Search OWASP, MDN, web.dev, W3C, official language docs, and AI provider docs |
|
|
104
|
+
| `gt_audit` | Scan your source files — finds real issues at exact `file:line` with live fixes attached |
|
|
105
|
+
| `gt_changelog` | Fetch release notes before you run `npm update` and regret it |
|
|
106
|
+
| `gt_compat` | Check browser and runtime compatibility — before Safari breaks your launch |
|
|
107
|
+
| `gt_compare` | Compare 2–3 libraries side-by-side so you can finally pick one and move on |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## `gt_audit` — the one that finds what you missed
|
|
112
|
+
|
|
113
|
+
Walks your project, pinpoints issues at exact `file:line` locations, then fetches current fix guidance from official sources for every issue type it finds. A code reviewer who read the spec this morning and has no feelings about telling you your SQL is injectable.
|
|
114
|
+
|
|
115
|
+
### How it works
|
|
116
|
+
|
|
117
|
+
1. Reads all `.ts`, `.tsx`, `.js`, `.jsx`, `.css`, `.html`, `.py` files up to a configurable limit (default: 50, max: 200)
|
|
118
|
+
2. Skips test files, generated files, and commented-out lines (both `//` and `#`)
|
|
119
|
+
3. Runs 100+ patterns — sourced from OWASP cheat sheets, typescript-eslint rules, react.dev/reference/rules, web.dev, and the OWASP Python Security Cheat Sheet
|
|
120
|
+
4. For the top unique issue types, fetches current fix guidance from the authoritative source
|
|
121
|
+
5. Reports each finding with file path, line number, the problem, and a concrete fix
|
|
122
|
+
|
|
123
|
+
### Audit categories
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
gt_audit({ categories: ["all"] }) // default — all 18 categories
|
|
127
|
+
gt_audit({ categories: ["security", "node"] }) // OWASP + Node.js anti-patterns
|
|
128
|
+
gt_audit({ categories: ["python", "security"] }) // Python OWASP scan
|
|
129
|
+
gt_audit({ categories: ["accessibility"] }) // WCAG AA scan
|
|
130
|
+
gt_audit({ categories: ["typescript", "react"] }) // type safety + React rules
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
| Category | Patterns | What it checks |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| `layout` | 6 | CLS-causing images, raw `<img>` vs next/image, 100vh on mobile, missing font-display, render-blocking scripts, CSS `@import` chains |
|
|
136
|
+
| `performance` | 7 | Missing lazy loading, useEffect data fetching, barrel file tree-shaking, missing Suspense boundaries, `document.querySelector` in React, inline object/array props, missing fetchpriority on LCP image |
|
|
137
|
+
| `accessibility` | 10 | Missing alt text (WCAG 1.1.1), onClick on div/span (WCAG 2.1.1), icon-only buttons without aria-label, inputs without labels, `outline: none`, positive tabIndex, `role="button"` on non-buttons, placeholder href, missing lang, prefers-reduced-motion |
|
|
138
|
+
| `security` | 11 | XSS via innerHTML, SQL injection via template literals, command injection, SSRF via user-controlled URLs, path traversal in fs calls, `NEXT_PUBLIC_` secret exposure, hardcoded credentials, unvalidated Server Actions, implied eval, CORS wildcard, dynamic code execution |
|
|
139
|
+
| `react` | 7 | forwardRef deprecated (React 19), useFormState renamed, array index as key, missing event listener cleanup, conditional hook calls (Rules of Hooks), component called as function, side effects at render scope |
|
|
140
|
+
| `nextjs` | 6 | Sync `cookies()`/`headers()`/`params` without await (Next.js 16), `use client` on layout, Tailwind v3 directives, Route Handler without error handling, `middleware.ts` not renamed to `proxy.ts`, pages without metadata |
|
|
141
|
+
| `typescript` | 7 | `any` type, non-null assertions, missing return types, `@ts-ignore`, floating Promises, `require()` instead of import, double assertion |
|
|
142
|
+
| `node` | 5 | `console.log` in production, synchronous fs operations, unhandled callback errors, `process.exit()` without cleanup, plain HTTP fetch |
|
|
143
|
+
| `python` | 11 | SQL injection via f-string/format(), `eval()`/`exec()` with dynamic input, `subprocess` with `shell=True`, `os.system()`, bare `except:` clauses, `pickle.loads()` from untrusted source, MD5/SHA1 for passwords, `requests verify=False`, mutable default arguments, `print()` in production, `open()` path traversal |
|
|
144
|
+
|
|
145
|
+
### Options
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
gt_audit({
|
|
149
|
+
projectPath: "./src", // defaults to cwd
|
|
150
|
+
categories: ["security"], // or "all" (default)
|
|
151
|
+
maxFiles: 100, // 1–200, default 50
|
|
152
|
+
tokens: 6000, // max tokens per docs fetch, default 4000
|
|
153
|
+
})
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Sample output
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
# Code audit report
|
|
160
|
+
> Path: /projects/my-app
|
|
161
|
+
> Files scanned: 47 | Issues: 23 | Unique types: 9
|
|
162
|
+
> Categories: all
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## [CRITICAL] SQL built via template literal
|
|
167
|
+
Category: security | Severity: critical | Count: 2
|
|
168
|
+
|
|
169
|
+
Building SQL queries with template literals exposes the app to injection when
|
|
170
|
+
user input reaches the string.
|
|
171
|
+
|
|
172
|
+
Fix: db.query('SELECT * FROM users WHERE id = $1', [userId])
|
|
173
|
+
|
|
174
|
+
Files:
|
|
175
|
+
- src/db/users.ts:47
|
|
176
|
+
- src/api/search.ts:23
|
|
177
|
+
|
|
178
|
+
Live fix: OWASP SQL Injection Prevention Cheat Sheet
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## `gt_changelog` — read this before running `npm update`
|
|
184
|
+
|
|
185
|
+
Fetches release notes for any library. Hits GitHub Releases API first, falls back to CHANGELOG.md, then the docs site changelog page. Pass a version filter to see just what changed in the version you're moving to — not a wall of history going back to 2018.
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
gt_changelog({ libraryId: "vercel/next.js" })
|
|
189
|
+
gt_changelog({ libraryId: "facebook/react", version: "19" })
|
|
190
|
+
gt_changelog({ libraryId: "prisma", version: "6.0.0" })
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## `gt_compat` — does this actually work in Safari
|
|
196
|
+
|
|
197
|
+
Checks whether a web API, CSS feature, or JavaScript syntax is safe to use in your target environments. Pulls live data from MDN and caniuse.com. Run this before you ship the feature, not after your QA person opens it on an iPhone.
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
gt_compat({ feature: "CSS container queries" })
|
|
201
|
+
gt_compat({ feature: "Array.at()" })
|
|
202
|
+
gt_compat({ feature: "Web Bluetooth API" })
|
|
203
|
+
gt_compat({ feature: "CSS :has() selector", environments: ["safari", "firefox"] })
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## `gt_compare` — pick one already
|
|
209
|
+
|
|
210
|
+
Side-by-side comparison of 2–3 libraries. Fetches live docs for each and filters to content relevant to your criteria. Useful for the "prisma vs drizzle" debate you've been having with yourself for three weeks while using neither.
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
gt_compare({ libraries: ["prisma", "drizzle-orm"] })
|
|
214
|
+
gt_compare({ libraries: ["trpc", "hono"], criteria: "TypeScript support" })
|
|
215
|
+
gt_compare({ libraries: ["zod", "valibot", "yup"], criteria: "bundle size DX" })
|
|
216
|
+
gt_compare({ libraries: ["react", "solid-js"], criteria: "performance rendering" })
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## `gt_search` — anything that isn't a specific library
|
|
222
|
+
|
|
223
|
+
For questions not tied to a particular package. Pulls from OWASP, MDN, web.dev, W3C, official language docs, AI provider docs, and everything else in the topic map below. Good for when you know what you need but not which library page it lives on.
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
gt_search({ query: "WCAG 2.2 focus indicators" })
|
|
227
|
+
gt_search({ query: "JWT vs session cookies" })
|
|
228
|
+
gt_search({ query: "Core Web Vitals LCP optimization" })
|
|
229
|
+
gt_search({ query: "gRPC vs REST tradeoffs" })
|
|
230
|
+
gt_search({ query: "OpenTelemetry Node.js setup" })
|
|
231
|
+
gt_search({ query: "RAG retrieval patterns" })
|
|
232
|
+
gt_search({ query: "WebAssembly use cases" })
|
|
233
|
+
gt_search({ query: "MCP protocol tool definition" })
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Covered topic areas
|
|
237
|
+
|
|
238
|
+
| Area | Topics |
|
|
239
|
+
|---|---|
|
|
240
|
+
| Security | OWASP Top 10, SQL injection, XSS / CSP, CSRF, HSTS, authentication, CORS, JWT, OAuth 2.1, OIDC, WebAuthn / passkeys |
|
|
241
|
+
| Accessibility | WCAG 2.2, WAI-ARIA, keyboard navigation |
|
|
242
|
+
| Performance | Core Web Vitals, image optimization, web fonts, Speculation Rules API |
|
|
243
|
+
| Web APIs | Fetch, Web Workers, Service Workers, WebSocket, WebRTC, IndexedDB, Web Crypto, Intersection Observer, ResizeObserver, Web Animations API, WebAssembly |
|
|
244
|
+
| CSS | Grid, Flexbox, Container Queries, Custom Properties, View Transitions, Cascade Layers |
|
|
245
|
+
| HTTP & protocols | Headers, caching, HTTP/2, HTTP/3, REST, OpenAPI, GraphQL, gRPC / Protocol Buffers, Server-Sent Events |
|
|
246
|
+
| Standards | JSON Schema, JSON-LD / Structured Data, OpenTelemetry, Semantic Versioning, MCP Protocol |
|
|
247
|
+
| AI | Agents & tool calling, RAG, prompt engineering, vector search / embeddings |
|
|
248
|
+
| Infrastructure | Docker, Kubernetes, GitHub Actions, Terraform, monorepo patterns |
|
|
249
|
+
| Databases | PostgreSQL, Redis, MongoDB |
|
|
250
|
+
| Languages | Rust, Go, Python, Node.js, TypeScript |
|
|
251
|
+
| Frameworks | NestJS, Elysia, Payload CMS, Kysely, Pinia, React Native / Expo + full ecosystem |
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## `gt_auto_scan` — best practices for your whole stack at once
|
|
256
|
+
|
|
257
|
+
Point it at your project root. It reads the manifest, figures out what you're actually using, and pulls best practices for each dependency. One call instead of twenty, zero arguments required if you're already in the project folder.
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
gt_auto_scan({ projectPath: "." })
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Supports `package.json` (Node.js), `requirements.txt` / `pyproject.toml` (Python — pip, uv, hatch, rye, pdm, Poetry), `Cargo.toml` (Rust), `go.mod` (Go), `pom.xml` (Maven), `build.gradle` / `build.gradle.kts` (Gradle), and `composer.json` (PHP).
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Usage
|
|
268
|
+
|
|
269
|
+
### Natural language
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
use gt for nextjs
|
|
273
|
+
use gt for drizzle migrations
|
|
274
|
+
gt audit
|
|
275
|
+
use gt to check WCAG focus indicators
|
|
276
|
+
use gt for OpenTelemetry setup
|
|
277
|
+
find all issues and fix with gt
|
|
278
|
+
use gt for gRPC
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Direct tool calls
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
gt_resolve_library({ libraryName: "nestjs" })
|
|
285
|
+
gt_get_docs({ libraryId: "nestjs/nest", topic: "guards" })
|
|
286
|
+
gt_best_practices({ libraryId: "vercel/next.js", topic: "caching" })
|
|
287
|
+
gt_auto_scan({ projectPath: "." })
|
|
288
|
+
gt_search({ query: "OpenTelemetry Node.js distributed tracing" })
|
|
289
|
+
gt_audit({ projectPath: ".", categories: ["security", "accessibility"] })
|
|
290
|
+
gt_changelog({ libraryId: "vercel/next.js", version: "15" })
|
|
291
|
+
gt_compat({ feature: "CSS container queries", environments: ["safari"] })
|
|
292
|
+
gt_compare({ libraries: ["prisma", "drizzle-orm"], criteria: "TypeScript support" })
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
<p align="center">
|
|
298
|
+
<img src="./network.webp" alt="GroundTruth — documentation source network: llms.txt, OWASP, MDN, GitHub, npm" width="100%" />
|
|
299
|
+
</p>
|
|
300
|
+
|
|
301
|
+
## How docs are fetched
|
|
302
|
+
|
|
303
|
+
For every library docs request, GroundTruth tries sources in this order and stops at the first one that returns useful content:
|
|
304
|
+
|
|
305
|
+
1. **`llms.txt` / `llms-full.txt`** — context files published by the project maintainer specifically for LLM consumption. More reliable than scraping the docs site.
|
|
306
|
+
2. **Jina Reader** (`r.jina.ai`) — converts the official docs page to clean markdown. Handles JS-rendered sites that would return nothing via a plain fetch.
|
|
307
|
+
3. **GitHub README / releases** — latest release notes and README from the project repository.
|
|
308
|
+
4. **npm / PyPI metadata** — fallback for packages outside the curated registry.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Library coverage — 363+ libraries
|
|
313
|
+
|
|
314
|
+
Every major ecosystem. If a library publishes an `llms.txt`, it's probably in here.
|
|
315
|
+
|
|
316
|
+
| Ecosystem | Libraries |
|
|
317
|
+
|---|---|
|
|
318
|
+
| React / Next.js | React, Next.js, shadcn/ui, Radix UI, Tailwind CSS, Headless UI, Ariakit, Zag.js, Panda CSS |
|
|
319
|
+
| State management | Zustand, Jotai, TanStack Query, SWR, Redux Toolkit, Valtio, MobX, XState, Pinia |
|
|
320
|
+
| Backend (Node.js) | Express, Fastify, Hono, NestJS, Elysia, Nitro, tRPC |
|
|
321
|
+
| Backend (Python) | FastAPI, Django, Flask, Pydantic |
|
|
322
|
+
| Backend (Go) | Gin, Fiber, GORM, chi |
|
|
323
|
+
| Backend (Rust) | Axum, Actix Web, sqlx, Tokio |
|
|
324
|
+
| Database / ORM | Prisma, Drizzle, Kysely, TypeORM, Mongoose, Knex, Supabase, Neon, Turso, Electric SQL |
|
|
325
|
+
| Vector databases | Pinecone, Qdrant |
|
|
326
|
+
| AI / ML (JS) | Vercel AI SDK, Anthropic SDK, OpenAI SDK, LangChain.js, LlamaIndex.TS, Transformers.js, Ollama, assistant-ui |
|
|
327
|
+
| AI / ML (Python) | LangChain, LlamaIndex, CrewAI, LangGraph, HuggingFace Transformers |
|
|
328
|
+
| Testing | Vitest, Playwright, Jest, Testing Library, Cypress, MSW |
|
|
329
|
+
| Auth | Clerk, NextAuth, Better Auth, Lucia, Passport.js |
|
|
330
|
+
| Validation | Zod, Yup, Valibot, Effect |
|
|
331
|
+
| Rich text | Tiptap, Lexical, CodeMirror, Slate.js |
|
|
332
|
+
| Content | MDX, unified, Contentlayer, Fumadocs, gray-matter |
|
|
333
|
+
| CMS | Payload CMS, Strapi, Contentful |
|
|
334
|
+
| Email | Resend, Nodemailer |
|
|
335
|
+
| Payments | Stripe |
|
|
336
|
+
| Mobile | Expo, React Native, React Navigation, NativeWind, Reanimated, MMKV, FlashList, Skia, Moti |
|
|
337
|
+
| Build tools | Vite, Turbopack, SWC, Rollup, Webpack, Biome, ESLint, Prettier, Turborepo, Nx |
|
|
338
|
+
| Runtime | Node.js, Bun, Deno |
|
|
339
|
+
| Cloud | Vercel, Cloudflare Workers, AWS SDK, Firebase |
|
|
340
|
+
| HTTP clients | Axios, ky |
|
|
341
|
+
| Real-time | Socket.IO, PartyKit |
|
|
342
|
+
| Observability | OpenTelemetry, Sentry, Pino |
|
|
343
|
+
| GraphQL clients | Apollo Client, urql |
|
|
344
|
+
| HTTP utils | clsx, tailwind-merge |
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## vs. Context7
|
|
349
|
+
|
|
350
|
+
Context7 is solid. Here's why I reach for this instead.
|
|
351
|
+
|
|
352
|
+
| | GroundTruth | Context7 |
|
|
353
|
+
|---|---|---|
|
|
354
|
+
| Hosting | Self-hosted | Cloud |
|
|
355
|
+
| Rate limits | None | Yes |
|
|
356
|
+
| Source priority | llms.txt → Jina → GitHub | Doc page embeddings |
|
|
357
|
+
| Code audit | Yes — 100+ patterns, 18 categories, file:line, live fixes | No |
|
|
358
|
+
| Freeform search | Yes — OWASP, MDN, AI docs, web standards | Library docs only |
|
|
359
|
+
| Changelog lookup | Yes — GitHub Releases, CHANGELOG.md, docs site | No |
|
|
360
|
+
| Browser compatibility | Yes — MDN + caniuse.com | No |
|
|
361
|
+
| Library comparison | Yes — 2–3 libraries side-by-side, any criteria | No |
|
|
362
|
+
| Libraries | 363+ curated + npm/PyPI fallback | ~130 |
|
|
363
|
+
| Python / Rust / Go | Yes | Limited |
|
|
364
|
+
| API key required | No | No |
|
|
365
|
+
|
|
366
|
+
The two tools approach the same problem from different angles. Context7 embeds doc pages and retrieves them by semantic similarity. GroundTruth fetches from the source at query time and prioritizes `llms.txt` files — content the maintainers specifically wrote for LLM consumption. Neither is universally better, but when you hit a rate limit at 11pm debugging a production issue, "self-hosted with no quota" stops being a nice-to-have.
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Tests
|
|
371
|
+
|
|
372
|
+
565 tests across 19 files. Every audit pattern has a test. Every manifest parser has a test. If a pattern ships without a test, the CI pipeline says no before any human has to.
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
npm test # run all tests
|
|
376
|
+
npm run test:coverage # with V8 coverage report
|
|
377
|
+
npm run typecheck # TypeScript strict check (no emit)
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
| File | Coverage |
|
|
381
|
+
|---|---|
|
|
382
|
+
| `src/sources/registry.test.ts` | LIBRARY_REGISTRY integrity, `lookupById`, `lookupByAlias`, fuzzy search |
|
|
383
|
+
| `src/tools/audit.test.ts` | `buildCommentMap`, all 100+ patterns — Python, security, TypeScript, React, Node |
|
|
384
|
+
| `src/tools/auto-scan.test.ts` | All 8 manifest parsers using temp directories (package.json, requirements.txt, pyproject.toml, Cargo.toml, go.mod, pom.xml, composer.json, build.gradle) |
|
|
385
|
+
| `src/utils/extract.test.ts` | Topic relevance ranking, truncation, document order preservation |
|
|
386
|
+
| `src/utils/sanitize.test.ts` | Prompt injection stripping, `<script>`/`<style>` removal, navigation link cleanup |
|
|
387
|
+
|
|
388
|
+
Tests run in CI on every push and pull request to `main`. See `.github/workflows/ci.yml`.
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## Requirements
|
|
393
|
+
|
|
394
|
+
- Node.js 20+
|
|
395
|
+
- Claude Code, Cursor, VS Code (MCP extension), or Claude Desktop
|
|
396
|
+
|
|
397
|
+
That's it. No Docker. No config files. No environment variables unless you want the GitHub token.
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Contributing
|
|
402
|
+
|
|
403
|
+
The library registry lives in `src/sources/registry.ts`. Adding a library is a PR with `id`, `name`, `docsUrl`, and `llmsTxtUrl` if the project publishes one. If you've been frustrated by a library not being covered, that's the fix — it takes about five minutes.
|
|
404
|
+
|
|
405
|
+
Issues and requests: [github.com/rm-rf-prod/GroundTruth-MCP/issues](https://github.com/rm-rf-prod/GroundTruth-MCP/issues)
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## Star history
|
|
410
|
+
|
|
411
|
+
[](https://star-history.com/#rm-rf-prod/GroundTruth-MCP&Date)
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## License
|
|
416
|
+
|
|
417
|
+
[Elastic License 2.0](./LICENSE) — free to use, free to self-host, free to build on. The one thing you can't do is turn it into a managed service and sell it. Fair enough.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const SERVER_NAME = "gt-mcp-server";
|
|
2
|
+
export declare const SERVER_VERSION = "2.2.0";
|
|
3
|
+
export declare const REGISTRY_BADGE_SIZE = 363;
|
|
4
|
+
export declare const CHARS_PER_TOKEN = 3.8;
|
|
5
|
+
export declare const DISK_CACHE_DIR: string;
|
|
6
|
+
export declare const DEFAULT_TOKEN_LIMIT = 8000;
|
|
7
|
+
export declare const MAX_TOKEN_LIMIT = 20000;
|
|
8
|
+
export declare const CACHE_TTL_MS: number;
|
|
9
|
+
export declare const FETCH_TIMEOUT_MS = 15000;
|
|
10
|
+
export declare const JINA_BASE_URL = "https://r.jina.ai";
|
|
11
|
+
export declare const NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
12
|
+
export declare const PYPI_URL = "https://pypi.org/pypi";
|
|
13
|
+
export declare const GITHUB_API_URL = "https://api.github.com";
|
|
14
|
+
export declare const GITHUB_RAW_URL = "https://raw.githubusercontent.com";
|
|
15
|
+
export declare const INJECTION_PATTERNS: RegExp[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const a0_0xf8606e=a0_0x3f0c;(function(_0x56a970,_0x420860){const _0xc56e9=a0_0x3f0c,_0x2d60df=_0x56a970();while(!![]){try{const _0x2f1b18=-parseInt(_0xc56e9(0x8d,'1Jb*'))/0x1*(-parseInt(_0xc56e9(0x8a,'(hC^'))/0x2)+-parseInt(_0xc56e9(0x8b,'MNo@'))/0x3+parseInt(_0xc56e9(0x9e,'l(#Z'))/0x4+-parseInt(_0xc56e9(0xa2,'MNo@'))/0x5+parseInt(_0xc56e9(0xa1,')Xe&'))/0x6*(parseInt(_0xc56e9(0x99,'7mtT'))/0x7)+parseInt(_0xc56e9(0x85,'DCnd'))/0x8+-parseInt(_0xc56e9(0x94,'YFE6'))/0x9;if(_0x2f1b18===_0x420860)break;else _0x2d60df['push'](_0x2d60df['shift']());}catch(_0x1c4ba8){_0x2d60df['push'](_0x2d60df['shift']());}}}(a0_0x50e5,0xeadd3));export const SERVER_NAME=a0_0xf8606e(0x9b,'YFE6')+'ver';export const SERVER_VERSION=a0_0xf8606e(0x8f,'OzqG');export const REGISTRY_BADGE_SIZE=0x16b;export const CHARS_PER_TOKEN=3.8;function a0_0x3f0c(_0x2cf7b8,_0x5a1ed5){_0x2cf7b8=_0x2cf7b8-0x83;const _0x50e594=a0_0x50e5();let _0x3f0c96=_0x50e594[_0x2cf7b8];if(a0_0x3f0c['zgmqye']===undefined){var _0x1f00c7=function(_0x51bea8){const _0x5b5768='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x51df52='',_0x1dc44f='';for(let _0x343036=0x0,_0xdab292,_0x3f23ce,_0x4f8d31=0x0;_0x3f23ce=_0x51bea8['charAt'](_0x4f8d31++);~_0x3f23ce&&(_0xdab292=_0x343036%0x4?_0xdab292*0x40+_0x3f23ce:_0x3f23ce,_0x343036++%0x4)?_0x51df52+=String['fromCharCode'](0xff&_0xdab292>>(-0x2*_0x343036&0x6)):0x0){_0x3f23ce=_0x5b5768['indexOf'](_0x3f23ce);}for(let _0x300168=0x0,_0x8a60b4=_0x51df52['length'];_0x300168<_0x8a60b4;_0x300168++){_0x1dc44f+='%'+('00'+_0x51df52['charCodeAt'](_0x300168)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x1dc44f);};const _0x5d9eee=function(_0x2880b6,_0x7eea9b){let _0xc868dc=[],_0x587687=0x0,_0x570141,_0xe1429a='';_0x2880b6=_0x1f00c7(_0x2880b6);let _0x20f90f;for(_0x20f90f=0x0;_0x20f90f<0x100;_0x20f90f++){_0xc868dc[_0x20f90f]=_0x20f90f;}for(_0x20f90f=0x0;_0x20f90f<0x100;_0x20f90f++){_0x587687=(_0x587687+_0xc868dc[_0x20f90f]+_0x7eea9b['charCodeAt'](_0x20f90f%_0x7eea9b['length']))%0x100,_0x570141=_0xc868dc[_0x20f90f],_0xc868dc[_0x20f90f]=_0xc868dc[_0x587687],_0xc868dc[_0x587687]=_0x570141;}_0x20f90f=0x0,_0x587687=0x0;for(let _0x2fe401=0x0;_0x2fe401<_0x2880b6['length'];_0x2fe401++){_0x20f90f=(_0x20f90f+0x1)%0x100,_0x587687=(_0x587687+_0xc868dc[_0x20f90f])%0x100,_0x570141=_0xc868dc[_0x20f90f],_0xc868dc[_0x20f90f]=_0xc868dc[_0x587687],_0xc868dc[_0x587687]=_0x570141,_0xe1429a+=String['fromCharCode'](_0x2880b6['charCodeAt'](_0x2fe401)^_0xc868dc[(_0xc868dc[_0x20f90f]+_0xc868dc[_0x587687])%0x100]);}return _0xe1429a;};a0_0x3f0c['iwdjlZ']=_0x5d9eee,a0_0x3f0c['VgVzWH']={},a0_0x3f0c['zgmqye']=!![];}const _0xdaaec8=_0x50e594[0x0],_0x478e48=_0x2cf7b8+_0xdaaec8,_0x3f4905=a0_0x3f0c['VgVzWH'][_0x478e48];return!_0x3f4905?(a0_0x3f0c['vSHztV']===undefined&&(a0_0x3f0c['vSHztV']=!![]),_0x3f0c96=a0_0x3f0c['iwdjlZ'](_0x3f0c96,_0x5a1ed5),a0_0x3f0c['VgVzWH'][_0x478e48]=_0x3f0c96):_0x3f0c96=_0x3f4905,_0x3f0c96;}function a0_0x50e5(){const _0x4e9dd5=['DCoVgNddVXSpWRddRCoP','CSkUACoMW4BdQ8or','eCkDdSkFr2JcQSovrYerWPC','ACk7tSot','WRdcOCkKW6z/mdrTWOuYnmk8W5a','W44QwYhcGthcN8kAASoAWOJcLmoc','W4xdSteKCmoxxCoDFLzlWOft','j8kSs8ogmCk2iIlcQ8kG','WPrLbMhdJ8kvq07cN8k4','WRSJBmo/ob53W5eWfq','WRqAvCkMWQGXWPDFW7xcHgG4tvu','WRahW7xdUSoWxNjCoSoL','W5L/j8kwW77dMfujz8kTW6ldOgm','WRtcPmkJW6v6mwzvWRGVaSkx','WQtcOfNdLd9OnvlcHqy','eePbWR7dHmkYmI8','W4hdUdePDCowx8oVw0b3WRD1','tmodWPZdTG03jmod','W5xdQGlcRapcVCoWWRtdH19bWRa','xmktD0lcPaJdJ0G5ia','db8SWQdcSW','WPzIxh7dJSoi','WQChWQJdOCoWqhncm8o4','W4WTxsJcHZRcMSodu8oMWOBcUmoHdG','W6/dSxbeWO7cIZBcKLtdKa','W7/dOXZcLhPLktxcRZnhWQVcKa','wulcQXZcGSoIW7JdOq','qeddMrKYgrZcL2pcIW','WRa4Dq','bmkqWQFdHZNcOGFcHGCFWPO/','eNpdQZK6ady','W5iZcgtcNgxdJmkfcmoF','WQVcOaddIs8InW7cKHe'];a0_0x50e5=function(){return _0x4e9dd5;};return a0_0x50e5();}export const DISK_CACHE_DIR=process.env.GT_CACHE_DIR??(process.env.HOME?process.env.HOME+(a0_0xf8606e(0x9a,')Xe&')+a0_0xf8606e(0x9f,'zfoz')):a0_0xf8606e(0xa3,'zfoz')+a0_0xf8606e(0x95,'JEcx'));export const DEFAULT_TOKEN_LIMIT=0x1f40;export const MAX_TOKEN_LIMIT=0x4e20;export const CACHE_TTL_MS=0x1e*0x3c*0x3e8;export const FETCH_TIMEOUT_MS=0x3a98;export const JINA_BASE_URL='https://r.'+'jina.ai';export const NPM_REGISTRY_URL=a0_0xf8606e(0x89,'YFE6')+a0_0xf8606e(0x86,')$UA')+a0_0xf8606e(0x90,'XjJu');export const PYPI_URL=a0_0xf8606e(0x93,'MhvX')+a0_0xf8606e(0x91,')$UA')+'i';export const GITHUB_API_URL=a0_0xf8606e(0x83,'XjJu')+a0_0xf8606e(0x8e,'TZ8D')+'om';export const GITHUB_RAW_URL=a0_0xf8606e(0x84,'sn6)')+a0_0xf8606e(0x9c,'yjGe')+a0_0xf8606e(0x96,'7mtT')+a0_0xf8606e(0x97,'sn6)');export const INJECTION_PATTERNS=[/ignore\s+(all\s+)?(previous|prior|above)\s+instructions?/gi,/you\s+(are|must|should|will|have\s+to)\s+now/gi,/\bSYSTEM\s*:/g,/\bASSISTANT\s*:/g,/\b(JAILBREAK|DAN|DO ANYTHING NOW)\b/gi,/<\s*(?:system|instructions?)\s*>/gi,/forget\s+(everything|all)\s+(you|your)/gi,/new\s+instructions?.*?:/gi,/override\s+(your\s+)?(previous\s+)?instructions?/gi];
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const a1_0x292dff=a1_0x2ee7;(function(_0x1cdb01,_0x33dbd2){const _0x2db614=a1_0x2ee7,_0x5ed0aa=_0x1cdb01();while(!![]){try{const _0x67140e=parseInt(_0x2db614(0x1bc,'b^0H'))/0x1+-parseInt(_0x2db614(0x160,'2J49'))/0x2*(-parseInt(_0x2db614(0x1a9,'U]Q)'))/0x3)+-parseInt(_0x2db614(0x21d,'oZ%Q'))/0x4*(parseInt(_0x2db614(0x20f,'S]Xl'))/0x5)+parseInt(_0x2db614(0x1e0,'3v[%'))/0x6+-parseInt(_0x2db614(0x1de,'UL*E'))/0x7+parseInt(_0x2db614(0x161,'#q8W'))/0x8+-parseInt(_0x2db614(0x1e3,'h1o8'))/0x9;if(_0x67140e===_0x33dbd2)break;else _0x5ed0aa['push'](_0x5ed0aa['shift']());}catch(_0x396f93){_0x5ed0aa['push'](_0x5ed0aa['shift']());}}}(a1_0x44c1,0x68e8e));import{McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import{StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import{SERVER_NAME,SERVER_VERSION}from'./constants.js';import{getInstallId}from'./utils/watermark.js';import{registerResolveTool}from'./tools/resolve.js';import{registerDocsTool}from'./tools/docs.js';import{registerBestPracticesTool}from'./tools/best-practices.js';function a1_0x2ee7(_0x51324e,_0x32e595){_0x51324e=_0x51324e-0x157;const _0x44c1a2=a1_0x44c1();let _0x2ee703=_0x44c1a2[_0x51324e];if(a1_0x2ee7['KwVTAg']===undefined){var _0x28c10e=function(_0xa5b214){const _0x4322e1='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x1f57bc='',_0x22f17e='';for(let _0x4af583=0x0,_0x49ede4,_0x163a4a,_0x3d0a3e=0x0;_0x163a4a=_0xa5b214['charAt'](_0x3d0a3e++);~_0x163a4a&&(_0x49ede4=_0x4af583%0x4?_0x49ede4*0x40+_0x163a4a:_0x163a4a,_0x4af583++%0x4)?_0x1f57bc+=String['fromCharCode'](0xff&_0x49ede4>>(-0x2*_0x4af583&0x6)):0x0){_0x163a4a=_0x4322e1['indexOf'](_0x163a4a);}for(let _0x265f3b=0x0,_0x383d62=_0x1f57bc['length'];_0x265f3b<_0x383d62;_0x265f3b++){_0x22f17e+='%'+('00'+_0x1f57bc['charCodeAt'](_0x265f3b)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x22f17e);};const _0x1c5efc=function(_0x26d13c,_0x44d81a){let _0x1b2af9=[],_0x3e334c=0x0,_0x4e5871,_0x8d8aea='';_0x26d13c=_0x28c10e(_0x26d13c);let _0xaf463a;for(_0xaf463a=0x0;_0xaf463a<0x100;_0xaf463a++){_0x1b2af9[_0xaf463a]=_0xaf463a;}for(_0xaf463a=0x0;_0xaf463a<0x100;_0xaf463a++){_0x3e334c=(_0x3e334c+_0x1b2af9[_0xaf463a]+_0x44d81a['charCodeAt'](_0xaf463a%_0x44d81a['length']))%0x100,_0x4e5871=_0x1b2af9[_0xaf463a],_0x1b2af9[_0xaf463a]=_0x1b2af9[_0x3e334c],_0x1b2af9[_0x3e334c]=_0x4e5871;}_0xaf463a=0x0,_0x3e334c=0x0;for(let _0x78c374=0x0;_0x78c374<_0x26d13c['length'];_0x78c374++){_0xaf463a=(_0xaf463a+0x1)%0x100,_0x3e334c=(_0x3e334c+_0x1b2af9[_0xaf463a])%0x100,_0x4e5871=_0x1b2af9[_0xaf463a],_0x1b2af9[_0xaf463a]=_0x1b2af9[_0x3e334c],_0x1b2af9[_0x3e334c]=_0x4e5871,_0x8d8aea+=String['fromCharCode'](_0x26d13c['charCodeAt'](_0x78c374)^_0x1b2af9[(_0x1b2af9[_0xaf463a]+_0x1b2af9[_0x3e334c])%0x100]);}return _0x8d8aea;};a1_0x2ee7['jZcMIx']=_0x1c5efc,a1_0x2ee7['XmyDhu']={},a1_0x2ee7['KwVTAg']=!![];}const _0x729f00=_0x44c1a2[0x0],_0x3e9fd3=_0x51324e+_0x729f00,_0x189dd4=a1_0x2ee7['XmyDhu'][_0x3e9fd3];return!_0x189dd4?(a1_0x2ee7['sNmgLb']===undefined&&(a1_0x2ee7['sNmgLb']=!![]),_0x2ee703=a1_0x2ee7['jZcMIx'](_0x2ee703,_0x32e595),a1_0x2ee7['XmyDhu'][_0x3e9fd3]=_0x2ee703):_0x2ee703=_0x189dd4,_0x2ee703;}import{registerAutoScanTool}from'./tools/auto-scan.js';function a1_0x44c1(){const _0x3d4a38=['pmk8zwu8W4hcUYRcSCke','dHn3smotW7FcGSkZW6Lq','CSksBLbglSkqW6ZdG0K','W5W+o8oTB3fjW4NcVCkR','W7ihv2xcUfVdR8kbe8ks','Emksph56','m8kiwXuAW5iwW4SYWPy','WRDn4Okaqf/dU8kZgGlcOq','WP3cKmoeB8kGmSoSzt4D','WOZdN8kbWQFdKMbwFhFdLW','EmkvWQddJ1mgWQNdVSk3WRy','CSoZbN0RW4BcUW7cOmkh','oG8/W7VcOSo3mSkFaSoa','dGH6tSkwW6ldG8kKWQXp','qSoRldddVrm0rCo2dG','WRKqqNhcHmoNW7qoFmk8','W43cV8kxBZ0yW4GbmMy','W6VdGrPcDf3dOcNdG8oy','B8kqnSoyiK7cTmkxxmoD','p8kLWRJdQatcSCouymkrva','W5NdOmopnM0uW7WpmxFcINe','qH7cRNldHKBcJ8oxWRxdPa','W7i/qxBcVhZdPCkCfmkr','uSoiis4KDSosoa7dRW','xXxdUJJcG1FcMmoCW77cQq','jSkInxD5W4xdQtBcQmof','cSkrkCowW4zcoSoYxY0','nSkSW77dMmk7EmkKW53cIcvqvSkH','drJdSmkPA8oSr8kkFmoeaCkQW7m','kJNcUdhdOxJdQ8oqW4ldJq','W45xWOHHW510gXCxWPu','WQxcQCoeWQtcRK5wmCkKWQK','WOdcRYddPHaMFr/cKSki','fSoGW7ddH1JcLIJdH8okWQ0','WOJcQ8knoxHoW40klMi','B8otk3GxuqmDW5HW','iCobyCowiKhcUCkCx8oA','cCkDnr4YsmoUa0a','umoQmdBcUJq1rSk9kG','W75GtSodWOiwm0bTBq','nNFdP8kiW7RdLCkwW7aWWQq','qKvKb8ksWOClCCkvW4e','WPxcK8odW7pdH3XAFtNcKq','rtldNSoWWORcGCkdxt7dGW','aXn/x8oFW6VdHmoOWQHs','cv3cOG7cIf8DWQD9tSoB','C8kho8oGsSoOFdLzlG','bbrTxSotW7FcISoGWQvD','WOzCjCkuWRrqdvTcW58','W7LYuSofW4KvBqf5Fa','WO/cRSkinZ/dVCks','W4FcLX/dRg8xW5tcRwxdSa','wqNcTCo5kSkOaSkOy8ow','a8oHWO/dL1tcKYpdH8odWRa','p8oNDwRdTZPlW5T7W4S','WPxcKLKZW4BdHCo4n8kmW7u','WRLesKZcSSoiWR5wnCkS','zhqJumoIs3/dRmoJW5m','q8kul8oOW4DEDCkkcwS','B8kBWQ/dRHlcSCouhCoFbW','ar14wmkEW5qiymkbW54','AJNcHIBdTMBcOmozW4xdGq','W783y8ouWPOrpZbOAq','WPRcHmomW7xdNYqtDd7dNq','BwSSW67dQSoOymoYtCobWRpdUG','FmortZa/W4RdTt3dPCke','n8o4cuVcGcGEWRtcS8ksWROeW5y','hfZcTmo5yCo/umkIy8or','mrD3xCoj','jHCT','W44Q4OAolSoDWQ4Dv2FdKG','lmk0WRldOGFcQ8kxbSkysq','ushdJCo6W5BcImowuIpdLa','WPiPBSoVBNTgW5RdTmkY','yCopoCo6smkXFd5zzW','DmkTxGZdKhXdWP/dNmkF','F8occtKqweboW5P8','B3RdJhtcUYldQ8kuWPpdGq','WP8PpCoWAhPoW4ldTmkP','zCk5WQJdLvKCW7pdLokcQCoh','W7ifr2hcVgtdV8oAvSoc','trDSrmoCW6hdICk8W6Ly','WR/dRb5BzvpdJd/cGmox','WOrVW4LmWQ7dHxhcUCowAa','nWv3hSodWPncpYHV','W65KrmkrWO4rpubTyq','W4HdzmktWR4dabrvWPO','AmkJsLJdJxDdW4ZcKmkq','WR4LsZxcVcJdOmkAgmkq','s8o3cGHnhfOpWPSX','WRPnW6CizCoGWRyir8kA','W6VdGrLsC0BdOcRdKSoy','mCkjiEkhJ3b1W48ixCor','t0BcQ8oQo8kchmkVzmoa','FZpcQ2hdLSk3i8o2hHG','B8kSWRldTWFdUmormSksua','F3BcGYdcUx/cRCotW5FcLq','W6G7aCobWOWxEuW6Aq','z0f+W7xcL2tcP3Xor8ocovC','aKD/c8oXW5dcISkbWO0C','lSkYlZ3dRMSwW7DxW4JdUYFcUq','WQHvqmoXWP7cQmkNWRNdKHe','WPTkzmkvWRGyxe8xWO4','WPZdMeJcQ3zbWPxdJN7dLSoQyLC','FmoBBIG+DSoVjvVdGa','WOrgz8kvWROcdrrdWPa','b8kuWO/dKu7dUmo0e8kUeq','ACk+hspdNxPsWONcN8kn','WO7IG7TAW5WGg8oqW6XJW70','lCoaimocmG3cSSowxSow','pmoZpM9WWOpdRZBdPCkw','v20VbCkwW6pdNSkxWRTz','WOxcHmkdW6RcHefDFCoGWRW','n3xcQCkgW7hdMSkvW6j0WQS','fMBcPHpcMu8XWQbOAq','nHDXwSosW5Orl2LR','W4vlzmktWR5qefTuWOO','kN10WQJcRmkRxCoMkSkv','xSo2tsvfWQFdQfmCWPW','kJ1OWQNcVmk7s8k14Oc0WPu','oMFdPCoBWP7cLSoA4OsxDmkQ','pmkLW7VdPHBdUmorl8kphq','W5GfW5j+W44','wSoByJv4ACkBjLVdKq','sCo/thbxW67dOWmCWOK','CCoYsZjdW6BdQvOKW50','WOZcQ8khi+kbJaldTG0VBa','WOpcS2hIGObjsqjFW5pcHq','W714u8ouW4KqBWDOAq','WPVdNSoyFCoHn8oNBgPB','W4lcUJxdIXPTfLNdN8oa','WQShcIhcN8o1W6qpCmo/','W4/cGr7cVYSzW4pdVJhdJq','DgddJhtcU1FcSCovW4hcIa','qchdKCkJWP3cHSketc/dMa','n8kAuH5EW4mxW4C3WOa','k+kgLMPYWRWXimk7W6pdKG','W6TrsSoSW5VcGSoyWORcNEkbSW','WRzZswdcTgZdQCkFe8km','haNIHzxcVdNcQs/cP3pdLG','o8oGWRNdPbhcRmkxmmkpxa','r8o9z0JdMbWTqmo6ta','WPXZmI7dH8kpwbbXW6G','WR/dQWHsifxdIWxdGCom','WR8DvCoXW5/dImoiWPNdIw0','W4KOW4j0W49JlWycWPe','vuRcOSoVFSk7h8k0jSox','W5JcGCkWvWjtW40','u8oaCN02E8ojjfRcLa','WPRcLCkPdHxdRCkpWOvOCW','WPXJEx3cSSkpvfr2WQa','W5mtW4fJW5HKxfydWPu','WOzljCkbWRiivfvBWPm','W4FdN8omAtldPmkEWOiQyW','zdNcHsddUglcOCoBW4pcHq','W5/cQq4ZWQK8vSoIWOrZ','B8kOWR7dRrldUmoakCkjvq','WOfnD8kgWQKjpvanW58','prvWemkbWQrup31T','caz9q8kyWQtdV8k7WQWC','yw3cQtxdRhJcQSoLW4lcGG','W65vWQDvpCkHW6OhdCk7l8kLzW','pSoLFSkU4OE4WRf0ocy3','pgdcRSkcW7hdHCoA4OkrDmkl','WP3cHCknW6hdIxOtC3FdGG','ACk4waVcMx5iWOJdNmkA','y8k/tHhdM3zkWOxcImka','WRlcRmknWR7cOKnztmoIW6G','WR8nawRdLSorW7GiFSk5','W7xdQmoqW6pdJqar4OAdW6dcRW','WR48wwBdPWlcHSord8kr','D8komSkUlSo+CdKuia','WP0vW4vIW4G3aaqrWPm','oCkEwbiDW54zW4r7WPC','i8krtb4tW5iwW5WOW50','m1aRWQxdKshcSebgua','wCoXptVdSJS0u8kZqq','W7VdTXvqlJJcH3tcGmoE','W4xdIcy3W53dT8oRpSkFW74','zmopde9hWObnW6S0WR3cSq3dJa','tdpdT1ldLfGKWOSV4Ocy','CNhcNZRdVIZcOmowW4lcHa','WO7cMGNdTIerWOddOxJdRG','jM7cKZBcUu3cLCoZWP3dGq','cSoEcSokW7rGCSkSnJu','y8k0vaW','dmoHeSkqluJcVCodrSob','cmkWdh4tWQVcU1CwWO8','WOpcVYddPWX7wWVdLCog','sHxcTfpdMeuGW59HAq','WPFdIIy/W5VcImocbCoEW6m','ExbOWQJcUSo+x8oHamob','WOT4EMhdOmkrxf5WW6G','stpcKmoXWOVcNCkcvYFdKW','CUkbOIn4W5pcK1qTz20','W7KjeCoaW5ldUmo4WQ7dKW','s8kAW6i1fWTqu8oZW7lcU0zK','jN/cMsBcUx7cOmoBW53dGq','FmksnZfMfSoDW73cJe0','W6BcSLTwBLBcNZVdJSoa','sJtcL8o4W57cG8keusddKW','xmomBti3mUkcR3DOW5e','rJtdNmoRW57cHSkgeZ7dMq','DSkrtqGlW5ilWOP7W5W','e8ooWQHVsfXezSklW5e','W4VcMXNdT28AW4NdU3tcUa','m8kCwX9qWR1oWOz7WPq','lttcTCkeW7xdMSoAW6CHWQO','WQKldg/cK8oLW6m','AmoppCoHbmoLDIinzq','tdpdSfldMLTL4OoRl0O','re9PvmomW4iozSkAW5G','WQTnW6apkSo2WRijbmk4','mgBdP8kaWRtdMSktW6CMWQW','rIpdISoXWPFcH8kphMldUq','WOtdMCouB8kYymoPyMXB','WPK4lCoRixrgW5RdUmkU','wmoDAd41yCkXxw/dMa','rv9KvmozW5nnzCkBW54','tqzRx8oEWQtdMCk8WQHs','W7BdQGiBigddMJVdG8on','W65CWQjto8oIWOi0fCkrdW','DmkvWQBdJeSqW5JcMmouWOu'];a1_0x44c1=function(){return _0x3d4a38;};return a1_0x44c1();}import{registerSearchTool}from'./tools/search.js';import{registerAuditTool}from'./tools/audit.js';import{registerChangelogTool}from'./tools/changelog.js';import{registerCompatTool}from'./tools/compat.js';import{registerCompareTool}from'./tools/compare.js';const server=new McpServer({'name':SERVER_NAME,'version':SERVER_VERSION},{'instructions':a1_0x292dff(0x1e4,'H#L9')+a1_0x292dff(0x183,'oZ%Q')+a1_0x292dff(0x227,'TEq&')+a1_0x292dff(0x1a8,'&[OF')+a1_0x292dff(0x1ba,'tYk1')+a1_0x292dff(0x1c3,'HOLY')+a1_0x292dff(0x1e1,'2J49')+a1_0x292dff(0x19e,'S]Xl')+a1_0x292dff(0x1a5,'1Oc5')+a1_0x292dff(0x1a3,'tYk1')+a1_0x292dff(0x216,'3ikQ')+a1_0x292dff(0x1b4,'Hs5d')+a1_0x292dff(0x173,'f%]y')+a1_0x292dff(0x1d5,'e$0^')+a1_0x292dff(0x222,'DyKp')+a1_0x292dff(0x234,'3hzW')+a1_0x292dff(0x15d,'2yuw')+a1_0x292dff(0x187,'!@Xx')+a1_0x292dff(0x1cc,'LnsC')+a1_0x292dff(0x1e6,'HOLY')+a1_0x292dff(0x178,'&[OF')+a1_0x292dff(0x1ef,'P^sq')+a1_0x292dff(0x159,'7KG7')+a1_0x292dff(0x1a7,'f%]y')+'re,\x20and\x20mo'+a1_0x292dff(0x209,'VxfK')+a1_0x292dff(0x203,'6B]I')+a1_0x292dff(0x1eb,'&[OF')+a1_0x292dff(0x1d9,'97oM')+a1_0x292dff(0x1fa,'S]Xl')+a1_0x292dff(0x1d4,'LnsC')+a1_0x292dff(0x163,'j&^T')+a1_0x292dff(0x1df,'&[OF')+a1_0x292dff(0x200,'h1o8')+a1_0x292dff(0x1ec,'vUae')+a1_0x292dff(0x210,'H#L9')+a1_0x292dff(0x1aa,'TEq&')+a1_0x292dff(0x1d3,'DyKp')+a1_0x292dff(0x1e9,'&Fld')+a1_0x292dff(0x1ee,'U]Q)')+a1_0x292dff(0x16f,'U]Q)')+a1_0x292dff(0x167,'f%]y')+a1_0x292dff(0x1f0,'jwtC')+a1_0x292dff(0x1a6,'VSvk')+'for\x20any\x20li'+a1_0x292dff(0x1bb,'VSvk')+'tered\x20by\x20t'+a1_0x292dff(0x1b5,'PRay')+a1_0x292dff(0x1d7,'z7gH')+a1_0x292dff(0x21f,'vhKw')+a1_0x292dff(0x175,'g]Jb')+a1_0x292dff(0x208,'HOLY')+'ctices,\x20pa'+'tterns,\x20an'+a1_0x292dff(0x206,'LnsC')+a1_0x292dff(0x220,'VSvk')+a1_0x292dff(0x18f,'HOLY')+a1_0x292dff(0x19c,'7KG7')+a1_0x292dff(0x21c,'3ikQ')+a1_0x292dff(0x1fb,'7KG7')+'detect\x20ALL'+a1_0x292dff(0x1cd,'&[OF')+a1_0x292dff(0x182,'6B]I')+a1_0x292dff(0x19a,'UYCi')+a1_0x292dff(0x1cf,'rCH$')+a1_0x292dff(0x22a,'6B]I')+a1_0x292dff(0x194,'BjYJ')+a1_0x292dff(0x1b2,'3v[%')+a1_0x292dff(0x228,'UYCi')+a1_0x292dff(0x174,'uFQV')+a1_0x292dff(0x21b,'&[OF')+'when\x20the\x20u'+a1_0x292dff(0x19f,'e$0^')+a1_0x292dff(0x1d1,'tYk1')+a1_0x292dff(0x1f2,'pARn')+a1_0x292dff(0x169,'#q8W')+a1_0x292dff(0x1b6,'3hzW')+a1_0x292dff(0x1fe,'7KG7')+a1_0x292dff(0x15f,'P^sq')+a1_0x292dff(0x184,'uFQV')+a1_0x292dff(0x17e,'j&^T')+a1_0x292dff(0x1a4,'vhKw')+a1_0x292dff(0x17c,'!@Xx')+a1_0x292dff(0x213,'UYCi')+'curity,\x20ac'+a1_0x292dff(0x1ca,'g]Jb')+a1_0x292dff(0x164,'z7gH')+a1_0x292dff(0x231,'3ikQ')+'.\x20No\x20libra'+a1_0x292dff(0x15a,'U]Q)')+a1_0x292dff(0x16b,'6B]I')+a1_0x292dff(0x1cb,'Klve')+'Scan\x20actua'+a1_0x292dff(0x1b9,'3ikQ')+a1_0x292dff(0x189,'&[OF')+a1_0x292dff(0x162,'3ikQ')+a1_0x292dff(0x1ab,'&[OF')+a1_0x292dff(0x1dc,'3ikQ')+a1_0x292dff(0x1dd,'tYk1')+a1_0x292dff(0x1b8,'1Oc5')+(a1_0x292dff(0x179,'z7gH')+a1_0x292dff(0x199,'3ikQ')+a1_0x292dff(0x180,'LnsC')+a1_0x292dff(0x185,'VSvk')+a1_0x292dff(0x16a,'h1o8')+a1_0x292dff(0x1ad,'tYk1')+a1_0x292dff(0x20e,'97oM')+a1_0x292dff(0x1ff,'Hs5d')+a1_0x292dff(0x195,'!@Xx')+a1_0x292dff(0x229,'6B]I')+a1_0x292dff(0x21a,'P^sq')+a1_0x292dff(0x1a0,'&Fld')+a1_0x292dff(0x1c5,'g]Jb')+a1_0x292dff(0x1ac,'jwtC')+a1_0x292dff(0x1f8,'pARn')+a1_0x292dff(0x1a2,'VxfK')+a1_0x292dff(0x22e,'ACs4')+a1_0x292dff(0x166,'H#L9')+a1_0x292dff(0x170,'1Oc5')+a1_0x292dff(0x1ce,'z7gH')+a1_0x292dff(0x221,'DyKp')+a1_0x292dff(0x1ed,'vhKw')+a1_0x292dff(0x172,'vhKw')+a1_0x292dff(0x20a,'2yuw')+a1_0x292dff(0x1fc,'tYk1')+a1_0x292dff(0x22d,'z7gH')+a1_0x292dff(0x230,'U]Q)')+'\x20Check\x20bro'+a1_0x292dff(0x18a,'VxfK')+a1_0x292dff(0x15e,'f%]y')+a1_0x292dff(0x211,'l(Ho')+a1_0x292dff(0x22c,'VxfK')+a1_0x292dff(0x233,'3ikQ')+a1_0x292dff(0x157,'&Fld')+a1_0x292dff(0x15b,'ACs4')+'yntax.\x0a9.\x20'+a1_0x292dff(0x1b3,'ACs4')+a1_0x292dff(0x1e8,'h1o8')+'\x202–3\x20libra'+a1_0x292dff(0x212,'2yuw')+'by-side\x20to'+a1_0x292dff(0x218,'HOLY')+a1_0x292dff(0x18e,'&Fld')+a1_0x292dff(0x1d6,'oZ%Q')+a1_0x292dff(0x1bf,'97oM')+a1_0x292dff(0x186,'Klve')+a1_0x292dff(0x224,'Hs5d')+a1_0x292dff(0x226,'LnsC')+a1_0x292dff(0x1c6,'TEq&')+a1_0x292dff(0x177,'1Oc5')+a1_0x292dff(0x1d2,'jwtC')+a1_0x292dff(0x18b,'Hs5d')+a1_0x292dff(0x1f4,'vhKw')+a1_0x292dff(0x18d,'z7gH')+a1_0x292dff(0x1ea,'!@Xx')+a1_0x292dff(0x202,'f%]y')+a1_0x292dff(0x20c,'2J49')+a1_0x292dff(0x1c2,'2yuw')+a1_0x292dff(0x1e2,'jwtC')+'uery:\x20\x22lat'+a1_0x292dff(0x1d0,'P^sq')+a1_0x292dff(0x1c7,'DyKp')+a1_0x292dff(0x1e7,'DyKp')+a1_0x292dff(0x223,'vUae')+'})\x0a\x0a\x22use\x20g'+a1_0x292dff(0x171,'oZ%Q')+a1_0x292dff(0x1b7,'HOLY')+a1_0x292dff(0x1d8,'H#L9')+a1_0x292dff(0x1f7,'H#L9')+a1_0x292dff(0x201,'3ikQ')+a1_0x292dff(0x188,'b^0H')+a1_0x292dff(0x1f5,'HOLY')+a1_0x292dff(0x1f9,'pARn')+a1_0x292dff(0x21e,'TEq&')+a1_0x292dff(0x17b,'Klve')+a1_0x292dff(0x1c4,'f%]y')+'raryName:\x20'+a1_0x292dff(0x1da,'kv7*')+a1_0x292dff(0x225,'vUae')+a1_0x292dff(0x20d,'UYCi')+a1_0x292dff(0x17d,'&[OF')+a1_0x292dff(0x219,'jwtC')+a1_0x292dff(0x158,'pARn')+a1_0x292dff(0x1c9,'3ikQ')+a1_0x292dff(0x215,'l(Ho')+a1_0x292dff(0x217,'tQ&X')+a1_0x292dff(0x1fd,'uFQV')+a1_0x292dff(0x1e5,'jwtC')+a1_0x292dff(0x205,'2J49')+a1_0x292dff(0x20b,'z7gH')+a1_0x292dff(0x1b1,'(]g5')+a1_0x292dff(0x196,'3hzW')+a1_0x292dff(0x1bd,'!@Xx')+a1_0x292dff(0x214,'jwtC')+a1_0x292dff(0x168,'6B]I')+a1_0x292dff(0x15c,'b^0H')+'o\x20audit\x22:\x0a'+a1_0x292dff(0x207,'97oM')+a1_0x292dff(0x165,'f%]y')+a1_0x292dff(0x1c8,'e$0^'))+('\x22\x20})\x20to\x20sc'+a1_0x292dff(0x19d,'(]g5')+a1_0x292dff(0x16c,'vhKw')+a1_0x292dff(0x1f1,'b^0H')+a1_0x292dff(0x204,'PRay')+a1_0x292dff(0x1af,'h1o8')+a1_0x292dff(0x1b0,'97oM')+a1_0x292dff(0x18c,'S]Xl')+a1_0x292dff(0x192,'LnsC')+a1_0x292dff(0x232,'h1o8')+a1_0x292dff(0x22b,'UL*E')+a1_0x292dff(0x176,'H#L9')+a1_0x292dff(0x16e,'TEq&')+a1_0x292dff(0x191,'BjYJ')+a1_0x292dff(0x1db,'HOLY')+'\x20official\x20'+a1_0x292dff(0x1f3,'b^0H')+'no\x20stale\x20t'+a1_0x292dff(0x19b,'vUae')+a1_0x292dff(0x1c1,'P^sq'))});registerResolveTool(server),registerDocsTool(server),registerBestPracticesTool(server),registerAutoScanTool(server),registerSearchTool(server),registerAuditTool(server),registerChangelogTool(server),registerCompatTool(server),registerCompareTool(server);async function main(){const _0x39cdf8=a1_0x292dff,_0x4322e1=new StdioServerTransport();await server[_0x39cdf8(0x16d,'Hs5d')](_0x4322e1),console[_0x39cdf8(0x181,'j&^T')](SERVER_NAME+'\x20v'+SERVER_VERSION+(_0x39cdf8(0x17f,'g]Jb')+_0x39cdf8(0x193,'H#L9'))+getInstallId()+']');}main()[a1_0x292dff(0x1c0,'P^sq')](_0x1f57bc=>{const _0x5b9f9e=a1_0x292dff;console[_0x5b9f9e(0x1f6,'UYCi')]('Fatal\x20erro'+'r:',_0x1f57bc),process[_0x5b9f9e(0x235,'DyKp')](0x1);});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
declare class LRUCache<T> {
|
|
2
|
+
private readonly store;
|
|
3
|
+
private readonly maxSize;
|
|
4
|
+
constructor(maxSize?: number);
|
|
5
|
+
get(key: string): T | undefined;
|
|
6
|
+
set(key: string, data: T, ttlMs?: number): void;
|
|
7
|
+
has(key: string): boolean;
|
|
8
|
+
clear(): void;
|
|
9
|
+
size(): number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Persistent disk cache — survives across npx invocations.
|
|
13
|
+
* Keys are SHA-256 hashed; entries are JSON files with TTL metadata.
|
|
14
|
+
* Falls back silently to no-op on any I/O error.
|
|
15
|
+
*/
|
|
16
|
+
export declare class DiskCache {
|
|
17
|
+
private dir;
|
|
18
|
+
private initialized;
|
|
19
|
+
constructor(dir?: string);
|
|
20
|
+
private ensureDir;
|
|
21
|
+
private keyToPath;
|
|
22
|
+
get(key: string): Promise<string | undefined>;
|
|
23
|
+
set(key: string, data: string, ttlMs?: number): Promise<void>;
|
|
24
|
+
has(key: string): Promise<boolean>;
|
|
25
|
+
}
|
|
26
|
+
export declare const docCache: LRUCache<string>;
|
|
27
|
+
export declare const resolveCache: LRUCache<unknown>;
|
|
28
|
+
export declare const diskDocCache: DiskCache;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const a2_0x5d528d=a2_0x2da4;(function(_0x200b2e,_0x21b303){const _0x3996ed=a2_0x2da4,_0x27408b=_0x200b2e();while(!![]){try{const _0x5eb25c=parseInt(_0x3996ed(0x210,'FE*I'))/0x1*(parseInt(_0x3996ed(0x211,'hDhK'))/0x2)+-parseInt(_0x3996ed(0x217,'cQIj'))/0x3*(parseInt(_0x3996ed(0x203,'5aMR'))/0x4)+parseInt(_0x3996ed(0x200,'Sw!p'))/0x5+parseInt(_0x3996ed(0x233,'U&M['))/0x6*(-parseInt(_0x3996ed(0x222,'Sw!p'))/0x7)+-parseInt(_0x3996ed(0x202,'%I1V'))/0x8+-parseInt(_0x3996ed(0x22b,'pq^u'))/0x9*(-parseInt(_0x3996ed(0x1ee,'3($d'))/0xa)+parseInt(_0x3996ed(0x1f3,'^3&G'))/0xb*(-parseInt(_0x3996ed(0x1f5,'YWHW'))/0xc);if(_0x5eb25c===_0x21b303)break;else _0x27408b['push'](_0x27408b['shift']());}catch(_0x1deb0f){_0x27408b['push'](_0x27408b['shift']());}}}(a2_0x3e20,0x5c7d7));import{CACHE_TTL_MS,DISK_CACHE_DIR}from'../constants.js';import{createHash}from'crypto';function a2_0x3e20(){const _0x5d24fa=['W6ihW5RcVGLj','W7lcIgm','W63cKLHGcb8CruTaWPFdI8o9','W61VW70','vSkCW5pdMZrOWO0','WQ0rtSkrhCkzwSkdrmk/qwzA','WPpdSSkjWQXvpCk2bmoW','W7bLW74','BmkTWQCWuW','WQ3dLWyMxq','WRKLWRFcMrfhnmkSWQar','FtJcHmkeBcBdIwDaW5a','W4dcSsBdIG','WQuYWPTtmW','W6mBWP7dJwNdOW','WPT2t8kHtmoIWQBdKd8','kfpdHWj5WR/dKu/dPhi','W7BdSSoPW4NcVG','kYGa','W4xcP8onWRy5nqRdVSoP','W7iqzG','WQZdRSoNWPi8WPxcI2a','WRNcMNTho8k4WQxcLmoi','FwpdMxzeW7hdLSkrW59iW6fz','gmo0WPDh','WQfXnCo/vq','W4NcP8oa','W7PVW6xcUfKO','cvRcICollCkkw8k2WQZdNdxdJ8o4','hSoCWRtcQCkP','W6m0nmojqCo3DZ4','ptueWQWQW650W6v/','W78tWQOxDa','oMlcG8o1WRhdScRdTmkMWR/dTG','tCouW40oWPdcGmoCzsJdUfS4gW','W48yW4y','W6xcVatcOYpcVSkOWOuocL0dWPi','F8kWW4tdV8o1WQ80','WR99WQyKW6C','lJhcKrOzWPxdUSkIW4a','BL/dLSkZiCksW7rcz3W','W5SjW53cUbC','mt4YWQW0W64','sSkdW6xcRCkcW75jW6f2','BdtdH8kK','aCkfvrldU8omz8o+WPS','rrBcRCo+BG','WRiVWOy','buiwWOu','FshdLCoOWRa','W4FcQmonW6fbdSkdpmohWP0','WOtdQ2JdIM3dI8k0BXq','W53cTSoBWPaZ','pYGa','WQfXkmoKxSoZsWOY','WPxdM1u','qapcRSo5BG','WR5xW7qdF8oIWOJcNSkOW6RcTG','WRX5W4hdRq5kaa','xCkoWOtdUc99WOxdOSognq','W794WQi','WQLekLf7qCo5vKJcVCkIktW','ysBcICkrCsi','ESkHWRGRrf3cTYtdVW','W74cW4dcUW','nsWmWPyXW7fI','WQldUf3dPNa','lSkKW7xdKSoOWOSanSoZ','sCkMWPTpW4xdPmkj','W63cVSo7WQuO','W5j5W5JcN3O','c8krWP8wWPO','kZVcNW','WQZdQ8k+W64RWQdcR2pdTSoH','W4q3lYGZ','cvRcH8ofkmosdCkpWQpdQqm','W4vKW4u','nqBcJ8o3CCkxW5DYD1VdNq','W7zxlmkWtCkszSkkpfO','q8kqaWmed8k7'];a2_0x3e20=function(){return _0x5d24fa;};return a2_0x3e20();}import{readFile,writeFile,mkdir,stat}from'fs/promises';import{join}from'path';function a2_0x2da4(_0x88b4c6,_0x42550c){_0x88b4c6=_0x88b4c6-0x1eb;const _0x3e2045=a2_0x3e20();let _0x2da44d=_0x3e2045[_0x88b4c6];if(a2_0x2da4['ybtsLI']===undefined){var _0x3d7a7c=function(_0x21d2e5){const _0x392226='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x7ad7d6='',_0x4808b0='';for(let _0x2a710b=0x0,_0x35f693,_0x5f3876,_0x4a14aa=0x0;_0x5f3876=_0x21d2e5['charAt'](_0x4a14aa++);~_0x5f3876&&(_0x35f693=_0x2a710b%0x4?_0x35f693*0x40+_0x5f3876:_0x5f3876,_0x2a710b++%0x4)?_0x7ad7d6+=String['fromCharCode'](0xff&_0x35f693>>(-0x2*_0x2a710b&0x6)):0x0){_0x5f3876=_0x392226['indexOf'](_0x5f3876);}for(let _0x134c7c=0x0,_0x342f11=_0x7ad7d6['length'];_0x134c7c<_0x342f11;_0x134c7c++){_0x4808b0+='%'+('00'+_0x7ad7d6['charCodeAt'](_0x134c7c)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x4808b0);};const _0x133e83=function(_0xb0ae7e,_0x32fb33){let _0x1dc8c9=[],_0x21d8ef=0x0,_0x180f22,_0x344bc0='';_0xb0ae7e=_0x3d7a7c(_0xb0ae7e);let _0x1e6f0d;for(_0x1e6f0d=0x0;_0x1e6f0d<0x100;_0x1e6f0d++){_0x1dc8c9[_0x1e6f0d]=_0x1e6f0d;}for(_0x1e6f0d=0x0;_0x1e6f0d<0x100;_0x1e6f0d++){_0x21d8ef=(_0x21d8ef+_0x1dc8c9[_0x1e6f0d]+_0x32fb33['charCodeAt'](_0x1e6f0d%_0x32fb33['length']))%0x100,_0x180f22=_0x1dc8c9[_0x1e6f0d],_0x1dc8c9[_0x1e6f0d]=_0x1dc8c9[_0x21d8ef],_0x1dc8c9[_0x21d8ef]=_0x180f22;}_0x1e6f0d=0x0,_0x21d8ef=0x0;for(let _0x510c65=0x0;_0x510c65<_0xb0ae7e['length'];_0x510c65++){_0x1e6f0d=(_0x1e6f0d+0x1)%0x100,_0x21d8ef=(_0x21d8ef+_0x1dc8c9[_0x1e6f0d])%0x100,_0x180f22=_0x1dc8c9[_0x1e6f0d],_0x1dc8c9[_0x1e6f0d]=_0x1dc8c9[_0x21d8ef],_0x1dc8c9[_0x21d8ef]=_0x180f22,_0x344bc0+=String['fromCharCode'](_0xb0ae7e['charCodeAt'](_0x510c65)^_0x1dc8c9[(_0x1dc8c9[_0x1e6f0d]+_0x1dc8c9[_0x21d8ef])%0x100]);}return _0x344bc0;};a2_0x2da4['qTldwP']=_0x133e83,a2_0x2da4['BNfsKy']={},a2_0x2da4['ybtsLI']=!![];}const _0x2b639a=_0x3e2045[0x0],_0x2e6e2c=_0x88b4c6+_0x2b639a,_0x4a8916=a2_0x2da4['BNfsKy'][_0x2e6e2c];return!_0x4a8916?(a2_0x2da4['pxnPEn']===undefined&&(a2_0x2da4['pxnPEn']=!![]),_0x2da44d=a2_0x2da4['qTldwP'](_0x2da44d,_0x42550c),a2_0x2da4['BNfsKy'][_0x2e6e2c]=_0x2da44d):_0x2da44d=_0x4a8916,_0x2da44d;}class LRUCache{[a2_0x5d528d(0x237,'Vu[z')]=new Map();[a2_0x5d528d(0x21f,'s7[2')];constructor(_0x392226=0xc8){const _0x7162a2=a2_0x5d528d;this[_0x7162a2(0x232,'QeJo')]=_0x392226;}[a2_0x5d528d(0x1f8,'qNgx')](_0x7ad7d6){const _0x442346=a2_0x5d528d,_0x4808b0=this[_0x442346(0x207,'o)A6')]['get'](_0x7ad7d6);if(!_0x4808b0)return undefined;if(Date[_0x442346(0x226,'YWHW')]()>_0x4808b0[_0x442346(0x21d,'dB46')])return this[_0x442346(0x236,'dB46')][_0x442346(0x1f9,'CbvR')](_0x7ad7d6),undefined;return this['store'][_0x442346(0x22e,')fe5')](_0x7ad7d6),this[_0x442346(0x224,'@4@1')]['set'](_0x7ad7d6,_0x4808b0),_0x4808b0['data'];}[a2_0x5d528d(0x1f0,'s7[2')](_0x2a710b,_0x35f693,_0x5f3876=CACHE_TTL_MS){const _0x49965=a2_0x5d528d;if(this[_0x49965(0x1f7,'gmX)')][_0x49965(0x20e,'I)qr')]>=this[_0x49965(0x232,'QeJo')]){const _0x4a14aa=this[_0x49965(0x220,'%I1V')][_0x49965(0x1f6,'97JF')]()['next']()[_0x49965(0x216,'sZm[')];if(_0x4a14aa!==undefined)this[_0x49965(0x1eb,'CfGa')][_0x49965(0x1ec,')(Hs')](_0x4a14aa);}this[_0x49965(0x212,'qNgx')]['set'](_0x2a710b,{'data':_0x35f693,'expiresAt':Date[_0x49965(0x21a,'RGhi')]()+_0x5f3876});}[a2_0x5d528d(0x22f,'^ITf')](_0x134c7c){const _0x5ea519=a2_0x5d528d;return this[_0x5ea519(0x201,'o)A6')](_0x134c7c)!==undefined;}[a2_0x5d528d(0x1fb,'N$ji')](){const _0x625a5c=a2_0x5d528d;this['store'][_0x625a5c(0x228,'jmzT')]();}['size'](){const _0x1611b7=a2_0x5d528d;return this[_0x1611b7(0x20c,'sZm[')][_0x1611b7(0x23a,'hDhK')];}}export class DiskCache{[a2_0x5d528d(0x20d,'CfGa')];[a2_0x5d528d(0x22c,'49k5')+'d']=![];constructor(_0x342f11=DISK_CACHE_DIR){this['dir']=_0x342f11;}async[a2_0x5d528d(0x234,'FE*I')](){const _0x66b917=a2_0x5d528d;if(this[_0x66b917(0x206,'pq^u')+'d'])return!![];try{return await mkdir(this[_0x66b917(0x22a,'@4@1')],{'recursive':!![]}),this[_0x66b917(0x239,'L^X(')+'d']=!![],!![];}catch{return![];}}[a2_0x5d528d(0x205,'YWHW')](_0xb0ae7e){const _0x7e0255=a2_0x5d528d,_0x32fb33=createHash('sha256')[_0x7e0255(0x21c,'L^X(')](_0xb0ae7e)['digest'](_0x7e0255(0x1f2,'TXAM'));return join(this['dir'],_0x32fb33+_0x7e0255(0x204,'RGhi'));}async[a2_0x5d528d(0x213,'s7[2')](_0x1dc8c9){const _0x388108=a2_0x5d528d;if(!await this[_0x388108(0x1ed,'9$3A')]())return undefined;const _0x21d8ef=this[_0x388108(0x20b,'#Yhu')](_0x1dc8c9);try{const _0x180f22=await readFile(_0x21d8ef,_0x388108(0x20f,'vrqs')),_0x344bc0=JSON[_0x388108(0x223,'^3&G')](_0x180f22);if(Date[_0x388108(0x215,'!E]T')]()>_0x344bc0[_0x388108(0x1fd,'s7[2')])return import(_0x388108(0x219,'QeJo')+'s')[_0x388108(0x21e,'lad!')](({unlink:_0x1e6f0d})=>_0x1e6f0d(_0x21d8ef)['catch'](()=>void 0x0)),undefined;return _0x344bc0[_0x388108(0x20a,'vrqs')];}catch{return undefined;}}async[a2_0x5d528d(0x231,'CbvR')](_0x510c65,_0x5b7b78,_0x48c08d=CACHE_TTL_MS){const _0xa0969c=a2_0x5d528d;if(!await this['ensureDir']())return;const _0x3184da=this[_0xa0969c(0x205,'YWHW')](_0x510c65),_0x456871={'data':_0x5b7b78,'expiresAt':Date[_0xa0969c(0x235,'CbvR')]()+_0x48c08d};try{await writeFile(_0x3184da,JSON[_0xa0969c(0x214,'gmX)')](_0x456871),_0xa0969c(0x225,'Sw!p'));}catch{}}async['has'](_0x4fe385){const _0x3970d6=a2_0x5d528d;if(!await this[_0x3970d6(0x1f4,'^R]m')]())return![];const _0x2b93d3=this[_0x3970d6(0x1f1,'qNgx')](_0x4fe385);try{const _0x59544d=await stat(_0x2b93d3);if(!_0x59544d[_0x3970d6(0x208,'s7[2')]())return![];const _0x96ed9b=await readFile(_0x2b93d3,_0x3970d6(0x1fe,'cQIj')),_0x481e16=JSON[_0x3970d6(0x1ef,'x&(Z')](_0x96ed9b);return Date['now']()<=_0x481e16[_0x3970d6(0x221,'5aMR')];}catch{return![];}}}export const docCache=new LRUCache(0xc8);export const resolveCache=new LRUCache(0x1f4);export const diskDocCache=new DiskCache();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FetchResult } from "../types.js";
|
|
2
|
+
export declare function fetchWithTimeout(url: string, ms?: number, extraHeaders?: Record<string, string>): Promise<Response>;
|
|
3
|
+
/** Fetch via Jina Reader — converts any URL to clean markdown */
|
|
4
|
+
export declare function fetchViaJina(url: string): Promise<string | null>;
|
|
5
|
+
/** Try llms.txt, then llms-full.txt, then Jina, then direct HTML */
|
|
6
|
+
export declare function fetchDocs(docsUrl: string, llmsTxtUrl?: string, llmsFullTxtUrl?: string): Promise<FetchResult>;
|
|
7
|
+
/** Fetch GitHub README or a specific file from a repo */
|
|
8
|
+
export declare function fetchGitHubContent(githubUrl: string, path?: string): Promise<FetchResult | null>;
|
|
9
|
+
/** Fetch latest GitHub release notes (tag name + body) */
|
|
10
|
+
export declare function fetchGitHubReleases(githubUrl: string): Promise<string | null>;
|
|
11
|
+
/** Fetch examples or migration guides from official GitHub repo */
|
|
12
|
+
export declare function fetchGitHubExamples(githubUrl: string): Promise<string | null>;
|
|
13
|
+
/** Query npm registry for package metadata */
|
|
14
|
+
export declare function fetchNpmPackage(packageName: string): Promise<unknown>;
|
|
15
|
+
/** Query PyPI for package metadata */
|
|
16
|
+
export declare function fetchPypiPackage(packageName: string): Promise<unknown>;
|