Skip to main content
Glama

Extract Data from Document

talonic_extract

Extract structured, schema-validated data from documents (PDFs, images, scans) and get clean JSON with per-field confidence scores and document metadata.

Instructions

Extract structured, schema-validated data from a document using Talonic. Returns clean JSON matching the schema, with per-field confidence scores and metadata about the document (detected type, language, page count).

USE WHEN:

  • The user has a document (PDF, image, scan, DOCX, etc.) and wants specific fields pulled out.

  • You need structured data (vendor name, total amount, dates, parties, terms) rather than free text.

  • The user uploads or references any invoice, contract, certificate, statement, or form.

  • You want validated JSON instead of trying to OCR + parse with raw LLM calls.

DO NOT USE WHEN:

  • The user just wants the full text content (use talonic_to_markdown after extracting once).

  • The user wants to find documents matching a query (use talonic_search or talonic_filter).

FILE SOURCES (provide exactly one):

  • file_data + filename (RECOMMENDED for chat clients): base64-encoded file bytes plus the original filename (with extension). Use this whenever you already have the file in memory, e.g. the user attached it to the conversation. Works in every MCP client regardless of where the file lives on disk.

  • file_path: a local path to the document. Only works if the MCP server process can read that path on its own filesystem; many chat clients (Claude Desktop, Cowork) store user uploads in a sandbox the MCP server cannot access, in which case use file_data instead.

  • file_url: a URL the Talonic API will fetch directly. Use for documents already on the public web.

  • document_id: re-extract a document already in the workspace.

SCHEMA FORMATS (provide at most one of schema or schema_id):

  • JSON Schema (most reliable): { type: "object", properties: { vendor_name: { type: "string" } } }

  • Flat key-type map: { vendor_name: "string", invoice_total: "number" } -- API normalises server-side. If you get a "no fields" error, fall back to JSON Schema.

  • schema_id: id of a saved schema from talonic_list_schemas. Accepts the UUID or the SCH-XXXXXXXX short id.

IMPORTANT: production currently rejects requests with no schema. Always provide either an inline schema or a schema_id.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
file_dataNoBase64-encoded file bytes. Recommended path when the agent already has the file in memory (e.g., the user attached a PDF to the conversation). Pair with `filename` so MIME type can be inferred. Works regardless of where the file lives on disk.
filenameNoOriginal filename including extension, e.g. 'invoice.pdf'. Used to infer MIME type when uploading via `file_data`. Required when `file_data` is provided.
file_pathNoLocal path to a document file. Only works if the MCP server has read access to that path. In sandboxed chat clients (Claude Desktop, Cowork) where uploads land in a host-owned directory, use `file_data` instead.
file_urlNoURL to a document file. The Talonic API fetches it server-side. Use this for documents already on the public web.
document_idNoID of a document already in the workspace, to re-extract with a new schema.
schemaNoInline schema definition. Most reliable: full JSON Schema {type:'object', properties:{...}}. Also accepted: a flat key-type map {field_name:'string', amount:'number'} which the API normalises. Mutually exclusive with `schema_id`.
schema_idNoID of a saved schema. Accepts UUID or SCH-XXXXXXXX short id. Mutually exclusive with `schema`.
instructionsNoNatural-language guidance for the extractor, e.g. 'Focus on the billing section. Amounts are in EUR.'
include_markdownNoInclude OCR-converted markdown in the response alongside structured data.

