Create and edit PDFs: text, Markdown, tables, metadata and pages, with Japanese font embedding.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
One-click editor setup isnβt available for this listing yet β we donβt have a confirmed install command, and weβd rather show nothing than point your editor at the wrong package or host. Follow the projectβs own setup instructions, linked above.
MCP server that creates PDFs from text, Markdown, or tabular data and edits existing ones (metadata and page operations). Built on normativepdf β a clause-driven PDF library in which every behaviour is tied to an ISO 32000 clause β with CJK font embedding via harfbuzz subsetting.
Part of the PDF family alongside pdf-reader-mcp (structure analysis) and pdf-verify-mcp (authenticity verification). Where pdf-reader-mcp tells you what is in a PDF and pdf-verify-mcp tells you whether it is genuine, pdf-writer-mcp is the one that writes it.
[!IMPORTANT] All file paths must be absolute (since v0.7.0). Relative paths and paths containing
..are rejected β a relative path would resolve against the MCP host's working directory, which is not the directory you think it is. This applies toinputPath,inputPaths,outputPath,outputDir,fontPathandattachmentPath. Input PDFs larger than 100 MB are also rejected.
| Tool | Purpose |
|---|---|
create_text_pdf | Plain text β honours \n, blank lines separate paragraphs, long lines wrap |
create_markdown_pdf | Markdown β headings, paragraphs, bullet/ordered lists, code blocks, quotes, rules, tables |
create_table_pdf | Ruled tables β automatic column widths, cell wrapping, headers repeated across page breaks |
Shared options: outputPath, returnBase64, fontPath, fontSize, pageSize (A4/A3/A5/LETTER/LEGAL), margin, title, author, onMissingGlyph, tagged, lang, pdfVersion.
Pass pdfVersion: "2.0" to write an ISO 32000-2 file. The default stays "1.7", and its bytes are unchanged.
The version is not only a header. ISO 32000-2 attaches two obligations to it, and both are met:
/ID becomes Required (Table 15). Both elements are equal on a first write (R-14.4-6), and the value stays deterministic under SOURCE_DATE_EPOCH.CreationDate and ModDate (Β§14.3.3); the title, author and producer move to the XMP metadata stream, where PDF 2.0 says document metadata belongs.tagged: true cannot be combined with it. The only accessibility declaration this server writes is PDF/UA-1 (ISO 14289-1), which is built on PDF 1.7 β putting it in a 2.0 file would be a claim nothing could measure. PDF/UA-2 output is not implemented, so the combination is refused rather than silently produced.
Pass tagged: true to produce an accessible, tagged PDF conforming to PDF/UA-1 (ISO 14289). Output is verified compliant by veraPDF (--flavour ua1, 106/106 rules).
Markdown maps onto the structure tree: headings β H1βH6, lists β L/LI/LBody, tables β Table/TR/TH/TD (headers get /Scope), quotes β BlockQuote, code β Code. Rules, borders and code backgrounds become artifacts. Heading levels are normalised so they start at H1 and never skip β a Markdown # β ### jump becomes H1 β H2 in the structure, while visual sizes stay as authored.
PDF/UA mandates a document title, so tagged: true requires title. lang (BCP 47) is inferred from the text when omitted and reported via warnings β pass it explicitly when you know it, since a wrong /Lang makes screen readers mispronounce the text.
[!NOTE] Tagging is opt-in β default output is unchanged.
Machine validation (veraPDF) only sees whether things exist. It cannot judge whether reading order or alt text are appropriate β human review still matters.
| Tool | Purpose |
|---|---|
merge_pdfs | Concatenate 2β50 PDFs in order; metadata inherited from the first file |
split_pdf | One output file per page range |
extract_pages | Extract pages in the requested order (doubles as reordering) |
delete_pages | Remove pages (deleting every page is rejected) |
reorder_pages | Reorder by an explicit permutation of all pages |
rotate_pages | Rotate clockwise (90/180/270), accumulating over existing rotation. Edits in place, so the warning below does not apply |
[!WARNING] The five tools other than
rotate_pagesrebuild the document from its pages.
- Carried over: attachments (
/Names /EmbeddedFiles,/AF),/Lang,/ViewerPreferences,/OutputIntents- Not carried over: the tagged structure tree, XMP, and anything tied to page numbers or page references (bookmarks, page labels, named destinations)
- Whatever is lost is reported in
warningsβ nothing disappears silently
Page specs use "1,3-5,8-" (1-based; -3 means up to page 3, 8- means page 8 to the end). Order is preserved and duplicates are removed.
| Tool | Purpose |
|---|---|
set_metadata | Update Info dictionary fields (title / author / subject / keywords / creator), preserving the rest. On documents carrying XMP, dc:title etc. are kept in sync (PDF/UA and PDF/A declarations preserved) |
add_bookmarks | Set the outline (bookmarks); nestable via children, replaces any existing outline |
add_annotation | Add a sticky note (text), highlight, or square annotation. On tagged PDFs the annotation is nested in an Annot element and stays PDF/UA conformant β pass alt to describe it |
attach_file | Embed a file (/Names /EmbeddedFiles + catalog /AF + /AFRelationship) β the PDF/A-3 shape |
stamp_page_numbers | Stamp page numbers ({n} / {total}, six positions, pages, startAt). Becomes an artifact on tagged PDFs, so conformance holds |
fill_form | Fill AcroForm fields. Japanese values via an embedded font; can flatten in the same pass |
flatten_form | Flatten a form into static content. Refuses tagged PDFs by default (breaks PDF/UA) |
tag_form_fields | Repair the form inside a tagged PDF for PDF/UA-1 (nest widgets in Form, set /Tabs S, add /TU alternate names; pass labels for human-readable names). Idempotent |
ensure_tagged | Put an existing PDF into the PDF/UA-1 container β Scaffolding an untagged PDF |
ensure_pdfa | Put an existing PDF into the PDF/A-3b / PDF/A-4 / PDF/A-4f container (flavour) β The archival container |
add_watermark | Overlay a diagonal watermark ("η€Ύε€η§" / "DRAFT"). Behind the body content by default; artifact on tagged PDFs |
Shared options: outputPath, returnBase64, allowBreakingSignatures.
[!IMPORTANT] Editing signed PDFs: an ordinary save rewrites the whole file, so editing normally invalidates existing signatures. PDFs containing
/ByteRangeare rejected by default.
preserveSignatures: trueβ appends an ISO 32000 incremental update that keeps every signature valid (the original bytes are untouched). Supported by every editing tool that adds to a document:add_annotation,set_metadata,add_bookmarks,tag_form_fields,ensure_tagged,attach_file,stamp_page_numbers,add_watermark(on tagged PDFs the structure-tree changes ride the same increment)allowBreakingSignatures: trueβ proceed destructively, invalidating signatures- Certified documents (DocMDP) are refused when the change type is not permitted by the certification level (Β§12.8.2.2)
Measured: stacked increments on a really-signed PDF keep pdf-verify-mcp reporting VALID, and incremental structure updates on tagged PDFs stay veraPDF COMPLIANT (106/106).
ensure_tagged)ensure_tagged puts an existing PDF into the PDF/UA-1 container. On tagged input the structure tree is left untouched and only missing document-level requirements are repaired (MarkInfo, /Lang, DisplayDocTitle, XMP). On a document that never had a structure tree, a minimal scaffold is created β each page's content wrapped in a single P element, which makes the text reachable by assistive technology and passes veraPDF (measured: 106/106).
[!WARNING] This is a scaffold, not accessibility. A machine cannot infer meaning, so headings, lists, tables, reading order and figure alt text are not produced. The tool says so in its
warnings. (Wrapping the content inArtifactwould also pass veraPDF while hiding the body from screen readers β conformance theatre, deliberately not implemented.) Where you control the source,create_*withtagged: trueproduces real structure;ensure_taggedis for documents you were handed.
ensure_pdfa)ensure_pdfa is the archival (PDF/A-3b) counterpart of ensure_tagged. It adds only the document-level requirements:
/ID (ISO 32000-1 Β§14.4)GTS_PDFA1; ICC profile generated and embedded)pdfaid declaration (the creation date is inherited from Info /CreationDate)[!WARNING] Content streams, fonts and the structure tree are untouched β so this does not make a PDF conform. Write the declaration, then measure it: verify with pdf-verify-mcp's
validate_conformance(flavour: "pdfa-3b"). Measured on the electronic-bookkeeping sample: veraPDF 146/146 COMPLIANT, PDF/UA-1 still 106/106, attachment preserved.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/pdf-writer-pdf-agent-stack)<a href="https://allmcps.com/mcp/pdf-writer-pdf-agent-stack"><img src="https://allmcps.com/api/badge/pdf-writer-pdf-agent-stack?style=directory" alt="PDF Writer (PDF Agent Stack) on AllMCPs" /></a>