ctxpeek
Allows fetching files from public Bitbucket repositories at specific refs.
Allows fetching files from Codeberg repositories (extendable integration).
Allows fetching files from Gitea repositories (extendable integration).
Allows fetching files from public GitHub repositories at specific refs (branch, tag, commit) for documentation or code inspection.
Allows fetching files from public GitLab repositories at specific refs.
Integrates with npm registry to resolve package names to their repository URLs for documentation fetching.
Integrates with Packagist to resolve PHP package names to their repository URLs.
Integrates with PyPI to resolve Python package names to their repository URLs.
Integrates with RubyGems to resolve Ruby gem names to their repository URLs.
Allows fetching files from SourceHut repositories (extendable integration).
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ctxpeekget the README from vercel/next.js@v15.0.0"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Get Started · Tools · Configuration · vs Context7 · The Story
Status: Current baseline complete and stable. GitHub + GitLab + Bitbucket. Plug-in slots for new forges, lockfiles, and registries. Planning is focused on what comes next.
What it does
ctxpeek is a local stdio MCP server. Add it to your client, then ask your assistant about any library by owner/repo:
npx -y ctxpeekWhen you say "show me the routing docs from vercel/next.js@v15.0.0", your model calls ctxpeek, ctxpeek fetches the actual file from the actual repo at that commit, returns it as markdown, and your model works with information it can trust.
It also resolves fuzzy names ("drizzle orm" → drizzle-team/drizzle-orm via npm/PyPI/crates/Go/RubyGems/Packagist/Hex), so the model can get to the right repo before listing its docs tree.
Built for agentic clients. The model lists a tree, picks a path, reads the file, decides if it's right, calls again. We don't do top-k chunk dumps and we don't run a vector store — agents navigate structure faster than they unpack similarity scores. More on that in the architecture doc.
What you get out of the box:
Local-first. Cache, listing, and fetch all run on your machine. No telemetry. Your queries don't leave.
Any public repo on GitHub, GitLab, or Bitbucket. Codeberg / Gitea / sourcehut are one file away — see extending ctxpeek.
Ref-native by default. Branch, tag, commit sha, and monorepo subpath are part of the input:
owner/repo@ref#subpath.Version-pinned docs without ingestion.
owner/repo@v15.0.0,owner/repo@main, andowner/repo@<sha>all read the matching git snapshot directly.Free, forever. Bring your own GitHub PAT — or none. A warm cache reads locally; authenticated conditional REST responses that return 304 do not count against your GitHub primary rate limit.
Markdown out, not JSON. ~75% smaller for the same information. Docs trees and large-file guards self-report
~tokenswhere it helps the model budget.No third-party instruction channel. ctxpeek only serves file contents from repos you name. The ContextCrush class of bug (Custom Rules served verbatim from a third-party registry) is structurally absent — see Threat model.
Why not Context7
Context7 is the obvious comparison, but the core difference is not "hosted vs local" or even privacy. The core difference is the retrieval model.
Context7 starts from a library ID in a hosted documentation corpus, then returns topic-shaped context. That is useful when you want curated snippets for a popular library. ctxpeek starts from a git snapshot: repo, ref, and optional subpath. The agent lists the docs tree, inspects paths, fetches exact files, and can move between versions because every tool understands owner/repo@ref.
For an AI agent, the loop looks different:
Context7:
resolve a library ID
ask the hosted corpus for docs about a topic
receive selected context
answer from that curated bundle
ctxpeek:
resolve or accept owner/repo@ref
list the docs tree at that git snapshot
choose the exact path to inspect
fetch, peek, compare refs, and repeat as neededSo Context7 is retrieval as answer assembly: the service decides which corpus entries fit the topic. ctxpeek is retrieval as navigation: the model keeps the source tree in the loop and decides the next file, ref, or subpath to inspect.
Context7 | ctxpeek | |
Thinking model | Resolve a library ID, ask for a topic, receive curated context from the hosted corpus. | Resolve a repo/ref, inspect the tree, fetch exact files from the matching git snapshot. |
Agent control | The agent mostly controls topic, token budget, and follow-up question. | The agent controls repo, ref, subpath, file path, partial reads, diffs, and follow-up navigation. |
Version model | Version-specific library IDs are possible when that version exists in the corpus. | Branches, tags, and commit shas are the native address space: |
Fresh dev branches | A new library or version has to be submitted, crawled, indexed, or refreshed before it is useful. | Works as soon as the ref exists on the forge. Pin |
Agent workflow | Best for "give me the relevant snippet for this topic." | Best for "show me this project's docs at this version, then let the agent navigate." |
Monorepos | The library ID usually points at a selected docs surface. |
|
Library coverage | Curated registry. If it is not in the corpus, it must be added first. | Any public repo on GitHub, GitLab, or Bitbucket. Including your own libraries and unreleased branches. |
Wrong-library risk |
|
|
Prompt-injection surface | A hosted documentation layer can add authoring or policy surface beyond the upstream repo. | No third-party authoring layer. ctxpeek serves files from the repo/ref you named. Content-layer bugs, like a malicious README, remain. |
Operational model | Hosted service, optional account/API key for higher usage. | Local stdio MCP process. Bring a forge token or use public CDN fallbacks. |
Privacy | Queries go to the hosted service. | Query privacy falls out of the architecture, but it is not the main pitch. The main pitch is ref-addressed source-of-truth docs. |
Context7 optimizes for a curated documentation answer. ctxpeek optimizes for a reproducible documentation snapshot. If your question depends on which branch, tag, commit, or monorepo package the docs came from, ctxpeek is the better primitive.
Long-form:
docs/comparison.md(vs Context7, GitMCP, Ref Tools).
The story
I built ctxpeek because I got tired of doing the same dance every day.
I'd been elbows-deep in two of my own libraries — tamimbinhakim/imprint-pdf and tamimbinhakim/dyadpy — refactoring APIs faster than I could ship them. The repos were the source of truth. They had to be. I was the one writing the docs.
Then I'd open a different project to actually use those libraries — to dogfood them, see if the API I'd just shipped was any good. The AI in that editor was, predictably, useless about my libraries. Of course it was. Its training data was months old, and even if it weren't, my last refactor was twenty minutes ago. So it would politely hallucinate an API that hadn't existed since last Tuesday, and I'd waste a turn correcting it.
So I'd do the dance:
Open the library's repo in another tab.
Find
llms-full.txt— and hope I'd remembered to regenerate it after the rename.Paste it into the chat. Watch a third of my context window evaporate on docs the model would have ignored half of anyway.
Repeat tomorrow because I'd shipped another breaking change at 1 AM.
I tried Context7. It's well-built and the team clearly cares. But its unit of work is a library in a hosted docs corpus, not a git ref. My problem was ref-shaped: this branch, this tag, this commit, this monorepo package. My library changed thirty minutes ago. I needed the docs at the version I was actually using, not the nearest indexed version.
The fix turned out to be obvious in hindsight: the canonical source for a library's docs is its git repo. So pull straight from there. Pin to a sha for reproducibility, pin to @main for branch docs, cache locally so repeat reads cost zero, and use ETags when REST fallback has a validator. No middleman.
That's ctxpeek. The tool I wanted on my own machine, six months ago.
Quick Start
1. Add ctxpeek to your MCP client
For Claude Code, add ctxpeek directly with the claude CLI:
claude mcp add --transport stdio --scope user ctxpeek -- npx -y ctxpeek
claude mcp listInside Claude Code, run /mcp to confirm the server is connected.
Add this to ~/.cursor/mcp.json for global use, or .cursor/mcp.json inside a project:
{
"mcpServers": {
"ctxpeek": {
"command": "npx",
"args": ["-y", "ctxpeek"]
}
}
}Add this to .vscode/mcp.json in your workspace, or to your user MCP config:
{
"servers": {
"ctxpeek": {
"type": "stdio",
"command": "npx",
"args": ["-y", "ctxpeek"]
}
}
}Add this to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"ctxpeek": {
"command": "npx",
"args": ["-y", "ctxpeek"]
}
}
}codex mcp add ctxpeek -- npx -y ctxpeekUse this only for Claude Desktop. Claude Code should use the claude mcp add command above.
{
"mcpServers": {
"ctxpeek": {
"command": "npx",
"args": ["-y", "ctxpeek"]
}
}
}npx is a .cmd shim on Windows, and several MCP clients fail to spawn it directly. Wrap it with cmd /c:
{
"mcpServers": {
"ctxpeek": {
"command": "cmd",
"args": ["/c", "npx", "-y", "ctxpeek"]
}
}
}Run npx -y ctxpeek doctor once to verify your environment.
Authentication
ctxpeek looks for a GitHub token in this order — first one wins, none required:
--token <pat>flag$GITHUB_TOKENenv vargh auth tokenif the GitHub CLI is installed and logged inAnonymous (60 req/hr REST; the CDN does the heavy lifting)
If you already run gh auth login, you're done. ctxpeek doctor reports which path won.
2. Use it from your assistant
Reference any repo as [forge:]owner/repo[@ref][#subpath]:
"Set up Drizzle ORM with Postgres in Next.js 15 server actions"
"Show me the routing docs from vercel/next.js@v15.0.0"
"Search tailwindlabs/tailwindcss@main for 'arbitrary values'"
"Use the latest tamimbinhakim/dyadpy@main API to wire up an SSE endpoint"The model picks the right tool from the ctxpeek surface automatically. No magic incantation.
Repo parameter format
[forge:]owner/repo[@ref][#subpath]vercel/next.js // main HEAD, GitHub
vercel/next.js@v15.0.0 // tagged release
vercel/next.js@canary // branch
vercel/next.js@a3b1f7c // commit sha (short or full)
tailwindlabs/tailwindcss@main#packages/tailwindcss/docs // monorepo subtree
gitlab:gitlab-org/gitlab@master // GitLab (alias: gl:)
bitbucket:atlassian/python-bitbucket // Bitbucket Cloud (alias: bb:)Full grammar: docs/reference/repo-spec.md.
Tools
resolve_repo // "drizzle orm" → drizzle-team/drizzle-orm. Project-aware: prefers
// cwd/ancestor deps and npm workspace packages, including repo#subpath.
// Returns the latest release tag so the planner can pin on the first call.
list_docs // Markdown tree of docs files, with size hints, freshness badges,
// llms.txt highlights. Optional `since: "2025-04-01"` filter for
// "what changed after the model's training cutoff?".
fetch_doc // One file at a pinned commit, YAML frontmatter + body. Supports
// `lines` / `head_bytes` for partial reads.
peek // First N lines of a file before committing to a full fetch.
get_changes // Unified diff for one file across two refs.
changelog // Slice CHANGELOG.md / HISTORY.md between two refs.
related_repos // Scrape README + llms.txt for github.com peer links — "often used with…".
get_issues // Search a repo's issues / PRs (separate /search/issues bucket, 30/min).
cache_status // Diagnostic: cache hits, sizes, snapshot sha, last revalidate.
rate_limits // GitHub buckets; pass `details: true` for local throttle internals.Full reference: docs/reference/tools.md.
CLI surface
ctxpeek Start the MCP stdio server (default)
ctxpeek doctor Environment self-check
ctxpeek warm <spec...> Pre-pull refs + doc trees for repos or a recipe
ctxpeek recipe install <path> Pre-warm from a recipe file
ctxpeek cache status [repo] On-disk cache report
ctxpeek cache gc Garbage-collect the cache
ctxpeek --version | --helpConfiguration
Discovery (highest precedence first):
CLI args to
ctxpeek.ctxpeek.tomlin cwd or any ancestor up to$HOME~/.config/ctxpeek/config.tomlEnv vars
Built-in defaults
A starter config:
[cache]
dir = "~/.cache/ctxpeek"
max_size = "1GiB"
gc_days = 14
[fetch]
prefer_cdn = true
concurrent_max = 8
secondary_budget = 60
[auth]
github_token_env = "GITHUB_TOKEN"Full reference: docs/reference/configuration.md.
Recipes
A recipe is a shareable bundle of pre-pinned repos. Pre-warm a stack with one command:
npx -y ctxpeek recipe install ./.ctxpeek.recipe.toml# .ctxpeek.recipe.toml
[[repo]]
spec = "vercel/next.js@v15.0.0"
alias = "next"
[[repo]]
spec = "drizzle-team/drizzle-orm@v0.30.1"
alias = "drizzle"
[[repo]]
spec = "clerk/javascript@v5#packages/clerk-js"
alias = "clerk"Authoring guide: docs/guides/recipes.md. Examples: examples/recipes/.
Privacy
ctxpeek makes no network call to any host other than:
api.github.com,cdn.jsdelivr.netgitlab.com,api.bitbucket.org(only when you use agitlab:orbitbucket:repo spec)registry.npmjs.org,pypi.org,crates.io,rubygems.org,repo.packagist.org,pkg.go.dev,hex.pm(only whenresolve_repois called)
No telemetry. No analytics. Your query strings never leave your machine except as the URL path of those documented hosts.
Threat model
What's structurally absent
No third-party authoring channel. The ContextCrush class can't exist here — there's no registry layer, no place for anyone other than the actual repo maintainer to author content delivered to your agent.
No hosted query log. Outbound calls are the ones above, only when you make them.
No opaque hosted trust score. Resolution uses visible registry/forge evidence: URL field, package-name match, optional package-manifest verification, repo stars, and GitHub search only as the final fallback. Candidates are returned to the model when ambiguous.
What ctxpeek does not solve
Content-layer prompt injection. If a
README.mdorllms.txtcontains an instruction-shaped payload,fetch_docreturns it verbatim and your model will see it. True of any tool that retrieves third-party docs. Pin to a sha you've reviewed; prefer release tags over@mainfor production prompts; don't auto-execute model output.Repository takeover. A compromised maintainer can land a malicious commit on the branch you're pinned to. Pin a sha you trust.
CDN compromise. jsDelivr is donation-funded. If it served tampered bytes, ctxpeek would deliver them. Run with
--no-cdnif that's not acceptable.Recipe supply chain. A
.ctxpeek.recipe.tomlyou install can pre-warm any repo it lists. Same posture as apackage.jsondep — read what you install.
If you find a real vulnerability, see SECURITY.md.
When not to use ctxpeek
You need symbol-level navigation across a repo (where is
useStatedefined?) — usegithub-mcp-serverordeepwiki.You want to write to the repo (open issues, create PRs, commit) — ctxpeek is read-only by design.
You want curated, ranked snippets across many libraries from one hosted index — that's Context7's strength when its tradeoffs are acceptable.
Your environment blocks outbound HTTPS. ctxpeek needs to reach
api.github.com(or the CDN) at least once per repo. A warm cache works fully offline.
Honest tradeoffs
Unauthenticated
raw.githubusercontent.comwas rate-limited on May 8, 2025 (changelog) with no documented way to authenticate. That's why ctxpeek defaults to jsDelivr for raw reads, even with a PAT.Authenticated 304s are free (docs). ctxpeek uses
If-None-Matchon REST fallbacks when it has an ETag.GraphQL has no ETag. For file content, local cache + CDN + REST/ETag is the better path. GraphQL is currently reserved for metadata batching where it reduces resolver overhead.
No semantic search, no vector store — deliberate. Pre-agentic retrieval handed the model a top-k chunk dump because it couldn't go look itself. Agentic clients can list a tree, read a path, decide, and call again — so the right primitive is the structure the corpus author already encoded (filenames, folders, llms.txt).
list_docsshows the tree;fetch_docreturns the file. Full argument: architecture.md.MCP structured output support is uneven across clients as of May 2026. Some clients pass
structuredContentto the model verbatim. ctxpeek returns structured data only where useful; markdown is the source of truth.llms.txtis a proposal, not a standard. ctxpeek boosts hits inside it when present; it's never required.
Documentation
Install and first session | |
All config keys | |
Every tool's input / output | |
The | |
Tokens, | |
Stack bundles | |
What's cached, where, for how long | |
Add a forge / lockfile parser / registry | |
Windows, ENOENT, rate limits | |
ctxpeek vs Context7 vs GitMCP vs Ref Tools | |
How it works inside | |
Reporting vulnerabilities | |
Dev setup, conventions |
Roadmap
The current baseline is done: the MCP server, resolver, doc tree/fetch tools, change/changelog helpers, related repo and issue lookup, cache inspection, doctor, recipes, multi-forge support, and extension registries are in place.
The next roadmap pass is planning work, not a committed release train:
Area | Planning direction | Status |
Freshness UX | Clearer branch/ref freshness messaging, richer per-file last-commit signals, and better changed-since workflows. | Scoping |
Monorepos | Extend | In progress |
Auth + forges | Harden private-repo paths, document token scopes per forge, and evaluate Codeberg / Gitea / sourcehut adapters. | Scoping |
Ecosystem breadth | More lockfile parsers and registry probes where they materially improve | Backlog |
v1 readiness | Schema freeze, SLO docs, security review, release hygiene, and sharper compatibility notes for MCP clients. | Backlog |
What's deliberately not on the roadmap: a vector store, a hosted docs corpus, a hosted resolver as authority, a curated library registry, or write operations on repos. See non-goals in the architecture doc.
Development
git clone https://github.com/tamimbinhakim/ctxpeek.git
cd ctxpeek
pnpm install
pnpm build
pnpm test
pnpm dev # runs ctxpeek from sourceConventions and CI gates live in CONTRIBUTING.md. The repo uses TypeScript (Node ≥ 20, strict everything), Biome for JS/TS, prettier for markdown, ruff for the few Python scripts under scripts/, commitlint with Conventional Commits, changesets for releases, and vitest for tests.
Become a Sponsor!
ctxpeek is free and built in the open. If your team relies on it, sponsoring covers the maintenance and the next round of features.
❤︎ Sponsor ctxpeek on GitHub
License
Apache-2.0. Apache over MIT for the explicit patent grant — the MCP ecosystem is still churning.
Built because the docs your model is reading should come from the actual repo, at the version you actually use.
— Tamim Bin Hakim
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/tamimbinhakim/ctxpeek'
If you have feedback or need assistance with the MCP directory API, please join our Discord server