pdfedit-mcp
Edit text inside existing PDFs: replace, delete, redact, insert, fill forms; original fonts kept.
¿Debería usar esto?
Calidad y seguridad
Basado en el análisis automatizado de las definiciones de herramientas y el cumplimiento del protocolo.
Costo de contexto
Este es el número aproximado de tokens que se consumen cada vez que las herramientas del servidor se cargan en el contexto de un modelo. Los recuentos más altos reducen la atención disponible para otras tareas.
Instalar
Instalación con un clic
Agrega esto a tu archivo `claude_desktop_config.json`:
{
"mcpServers": {
"pdfedit-mcp": {
"command": "npx",
"args": [
"@niubai/pdfedit-mcp"
]
}
}
}Paquetes ejecutables
0.1.4stdioPuntos de conexión remotos
https://pdfedit-mcp-remote.niubai-pdfedit-remote-worker.workers.dev/mcpstreamable-httpQué puede hacer
Inventario de herramientas
Herramientas (5)
🟡pdf_edit(file, edits, options, password, output_path)
Edit the text of an existing PDF in place: replace, delete, redact, insert, or fill form fields, keeping the original layout, fonts and everything you did not point at. `edits[]` is taken exactly as the API takes it (`op`, `scope`, `match`, `fit`), and the result carries up to 3 before/after previews of the pages that changed. To change text on one page only, set `scope.pages`; to pick one of several identical matches, use `scope.after` with nearby text or `scope.occurrence`. Use `op: 'redact'` when the text must be unrecoverable.
Esquema de entrada
{
"type": "object",
"properties": {
"file": {
"type": "string",
"minLength": 1,
"description": "The PDF: an absolute (or ~) local path, which this server uploads for you, an https:// URL the API fetches, or an `f_…` file id from an earlier call."
},
"edits": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"at": {
"anyOf": [
{
"type": "object",
"properties": {
"after": {
"description": "Anchor text to insert after; the first occurrence on the page wins, and the style is inherited from it.",
"type": [
"string",
"null"
]
},
"page": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
},
"placement": {
"type": "string",
"enum": [
"inline",
"below"
],
"description": "With `after`: 'inline' writes one space past the anchor's right edge on its own baseline; 'below' writes at the anchor line's left edge, one leading down. (default: \"inline\")"
},
"units": {
"type": "string",
"enum": [
"pt",
"fraction"
],
"description": "(default: \"pt\")"
},
"x": {
"description": "Baseline origin x. Points from the page's left edge, or a fraction of the page width when units='fraction'.",
"type": [
"number",
"null"
]
},
"y": {
"description": "Baseline origin y: where the first line sits, measured from the page's TOP edge (PDF viewer convention, as every bbox and span origin in this API). A fraction of the page height when units='fraction'.",
"type": [
"number",
"null"
]
}
},
"required": [
"page"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fields": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
{
"type": "null"
}
]
},
"find": {
"type": [
"string",
"null"
]
},
"fit": {
"type": "string",
"enum": [
"auto",
"reflow",
"strict"
],
"description": "(default: \"auto\")"
},
"flatten": {
"type": "boolean",
"description": "(default: false)"
},
"match": {
"type": "object",
"properties": {
"across_lines": {
"type": "boolean",
"description": "(default: false)"
},
"mode": {
"type": "string",
"enum": [
"exact",
"icase",
"word",
"regex"
],
"description": "(default: \"exact\")"
},
"normalize": {
"type": "boolean",
"description": "(default: true)"
}
},
"additionalProperties": false
},
"op": {
"type": "string",
"enum": [
"replace",
"delete",
"redact",
"insert",
"form"
],
"description": "(default: \"replace\")"
},
"replace": {
"type": [
"string",
"null"
]
},
"scope": {
"type": "object",
"properties": {
"after": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"before": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"layers": {
"type": "array",
"items": {
"type": "string",
"enum": [
"content",
"forms",
"annotations"
]
},
"description": "Page layers to match in. All three are implemented; a match on the 'forms' layer is applied to the field's value, not to the page."
},
"occurrence": {
"anyOf": [
{
"type": "string",
"enum": [
"all",
"first",
"last"
]
},
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
],
"description": "(default: \"all\")"
},
"page_labels": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
]
},
"pages": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
}
],
"description": "(default: \"all\")"
},
"region": {
"anyOf": [
{
"type": "object",
"properties": {
"units": {
"type": "string",
"enum": [
"fraction",
"pt"
],
"description": "(default: \"fraction\")"
},
"x0": {
"type": "number"
},
"x1": {
"type": "number"
},
"y0": {
"type": "number"
},
"y1": {
"type": "number"
}
},
"required": [
"x0",
"x1",
"y0",
"y1"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"span_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"style": {
"anyOf": [
{
"type": "object",
"properties": {
"color": {
"anyOf": [
{
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
{
"type": "null"
}
]
},
"font": {
"type": [
"string",
"null"
]
},
"size": {
"anyOf": [
{
"type": "number",
"minimum": 1,
"maximum": 200
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
{
"type": "null"
}
]
},
"text": {
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
},
"description": "The edits to apply, in order, exactly as `POST /v1/edit` takes them."
},
"options": {
"type": "object",
"properties": {
"async": {
"type": "boolean",
"description": "(default: false)"
},
"atomic": {
"type": "boolean",
"description": "(default: true)"
},
"break_signature": {
"type": "boolean",
"description": "(default: false)"
},
"collateral_threshold": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991,
"description": "(default: 8)"
},
"dry_run": {
"type": "boolean",
"description": "(default: false)"
},
"font": {
"type": "object",
"properties": {
"policy": {
"type": "string",
"enum": [
"auto",
"metric_only",
"exact_only"
],
"description": "(default: \"auto\")"
}
},
"additionalProperties": false
},
"ocr": {
"type": "string",
"enum": [
"auto",
"on",
"off"
],
"description": "(default: \"auto\")"
},
"ocr_lang": {
"type": "array",
"items": {
"type": "string",
"enum": [
"zh",
"en"
]
}
},
"preview": {
"type": "string",
"enum": [
"changes",
"pages",
"none"
],
"description": "(default: \"changes\")"
},
"redact_metadata": {
"type": "boolean",
"description": "(default: false)"
},
"redact_style": {
"type": "string",
"enum": [
"box",
"text"
],
"description": "(default: \"box\")"
},
"redact_verify_ocr": {
"type": "boolean",
"description": "(default: true)"
},
"retain": {
"type": "boolean",
"description": "(default: true)"
},
"strict": {
"type": "boolean",
"description": "(default: false)"
},
"tidy": {
"type": "boolean",
"description": "(default: true)"
},
"watermark": {
"type": "string",
"enum": [
"auto",
"on",
"off"
],
"description": "(default: \"auto\")"
},
"webhook_url": {
"anyOf": [
{
"type": "string",
"minLength": 1,
"maxLength": 2083,
"format": "uri"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"password": {
"description": "The document open password, when it has one.",
"type": "string"
},
"output_path": {
"description": "Where to write the edited PDF (stdio mode only). Default: `<name>.edited.pdf` next to the input.",
"type": "string"
}
},
"required": [
"file",
"edits"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟡pdf_batch(file, edits, records, records_url, options, ...)
Apply the same edits to one template PDF once per record, producing one output document per record — a mail merge over an existing PDF. Returns a `job_id`: call `pdf_job` with it for the per-record results. To change text on one page only, set `scope.pages`; to pick one of several identical matches, use `scope.after` with nearby text or `scope.occurrence`. Use `op: 'redact'` when the text must be unrecoverable.
Esquema de entrada
{
"type": "object",
"properties": {
"file": {
"type": "string",
"minLength": 1,
"description": "The PDF: an absolute (or ~) local path, which this server uploads for you, an https:// URL the API fetches, or an `f_…` file id from an earlier call. Used as the template for every record."
},
"edits": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"at": {
"anyOf": [
{
"type": "object",
"properties": {
"after": {
"description": "Anchor text to insert after; the first occurrence on the page wins, and the style is inherited from it.",
"type": [
"string",
"null"
]
},
"page": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
},
"placement": {
"type": "string",
"enum": [
"inline",
"below"
],
"description": "With `after`: 'inline' writes one space past the anchor's right edge on its own baseline; 'below' writes at the anchor line's left edge, one leading down. (default: \"inline\")"
},
"units": {
"type": "string",
"enum": [
"pt",
"fraction"
],
"description": "(default: \"pt\")"
},
"x": {
"description": "Baseline origin x. Points from the page's left edge, or a fraction of the page width when units='fraction'.",
"type": [
"number",
"null"
]
},
"y": {
"description": "Baseline origin y: where the first line sits, measured from the page's TOP edge (PDF viewer convention, as every bbox and span origin in this API). A fraction of the page height when units='fraction'.",
"type": [
"number",
"null"
]
}
},
"required": [
"page"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fields": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
{
"type": "null"
}
]
},
"find": {
"type": [
"string",
"null"
]
},
"fit": {
"type": "string",
"enum": [
"auto",
"reflow",
"strict"
],
"description": "(default: \"auto\")"
},
"flatten": {
"type": "boolean",
"description": "(default: false)"
},
"match": {
"type": "object",
"properties": {
"across_lines": {
"type": "boolean",
"description": "(default: false)"
},
"mode": {
"type": "string",
"enum": [
"exact",
"icase",
"word",
"regex"
],
"description": "(default: \"exact\")"
},
"normalize": {
"type": "boolean",
"description": "(default: true)"
}
},
"additionalProperties": false
},
"op": {
"type": "string",
"enum": [
"replace",
"delete",
"redact",
"insert",
"form"
],
"description": "(default: \"replace\")"
},
"replace": {
"type": [
"string",
"null"
]
},
"scope": {
"type": "object",
"properties": {
"after": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"before": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"layers": {
"type": "array",
"items": {
"type": "string",
"enum": [
"content",
"forms",
"annotations"
]
},
"description": "Page layers to match in. All three are implemented; a match on the 'forms' layer is applied to the field's value, not to the page."
},
"occurrence": {
"anyOf": [
{
"type": "string",
"enum": [
"all",
"first",
"last"
]
},
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
],
"description": "(default: \"all\")"
},
"page_labels": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
]
},
"pages": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
}
],
"description": "(default: \"all\")"
},
"region": {
"anyOf": [
{
"type": "object",
"properties": {
"units": {
"type": "string",
"enum": [
"fraction",
"pt"
],
"description": "(default: \"fraction\")"
},
"x0": {
"type": "number"
},
"x1": {
"type": "number"
},
"y0": {
"type": "number"
},
"y1": {
"type": "number"
}
},
"required": [
"x0",
"x1",
"y0",
"y1"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"span_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"style": {
"anyOf": [
{
"type": "object",
"properties": {
"color": {
"anyOf": [
{
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
{
"type": "null"
}
]
},
"font": {
"type": [
"string",
"null"
]
},
"size": {
"anyOf": [
{
"type": "number",
"minimum": 1,
"maximum": 200
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
{
"type": "null"
}
]
},
"text": {
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
},
"description": "The edits applied to each record, with `{field}` placeholders filled from it."
},
"records": {
"description": "One object per output document.",
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
},
"records_url": {
"description": "A CSV or JSONL file of records, instead of `records`.",
"type": "string",
"format": "uri"
},
"options": {
"type": "object",
"properties": {
"async": {
"type": "boolean",
"description": "(default: false)"
},
"atomic": {
"type": "boolean",
"description": "(default: true)"
},
"break_signature": {
"type": "boolean",
"description": "(default: false)"
},
"collateral_threshold": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991,
"description": "(default: 8)"
},
"dry_run": {
"type": "boolean",
"description": "(default: false)"
},
"fail_fast": {
"type": "boolean",
"description": "(default: false)"
},
"filename": {
"type": [
"string",
"null"
]
},
"font": {
"type": "object",
"properties": {
"policy": {
"type": "string",
"enum": [
"auto",
"metric_only",
"exact_only"
],
"description": "(default: \"auto\")"
}
},
"additionalProperties": false
},
"ocr": {
"type": "string",
"enum": [
"auto",
"on",
"off"
],
"description": "(default: \"auto\")"
},
"ocr_lang": {
"type": "array",
"items": {
"type": "string",
"enum": [
"zh",
"en"
]
}
},
"output": {
"type": "string",
"enum": [
"zip",
"files"
],
"description": "(default: \"files\")"
},
"preview": {
"type": "string",
"enum": [
"changes",
"pages",
"none"
],
"description": "(default: \"changes\")"
},
"redact_metadata": {
"type": "boolean",
"description": "(default: false)"
},
"redact_style": {
"type": "string",
"enum": [
"box",
"text"
],
"description": "(default: \"box\")"
},
"redact_verify_ocr": {
"type": "boolean",
"description": "(default: true)"
},
"retain": {
"type": "boolean",
"description": "(default: true)"
},
"strict": {
"type": "boolean",
"description": "(default: false)"
},
"tidy": {
"type": "boolean",
"description": "(default: true)"
},
"watermark": {
"type": "string",
"enum": [
"auto",
"on",
"off"
],
"description": "(default: \"auto\")"
},
"webhook_url": {
"anyOf": [
{
"type": "string",
"minLength": 1,
"maxLength": 2083,
"format": "uri"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"password": {
"type": "string"
}
},
"required": [
"file",
"edits"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟢pdf_find(cursor, layers, limit, match, pages, ...)
Read the text of a PDF: every span with its page, position, font and span id, optionally filtered by `query` (the same four `match` modes an edit uses) and `pages`, over the `content`, `forms` and `annotations` layers. Paginated: pass the returned `next_cursor` back as `cursor` for the next page. Use it before `pdf_edit` to check what a document actually says and to pick the `scope` that selects the match you mean.
Esquema de entrada
{
"type": "object",
"properties": {
"cursor": {
"type": [
"string",
"null"
]
},
"layers": {
"minItems": 1,
"type": "array",
"items": {
"type": "string",
"enum": [
"content",
"forms",
"annotations"
]
}
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 1000,
"description": "(default: 200)"
},
"match": {
"type": "object",
"properties": {
"across_lines": {
"type": "boolean",
"description": "(default: false)"
},
"mode": {
"type": "string",
"enum": [
"exact",
"icase",
"word",
"regex"
],
"description": "(default: \"exact\")"
},
"normalize": {
"type": "boolean",
"description": "(default: true)"
}
},
"additionalProperties": false
},
"pages": {
"anyOf": [
{
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
}
]
},
{
"type": "null"
}
]
},
"query": {
"type": [
"string",
"null"
]
},
"file": {
"type": "string",
"minLength": 1,
"description": "The PDF: an absolute (or ~) local path, which this server uploads for you, an https:// URL the API fetches, or an `f_…` file id from an earlier call."
},
"password": {
"type": "string"
}
},
"required": [
"file"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟢pdf_preview(highlight, page, region, scale, file, ...)
Render one page of a PDF as a PNG image block, optionally cropped to `region` and with rectangles drawn over `highlight`. Use it to see a page before editing it, or to check the result afterwards.
Esquema de entrada
{
"type": "object",
"properties": {
"highlight": {
"anyOf": [
{
"maxItems": 200,
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
}
}
},
{
"type": "null"
}
]
},
"page": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991,
"description": "(default: 1)"
},
"region": {
"anyOf": [
{
"minItems": 4,
"maxItems": 4,
"type": "array",
"items": {
"type": "number"
}
},
{
"type": "null"
}
]
},
"scale": {
"anyOf": [
{
"type": "number",
"const": 1
},
{
"type": "number",
"const": 2
},
{
"type": "number",
"const": 3
}
],
"description": "(default: 2)"
},
"file": {
"type": "string",
"minLength": 1,
"description": "The PDF: an absolute (or ~) local path, which this server uploads for you, an https:// URL the API fetches, or an `f_…` file id from an earlier call."
},
"password": {
"type": "string"
}
},
"required": [
"file"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟢pdf_job(job_id, output_path)
The result of an async edit or a batch, by `job_id`: the same body `pdf_edit` returns once the job is done, plus `progress` while it is still queued or running, and `records` for a batch.
Esquema de entrada
{
"type": "object",
"properties": {
"job_id": {
"type": "string",
"minLength": 1,
"description": "The `job_id` an async edit or a batch returned."
},
"output_path": {
"description": "Where to write the finished document (stdio mode, single-document jobs only).",
"type": "string"
}
},
"required": [
"job_id"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}Comunidad
Evidencia