Unstructured Transform MCP Integration
Guide for parsing documents into structured, AI-ready data with PraisonAI agents using the Unstructured Transform MCP server
Add Document Parsing to AI Agent
Quick Start
- Install Dependencies
Install PraisonAI with MCP support:
bash pip install "praisonaiagents[mcp]"This integration requires
praisonaiagents1.6.154 or later. Connecting to a remote streamable-HTTP MCP server needs 1.6.152, and the result-aware loop guard from 1.6.154 keeps a long-running transform from being halted as “no progress” while the agent polls for status. - Set API Keys
Set your Unstructured API key (from transform.unstructured.io) and your model’s API key as environment variables:
bash export UNSTRUCTURED_API_KEY=your_unstructured_api_key_here export OPENAI_API_KEY=your_openai_api_key_here - Create a file
Create a new file
unstructured_transform.pywith the following code:python from praisonaiagents import Agent, MCP from praisonaiagents.config import ExecutionConfig import os import time def wait_seconds(seconds: int) -> str: """Pause before the next transform status check. Use 30 seconds unless told otherwise.""" seconds = max(1, min(int(seconds), 120)) time.sleep(seconds) return f"Waited {seconds} seconds." transform_tools = MCP( "https://mcp.transform.unstructured.io", headers={"Authorization": f"Bearer {os.environ['UNSTRUCTURED_API_KEY']}"}, ) transform_agent = Agent( instructions="""You parse documents into structured, AI-ready data. Use the Unstructured Transform tools to turn PDFs, Office files, images, and other documents into clean Markdown, then answer questions about the content. Transforms are ASYNC and take 30 seconds to a few minutes. After start_transform_job returns a job_id, ALWAYS call wait_seconds(30) BEFORE each check_job_status call. Never call check_job_status twice in a row without waiting in between. Keep waiting and checking until the status is COMPLETED, then call get_job_results and answer from the parsed content.""", model="gpt-4o-mini", execution=ExecutionConfig(max_tool_calls_per_turn=100), tools=[*transform_tools, wait_seconds], ) transform_agent.start( "Parse https://arxiv.org/pdf/1706.03762 to Markdown and list the section headings" )Two details make a multi-minute transform complete. The
wait_secondsfunction, passed alongside the MCP tools, gives the agent a way to pace its polling: without it the agent checks the status every couple of seconds and then concludes the job is taking too long while it is still running. AndExecutionConfig(max_tool_calls_per_turn=100)raises the default cap of 10 tool calls per turn, which a polling loop passes well before a job finishes. - Run the Agent
Execute your script:
bash python unstructured_transform.pyTransform is asynchronous: the agent starts a job with
start_transform_job, waits withwait_seconds, pollscheck_job_statusuntil it is complete, then retrieves the output withget_job_results. Large or scanned documents can take a few minutes.
Extract Structured Data
To pull named fields out of a document instead of converting the whole document, ask the agent for an extraction:
transform_agent.start(
"""Extract each plant's name, light needs, watering instructions, and humidity level from
https://docs.unstructured.io/img/pipelines/data-extractor/house-plant-care.png as JSON.
Suggest a schema first and show it to me before running the extraction."""
)Extraction runs on the element JSON that a parse produces rather than on the raw file, so the agent parses the document first, then extracts from the output_ref that get_job_results returns for it. It drafts a schema with suggest_extraction_schema_for_file when you have not supplied one, runs start_extraction_job, then polls with the same check_job_status and get_job_results tools. Two jobs run back to back, so an extraction takes longer than a parse alone.
Results come back as JSON matching the schema, wrapped with the source filename and the element JSON reference they were taken from. Extraction can only surface what the parse captured, so ask for a higher-fidelity parse if a first attempt comes back sparse. For prompt patterns, see Structured data extraction.