Purpose
GroundTruth-MCP is a self-hosted MCP server and command-line tool that provides the current official documentation for the libraries being used when a coding agent requests it. It addresses the problem of models writing code based on training data, leading to outdated usage: for example, still wrapping components with forwardRef after React 19, still calling cookies() synchronously after Next.js changed it to async, and Tailwind v4 having replaced the @tailwind directives with @import "tailwindcss". GroundTruth reads the library's own documentation at request time (llms.txt, documentation site markdown, or GitHub repository), ranks the relevant sections, and checks whether the answer covers the topic before returning it. It can also audit source code with 107+ patterns and link each finding to the current fix. It runs locally, with no account, no API keys, and no built-in rate limits.
Main Capabilities
- Documentation retrieval: matches the library name against a curated registry first, then against npm, PyPI, crates.io, and Go modules; sources are tried in order, and the first useful source wins: llms.txt / llms-full.txt, documentation page markdown fetched via Accept: text/markdown, HTML pages converted to markdown, GitHub README/documentation files/release notes, with the Jina reader as a fallback.
- Ranking and checking: scores each section against the topic using BM25, fills the token budget; the evidence gate counts the number of occurrences of topic words, their frequency, and whether they appear in headings or code blocks; link targets and URL query strings are not counted. Weak coverage triggers a second fetch targeting the topic; zero coverage returns an explicit miss with the sources checked, the outline of what those pages cover, and suggested next steps. Every successful answer ends with a ## Evidence footer containing the source URL, fetch date, and topic coverage numbers; the check is synonym-sensitive.
- Code auditing: gt_audit traverses the project, runs 107+ patterns across 18 categories, reports each issue as file:line, then fetches the fix from authoritative sources.
- Dependency-aware best practices: gt_practices reads manifests and lockfiles, determines the libraries and versions in use, and returns best practices sorted by usage count, with a defaultoutput of about 15K characters. Supports package.json, deno.json, requirements.txt, pyproject.toml, Cargo.toml, go.mod, pom.xml, build.gradle, build.gradle.kts, composer.json, Gemfile, and pubspec.yaml.
- Toolset: 14 tools, each available both as an MCP tool and as a CLI command; it also exposes 2 MCP resources (library-registry, library-docs) and 8 prompts (audit-my-project, upgrade-check, best-practices-scan, compare-libraries, security-check, migration-guide, find-examples, dependency-audit). You can ask questions in natural language, or call tools directly, for example gt-mcp <command>.
- Library coverage: 793 curated libraries covering 21 language ecosystems, with automatic fallback to npm, PyPI, crates.io, and Go modules outside the registry. 8.0.0 adds 195 libraries, covering Python, data and AI tooling, Java, Kotlin and Spring, .NET, Go, Rust, Ruby, PHP, Swift, Dart and Flutter, Elixir, C and C++, infrastructure, databases, observability, and more; all 598 existing entries were probed online: 35 broken documentation roots fixed, 115 migrated documentation sites updated, about 190 verified llms.txt indexes, and the curated URL table rechecked (2,638 URLs). See the registry source src/sources/registry.ts for the full list.
- Performance and caching: the binary is a small bootstrap that lazily loads the server and uses the Node compile cache; documentation pages are requested as markdown; the reader service is only a fallback; cached pages use stale-while-revalidate, with pages up to 7 days old returned immediately and refreshed in the background. The fetch layer keeps connections alive for 60 seconds, shares in-flight requests among identical callers, and respects eachCall cancellation and the GT_TOOL_TIMEOUT_MS deadline, caching 404s and oversized response bodies to avoid retries, temporarily skipping a host after repeated failures.
How to use
Requires Node.js 24 or newer.
Configure it in clients that use the mcpServers block, such as Cursor, Claude Desktop, and Windsurf (.cursor/mcp.json, claude_desktop_config.json, ~/.codeium/windsurf/mcp_config.json); VS Code uses .vscode/mcp.json. Other MCP clients run npx -y @groundtruth-mcp/gt-mcp@latest as a stdio server. Command line (the same tools, no MCP client needed): gt-mcp <command> runs the same 14 tools in-process and prints the answer; with no arguments, gt-mcp is the stdio MCP server. Exit codes: 0 normal, 1 tool error, 2 usage error. Logs stay quiet on stderr by default (GT_LOG_LEVEL defaults to warn). Server flags are still available: --version, --health, --routing-table, --help. @latest makes npx fetch a new version at the next session start; when a new version exists, tool responses carry a one-line notice (GT_NO_UPDATE_CHECK=1 turns the check off).
Optional GitHub token: GroundTruth reads READMEs, release notes, migration guides, and code examples from GitHub. Without a token, GitHub allows 60 requests per hour; a token with no extra scopes raises this to 5,000 and enables code search in gt_examples. In the JSON config, add "env": { "GT_GITHUB_TOKEN": "ghp_yourtoken" } next to args.
HTTP and Docker: when GT_HTTP_PORT is set, GroundTruth serves Streamable HTTP instead of stdio. It follows MCP spec 2026-07-28 and still serves 2025-era clients. The local loopback mode binds to 127.0.0.1; without GT_AUTH_TOKEN it is open to local callers and logs a warning, and with a token every path (including /health and /metrics) requires Authorization: Bearer <token>. The Docker image is 277 MB, runs as the unprivileged gt user, and binds to 0.0.0.0 inside the container, so it refuses to start without GT_AUTH_TOKEN; its health check sends the token; the -p 127.0.0.1: prefix keeps the port on the host loopback, and removing it allows serving other machines. Behind a reverse proxy: the server speaks plain HTTP, terminate TLS at the proxy and add the public hostname to GT_HTTP_ALLOWED_HOSTS, otherwise requests carrying that hostname get a 403; on a non-loopback bind the server will not start without GT_AUTH_TOKEN. Sessions are stateless by default, and GT_HTTP_STATEFUL=1 gives each 2025-era client its own session, closed after 30 minutes without requests. Authenticated callers can have the server fetch public URLs and run gt_audit and gt_auto_scan in any directory the process can read, so do not mount content you do not want read into the container. All configuration is optional, and invalid numeric or enum values fail at startup rather than silently falling back. gt-mcp --help prints the same list.
When it applies
- When a coding agent needs the target library's current official documentation.
- To run a 107+ pattern audit on a project and locate every finding to file:line and the current fix.
- To get dependency-aware best practices based on the libraries and versions identified from the lockfile.
- Prompt scenarios such as comparing libraries, checking upgrades, generating migration guides, security checks, finding examples, and dependency audits.
Limitations and notes
- Requires Node.js 24 or newer.
- It scrapes untrusted web content and hands it to the model; the prompt injection scrubber is best-effort pattern sanitization, and scraped documentation should be treated as untrusted input.
- Audit patterns have been made ReDoS-safe, bringing the worst-case input down from 9.5 seconds to 1 millisecond.
- GT_GITHUB_TOKEN and GT_JINA_API_KEY are never forwarded to other origins, including redirects.
- The disk cache only stores hash-keyed scrapFetch documents, do not save prompts or tool inputs.
- 8.0.0 has four breaking changes; stdio users reading text content on Node 24 or newer are unaffected.
- Report security vulnerabilities privately via GitHub Security Advisories; see SECURITY.md for scope and threat model.
- License is Elastic License 2.0: free to use, self-host, and build on; the only thing you may not do is offer it as a hosted service.
- Difference from Context7: Context7 indexes documentation into a vector database, which is fast but lags behind new releases; GroundTruth fetches from the source at query time and tells the model when a topic has no content.
- Adding a library is a pull request to src/sources/registry.ts, requiring id, name, docsUrl, and that field when the project publishes an llmsTxtUrl.
- CI runs the test suite on Node 24 and 26.