Skip to main content
Plannotator has two self-hostable services for the deprecated OSS share-link flow:
The OSS share-link flow is deprecated and retained for compatibility. No removal date has been announced. For new team sharing and collaboration, sign up for Workspaces.
You do not need either service for normal local reviews or to open a temporary session from another device. Install Plannotator and run it beside your coding agent for local use. See Remote access for phones, tablets, Tailscale, private networks, SSH, and development containers.

Understand the sharing services

The share portal is a static browser application. It has no application database, accounts, or built-in access control. For a normal Markdown share, Plannotator compresses the review into the complete URL after #. The browser does not send that fragment to the portal in its HTTP request. The portal loads the application, then the browser decodes the review locally. The fragment is not encrypted, so anyone with the complete URL can read the review. Large Markdown reviews and raw HTML use the paste service. The Plannotator client encrypts the payload before upload. The paste service stores ciphertext, while the decryption key stays in the complete share URL after #. Anyone with the complete link can fetch and decrypt the content. Deploy only the portal when hash-based Markdown links are enough. Deploy both services when you need encrypted short links or raw HTML sharing.
Neither service provides application authentication or certificates. Your hosting layer must provide HTTPS, access controls, rate limits, and network isolation where required.

Deploy the share portal

Build the portal from a Plannotator source checkout. Check out the release tag or reviewed commit you intend to operate before installing dependencies:
Deploy the contents of apps/portal/dist/ to a static host. Configure unknown paths, including /p/<paste-id>, to return index.html so direct short-link visits load the application. The hosting layer must provide HTTPS, access logs, caching rules, and any access control you require. Point new Plannotator sessions at the portal:
The process that starts Plannotator must inherit this variable. Existing sessions do not change their share base URL. The portal performs Plannotator’s automatic GitHub release check when it loads. Rendered shared content can also request remote images, fonts, scripts, or other resources it references. There is no setting that disables the release check.

Deploy the paste service

The paste service exposes POST /api/paste and GET /api/paste/:id. The repository includes two targets:
  • A Bun server with filesystem storage.
  • A Cloudflare Worker with KV storage.
Neither target authenticates callers. CORS controls which browser origins can use responses. It does not authenticate callers or block direct HTTP clients. The shared CORS helper always allows http://localhost and https://localhost origins, including ports. Setting an explicit origin list does not remove that localhost exception.

Run the Bun filesystem target

From the Plannotator source checkout:
Run the process under your normal service supervisor. The Bun target listens on all interfaces by default, even though its startup message prints a localhost URL. Enforce firewall or private-network isolation and put it behind an HTTPS reverse proxy. Do not leave port 19433 directly reachable from an untrusted network. The API has no authentication. If it is reachable beyond a trusted private network, add authentication and request-rate controls at the proxy or edge. The payload limit caps each upload, not the number of uploads or total storage growth. The data directory must have the ownership and backup policy you want. The process creates it when it is absent. The default maximum is 5 MiB of encrypted payload data. Each filesystem paste records its expiry time. An expired file is deleted when that paste is read or when the service next starts, so expired bytes can remain on disk past their logical expiry while a long-running service is idle. GitHub releases also include plannotator-paste-* binaries and matching .sha256 files for macOS, Linux, and Windows. Download the binary and same-named checksum file from the same release. Verify them before running the binary with the same PASTE_* variables:
On Windows, run Get-FileHash .\plannotator-paste-win32-x64.exe -Algorithm SHA256 and compare the result with plannotator-paste-win32-x64.exe.sha256.

Run the Cloudflare KV target

The repository’s apps/paste-service/wrangler.toml is a deployment example, not a namespace allocation for your account. Create your own KV namespace, replace both namespace IDs, and set ALLOWED_ORIGINS to your portal origin before deployment. Do not deploy the checked-in hosted namespace IDs into another environment.
Put the first command’s namespace ID in id and the preview command’s ID in preview_id before deploying. The current Worker target uses Cloudflare KV expiry with a fixed seven-day TTL and a fixed 5 MiB encrypted payload limit. Its supported runtime setting is ALLOWED_ORIGINS. The Bun-only PASTE_TTL_DAYS, PASTE_DATA_DIR, and PASTE_MAX_SIZE variables do not configure the Worker target.

Connect Plannotator to both services

Set both URLs in the environment that starts your coding agent:
Custom short links include the paste-service origin in the URL fragment so the static portal knows where to fetch the ciphertext. Anyone with the complete link has the paste ID and decryption key.

Deployment variables

See Environment variables for general PLANNOTATOR_* precedence and the setting that disables sharing.

Operator responsibilities

Authentication and network exposure

  • The static portal and paste API have no application authentication. Add access control at your hosting layer if your reviewers require it, then test the complete redirect and URL-fragment flow.
  • CORS is a browser boundary, not caller authentication.
  • A public paste API needs rate limits or equivalent abuse controls. The payload-size limit alone does not prevent repeated uploads.
  • The repository does not provision certificates or an HTTPS reverse proxy. The operator owns TLS for the portal and paste API.
  • Treat every complete share URL as a credential. Hash-based Markdown is readable from the URL. Short links contain the decryption key in the fragment.
  • Avoid putting complete share URLs in analytics, support tickets, screenshots, or logs with broader retention than the review.

Persistence, retention, and backup

  • Keep the Bun paste data directory on persistent storage only if short links must survive restarts.
  • Decide whether ephemeral ciphertext belongs in backups. A backup can retain bytes after the live paste expires, so its deletion schedule must match your policy.
  • Monitor disk use for the Bun target. Logical expiry does not guarantee immediate file removal from an idle, continuously running service.

Verify the deployment

1. Check the portal. Confirm that a direct portal route reaches the static application:
A working single-page application fallback returns 200. 2. Check the paste API. Send harmless data and inspect the CORS response:
Expect 201, an Access-Control-Allow-Origin header for the portal, and a JSON paste ID. 3. Test the deprecated sharing flow. Start a new Plannotator session with the custom variables. Create a normal Markdown link and an explicit short link. Confirm both use your portal, the short link fetches from your paste API, and an imported returned link restores the review annotations. For failures, check Troubleshooting, the browser network panel, the static host’s single-page application fallback, and the exact origin in the paste-service CORS setting.

What this deployment does not provide

The share portal and paste service do not provide a persistent Plannotator review server, account system, built-in authentication, certificate management, live collaborative editing, or centrally managed document history. They support asynchronous links for a deprecated OSS workflow. For new team sharing, durable documents, access management, and live collaboration, sign up for Workspaces. Last verified on August 10, 2026, against Plannotator product commit f8951cd and release v0.26.7. Maintained by the Plannotator project.
Last modified on August 13, 2026