Ryan Lindsey

me.ryanlindseyPublished by ryanlindsey.meOfficial publisherv1.36.0Updated Oct 24, 2026

Ryan Lindsey's professional corpus, exposed as MCP tools.

VerifiedStreamable HTTPWeb executableWeb Search & ScrapingKnowledge & Memory

Overview

AI-generated overview

A remote MCP server exposing Ryan Lindsey's professional corpus — contact details, résumé, case studies and writing — for reading and semantic search.

What you can do
Get contact details and working timezone, and the résumé as JSON Resume data, markdown or a short prose summary. List published case studies and posts with metadata and citation URLs. Fetch the full markdown of a single case study or post by slug. Run semantic search across posts, case studies and the résumé, returning passages with their published URLs and an exact-match flag. Learn about a private access tier and how to request a scoped token.
When to use it
Useful when you want an assistant to answer questions about Ryan Lindsey's background, work or writing, or to cite his published case studies and posts, without scraping the site.
Requirements
A remote streamable HTTP endpoint; no packages, environment variables or headers are declared. The public tools need no authentication; the private tier requires requesting a scoped token.
Before you install
The private access tier involves requesting a scoped token, so treat any token as a secret. Tool calls consume a rate-limited budget on the server. Content is published material about a person; cite it rather than presenting it as your own.

Installation

In SourceWeft

  1. Open Ryan Lindsey in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

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/me.ryanlindsey%2Fryanlindsey-me/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.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "ryan-lindsey": {
      "type": "http",
      "url": "https://mcp.ryanlindsey.me/mcp"
    }
  }
}

README

ryanlindsey.me

The code behind ryanlindsey.me: an Astro site on the Cloudflare developer platform, plus a second Worker serving a remote MCP server at mcp.ryanlindsey.me. One repository, two deployed Workers, one shared set of D1, KV, R2, Queues and Analytics Engine resources.

The site is built so that a person and an agent read the same corpus through different doors.

Source-visible so you can read how it is built. There is no LICENSE file, and the absence is deliberate rather than an oversight: no license means all rights reserved, so nothing here is licensed for reuse.

Deploys run on Workers Builds from main, and CI has no deploy step. CLAUDE.md carries the working notes, including the commands, the traps worth knowing before editing, and the reasoning behind the parts that look strange.

If you are an agent

Four entrypoints, stable by contract:

EntrypointWhat it is
/llms.txtThe curated index, and the place to start
/.well-known/ard.jsonThe ARD manifest, also served as ai-catalog.json
/.well-known/mcp/server-card.jsonThe server card, served on both origins
https://mcp.ryanlindsey.me/mcpThe protocol endpoint itself

This file does not list the rest, and the omission is the part worth reading. Every endpoint this site advertises lives in one list, ADVERTISED_SURFACE in src/lib/discovery/surface.ts, published as both the API catalog and the ARD manifest and checked by tests/discovery-catalog.test.ts. A table here would be a second copy, living outside the test suite, and it would drift the first time an endpoint moved. Fetch the catalog rather than trusting this file.

One thing is missing from that list on purpose. /fit and everything beneath it are unlisted by requirement, and a catalog is a published list of the paths its author finds interesting, so listing one there would un-list it.

How it fits together

mermaid
flowchart TB  person(["person"])  agent(["agent"])
  subgraph site["site Worker (ryanlindsey.me)"]    S["pages, posts, case studies, résumé<br>markdown variants, llms.txt, feeds<br>well-known catalogs<br>chat page and the form surfaces"]  end
  subgraph mcpw["MCP Worker (mcp.ryanlindsey.me)"]    G{"grant resolved<br>here, and only here"}    T["/mcp, the chat stream,<br>the fit engine"]    R[["rate limiter<br>Durable Object"]]    G --> T    T -->|every tool call spends budget| R  end
  P[("R2_PRIVATE")]
  person --> site  agent --> site  agent --> mcpw  site -->|service binding| mcpw  mcpw -->|reads published documents| site  T -. "private-docs.ts, the only reader" .-> P

