Get started with Unstructured Transform for PraisonAI
Learn how to connect the Unstructured Transform MCP server to a PraisonAI agent. Your agents can then point to your files and have Transform start producing partitioned, enriched, chunked, and embedded data based on your files in minutes.
PraisonAI is an open-source framework for building multi-agent AI systems in a few lines
of Python. Like other agent frameworks, it connects to the Transform MCP server from agent code: you declare the
server as an MCP client and hand its tools to an agent. Because Transform is a hosted remote MCP server, there is
nothing to install or run locally. You point the client at the server URL and authenticate with your Unstructured API
key.PraisonAI’s MCP class connects to a remote server over streamable HTTP and carries your Unstructured API key as an
Authorization: Bearer header on every request, including the initial handshake.
Python 3.10 or later on your local development machine. To check, in your terminal, run python --version or python3 --version. Install Python.
praisonaiagents 1.6.154 or later. Two fixes matter here: 1.6.152 added the remote streamable-HTTP MCP fix, without which PraisonAI cannot connect to a remote MCP server at all, and 1.6.154 made the agent’s loop guard result-aware. Before 1.6.154, the loop guard counted status polls as “no progress” and halted a transform after eight tool calls, so a multi-minute job never reached an answer. See the PraisonAI releases.
An Unstructured API key, which the Transform MCP server uses as a bearer token. Get an API key.
An API key for the agent’s underlying model, for example an OpenAI API key.
In your agent code, declare the Transform MCP server with the MCP class and hand it to an agent. The headers
setting attaches the Authorization: Bearer header to every request, so the handshake and the tool calls are both
authenticated.Transforms run as asynchronous jobs that take from about 30 seconds to a few minutes, and two settings keep the agent
from giving up before a job finishes. Both are explained under Pace the polling loop below:
import osimport timefrom praisonaiagents import Agent, MCPfrom praisonaiagents.config.feature_configs import ExecutionConfigTRANSFORM_MCP_URL = "https://mcp.transform.unstructured.io" # root URL - do not append /mcpdef 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( TRANSFORM_MCP_URL, headers={"Authorization": f"Bearer {os.environ['UNSTRUCTURED_API_KEY']}"},)transform_agent = Agent( instructions=( "You partition documents into structured, AI-ready data with the Unstructured Transform tools. " "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 partitioned content." ), model="gpt-4o-mini", execution=ExecutionConfig(max_tool_calls_per_turn=100), tools=[*transform_tools, wait_seconds],)
Use the server URL exactly as shown. Do not add /mcp or /sse to the end of the URL.
The two additions above are what make a multi-minute transform complete. Without them the agent connects and calls
the tools, but never reaches an answer:
wait_seconds, passed alongside the MCP tools. PraisonAI has no built-in pacing, so an agent left to itself
polls check_job_status every couple of seconds and then concludes the job is taking too long and stops, while
the transform is still running. Unpacking the MCP tools with *transform_tools lets you add this local function
to the same list. The instruction to call it between status checks matters as much as the tool itself.
ExecutionConfig(max_tool_calls_per_turn=100). PraisonAI caps a turn at 10 tool calls by default, which a
paced polling loop passes well before a job finishes. The cap then ends the turn with “Tool call limit reached
(10 calls)” rather than an answer.
Ask the agent to partition a document and answer a question about it:
transform_agent.start( "Partition https://arxiv.org/pdf/1706.03762 to Markdown and list the section headings.")
Transforming a document is asynchronous: the agent starts a job with start_transform_job, waits with
wait_seconds, polls check_job_status until it is complete, then retrieves the output with get_job_results.
Large or scanned documents can take a few minutes. The Transform tools the agent uses for this flow are
request_file_upload_url, start_transform_job, check_job_status, and get_job_results, alongside the local
wait_seconds function.
To pull specific fields out of a document rather than convert 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.")
The agent partitions the file first, then extracts from the partitioned element JSON using
suggest_extraction_schema_for_file (when you have not supplied a schema) and start_extraction_job, polling with the
same check_job_status and get_job_results tools. Extraction runs on the element JSON that a partition produces rather
than on the raw file, so it always follows a transform job, and chaining the two takes longer than a partition alone.
Results arrive 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 partition captured, so ask for a higher-fidelity partition if a first attempt comes back
sparse. For prompt patterns, see Structured data extraction.
Control Transform file partitioning output: Control how the Unstructured Transform MCP server instructs Transform to partition, enrich, chunk, and embed the data based on your files.
Control Transform generated sample code: Control how the Unstructured Transform MCP server generates sample curl or Python code that demonstrates how to use Transform to partition, enrich, chunk, and embed the data based on your files.