Skip to main content
Glama
Nizoka

pdfnative-mcp

Extract plain text from PDF

extract_text
Read-onlyIdempotent

Extracts plain text from PDFs, decoding font mappings to return page-level results and combined full text. Supports encrypted PDFs when a password is provided.

Instructions

Plain-text extraction: decodes Tj/TJ operands through each font's /ToUnicode CMap, /Encoding /Differences or base encoding and returns pages[] + fullText (positioned runs with includeRuns:true; pages selects 0-based pages). extractable is false only when a page decoded ENTIRELY to U+FFFD (a font with no usable mapping — expected for some subset fonts, not an error; extractableReason explains). Encrypted sources: pass password (PASSWORD_REQUIRED / PASSWORD_INVALID otherwise). Token-frugal: verbosity:'summary', fields:[…].

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pagesNoOptional 0-based page indices to extract. When omitted, every page is extracted.
fieldsNoOptional dot-path projection applied to the structured result (e.g. ['fullText'] or ['extractable']). Composes after verbosity. Unknown paths are omitted.
passwordNoPassword (user or owner) of an encrypted source. Never logged or echoed.
pdfBase64YesBase64-encoded PDF bytes.
verbosityNoResponse verbosity. 'full' (default) returns the per-page pages[] array and fullText; 'summary' returns a token-frugal { pageCount, extractedPageCount, extractable, charCount } and drops the text payloads.full
includeRunsNoWhen true, each page also carries `runs[]` — positioned text-showing operations `{ text, x, y, fontSize, fontName }` in device space (content-stream order). Useful for layout-aware extraction; larger responses.
maxTextLengthNoHard cap on total extracted characters across all pages (memory bound for adversarial input). Default 16000000. Exceeding it fails with OUTPUT_TOO_LARGE.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
pagesNo
fullTextNo
charCountNosummary only: length of fullText.
pageCountNo
extractableNoFalse when one or more requested pages produced text that is entirely U+FFFD replacement characters — a font with no usable /ToUnicode CMap or base encoding. Blank pages are still considered extractable.
extractableReasonNoPresent when extractable is false: why no text could be decoded.
extractedPageCountNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • changedInput schema / properties / password / description
      Previous value: -"Password to open an encrypted source PDF (user or owner — both are tried). Omit for unencrypted documents. Never logged or echoed back."New value: +"Password (user or owner) of an encrypted source. Never logged or echoed."
    • addedOutput schema / description
      Added value: +"Structured text-extraction result. Every property is optional because the result can be projected: verbosity:'summary' returns only the scalar summary fields, fields:[...] keeps a dot-path subset. Defaults return the full shape."
    • addedOutput schema / properties / charCount
      Added value: +{
      +  "description": "summary only: length of fullText.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedOutput schema / properties / extractableReason / description
      Previous value: -"Human-readable explanation when extractable=false. Absent when extractable=true."New value: +"Present when extractable is false: why no text could be decoded."
    • removedOutput schema / properties / pages / items / properties / runs / items / required
      Removed value: -[
      -  "text",
      -  "x",
      -  "y",
      -  "fontSize",
      -  "fontName"
      -]
    • removedOutput schema / properties / pages / items / required
      Removed value: -[
      -  "index",
      -  "text"
      -]
    • removedOutput schema / required
      Removed value: -[
      -  "pageCount",
      -  "extractedPageCount",
      -  "extractable",
      -  "pages",
      -  "fullText"
      -]
  2. Changed5 schema fields changedv1.6.0
    • addedInput schema / properties / includeRuns
      Added value: +{
      +  "default": false,
      +  "description": "When true, each page also carries `runs[]` — positioned text-showing operations `{ text, x, y, fontSize, fontName }` in device space (content-stream order). Useful for layout-aware extraction; larger responses.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / maxTextLength
      Added value: +{
      +  "description": "Hard cap on total extracted characters across all pages (memory bound for adversarial input). Default 16000000. Exceeding it fails with OUTPUT_TOO_LARGE.",
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / password
      Added value: +{
      +  "description": "Password to open an encrypted source PDF (user or owner — both are tried). Omit for unencrypted documents. Never logged or echoed back.",
      +  "maxLength": 4096,
      +  "minLength": 1,
      +  "type": "string"
      +}
    • changedOutput schema / properties / extractable / description
      Previous value: -"False when one or more requested pages had a non-empty content stream but yielded no extractable text (likely subset fonts without /ToUnicode)."New value: +"False when one or more requested pages produced text that is entirely U+FFFD replacement characters — a font with no usable /ToUnicode CMap or base encoding. Blank pages are still considered extractable."
    • addedOutput schema / properties / pages / items / properties / runs
      Added value: +{
      +  "description": "Positioned text runs (present only when includeRuns is true).",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "fontName": {
      +        "type": "string"
      +      },
      +      "fontSize": {
      +        "type": "number"
      +      },
      +      "text": {
      +        "type": "string"
      +      },
      +      "x": {
      +        "type": "number"
      +      },
      +      "y": {
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "text",
      +      "x",
      +      "y",
      +      "fontSize",
      +      "fontName"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  3. Changed2 schema fields changedv1.2.0
    • addedInput schema / properties / fields
      Added value: +{
      +  "description": "Optional dot-path projection applied to the structured result (e.g. ['fullText'] or ['extractable']). Composes after verbosity. Unknown paths are omitted.",
      +  "items": {
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "maxItems": 16,
      +  "type": "array"
      +}
    • addedInput schema / properties / verbosity
      Added value: +{
      +  "default": "full",
      +  "description": "Response verbosity. 'full' (default) returns the per-page pages[] array and fullText; 'summary' returns a token-frugal { pageCount, extractedPageCount, extractable, charCount } and drops the text payloads.",
      +  "enum": [
      +    "summary",
      +    "full"
      +  ],
      +  "type": "string"
      +}
  4. First observedv1.1.0

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only and idempotent, but the description adds crucial behavioral detail: the meaning of `extractable=false` as a legitimate condition explained by `extractableReason` rather than an error, the PASSWORD_REQUIRED/PASSWORD_INVALID error states, and the security note that passwords are never logged. It also explains the verbosity and runs mechanics, which are not expressed by annotations alone. No contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loaded with the core purpose. Every sentence carries meaningful operational or error-handling information, but the heavy use of parentheticals and one very long sentence make it slightly harder to parse. In comparison to a two-sentence standard, it is longer but justified by the complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, an output schema exists and the description covers supported input behaviors, edge cases (font mapping failure), encryption, security, and response verbosity tuning. The only minor gap is not enumerating all error codes (like OUTPUT_TOO_LARGE), but that appears in the schema parameter docs. Overall, an agent can select and invoke the tool correctly based on the description plus schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers all 7 parameters (100%), but the description enriches key ones: it explains that `pages` uses zero-based indices, that `fields` is a dot-path projection, that `verbosity:'summary'` produces a token-frugal response, and that `includeRuns` returns positioned runs. These are semantic overlaps that add value beyond the schema without repeating it fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first line 'Plain-text extraction' plus the technical mechanism ('decodes Tj/TJ operands through each font's /ToUnicode CMap...') states the exact operation and resource. It is clearly distinguished from siblings like extract_attachments and inspect_pdf, which perform different extraction/inspection tasks. The specific mention of pages, fullText, and includeRuns output confirms it is a text extraction tool with unique purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear operational context: it explains when to use `password` for encrypted sources, when `extractable` is false, and how `includeRuns` gives layout-aware extraction. It implies this is the tool for extracting text from PDFs, but it does not explicitly state 'use this instead of X' or list exclusions. The guidance is concrete and contextual but lacks direct sibling differentiation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.