How to self-host SimplePDF Copilot

Profile picture of Benjamin André-Micolon

SimplePDF Copilot is a MIT-licensed reference implementation for adding an AI chat sidebar to the SimplePDF editor. You can fork the Copilot app, deploy it on your own infrastructure, plug in your own AI provider, and route completed documents to your own storage.

The SimplePDF editor itself remains a hosted iframe. Self-hosting Copilot means you own the chat app, AI routing, prompts, tools, and storage flow around the editor.

This guide covers the path from localhost to production.

If you are using Claude Code, Codex, or another agentic coding tool, point it at the fork-and-go skill. The skill walks the agent through the fork, configuration, and deployment flow one question at a time.

What you self-host

  • Copilot chat app. Runs on your infrastructure. You control it.
  • System prompt and tool registry. Live in your Copilot deployment. You control them.
  • AI routing. Server-side, browser BYOK, or local endpoint. You control it.
  • Completed document storage. SimplePDF storage by default, or your storage with BYOS. You control it when BYOS is enabled.
  • SimplePDF editor iframe. Stays hosted by SimplePDF.

Prerequisites

  • A SimplePDF Pro plan or higher. Running Copilot on your own domain requires white-labeling, programmatic editor control, and an allowed origin in your SimplePDF dashboard. Without those capabilities, the editor only loads on the hosted demo origin or http://localhost:3001.
  • An AI provider key, a BYOK flow, or a local OpenAI-compatible endpoint. Anthropic, OpenAI, DeepSeek, Google Gemini, and Mistral are wired in out of the box.
  • A Node 24 runtime. The current Copilot deployment template uses Node 24 and the app runs unmodified on DigitalOcean App Platform, Cloudflare Containers, Vercel, Render, fly.io, Railway, or self-hosted Docker.

Step 1: Run the demo locally

Clone the repository and run the demo against the shared SimplePDF demo workspace. No SimplePDF account is required for this step.

git clone https://github.com/SimplePDF/simplepdf-embed.git
cd simplepdf-embed/copilot
npm install
cp .env.example .env
printf "\nVITE_SIMPLEPDF_COMPANY_IDENTIFIER=spdf-copilot\n" >> .env
npm run dev

The dev server runs on http://localhost:3001. Open the chat sidebar, paste a provider key, or point at a local OpenAI-compatible endpoint such as Ollama or LM Studio.

The demo workspace whitelists exactly one local origin: http://localhost:3001. Any other port or host will be refused by the iframe. To run on your own domain, continue to Step 2.

Step 2: Set up your SimplePDF account

Subscribe to Pro or higher. From the SimplePDF dashboard:

  1. Copy your companyIdentifier. This is the value you will put in VITE_SIMPLEPDF_COMPANY_IDENTIFIER.
  2. Whitelist your serving origin, for example https://app.example.com. The iframe refuses to load on origins that are not whitelisted.
  3. Optionally customize your branding to remove SimplePDF chrome from the editor.

Step 3: Deploy to your host

The fastest path is the one-click DigitalOcean deploy button in the SimplePDF Copilot README. DigitalOcean builds the copilot/ folder with Node 24 and prompts for environment variables.

  • VITE_SIMPLEPDF_COMPANY_IDENTIFIER (required): your SimplePDF company identifier.
  • SHARED_API_KEYS (optional): lets you share a demo without asking each visitor to paste a provider key.
  • REDIS_URL (optional): persists rate-limit counters across containers.
  • IP_HASH_SALT (required when REDIS_URL is set): salts persisted IP hashes.

For other deploy targets, including Cloudflare Containers, Vercel, Render, fly.io, Railway, and self-hosted Docker, follow the other deploy targets section of the README.

Once deployed, add the deployed origin, for example https://copilot.example.com, to your SimplePDF dashboard whitelist before opening the app.

Step 4: Wire up your AI provider

Server-side streaming lives in src/routes/api/chat.ts. Provider selection lives in src/server/language_model.ts. Use this path when your application owns the provider key, rate limits, logs, and tenant configuration.

For user-provided keys, the browser-direct BYOK path in src/lib/byok/ calls the provider from the browser and bypasses your server. This is also the right shape for local OpenAI-compatible endpoints such as Ollama or LM Studio.

Three routes, three trust boundaries:

  • Server-side provider key. Your app owns the provider account and tenant policy. AI traffic flows through your server to the AI provider.
  • Browser BYOK. Users bring their own provider key. AI traffic flows from the browser directly to the selected provider, bypassing your server.
  • Local OpenAI-compatible endpoint. AI traffic stays on the user's device or network. The browser talks to the local endpoint; nothing goes to a third-party AI provider.

Step 5: Route submissions to your own storage

By default, completed documents land in SimplePDF storage. With Bring Your Own Storage on Pro and above, completed documents upload directly from the browser to your configured storage using pre-signed URLs.

This changes the completed-document storage path. It does not, by itself, control what document context is sent to your configured AI provider. Configure the AI route separately in Step 4.

Configure storage:

Step 6: Verify the production setup

Before sharing the app with users, verify the full path end to end:

  1. Open the deployed Copilot URL from the whitelisted origin.
  2. Confirm the SimplePDF editor iframe loads without origin errors.
  3. Send a test prompt and confirm the selected AI route is used.
  4. Fill a field and confirm the value appears in the PDF editor.
  5. Submit or download a test document.
  6. If BYOS is enabled, confirm the completed PDF lands in your storage, not SimplePDF storage.
  7. Review logs for secrets, document text, PHI, PII, or other sensitive data you do not want persisted.

Customize the system prompt and tools

Once Copilot runs end to end on your infrastructure, the next layer of customization is the system prompt and tool registry exposed to the model. Both live under src/server/tools.ts. The chat UI itself is src/components/chat_pane.tsx. Locales are in src/locales/.

For everything else, including forking, configuration, and adapting Copilot to a non-trivial product surface, the fork-and-go skill drives an AI coding assistant through the work one decision at a time.

Troubleshooting

The editor iframe refuses to load

Check that the parent app origin is whitelisted in the SimplePDF dashboard. The local demo workspace only allows http://localhost:3001.

The local demo works but production does not

Confirm VITE_SIMPLEPDF_COMPANY_IDENTIFIER uses your own SimplePDF company identifier and that your production domain is in the allowed origins list.

Users are asked to paste an AI key

That is expected for BYOK mode. To share a preconfigured demo, configure SHARED_API_KEYS and use the ?share=<id> URL flow.

Rate limits reset on each deploy

In-memory rate limits reset when the app restarts. Use REDIS_URL and IP_HASH_SALT if counters need to persist across containers or restarts.

Completed PDFs do not land in your storage

Confirm Bring Your Own Storage is configured in SimplePDF and test with a small PDF before using production forms.

That's it! Your Copilot app now runs on your infrastructure, uses your configured AI route, and can send completed documents to your storage when BYOS is enabled.

If you have any questions, feel free to reach out to support@simplepdf.com

You may also be interested in