Labsco
FacundoLucci logo

plsreadme

β˜… 2

from FacundoLucci

Share markdown files and text as clean, readable web links. Works with Cursor, Claude Desktop, VS Code, Windsurf, and any MCP client.

πŸ”₯πŸ”₯πŸ”₯βœ“ VerifiedAccount requiredNeeds API keys
<p align="center"> <img src="https://plsreadme.com/icon.png" alt="plsreadme" width="80" /> </p> <h1 align="center">plsreadme</h1> <p align="center"> <strong>Paste markdown. Get a beautiful, shareable link. Done.</strong> </p> <p align="center"> <a href="https://plsreadme.com">Website</a> Β· <a href="https://www.npmjs.com/package/plsreadme-mcp">MCP Package</a> Β· <a href="https://github.com/FacundoLucci/plsreadme/issues/new?labels=feature-request">Request a Feature</a> </p> <p align="center"> <img src="https://img.shields.io/npm/v/plsreadme-mcp?style=flat-square&color=111827" alt="npm version" /> <img src="https://img.shields.io/badge/Cloudflare_Workers-deployed-F38020?style=flat-square&logo=cloudflare&logoColor=white" alt="Cloudflare Workers" /> <img src="https://img.shields.io/badge/MCP-compatible-10b981?style=flat-square" alt="MCP compatible" /> <img src="https://img.shields.io/github/license/FacundoLucci/plsreadme?style=flat-square" alt="License" /> </p>

The Problem

You wrote a README, a PRD, meeting notes, or an API doc in markdown. Now you need to share it with someone who doesn't have a markdown renderer, doesn't use GitHub, or just needs a clean link they can open in a browser.

plsreadme turns any markdown into a permanent, beautifully rendered web page in one step. No accounts. No sign-ups. No friction.

✨ Features

  • Instant sharing β€” Paste markdown or upload a file, get a plsrd.me link
  • Beautiful rendering β€” Clean typography, dark mode, mobile-responsive
  • Inline comments β€” Readers can click any paragraph and leave feedback
  • Review mode (current vs timeline) β€” Multi-version docs default to Current draft feedback with one-click access to full Timeline history
  • AI auto-formatting β€” Throw raw text at it; it comes out as clean markdown
  • MCP server β€” Share docs directly from Claude, Cursor, VS Code, or any MCP client
  • OpenClaw skill β€” Available on ClawHub for AI agent workflows
  • Short links β€” Every doc gets a compact plsrd.me/v/xxx URL
  • Raw access β€” Download the original .md file from any shared link
  • Version timeline + safe restore β€” /v/:id/versions + /v/:id/history + archive-first restore API for fast rollback
  • Clerk auth foundation β€” GitHub/Google sign-in wiring + Clerk-hosted email fallback + backend auth verification utilities
  • Ownership model (Phase 2) β€” docs can be linked to a Clerk user (owner_user_id) while preserving anonymous flows
  • My Links dashboard (Phase 3) β€” authenticated /my-links page with search/sort/pagination and quick copy/open actions
  • Legacy link claiming (Phase 4) β€” signed-in users can claim older anonymous links by proving the original admin_token
  • Zero config website demo β€” No account or API key needed to try it in the browser

Auth Paths And Rollout State

Recommendation order:

  1. Try in browser first β€” fastest demo path, no MCP setup required.
  2. Use hosted remote MCP with browser login when client support is verified.
  3. Use API key / local MCP fallback when interactive login is unavailable.

Current rollout state:

JourneyStatus todayOwnership ruleSource tag
Anonymous website demoAvailable now via browser-verified demo flowowner_user_id = NULL until user later saves/claims the docweb_demo
Signed-in website createAvailable nowdoc is created with the signed-in Clerk user as ownerweb_signed_in
Hosted remote MCP with browser loginAvailable now in supported clientscreates owned docs for the signed-in user after browser loginmcp_remote_login
Hosted remote MCP with API keyAvailable now as the compatibility fallbackcreates owned docs for the API key ownermcp_remote_api_key
Local npm MCP with API keyAvailable now and recommended for local stdio setupscreates owned docs for the API key ownermcp_local_api_key
Local npm MCP anonymous fallbackStill available only with explicit opt-inremains anonymous unless later claimed/savedmcp_local_anonymous