The split into two Workers is not cosmetic. An ai binding in the site's config makes astro build open a remote proxy session that credential-free CI cannot authenticate, so inference lives on the second Worker and the site reaches it over a service binding. Each Worker names the other, and the cycle is deliberate and legal, because a service binding resolves when it is called rather than when the Worker is defined.

The drawing is deliberately incomplete. It carries the structure and leaves out the rest: which storage each Worker touches, which models it calls, the queue consumer, the crons. The site publishes its own drawing of the deployed inventory on /ops, over the one description of this architecture the repository keeps, src/lib/architecture.ts. That page also reports what the system has done lately and what it cost, read at request time rather than asserted here.

What this repo guarantees

Four claims, each paired with the file that proves it rather than with an assurance.

ClaimEnforced by
The private tier is a partition rather than a filter. The public document layer's env interface does not name the private bucket at all.tests/tier-private-docs.test.ts, at the type level
An unauthenticated tools/list cannot enumerate a gated tool name, and calling one by name answers unknown-tool rather than a refusal confirming it.tests/mcp-gated.test.ts, "invisibility without a grant"
No test reaches Workers AI, Vectorize, Browser Rendering or a real secret. No deployed config declares the override variables, and an unrecognized value throws.tests/workers.ts sets them in one place, tests/mcp-env.test.ts keeps them out of both deployed configs, and an unrecognized value throws at the call site, as in src/lib/turnstile.ts
The MCP Worker's binding list cannot drift from its wrangler config, in either direction.tests/mcp-env.test.ts

Five minutes in this codebase

Four files, in reading order. They explain the rest.

  1. src/lib/discovery/surface.ts, every endpoint this site advertises, in one list, carrying the reason it is one list and not two.
  2. src/lib/tier/grant.ts, the only place a token is verified. The site Worker holds no copy: it treats the token as an opaque string and asks over the service binding, so the boundary has one implementation rather than two that agree.
  3. tests/workers.ts, why the suite boots real Workers inside workerd, and what it refuses to reach.
  4. src/components/ArchitectureDiagram.astro, for its header rather than its output. That header records that two claims in its own first draft were false, names them, and says what the mistake taught. It is a fair sample of how the rest of this repository is commented.

Releases

release-please watches main and keeps a release pull request open with the next version and its changelog. Merging that pull request tags the release and publishes it.

Pull requests are squash-merged, so the pull request title is the commit subject release-please reads. A title without a recognized type(scope): summary prefix is skipped silently: no version bump, no changelog entry. feat is a minor bump, fix and perf are patches, and type!: or a BREAKING CHANGE: footer is a major. The full set of types lives in release-please-config.json under changelog-sections.

Source: README.md at commit 6b24b76

Tools

8

get_contact

Contact details

How to reach Ryan Lindsey, and his working timezone.

Takes no parameters.

get_resume

Résumé

Ryan Lindsey's résumé: JSON Resume data, the published markdown document, or a short prose summary.

Parametersformat

list_case_studies

List case studies

Published case studies with their metadata and citation URLs.

Takes no parameters.

get_case_study

Get a case study

The full markdown of one published case study, by slug.

Parametersslugrequired

list_writing

List writing

Published posts with their descriptions and citation URLs.

Takes no parameters.

get_post

Get a post

The full markdown of one published post, by slug.

Parametersslugrequired

search_writing

Search the writing

Semantic search across the published posts, case studies and résumé. Each result is a passage, the URL it is published at, and an "exact" flag saying whether the excerpt is the passage that matched.

Parameterslimitqueryrequired

request_private_access

Request private access

Explains the private access tier and how to request a scoped token.

Takes no parameters.

Version history

1
  1. v1.36.0LatestSep 22, 2026

Score

90% 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.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

    Declare a license in the repository or the registry entry.