Backend for the share-as-link feature of Local Web Clipper.
Accepts markdown from the extension (or CLI / MCP server), optionally runs Claude Sonnet via Vercel AI Gateway to produce a beautifully styled HTML reading page, stores the result in Vercel Blob, and serves it at https://<your-domain>/c/<slug>.
Authenticated. Stores a clip and returns a shareable URL.
Headers
Authorization: Bearer <SHARE_AUTH_TOKEN>
Content-Type: application/json
Body
Optional BYOK header
X-Provider-Key: sk-ant-... // if set, the chosen model's provider is called
// DIRECTLY with this key (bypasses Vercel AI Gateway).
// The key is held in function memory only — never logged,
// never persisted. See "BYOK & privacy" below.
Modes:
"markdown"— raw markdown rendered through a clean reader shell. No AI call. Fast & free."markdown-summary"— Sonnet summarizes the markdown (TL;DR + key points), then the reader shell renders the summary."html"— Sonnet generates a fully visual self-contained HTML page with TL;DR baked in.
Response
{ "slug": "title-x7k2p9", "url": "https://your-domain.com/c/title-x7k2p9", "mode": "html" }Public. Serves the stored HTML page. Returns 404 if the slug doesn't exist.
npm install
cp .env.example .env.local # fill in values for `vercel dev`
npx vercel link # link to a Vercel project
npx vercel env pull # pull env vars after configuring on Vercel
npm run dev # local: http://localhost:3000
npm run deploy:prod # production deploy| Variable | How to get it |
|---|---|
SHARE_AUTH_TOKEN |
Generate with openssl rand -hex 32. Paste the same value into the extension's settings. |
BLOB_READ_WRITE_TOKEN |
Auto-injected after you connect a Blob store to the project (Storage → Create → Blob). |
AI_GATEWAY_API_KEY |
Auto-injected after enabling AI Gateway on the project (or create a key at vercel.com/dashboard/ai-gateway). |
curl -X POST https://your-domain.com/api/clip \
-H "Authorization: Bearer $SHARE_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Hello\n\nA test clip.",
"title": "Hello",
"mode": "markdown"
}'For mode: "html" or mode: "markdown-summary", expect a 5–15 second delay while Sonnet runs.
- Browser extension — Local Web Clipper (selectable share destination)
- CLI —
sharebinary (planned, same npm package as MCP) - MCP server —
share-mcpstdio binary exposing one tool to any MCP-capable agent (Claude Code, Cursor, etc.)
This backend supports two modes of paying for AI:
- Shared mode (default). Requests use the backend operator's
AI_GATEWAY_API_KEYvia Vercel AI Gateway. Everyone using this deployment shares one bill. Required: the operator trusts callers, callers trust the operator with their clip content. - Bring-your-own-key (BYOK). The extension sends an
X-Provider-Keyheader. The backend uses that key to call the provider (Anthropic / OpenAI / DeepSeek) directly, bypassing the Gateway. The caller's provider account pays.
Your API key passes through the backend operator's infrastructure:
extension → HTTPS → Vercel function (decrypts TLS, sees key) → provider API
The operator could, in principle, write code that captures your key. This is fundamental to any centrally-hosted backend. What's done in this repo to minimize the risk:
| Layer | Protection |
|---|---|
| Transport | Key sent in a header (not JSON body) to reduce accidental body-logging risk |
| Server logging | Zero console.* statements touch the key. grep "byokKey" api/clip.ts to verify |
| Server storage | Key held in a local variable for the duration of one request, then garbage-collected. Never written to Blob / KV / disk |
| Error scrubbing | Any error message containing the key (e.g. from a misbehaving SDK) is run through message.split(byokKey).join('[REDACTED]') before being returned |
| CORS | Endpoint is gated by SHARE_AUTH_TOKEN — random websites can't POST clips |
| Source | This whole repo is public. The BYOK code path is ~15 lines, easy to audit |
The operator cannot fix the fundamental trust requirement. If you don't trust them, self-host (next section).
Takes about 5 minutes if you have a Vercel account:
git clone https://github.com/DigitalOutbreak/web-clipper-share
cd web-clipper-share
npm install
npx vercel link # creates a new Vercel project under your account
npx vercel env add SHARE_AUTH_TOKEN production # paste a value from `openssl rand -hex 32`
# Connect a Blob store via Vercel dashboard → Storage → Create → Blob
# Enable AI Gateway via Vercel dashboard → AI Gateway
npx vercel deploy --prodThen in the extension's Settings → Share backend:
- Replace the
Endpoint URLwith your own Vercel deployment URL - Paste your
SHARE_AUTH_TOKENin the auth field - Leave the BYOK fields blank (your AI Gateway is billing you anyway)
Now nothing touches anyone else's infrastructure.
BYOK keys are stored in browser.storage.local (device-only). They are not synced via your Google account, and they are not included when you click "Export all settings" (that only exports storage.sync).
{ "markdown": "# Title\n\nBody text...", // required, <= 200KB "title": "Title", // optional, used for slug + <title> "mode": "html", // "markdown" | "markdown-summary" | "html" "sourceUrl": "https://example.com/article", // optional, surfaced in HTML metadata "model": "anthropic/claude-sonnet-4-6" // optional, model id (see allowlist in api/clip.ts) }