Hosted remote MCP rollout notes:

  • https://plsreadme.com/mcp
  • https://plsreadme.com/sse

Those hosted remote MCP routes are live behind OAuth-protected browser login in code, including /authorize, /oauth/token, and /oauth/register.

Operational notes:

  • D1 doc_create_events is the canonical create-attribution table across web, hosted MCP, and local MCP flows.

  • docs.raw_view_count tracks every render hit, while docs.view_count is reserved for likely-human reads.

  • See docs/runbooks/auth-surface-monitoring.md for the production query set and response steps.

  • access tokens last about 1 hour

  • refresh tokens last about 30 days

  • reconnecting the same client replaces the older grant

  • signing out of the website does not revoke an existing editor grant by itself

  • this repo is now wired to a dedicated Cloudflare Workers KV binding named OAUTH_KV

When browser login is not available in your client, create a personal API key from /my-links and use either the hosted remote header fallback or the local npx -y plsreadme-mcp package.

Website demo trust model today:

  • anonymous website creates on /api/create-link require a short-lived browser verification grant
  • signed-in website creates skip that grant and stay friction-light
  • post-create UI now branches into Save to my account, Connect your editor, and Copy link

API

Copy & paste β€” that's it
curl -X POST https://plsreadme.com/api/render \
  -H "Content-Type: application/json" \
  -d '{"markdown": "# Hello World\n\nThis is my doc."}'
Copy & paste β€” that's it
{
  "id": "abc123def456",
  "url": "https://plsreadme.com/v/abc123def456",
  "raw_url": "https://plsreadme.com/v/abc123def456/raw",
  "admin_token": "sk_..."
}

Save the admin_token β€” you'll need it to edit or delete:

Copy & paste β€” that's it
# Update
curl -X PUT https://plsreadme.com/v/abc123def456 \
  -H "Authorization: Bearer sk_..." \
  -H "Content-Type: application/json" \
  -d '{"markdown": "# Updated content"}'

# Delete
curl -X DELETE https://plsreadme.com/v/abc123def456 \
  -H "Authorization: Bearer sk_..."

Version timeline + safe restore

Use the timeline endpoint to review revision context during AI iteration cycles:

Copy & paste β€” that's it
curl https://plsreadme.com/v/abc123def456/versions
Copy & paste β€” that's it
{
  "id": "abc123def456",
  "current_version": 5,
  "total_versions": 5,
  "versions": [
    { "version": 5, "is_current": true, "raw_url": "https://plsreadme.com/v/abc123def456/raw" },
    { "version": 4, "is_current": false, "raw_url": "https://plsreadme.com/v/abc123def456/raw?version=4" }
  ]
}

If an AI edit regresses the doc, restore a prior snapshot (archive-first, non-destructive):

Copy & paste β€” that's it
curl -X POST https://plsreadme.com/v/abc123def456/restore \
  -H "Authorization: Bearer sk_..." \
  -H "Content-Type: application/json" \
  -d '{"version": 4}'

Restore is rate-limited similarly to updates (currently 60/hour per actor key) to reduce abuse.

For docs owned by an authenticated Clerk user, update/delete/restore also require that owner session (to prevent cross-user mutation), while anonymous docs continue to work with admin_token only.

Review mode usage notes (Current draft first, Timeline on demand)

The document viewer now exposes comment review controls:

  • Current draft β€” shows only comments tied to the latest doc version (default when a doc has multiple versions).
  • Timeline β€” shows the full cross-version comment history.

You can fetch the same modes directly from the API:

Copy & paste β€” that's it
# Latest-version comments only
curl "https://plsreadme.com/api/comments/abc123def456?view=current"

# Full timeline comments (default API behavior)
curl "https://plsreadme.com/api/comments/abc123def456?view=all"

Viewer links persist the mode in the URL for shareable review context:

  • https://plsreadme.com/v/abc123def456?view=current
  • https://plsreadme.com/v/abc123def456?view=timeline

To claim a legacy anonymous link into your signed-in account:

Copy & paste β€” that's it
curl -X POST https://plsreadme.com/api/auth/claim-link \
  -H "Authorization: Bearer <clerk-session-jwt>" \
  -H "Content-Type: application/json" \
  -d '{"id":"abc123def456","adminToken":"sk_..."}'

