edit-pdf
Can be used as an OpenAI-compatible local model endpoint via the Base URL setting for the built-in agent.
Supports OpenAI API keys and OpenAI-compatible endpoints to power the built-in chat agent for editing PDFs.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@edit-pdfChange the total on invoice.pdf to $0.00 and add a DRAFT watermark"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
edit·pdf
Edit PDFs with AI agents. Two ways to drive it:
Built-in agent — chat in the app, bring your own API key.
External agent over MCP — connect Claude Code / Codex / Cursor, and it edits the same live document you have open in the browser.
Edits appear in the open tab within ~1.5 s, from either side. Every change is an undoable batch.
Why this exists
Most "AI PDF" tools paste a new PDF over the old one, so the result is a picture: the text you "replaced" is still there underneath, still copyable, still searchable. That is dangerous for anything you redact.
This project treats editing as a replayable list of operations applied by a real PDF engine, and redaction genuinely deletes glyphs from the content stream.
Related MCP server: fablecut-webmcp
Quick start
bun install
bun dev # http://localhost:3000Drop a PDF on the landing page. That creates a session with a short id (/s/abc12345).
To use the built-in agent, open settings in the agent panel and add an API key. It is kept in your browser's localStorage and sent to your local server per request — never written to disk.
Alternatively, set a server-side key:
OPENAI_API_KEY=sk-... bun dev
# or
ANTHROPIC_API_KEY=sk-ant-... bun devAny OpenAI-compatible endpoint works (OpenRouter, Ollama, LM Studio, vLLM) via the Base URL field.
Connecting an external agent (MCP)
The app exposes an MCP server that talks to the running dev server, so an external agent operates on the session you already have open.
bun run mcpRegister it with your client. For Claude Code:
claude mcp add edit-pdf -- bun run /absolute/path/to/edit-pdf/mcp/server.tsOr in a JSON config:
{
"mcpServers": {
"edit-pdf": {
"command": "bun",
"args": ["run", "/absolute/path/to/edit-pdf/mcp/server.ts"],
"env": { "EDIT_PDF_URL": "http://localhost:3000" }
}
}
}Then, in a conversation with the agent:
List my edit-pdf sessions, open the one called
invoice.pdf, and change the total to $0.00.
The agent calls list_sessions → use_session → read_document → find_text → edit_pdf, and the change shows up in your open browser tab.
MCP tools
Tool | Purpose |
| Sessions currently open in the app |
| Pin a default session for the conversation |
| Page count, sizes, per-page text preview |
| Locate text, returns exact boxes |
| Apply operations |
| Render a page to PNG to verify visually |
| Revert the last batch |
| URL to download the current PDF |
Coordinate systems (the part that bites)
Two spaces exist, and mixing them is the most common source of misplaced edits:
Space | Origin | Y direction | Used by |
PDF user space | bottom-left | up |
|
Edit space | top-left | down |
|
find_text returns both: x/y (PDF space) and a ready-to-use topLeft box. Pass topLeft straight into edit_pdf and you cannot get it wrong.
Units are PDF points (1/72 inch).
Operations
All coordinates are in edit space (top-left origin, y down).
Op | Notes |
|
|
| Uses |
| Removes text in the box from the content stream, then paints over it |
| Semi-transparent rectangle |
| Vector primitives |
| Base64 PNG/JPEG data URL |
| Diagonal text, all pages or a subset |
| Structural |
|
|
| Title, author, subject, keywords |
Example:
{
"operations": [
{ "type": "replace_text", "page": 1, "find": "Total: $1,299.00", "text": "Total: $0.00" },
{ "type": "watermark", "text": "DRAFT", "opacity": 0.2 },
{ "type": "page_numbers", "position": "bottom-center" }
]
}HTTP API
Everything the UI does goes through this API, so you can script it directly.
# Upload
curl -X POST localhost:3000/api/sessions -F file=@invoice.pdf
# -> {"session":{"id":"abc12345", ...}}
# Inspect
curl localhost:3000/api/sessions/abc12345/read
curl "localhost:3000/api/sessions/abc12345/find?q=Total"
# Edit
curl -X POST localhost:3000/api/sessions/abc12345/ops \
-H 'Content-Type: application/json' \
-d '{"operations":[{"type":"page_numbers"}]}'
# Render a page
curl -o page1.png "localhost:3000/api/sessions/abc12345/page?page=1&scale=2"
# Undo / download
curl -X DELETE localhost:3000/api/sessions/abc12345/ops
curl -o out.pdf "localhost:3000/api/sessions/abc12345?download=1"Pass baseVersion with an edit to get a 409 if the document changed underneath you, instead of silently clobbering a concurrent edit.
How it works
app/ Next.js App Router UI + API routes
components/ Workspace, PageViewer, AgentPanel, SettingsDialog
lib/pdf/engine.ts Op -> pdf-lib mutations (the core)
lib/pdf/content-stream.ts PDF content-stream tokenizer + text stripping
lib/pdf/redact.ts Walks page streams and Form XObjects, rewrites them
lib/pdf/render.ts pdf.js rendering + positioned text extraction
lib/agent/tools.ts Tool schemas + executeTool (shared by app and MCP)
lib/server/store.ts Sessions, history, render cache
mcp/server.ts MCP bridge to the running serverDeterministic edits. A session stores its original upload plus the ordered list of op batches. Undo replays the remaining batches from the original — so undo is exact, not "apply the inverse and hope".
True redaction. content-stream.ts tokenizes the page's content stream, tracks the graphics-state matrix (q/Q/cm) and text matrices (Tm/Td/T*), and drops the Tj/TJ/'/" operators whose origin lands inside the box. Text inside Do-referenced Form XObjects is scrubbed too. The result is re-serialised uncompressed.
One tool surface. The in-app agent and the MCP server both route through executeTool, so they cannot drift apart in capability or behaviour.
Limits
Standard fonts only. Non-Latin text (Arabic, CJK, emoji) is coerced to
?because WinAnsi encoding cannot represent it. Embedding a Unicode font is the fix; it is not implemented.RTL scripts are not shaped or reordered.
Redaction misses rasterised text. If a page is a scanned image, there are no glyphs to strip — only the visible box is applied, and the tool says so.
Covered text in complex layouts. Stripping is by text-run origin. A run that starts outside the box but extends into it is left intact.
Sessions are local. Stored in
.data/sessions/, no auth. This is a local-first tool; do not expose it to the internet as-is.40 MB upload cap.
Development
bun dev # dev server
bun run build # production build
bun run typecheck
bun run mcp # MCP server (needs a running dev server)node is not required — everything runs on Bun.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Create and improve live, shared interactive documents with your agent.
Generate and read PDFs for AI agents: a generate_pdf and a read_pdf tool, priced per document.
Create, review and edit Word, PowerPoint, Excel and PDF documents from any AI agent.
Read, edit and improve shared documents and knowledge with people and agents.
Related MCP Servers
- AlicenseBqualityFmaintenanceEnables AI agents to directly control your real Chrome browser with full context including login sessions, cookies, and open tabs. It provides tools for page scanning, JavaScript execution, CDP control, screenshots, and physical mouse/keyboard input for authentic browser automation.20245MIT
- AlicenseNot gradedqualityBmaintenanceEnables an AI agent to directly drive a live browser video editor session, reading selections and playhead, editing the timeline, and sharing the same undo stack as the human user.559 npm1MIT
- AlicenseAqualityCmaintenanceEnables AI clients to control the user's already-open, logged-in browser pages in real time over a local WebSocket channel, without Playwright, Puppeteer, Selenium, or any browser driver. Exposes tools for navigation, semantic page snapshots, clicking, form filling, JavaScript evaluation, screenshots, network monitoring, cookie handling, and tab management via the CDP.20MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents like Codex and Claude Code to control shared Chrome tabs, offering site-specific tools such as browsing and posting on Reddit. Agents can navigate the visible page and execute actions directly in the same tab.MIT