Implementation Reference

  • Handler function that builds ExtractParams from arguments, calls talonic.extract(), and returns the result or an error.
    export async function handleExtract(talonic: Talonic, args: ExtractArgs): Promise<ToolResult> {
      try {
        const params: ExtractParams = {}
        if (args.file_data !== undefined) {
          params.file = Buffer.from(args.file_data, "base64")
          if (args.filename !== undefined) params.filename = args.filename
        }
        if (args.file_path !== undefined) params.file_path = args.file_path
        if (args.file_url !== undefined) params.file_url = args.file_url
        if (args.document_id !== undefined) params.document_id = args.document_id
        if (args.schema !== undefined) params.schema = args.schema
        if (args.schema_id !== undefined) params.schema_id = args.schema_id
        if (args.instructions !== undefined) params.instructions = args.instructions
        if (args.include_markdown !== undefined) params.include_markdown = args.include_markdown
    
        const result = await talonic.extract(params)
        return jsonOk(result)
      } catch (err) {
        return toolError(err)
      }
    }
  • Zod-based input schema for the tool, defining all optional parameters: file_data, filename, file_path, file_url, document_id, schema, schema_id, instructions, include_markdown.
    const inputSchema = {
      file_data: z
        .string()
        .optional()
        .describe(
          "Base64-encoded file bytes. Recommended path when the agent already has the file in memory (e.g., the user attached a PDF to the conversation). Pair with `filename` so MIME type can be inferred. Works regardless of where the file lives on disk.",
        ),
      filename: z
        .string()
        .optional()
        .describe(
          "Original filename including extension, e.g. 'invoice.pdf'. Used to infer MIME type when uploading via `file_data`. Required when `file_data` is provided.",
        ),
      file_path: z
        .string()
        .optional()
        .describe(
          "Local path to a document file. Only works if the MCP server has read access to that path. In sandboxed chat clients (Claude Desktop, Cowork) where uploads land in a host-owned directory, use `file_data` instead.",
        ),
      file_url: z
        .string()
        .optional()
        .describe(
          "URL to a document file. The Talonic API fetches it server-side. Use this for documents already on the public web.",
        ),
      document_id: z
        .string()
        .optional()
        .describe("ID of a document already in the workspace, to re-extract with a new schema."),
      schema: z
        .record(z.string(), z.unknown())
        .optional()
        .describe(
          "Inline schema definition. Most reliable: full JSON Schema {type:'object', properties:{...}}. Also accepted: a flat key-type map {field_name:'string', amount:'number'} which the API normalises. Mutually exclusive with `schema_id`.",
        ),
      schema_id: z
        .string()
        .optional()
        .describe(
          "ID of a saved schema. Accepts UUID or SCH-XXXXXXXX short id. Mutually exclusive with `schema`.",
        ),
      instructions: z
        .string()
        .optional()
        .describe(
          "Natural-language guidance for the extractor, e.g. 'Focus on the billing section. Amounts are in EUR.'",
        ),
      include_markdown: z
        .boolean()
        .optional()
        .describe("Include OCR-converted markdown in the response alongside structured data."),
    }
  • Registration function that registers 'talonic_extract' tool on the MCP server with its schema and handler.
    export function registerExtract(server: McpServer, talonic: Talonic): void {
      server.registerTool(
        "talonic_extract",
        {
          title: "Extract Data from Document",
          description: DESCRIPTION,
          inputSchema,
        },
        async (args) => handleExtract(talonic, args as ExtractArgs),
      )
    }
  • Call site in createServer() where the extract tool is registered on the MCP server.
    registerExtract(server, talonic)
Behavior4/5

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

With no annotations, the description appropriately discloses return format (JSON with confidence scores, metadata), mentions that production rejects requests without a schema, and distinguishes behavioral nuances between file source options. Minor gaps: doesn't explicitly state read-only nature or error handling specifics, but is sufficient for safe use.

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 well-organized with headings and bullet points, making it scannable. While it is relatively long, every sentence adds value and is not redundant with the schema. Minor trimming could be done but overall efficient for 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 9 parameters, no output schema, and high complexity, the description covers all essential aspects: file sources, schema requirements, optional instructions, and include_markdown. It also provides fallback instructions for 'no fields' errors. Complete enough for an agent to invoke correctly.

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

Parameters5/5

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

Schema description coverage is 100%, so baseline 3. The description adds significant value beyond the schema by providing real-world context: recommended use of file_data+filename over file_path, explanation of sandbox limitations, details on schema formats with fallback behavior, and natural-language instructions parameter. Truly helps an agent use parameters correctly.

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 description clearly states it extracts structured, schema-validated data from documents and returns JSON with confidence scores and metadata. It distinguishes from siblings like talonic_to_markdown (full text) and talonic_search/talonic_filter (document search/filter).

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

Usage Guidelines5/5

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

Explicit 'USE WHEN' and 'DO NOT USE WHEN' sections provide clear context for when to use this tool versus alternatives. Also provides detailed guidance on file sources and schema formats, including order of precedence and fallback instructions.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/talonicdev/talonic-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server