MCP (AI Editors)

Current recommendation today:

  • use hosted remote MCP with browser login when your client supports it cleanly
  • use personal API key fallback when remote auth is unavailable or awkward in that client
  • use the local plsreadme-mcp package with PLSREADME_API_KEY for the safest stdio path

Connect your editor to plsreadme and share docs with natural language:

"Share this README as a plsreadme link" "Turn my PRD into a shareable page" "Make these meeting notes into a readable link"

MCP/agent auto-review loop with /versions

For iterative AI writing flows (draft β†’ critique β†’ revise), agents can consume /v/:id/versions as the source of truth:

  1. Keep the canonical readable URL (/v/:id) for humans.
  2. Poll /v/:id/versions between iterations.
  3. Compare current_version to the last reviewed version.
  4. If changed, fetch raw_url for the newest version and run review checks.
  5. If quality regresses, optionally trigger /v/:id/restore with admin token + owner session.

This gives automation deterministic revision tracking without scraping HTML.

See docs/ai-iteration-versioning.md for a full playbook.

πŸ›  MCP Tools

ToolWhat it does
plsreadme_share_fileShare a local file by path β†’ returns shareable link. Re-sharing updates the same link.
plsreadme_share_textShare markdown or plain text directly β†’ returns shareable link
plsreadme_updateUpdate an existing doc with new content (by ID or file path)
plsreadme_deleteDelete a shared doc permanently (by ID or file path)
plsreadme_listList all documents you've shared from this project

Prompts:

  • share-document β€” Guided flow to share content as a readable link
  • refactor-and-share β€” Uses your AI model to refactor raw text into polished markdown, then shares it

Plain text input? No problem β€” the MCP auto-structures it into markdown, or you can use the refactor-and-share prompt to leverage your AI's reasoning for a polished result.

.plsreadme Record File

The MCP server tracks your shared documents in a .plsreadme JSON file in your project root. This stores document IDs, URLs, and admin tokens needed for editing and deleting.

⚠️ Add .plsreadme to your .gitignore β€” it contains admin tokens. The tool will warn you if it's missing.

πŸ— Architecture

Built on Cloudflare's edge stack for speed everywhere:

Copy & paste β€” that's it
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Web / API  │────▢│  Cloudflare      │────▢│   R2    β”‚
β”‚  MCP Client β”‚     β”‚  Workers (Hono)  β”‚     β”‚ (docs)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”
                    β”‚     D1      β”‚
                    β”‚ (metadata)  β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • Hono β€” Lightweight web framework on Workers
  • Cloudflare D1 β€” SQLite at the edge for metadata, comments, analytics
  • Cloudflare R2 β€” Object storage for markdown documents
  • Durable Objects β€” Stateful MCP server endpoint
  • Workers AI β€” Optional fallback for text-to-markdown conversion

πŸ“ Project Structure

Copy & paste β€” that's it
plsreadme/
β”œβ”€β”€ worker/
β”‚   β”œβ”€β”€ index.ts              # Main worker entry
β”‚   β”œβ”€β”€ auth.ts               # Clerk JWT verification utilities/middleware
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”œβ”€β”€ auth.ts           # Auth config/session/protected identity endpoints
β”‚   β”‚   β”œβ”€β”€ docs.ts           # Document creation & rendering
β”‚   β”‚   β”œβ”€β”€ comments.ts       # Inline commenting system
β”‚   β”‚   β”œβ”€β”€ convert.ts        # AI textβ†’markdown conversion
β”‚   β”‚   β”œβ”€β”€ analytics.ts      # View tracking
β”‚   β”‚   β”œβ”€β”€ links.ts          # Short link handling
β”‚   β”‚   └── waitlist.ts       # Waitlist & notifications
β”‚   β”œβ”€β”€ mcp-agent.ts          # Remote MCP server (Durable Object)
β”‚   └── types.ts              # TypeScript types
β”œβ”€β”€ packages/
β”‚   └── mcp/                  # npm package: plsreadme-mcp
β”‚       └── src/index.ts      # MCP server (stdio transport)
β”œβ”€β”€ public/                   # Static assets & landing pages
β”œβ”€β”€ db/
β”‚   └── schema.sql            # D1 database schema
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ ai-iteration-versioning.md # Version timeline/restore patterns for human + agent loops
β”‚   β”œβ”€β”€ auth-clerk.md              # Auth setup + environment checklist
β”‚   └── runbooks/
β”‚       └── legacy-link-claim-rollout.md
β”œβ”€β”€ skill/
β”‚   └── plsreadme/            # OpenClaw agent skill
└── wrangler.jsonc             # Cloudflare Workers config

