Skip to main content
Glama

Extract plain text from PDF

extract_text
Read-onlyIdempotent

Extracts plain text from PDFs by decoding font mappings; returns page text and fullText, with options for page selection, passwords, and token-frugal summaries.

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). Tagged content carrying /ActualText (every pdfA document this server writes) returns that SOURCE text, in logical order; untagged right-to-left and Indic runs come back in the order their glyphs were drawn — generate with pdfA when faithful extraction of complex scripts matters. 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 the safety profile (readOnly, idempotent, non-destructive), and the description goes well beyond them: `extractable` is false only on ENTIRE U+FFFD decoding with extractableReason, ActualText/tagged-content returns SOURCE text in logical order, untagged RTL/Indic returns glyph-draw order, encrypted sources yield PASSWORD_REQUIRED/PASSWORD_INVALID, and maxTextLength overflow fails with OUTPUT_TOO_LARGE. This is unusually rich behavioral disclosure.

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 purpose and core extraction semantics are front-loaded and no sentence is pure filler, but the paragraph is dense and heavily backticked, mixing contract-level guarantees (ActualText ordering, error codes) with implementation detail. Slightly over-stuffed for a single description, though nothing is wasted.

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?

An output schema exists, so return shapes need not be re-explained, yet the description still clarifies the semantic meaning of `extractable`/`extractableReason`. With encryption handling, memory-bound behavior, and token-frugal options all covered, an agent has everything needed to call it correctly.

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?

Schema description coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema: the PASSWORD_REQUIRED/PASSWORD_INVALID error outcomes for `password`, the extractableReason semantics tied to extraction, and the interplay of verbosity:'summary' with the returned fields. It adds real inter-parameter behavior rather than restating field docs.

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?

States a specific verb+resource ('Plain-text extraction' returning pages[] + fullText) and implicitly distinguishes itself from siblings like extract_pages, extract_attachments and inspect_pdf by naming text extraction and its decoding mechanism (ToUnicode CMap, /Differences). An agent can identify what it does without opening the schema.

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?

Gives clear conditional guidance: pass `password` for encrypted sources, use includeRuns:true for positioned runs, verbosity:'summary' for token frugality, and prefer generating with pdfA when faithful extraction of complex scripts matters. It does not explicitly contrast with the closest sibling (extract_pages) or state when *not* to use it, so it stops short of full routing.

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