Back to Discover

ctx

connector

vanshulgoyal101

Turn a GitHub repo or docs site into agent-ready context: pack it or search it, over MCP.

View on GitHub
0 starsSynced Aug 6, 2026

Install to Claude Code

/plugin marketplace add vanshulgoyal101/ctx

README

ctx.vanshul.com

MCP Registry Endpoint License: MIT

A public Model Context Protocol (MCP) server, running as a Cloudflare Worker, that turns a GitHub repository or a documentation site into agent-ready context. Point an AI agent at it and it can pack a whole repo (or crawl a docs site) into one token-counted blob — or search it and get back only the relevant passages, each with its file/URL and line.

It's the agent-first companion to mcp/: where mcp reads a single web page, ctx reads whole repos and doc sites. The repo pipeline fetches, gunzips and parses the tarball in-process; docs extraction reuses Mozilla Readability + Turndown.

Endpoint

POST https://ctx.vanshul.com/mcp     # JSON-RPC 2.0 (MCP)
GET  https://ctx.vanshul.com/health  # { ok: true, tools: [...] }

Tools

ToolInputReturns
pack_repo{ repo, ref?, include?, exclude?, max_tokens? }The repo as one context blob with ==== path ==== headers + token estimate
search_context{ repo, query, ref?, include?, exclude?, max_matches?, context_chars? }Only the passages matching query, each with file, line and score
list_files{ repo, ref?, include?, exclude? }JSON: the text files ctx would include, with byte sizes
get_file{ repo, path, ref? }The full text of a single file
pack_docs{ url, depth?, max_pages?, max_tokens? }A crawled docs site as one context blob (each page → Markdown)
search_docs{ url, query, depth?, max_pages?, max_matches?, context_chars? }Only the docs passages matching query, each with page URL, line and score

repo is owner/repo, owner/repo/ref, or a github.com URL. url (for the docs tools) is an absolute http(s) docs page to start crawling from.

Connect from an MCP client

{ "mcpServers": { "ctx": { "url": "https://ctx.vanshul.com/mcp" } } }

Stdio-only clients bridge with npx mcp-remote https://ctx.vanshul.com/mcp.

Add it to your client

  • Cursor — Settings → MCP → Add new server, or drop this into ~/.cursor/mcp.json:
    { "mcpServers": { "ctx": { "url": "https://ctx.vanshul.com/mcp" } } }
    
  • Claude Desktop — add the same block to claude_desktop_config.json (Settings → Developer → Edit Config). If your version is stdio-only, use:
    { "mcpServers": { "ctx": { "command": "npx", "args": ["mcp-remote", "https://ctx.vanshul.com/mcp"] } } }
    
  • Continue / VS Code — add ctx with URL https://ctx.vanshul.com/mcp to your MCP servers config.

Try it with curl

# Pack a repo, capped to 8000 tokens
curl -s https://ctx.vanshul.com/mcp -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"pack_repo","arguments":{"repo":"sindresorhus/slugify","max_tokens":8000}}}'

# Search a repo for just the relevant passages
curl -s https://ctx.vanshul.com/mcp -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
       "params":{"name":"search_context","arguments":{"repo":"sindresorhus/slugify","query":"replace separator"}}}'

Layout

ctx/
├── src/
│   ├── worker.ts     # entry: routes /mcp, /health, rate limit, CORS
│   ├── mcp.ts        # JSON-RPC dispatch + the six tool definitions
│   ├── github.ts     # fetch tarball, gunzip, parse tar, filter files (no deps)
│   ├── pack.ts       # assemble the context blob + token estimate
│   ├── search.ts     # ranked passage search over files (file + line)
│   ├── docs.ts       # crawl a docs site into pages (BFS, same-section)
│   ├── extract.ts    # HTML -> Markdown / links (Readability + Turndown)
│   ├── fetcher.ts    # bounded fetch with re-validated redirects (SSRF)
│   └── security.ts   # SSRF guard (block private/internal addresses)
├── public/
│   ├── index.html    # landing page (served for non-API paths)
│   ├── og.png / og.svg
│   ├── robots.txt
│   └── sitemap.xml
├── tests/            # vitest: github (tar parsing), pack, search, mcp, worker
├── docs/             # architecture, tools/API reference, deployment
├── wrangler.toml
├── package.json
└── tsconfig.json

Develop & deploy

cd ctx
npm install
npm run typecheck
npm test           # vitest — full suite
npm run dev        # local worker at http://localhost:8787  (POST /mcp)
npm run deploy     # wrangler deploy

How it works

owner/repo → github.com tarball → DecompressionStream('gzip')
           → in-process tar parse → drop binaries/lockfiles/build dirs
           → pack (concat + token estimate) OR search (ranked passages)

The GitHub URL is always constructed from a fixed owner/repo slug, so the repo tools have no SSRF surface. The docs tools fetch caller-supplied URLs, so every URL and redirect hop is re-validated against the SSRF guard. Downloads are bounded (timeout, size caps, page/file-count caps) and results are cached per-isolate for a few minutes.

Security & limits

  • No SSRF: input is a repo slug, not an arbitrary URL; only github.com is fetched.
  • Bounded: 20s download timeout, ~60 MB uncompressed cap, 512 KB/file, ≤3000 files, per-IP rate limit.
  • Stateless & private: no code stored, no LLM in the loop; public repos by default (private with a token).

Authentication (optional)

Set a GITHUB_TOKEN Worker secret to lift GitHub's rate limit (60 → 5,000/hour) and read private repos:

wrangler secret put GITHUB_TOKEN

The token is a Worker secret only — never a tool argument — so it can't leak to an agent.

Documentation

License

MIT © Vanshul Goyal

Rendered live from vanshulgoyal101/ctx's GitHub README — not stored, always reflects the source repo.

1 Install Method

NameDescriptionCategorySource
streamable-http remoteHosted streamable-http endpointmcp-serverhttps://ctx.vanshul.com/mcp

0 Comments

Login required
Log in to post a comment or update on this repo.

No comments yet — be the first to share an update.