search
Search the writing corpus
Full-text (BM25) search across all essays, book chapters, and field notes. Returns ranked matches with a snippet, id, and canonical URL. Pass an id to get_document to read the full text.
limitqueryrequiredsection
io.github.saagpatelPublished by GitHub account saagpatelv0.1.0Updated Oct 24, 2026
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
The publisher's own server: PortfolioFit
Read-only MCP server over the public saagarpatel.dev corpus, letting an assistant search and read essays, book chapters and notes, and browse projects and…
Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.
Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.
Read https://sourceweft.com/mcp/io.github.saagpatel%2Fportfolio-mcp/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.Add this to your client's mcpServers config.
{
"mcpServers": {
"saagarpatel-dev-portfolio": {
"type": "http",
"url": "https://mcp.saagarpatel.dev/mcp"
}
}
}The agent-native layer of saagarpatel.dev: a Model Context Protocol server that lets any AI agent query Saagar's writing, projects, public-safe repo profiles, and benchmark results directly, instead of scraping HTML.
Read-only. Stateless. Public. No auth, no tracking, no database, no runtime egress.
The website stays a pure static site. This server is a sibling, not a backend bolted onto it:
portfolio-index repo): the build emits a static machine
corpus — corpus-index.json, per-document corpus/<id>.json, and
.well-known/mcp.json — plus public-safe repo profile artifacts when present,
served alongside the HTML. Already public.src/index.ts): a stateless Cloudflare Worker that bakes
the Layer 0 corpus into its bundle and serves it over MCP (streamable HTTP, the
WebStandardStreamableHTTPServerTransport). Zero runtime fetches.src/stdio.ts): the same server over stdio, for running
locally via npx saagar-portfolio-mcp. Identical tool/resource/prompt surface.The shared core (src/server.ts) is transport-agnostic; both layers wrap it.
All read-only (readOnlyHint: true). No tool takes a URL or filesystem path (no
SSRF / exfil surface).
Documents are also exposed as Resources (portfolio://essays/{slug}, portfolio://book/{slug},
portfolio://notes/{slug}, portfolio://profile), and there are two Prompts:
introduce_saagar and summarize_writing_on (grounded in a live search).
BM25 over a baked index (no embeddings in v1 — the committed corpus contains 166 docs and the calling LLM supplies the semantics). Titles are boosted. Embeddings are a measured Phase 3 upgrade, added only if retrieval quality proves insufficient.
From the repository root, use the pinned Node and npm versions from
.node-version and package.json. The checked-in public-safe corpus is enough
for routine checks; no sibling checkout, local portfolio import, signing key,
or Cloudflare credentials are needed.
make check runs lint, format validation, typecheck, tests, the stdio build and
protocol test, smoke, parity, and a package-content check. See
CI for the same aggregate gate. npm run dev starts
the local Worker.
npm run build:corpus regenerates source from a sibling checkout or an explicit
network URL; URL-mode builds omit OPERANT because its build inputs are not
published. Corpus generation is not required for ordinary fixture verification. npm run probe:mcp targets the live Worker by default, and the connected audit starts a
local Worker and invokes the separately installed mcp-audit CLI. Keep those
separate from local gates; deployment and signing remain operator-gated as
described below.
Inspect either transport with the MCP inspector:
Operator-gated (needs Cloudflare auth). v1 still deploys to the default
portfolio-mcp.<account>.workers.dev URL, and npm run probe:mcp uses that stable
Worker URL by default. Public discovery now advertises the verified custom endpoint
https://mcp.saagarpatel.dev/mcp; after any deploy, verify both the Worker and the
website manifest/readback path before changing .well-known/mcp.json.
wrangler.jsonc pins workers_dev: true so the public Worker URL stays live during any
future custom-domain experiments; do not remove it unless the website manifest has already
moved to a verified replacement endpoint.
Once published, anyone can run it locally with npx saagar-portfolio-mcp (no install).
Ed25519-sign .well-known/mcp.json so an agent or registry can verify it authentically
comes from Saagar (via saagar-mcp-kit's signing CLI, Node built-in crypto):
Override paths with --manifest=/--key=/--pub=/--sig=.
Commit the .sig + mcp-ed25519.pub (never the private key) into portfolio-index next to the manifest, then
redeploy the site. Re-run sign whenever the manifest changes (it signs the exact served bytes).
Designed to pass MCPAudit / mcp-trust (Saagar's own tools): only the inbound MCP
transport, no shell_execution / file_access / destructive / exfiltration, and no
caller-controlled egress (the corpus is baked). All tools are annotated read-only with
plain, non-injectable descriptions. bash scripts/audit-mcp.sh runs a connected scan.
Dogfooding this server surfaced a substring-matching false-positive bug in MCPAudit (it
matched port inside portfolio://); that fix lives in the MCPAudit repo and cut this
server's findings 62 → 14. The genuine tool surface scans clean (high_risk_servers: 0).
Node.js 24.21.0, npm 12.2.0, TypeScript, Cloudflare Workers, and the MCP SDK.
URL-mode corpus builds omit OPERANT, whose inputs are only available to local corpus builds. Worker deployment and package publication are not part of local verification.
Keep the published MCP endpoint and signed discovery manifest in sync when an operator authorizes a deployment. Registry publication remains a separate, explicitly authorized release action.
Source: README.md at commit 55de013
Search the writing corpus
Full-text (BM25) search across all essays, book chapters, and field notes. Returns ranked matches with a snippet, id, and canonical URL. Pass an id to get_document to read the full text.
limitqueryrequiredsectionGet a document
Return the full Markdown of one document by id, e.g. "writing/the-handoff" or "book/preface". Get ids from search or list_corpus.
idrequiredList the corpus
List every document with its id, title, type, date, and word count, plus per-type counts. The table of contents for the whole site. Optionally filter by type.
typeGet profile
Return Saagar Patel's profile: name, one-line summary, site, and the about / now / uses pages. Start here to understand who this is and what they work on.
Takes no parameters.
List projects
List the curated, public projects with stack, status, last-active date, and test/CI signals, plus anonymized portfolio-wide aggregates. Optionally filter by status.
limitstatusList repo profiles
List public-safe repo answering profiles with repo id, attention state, freshness, and proof counts. Profiles are static artifacts baked from saagarpatel.dev, not live repo health.
limitattentionStateGet repo profile
Return one public-safe repo answering profile by repo_id, including purpose, safe commands, agent surfaces, proof refs, freshness, exclusions, limitations, and integrity metadata.
repoIdrequiredGet OPERANT benchmark results
Return the public, sanitized OPERANT results: per-model operator-calibration-score (OCS) profiles, the headline figures, and the calibration-profiles (not a flat leaderboard) framing. Sourced from the published OPERANT mirror. Returns availability=false if no dataset was baked.
Takes no parameters.
100% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

fit.portfolioOfficial publisher
PortfolioFit is a remote MCP server that lets an assistant check normalized portfolios against mandates and compute allocation constraints and statistics.

dev.ryeOfficial publisher
Remote MCP endpoint exposing Cameron Rye's blog, portfolio projects, bio, reading list and live site stats, plus contact and newsletter tools.
Published by GitHub account shlokbam
Shlok Bam's portfolio's hosted MCP server; no sign-in required; Streamable HTTP; 10 tools.

Published by GitHub account HarshithNayakaL
Read-only MCP server exposing the developer documentation for a portfolio site's JSON API, MCP, A2A and NLWeb endpoints.

Published by GitHub account HarshithNayakaL
Read-only MCP access to Harshith Nayaka L's portfolio site, letting an assistant look up his profile, projects, case studies, FAQ and agent skills.
src/ types.ts corpus + projects + operant shapes bm25.ts dependency-free BM25 + snippet (pure) tools.ts createTools(corpus) -> the 8 tools (pure, injectable) corpus.ts loads the baked corpus + accessors corpus.generated.ts AUTO-GENERATED by build:corpus server.ts buildServer(): shared MCP core (tools + resources + prompts) index.ts Cloudflare Worker transport (streamable HTTP) stdio.ts Layer 2 stdio transport (the npx CLI)scripts/ build-corpus.mjs bakes Layer 0 and local OPERANT inputs into corpus.generated.ts probe-mcp.mjs probes an MCP HTTP endpoint (saagar-mcp-kit driver + domain calls) audit-mcp.sh connected MCPAudit scan of this server (dogfood)test/ vitest: bm25, tools, full-protocol server testsnpm cimake checknpx @modelcontextprotocol/inspector http://localhost:8787/mcp # Layer 1 (HTTP)npx @modelcontextprotocol/inspector node dist/stdio.js # Layer 2 (stdio, after build:cli)npm run build:corpus && npm run deploy # wrangler deploynpm run probe:mcp # post-deploy live MCP readbacknpm run build:corpus && npm run build:cli # -> dist/stdio.jsnpm login && npm publish # public package: saagar-portfolio-mcpnpx mcp-kit-sign gen-key --manifest=../portfolio-index/.well-known/mcp.json # one-time; private key -> .signing/ (gitignored, NEVER commit)npm run sign # writes <manifest>.sig + publishes mcp-ed25519.pubnpm run sign:verify # checks manifest bytes against .sig + public key