loading…
Search for a command to run...
loading…
MCP server for sharing markdown/text as beautiful, permanent web pages via plsreadme, with tools to share files/text, update and delete docs, and list previousl
MCP server for sharing markdown/text as beautiful, permanent web pages via plsreadme, with tools to share files/text, update and delete docs, and list previously shared links.
Paste markdown. Get a beautiful, shareable link. Done.
Website · MCP Package · Request a Feature
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.
plsrd.me linkplsrd.me/v/xxx URL.md file from any shared link/v/:id/versions + /v/:id/history + archive-first restore API for fast rollbackowner_user_id) while preserving anonymous flows/my-links page with search/sort/pagination and quick copy/open actionsadmin_tokenGo to plsreadme.com, paste your markdown, click share.
Recommendation order:
Current rollout state:
| Journey | Status today | Ownership rule | Source tag |
|---|---|---|---|
| Anonymous website demo | Available now via browser-verified demo flow | owner_user_id = NULL until user later saves/claims the doc |
web_demo |
| Signed-in website create | Available now | doc is created with the signed-in Clerk user as owner | web_signed_in |
| Hosted remote MCP with browser login | Available now in supported clients | creates owned docs for the signed-in user after browser login | mcp_remote_login |
| Hosted remote MCP with API key | Available now as the compatibility fallback | creates owned docs for the API key owner | mcp_remote_api_key |
| Local npm MCP with API key | Available now and recommended for local stdio setups | creates owned docs for the API key owner | mcp_local_api_key |
| Local npm MCP anonymous fallback | Still available only with explicit opt-in | remains anonymous unless later claimed/saved | mcp_local_anonymous |
Hosted remote MCP rollout notes:
https://plsreadme.com/mcphttps://plsreadme.com/sseThose 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:
/api/create-link require a short-lived browser verification grantSave to my account, Connect your editor, and Copy linkcurl -X POST https://plsreadme.com/api/render \
-H "Content-Type: application/json" \
-d '{"markdown": "# Hello World\n\nThis is my doc."}'
{
"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:
# 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_..."
Use the timeline endpoint to review revision context during AI iteration cycles:
curl https://plsreadme.com/v/abc123def456/versions
{
"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):
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.
The document viewer now exposes comment review controls:
You can fetch the same modes directly from the API:
# 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=currenthttps://plsreadme.com/v/abc123def456?view=timelineTo claim a legacy anonymous link into your signed-in account:
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_..."}'
Current recommendation today:
plsreadme-mcp package with PLSREADME_API_KEY for the safest stdio pathConnect 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"
/versionsFor iterative AI writing flows (draft → critique → revise), agents can consume /v/:id/versions as the source of truth:
/v/:id) for humans./v/:id/versions between iterations.current_version to the last reviewed version.raw_url for the newest version and run review checks./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.
Current as of April 5, 2026:
| Client | Recommended path | Browser login support | API key fallback | Notes |
|---|---|---|---|---|
| Claude Code | hosted remote MCP first | verified live | yes | best supported remote flow; local stdio with PLSREADME_API_KEY also works well |
| Cursor | hosted remote MCP first | documented, but build-dependent in practice | yes | use headers if your build does not surface the OAuth prompt |
| VS Code | hosted remote MCP when available | configuration exists, rollout varies by build | yes | type: "http" plus header fallback works when login UX is absent |
| Windsurf | hosted remote MCP when available | documented remote support | yes | use serverUrl + headers when browser auth is not exposed yet |
| Claude Desktop | local npm MCP | no verified remote browser flow here | yes | prefer stdio + PLSREADME_API_KEY |
| Raw HTTP / scripts | hosted remote header mode | no | yes | send Authorization: Bearer $PLSREADME_API_KEY directly |
Claude Code:
claude mcp add --transport http plsreadme https://plsreadme.com/mcp
Cursor:
{
"mcpServers": {
"plsreadme": {
"url": "https://plsreadme.com/mcp"
}
}
}
VS Code:
{
"servers": {
"plsreadme": {
"type": "http",
"url": "https://plsreadme.com/mcp"
}
}
}
Windsurf:
{
"mcpServers": {
"plsreadme": {
"serverUrl": "https://plsreadme.com/mcp"
}
}
}
Lifecycle notes:
1 hour30 daysGET /api/auth/mcp-grants and DELETE /api/auth/mcp-grants/:grantId to audit or revoke hosted editor grantsIf your client supports browser login, prefer this path. It is the cleanest setup and keeps owned docs tied to your website account automatically.
Create a personal API key from https://plsreadme.com/my-links first, then use one of these:
Claude Code:
claude mcp add --transport http \
--header "Authorization: Bearer $PLSREADME_API_KEY" \
plsreadme-api https://plsreadme.com/mcp
Cursor:
{
"mcpServers": {
"plsreadme-api": {
"url": "https://plsreadme.com/mcp",
"headers": {
"Authorization": "Bearer ${env:PLSREADME_API_KEY}"
}
}
}
}
VS Code:
{
"inputs": [
{
"type": "promptString",
"id": "plsreadme-api-key",
"description": "plsreadme personal API key",
"password": true
}
],
"servers": {
"plsreadme-api": {
"type": "http",
"url": "https://plsreadme.com/mcp",
"headers": {
"Authorization": "Bearer ${input:plsreadme-api-key}"
}
}
}
}
Windsurf:
{
"mcpServers": {
"plsreadme-api": {
"serverUrl": "https://plsreadme.com/mcp",
"headers": {
"Authorization": "Bearer ${env:PLSREADME_API_KEY}"
}
}
}
}
Raw remote endpoint users:
curl -i https://plsreadme.com/mcp \
-H "Authorization: Bearer $PLSREADME_API_KEY"
Claude Code:
claude mcp add --transport stdio \
--env PLSREADME_API_KEY=$PLSREADME_API_KEY \
plsreadme -- npx -y plsreadme-mcp
Cursor:
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"plsreadme": {
"command": "npx",
"args": ["-y", "plsreadme-mcp"],
"env": {
"PLSREADME_API_KEY": "${env:PLSREADME_API_KEY}"
}
}
}
}
VS Code:
Add to .vscode/mcp.json:
{
"inputs": [
{
"type": "promptString",
"id": "plsreadme-api-key",
"description": "plsreadme personal API key",
"password": true
}
],
"servers": {
"plsreadme": {
"command": "npx",
"args": ["-y", "plsreadme-mcp"],
"env": {
"PLSREADME_API_KEY": "${input:plsreadme-api-key}"
}
}
}
}
Claude Desktop:
Add to claude_desktop_config.json:
{
"mcpServers": {
"plsreadme": {
"command": "npx",
"args": ["-y", "plsreadme-mcp"],
"env": {
"PLSREADME_API_KEY": "<paste-your-personal-api-key>"
}
}
}
}
Windsurf:
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"plsreadme": {
"command": "npx",
"args": ["-y", "plsreadme-mcp"],
"env": {
"PLSREADME_API_KEY": "${env:PLSREADME_API_KEY}"
}
}
}
}
Notes:
PLSREADME_API_KEY by default so new docs are ownedPLSREADME_ALLOW_ANONYMOUS=1If you already used plsreadme-mcp anonymously:
/my-links.PLSREADME_API_KEY to your MCP client config.PLSREADME_ALLOW_ANONYMOUS=1 only as a temporary compatibility crutch for old workflows./api/auth/claim-link if you still have their admin_token.The migration rule is simple:
npx add-mcp plsreadme-mcp
clawhub install plsreadme
Build and run the stdio MCP server in a clean container:
docker build -t plsreadme-mcp:local .
docker run --rm -i plsreadme-mcp:local
The containerized server uses stdio (no ports, no env vars required).
| Tool | What it does |
|---|---|
plsreadme_share_file |
Share a local file by path → returns shareable link. Re-sharing updates the same link. |
plsreadme_share_text |
Share markdown or plain text directly → returns shareable link |
plsreadme_update |
Update an existing doc with new content (by ID or file path) |
plsreadme_delete |
Delete a shared doc permanently (by ID or file path) |
plsreadme_list |
List all documents you've shared from this project |
Prompts:
share-document — Guided flow to share content as a readable linkrefactor-and-share — Uses your AI model to refactor raw text into polished markdown, then shares itPlain 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.
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.
Built on Cloudflare's edge stack for speed everywhere:
┌─────────────┐ ┌──────────────────┐ ┌─────────┐
│ Web / API │────▶│ Cloudflare │────▶│ R2 │
│ MCP Client │ │ Workers (Hono) │ │ (docs) │
└─────────────┘ └──────────────────┘ └─────────┘
│
┌──────┴──────┐
│ D1 │
│ (metadata) │
└─────────────┘
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
# 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.db/migrations/004_owner_user_id.sql in existing environments before relying on ownership filters.db/migrations/007_doc_attribution_telemetry.sql before relying on doc_create_events or raw_view_count.owner_user_id = NULL (anonymous/public behavior preserved).plsreadme-mcp is published from packages/mcp by pushing an mcp-v* tag (see .github/workflows/publish-mcp.yml).
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
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 withwrangler secret put.
| Variable | Required | Description |
|---|---|---|
OPENAI_API_KEY |
No | OpenAI key for /api/convert text→markdown |
DISCORD_WEBHOOK_URL |
No | Waitlist signup notifications |
DISCORD_LINK_WEBHOOK_URL |
No | New link creation notifications |
RESEND_API_KEY |
No | Email notifications |
NOTIFICATION_EMAIL |
No | Email recipient for notifications |
CLERK_PUBLISHABLE_KEY |
For auth | Clerk publishable key for frontend auth wiring (social + email fallback) |
CLERK_JWT_ISSUER |
For auth | Clerk JWT issuer used by worker verification |
CLERK_JWT_AUDIENCE |
Optional | Expected audience claim for Clerk JWTs |
CLERK_SIGN_IN_URL |
Optional | Clerk-hosted sign-in URL hint (default /sign-in) |
CLERK_SIGN_UP_URL |
Optional | Clerk-hosted sign-up URL hint (default /sign-up) |
CLERK_SECRET_KEY |
Optional | Reserved 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).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.
| Limit | Value |
|---|---|
| Max document size | 200 KB |
| Upload rate limit | 30/hour per actor key |
| Update/restore rate limit | 60/hour per actor key |
| AI convert rate limit | 10/hour per IP |
| Link lifetime | Permanent |
Feature ideas? Bug reports? Open an issue.
PRs welcome for bug fixes and improvements.
MIT — do whatever you want with it.
Built by Facundo Lucci
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"plsreadme": {
"command": "npx",
"args": []
}
}
}