πŸ”§ Development

Copy & paste β€” that's it
# Install dependencies
npm install

# Run locally
npm run dev

# Deploy
npm run deploy

# Bootstrap schema (fresh local DB)
npm run db:migrate:local

# Audit unapplied migrations (remote + local)
npm run db:migrations:status

# Apply migration files explicitly
npm run db:migrations:apply        # remote
npm run db:migrations:apply:local  # local

Ownership phase migration notes:

  • wrangler.jsonc points migrations_dir to db/migrations, so migration status is auditable with explicit list/apply commands.
  • Apply db/migrations/004_owner_user_id.sql in existing environments before relying on ownership filters.
  • Apply db/migrations/007_doc_attribution_telemetry.sql before relying on doc_create_events or raw_view_count.
  • Legacy rows are intentionally backfilled as owner_user_id = NULL (anonymous/public behavior preserved).
  • Write routes still run a safe ownership schema ensure step (duplicate-column tolerant) for mixed-env rollout safety.
  • See docs/migrations.md for the explicit audit/apply workflow.

MCP package release

plsreadme-mcp is published from packages/mcp by pushing an mcp-v* tag (see .github/workflows/publish-mcp.yml).

Copy & paste β€” that's it
cd packages/mcp
npm version patch   # or minor/major
cd ../..
git add packages/mcp/package.json packages/mcp/package-lock.json
VERSION=$(node -p "require('./packages/mcp/package.json').version")
git commit -m "chore(mcp): release v${VERSION}"
git tag "mcp-v${VERSION}"
# push commit + tag from your machine to trigger npm publish workflow

Environment Variables

Start from .env.example and set values in your local/dev/prod environment.

Cloudflare tip: non-sensitive values can live in vars; sensitive values should be set with wrangler secret put.

VariableRequiredDescription
OPENAI_API_KEYNoOpenAI key for /api/convert text→markdown
DISCORD_WEBHOOK_URLNoWaitlist signup notifications
DISCORD_LINK_WEBHOOK_URLNoNew link creation notifications
RESEND_API_KEYNoEmail notifications
NOTIFICATION_EMAILNoEmail recipient for notifications
CLERK_PUBLISHABLE_KEYFor authClerk publishable key for frontend auth wiring (social + email fallback)
CLERK_JWT_ISSUERFor authClerk JWT issuer used by worker verification
CLERK_JWT_AUDIENCEOptionalExpected audience claim for Clerk JWTs
CLERK_SIGN_IN_URLOptionalClerk-hosted sign-in URL hint (default /sign-in)
CLERK_SIGN_UP_URLOptionalClerk-hosted sign-up URL hint (default /sign-up)
CLERK_SECRET_KEYOptionalReserved for future server-side Clerk integrations

If OAuth credentials are not configured yet, users can still click Sign in / Use email instead and complete auth through the Clerk-hosted email flow immediately.

Frontend auth shell notes:

  • /app.html and /my-links use public/clerk-auth-shell.js (Clerk-native browser SDK wiring).
  • Authenticated frontend API calls should read bearer tokens through window.plsreadmeGetAuthToken().

The core sharing functionality still requires zero configuration. Clerk auth, AI conversion, and notifications are opt-in.

For the full auth setup checklist, see docs/auth-clerk.md. For rollout + smoke checks, see docs/runbooks/mcp-auth-rollout-checklist.md.

πŸ“Š Limits

LimitValue
Max document size200 KB
Upload rate limit30/hour per actor key
Update/restore rate limit60/hour per actor key
AI convert rate limit10/hour per IP
Link lifetimePermanent

🀝 Contributing

Feature ideas? Bug reports? Open an issue.

PRs welcome for bug fixes and improvements.

πŸ“„ License

MIT β€” do whatever you want with it.


<p align="center"> <sub>Built by <a href="https://github.com/FacundoLucci">Facundo Lucci</a></sub> </p>