### Install dependencies Source: https://docs.pageindex.ai/cookbook/mcp/google-adk Install the required Google ADK and PageIndex libraries. ```bash %pip install -q --upgrade google-adk pageindex ``` -------------------------------- ### Install PageIndex SDK Source: https://docs.pageindex.ai/js-sdk Install the package via npm. ```bash npm install @pageindex/sdk ``` -------------------------------- ### Install dependencies Source: https://docs.pageindex.ai/cookbook/mcp/gemini-api Install the required Google GenAI and PageIndex libraries. ```bash %pip install -q --upgrade google-genai pageindex ``` -------------------------------- ### Install the PageIndex SDK Source: https://docs.pageindex.ai/getting-started Install the required Python package using pip. ```bash pip install -U pageindex ``` -------------------------------- ### Install dependencies Source: https://docs.pageindex.ai/cookbook/mcp/langchain Install the required libraries for LangChain MCP integration and PageIndex. ```bash %pip install -q --upgrade langchain-mcp-adapters "langchain[anthropic]" pageindex ``` -------------------------------- ### Install dependencies Source: https://docs.pageindex.ai/cookbook/mcp/openai-agents-sdk Install the required OpenAI Agents SDK and PageIndex client libraries. ```bash %pip install -q --upgrade openai-agents pageindex ``` -------------------------------- ### Install Dependencies Source: https://docs.pageindex.ai/cookbook/mcp/crewai Install the required crewai and pageindex packages. ```bash %pip install -q --upgrade crewai pageindex ``` -------------------------------- ### Install dependencies Source: https://docs.pageindex.ai/cookbook/mcp/claude-agent-sdk Install the required Claude Agent SDK and PageIndex client libraries. ```bash %pip install -q --upgrade claude-agent-sdk pageindex ``` -------------------------------- ### Install dependencies Source: https://docs.pageindex.ai/cookbook/mcp/openai-api Installs the required OpenAI and PageIndex Python packages. ```bash %pip install -q --upgrade openai pageindex ``` -------------------------------- ### Install Dependencies Source: https://docs.pageindex.ai/cookbook/mcp/camel Install the necessary CAMEL AI MCP and PageIndex packages. ```bash %pip install -q --upgrade "camel-ai[mcp]" pageindex ``` -------------------------------- ### Install dependencies Source: https://docs.pageindex.ai/cookbook/mcp/deepagents Install the required packages for Deep Agents, LangChain MCP adapters, and PageIndex. ```bash %pip install -q --upgrade deepagents langchain-mcp-adapters "langchain[anthropic]" pageindex ``` -------------------------------- ### Install Anthropic SDK Support Source: https://docs.pageindex.ai/sdk/agents Installs the necessary dependencies for Anthropic integration. ```bash pip install 'pageindex[anthropic]' ``` -------------------------------- ### Retrieve Agent Instructions Source: https://docs.pageindex.ai/sdk/agents Get the system prompt guidance for the agent. ```python instructions = client.agent_instructions(doc_id=doc_id) ``` -------------------------------- ### Install PageIndex dependencies Source: https://docs.pageindex.ai/cookbook/vision-rag-pageindex Install the required packages for PageIndex, requests, OpenAI, and PyMuPDF. ```bash %pip install -q --upgrade pageindex requests openai PyMuPDF ``` -------------------------------- ### Setup PageIndex and LangChain client Source: https://docs.pageindex.ai/cookbook/mcp/langchain Initialize the PageIndex client, configure the LLM, and set up the MultiServerMCPClient to connect to the PageIndex MCP server. ```python from langchain_mcp_adapters.client import MultiServerMCPClient from langchain.agents import create_agent from langchain_anthropic import ChatAnthropic from pageindex import PageIndexClient # Get your PageIndex API key from https://dash.pageindex.ai/api-keys PAGEINDEX_API_KEY = "YOUR_PAGEINDEX_API_KEY" # Get your Anthropic API key from https://platform.claude.com/settings/keys ANTHROPIC_API_KEY = "YOUR_ANTHROPIC_API_KEY" MODEL = "claude-sonnet-4-6" pi = PageIndexClient(api_key=PAGEINDEX_API_KEY) llm = ChatAnthropic( model=MODEL, api_key=ANTHROPIC_API_KEY, thinking={"type": "enabled", "budget_tokens": 10000}, max_tokens=16000, ) mcp_client = MultiServerMCPClient({"pageindex": {"transport": "http", "url": "https://api.pageindex.ai/mcp", "headers": {"Authorization": f"Bearer {PAGEINDEX_API_KEY}"}}}) async def ask(question, show_tool_results=False): tools = await mcp_client.get_tools() agent = create_agent(llm, tools) current = None async for event in agent.astream_events({"messages": question}, version="v2"): kind = event["event"] data = event["data"] if kind == "on_chat_model_stream": for block in (data["chunk"].content if isinstance(data["chunk"].content, list) else []): btype = block.get("type") if btype != current: if btype == "thinking": print("\n[thinking] ", end="", flush=True) elif btype == "text": print("\n", end="", flush=True) current = btype if btype == "thinking": print(block.get("thinking", ""), end="", flush=True) elif btype == "text": print(block.get("text", ""), end="", flush=True) elif kind == "on_tool_start": current = None print(f"\n[tool_use] {event['name']} {data['input']}") elif kind == "on_tool_end" and show_tool_results: print(f"\n[tool_result] {data['output']}") ``` -------------------------------- ### Install Claude Agent SDK Source: https://docs.pageindex.ai/sdk/agents Install the required package for Claude agent integration. ```bash pip install 'pageindex[claude]' ``` -------------------------------- ### Install PageIndex and LlamaIndex dependencies Source: https://docs.pageindex.ai/cookbook/mcp/llamaindex Install the necessary packages for LlamaIndex MCP integration and PageIndex client functionality. ```bash %pip install -q --upgrade llama-index-tools-mcp llama-index-llms-anthropic llama-index-core pageindex ``` -------------------------------- ### Install PageIndex and Pydantic AI dependencies Source: https://docs.pageindex.ai/cookbook/mcp/pydanticai Install the required Python packages for the agentic RAG implementation. ```bash %pip install -q --upgrade pydantic-ai pageindex ``` -------------------------------- ### Install PageIndex and Anthropic dependencies Source: https://docs.pageindex.ai/cookbook/mcp/claude-api Install the necessary Python packages for interacting with the Anthropic API and PageIndex client. ```bash %pip install -q --upgrade anthropic pageindex ``` -------------------------------- ### Browse Documents with JavaScript Source: https://docs.pageindex.ai/js-sdk/mcp-tools Examples for listing documents by time, performing semantic searches, and drilling into specific folders. ```javascript const result = await client.tools.browseDocuments({ limit: 10 }); for (const doc of result.documents) { console.log(`${doc.name} — ${doc.status}`); } if (result.has_more) { const next = await client.tools.browseDocuments({ limit: 10, offset: result.next_offset ?? 0, }); } ``` ```javascript const result = await client.tools.browseDocuments({ sort: "relevance", query: "quarterly revenue trends", limit: 5, }); ``` ```javascript const result = await client.tools.browseDocuments({ folderId: "folder-abc123", recursive: true, }); ``` -------------------------------- ### Request Body Examples Source: https://docs.pageindex.ai/api-reference Standard request structures for chat completions, including single and multiple document scoping. ```json { "messages": [ { "role": "user", "content": "What are the key findings of the first paper?" } ], "stream": false } ``` ```json { "doc_id": "pi-123456", "messages": [ { "role": "user", "content": "What are the key findings of this document?" } ], "stream": false } ``` ```json { "doc_id": ["pi-123456", "pi-789012"], "messages": [ { "role": "user", "content": "Compare these documents" } ], "stream": false } ``` -------------------------------- ### Get Folder Structure with JavaScript Source: https://docs.pageindex.ai/js-sdk/mcp-tools Retrieves the folder hierarchy and demonstrates a recursive function to print the tree structure. ```javascript const result = await client.tools.getFolderStructure({ depth: 3 }); console.log(`Total folders: ${result.total_folders}`); function printTree(node, indent = 0) { const pad = " ".repeat(indent * 2); console.log(`${pad}${node.name} (${node.file_count} files)`); for (const child of node.children) { printTree(child, indent + 1); } } printTree(result.tree); ``` -------------------------------- ### Perform Streaming Chat Requests Source: https://docs.pageindex.ai/js-sdk/chat Examples of streaming responses in real-time, including handling multi-turn conversations. ```javascript const stream = await client.api.chatCompletions({ messages: [ { role: "user", content: "Summarize this document" } ], doc_id: "pi-abc123def456", stream: true, }); for await (const chunk of stream) { const content = chunk.choices[0]?.delta?.content ?? ""; if (content) { process.stdout.write(content); } } ``` ```javascript const stream = await client.api.chatCompletions({ messages: [ { role: "user", content: "What is the main topic of this document?" }, { role: "assistant", content: "The main topic is climate change and its effects on agriculture." }, { role: "user", content: "What solutions does it propose?" }, ], doc_id: "pi-abc123def456", stream: true, }); for await (const chunk of stream) { const content = chunk.choices[0]?.delta?.content ?? ""; if (content) { process.stdout.write(content); } } ``` -------------------------------- ### Example Retrieval JSON Output Source: https://docs.pageindex.ai/cookbook/agentic-retrieval-pageindex A sample JSON structure representing retrieved content from a document, as expected by the retrieval assistant. ```json [ { "page": 45, "content": "## 6. Evaluation\n\nThe evaluation of context-engineered systems presents unprecedented challenges that transcend traditional language model assessment paradigms. These systems exhibit complex, multi-component architectures with dynamic, context-dependent behaviors requiring comprehensive evaluation frameworks that assess component-level diagnostics, task-based performance, and overall system robustness [841, 1141].\n\nThe heterogeneous nature of context engineering components-spanning retrieval mechanisms, memory systems, reasoning chains, and multi-agent coordination-demands evaluation methodologies that can capture both individual component effectiveness and emergent system-level behaviors [314, 939].\n\n### 6.1. Evaluation Frameworks and Methodologies\n\nThis subsection presents comprehensive approaches for evaluating both individual components and integrated systems in context engineering.\n\n#### 6.1.1. Component-Level Assessment\n\nIntrinsic evaluation focuses on the performance of individual components in isolation, providing foundational insights into system capabilities and failure modes.\n\nFor prompt engineering components, evaluation encompasses prompt effectiveness measurement through semantic similarity metrics, response quality assessment, and robustness testing across diverse input variations. Current approaches reveal brittleness and robustness challenges in prompt design, necessitating more sophisticated evaluation frameworks that can assess contextual calibration and adaptive prompt optimization $[1141,669]$." }, { "page": 46, ``` -------------------------------- ### Example JSON responses for tree retrieval Source: https://docs.pageindex.ai/sdk/documents Sample JSON payloads returned by the get_tree method during processing and after completion. ```json { "doc_id": "pi-abc123def456", "status": "processing" } ``` ```json { "doc_id": "pi-abc123def456", "status": "completed", "retrieval_ready": true, "result": [ { "title": "Financial Stability", "node_id": "0006", "page_index": 21, "text": "The Federal Reserve maintains financial stability through comprehensive monitoring and regulatory oversight...", "nodes": [ { "title": "Monitoring Financial Vulnerabilities", "node_id": "0007", "page_index": 22, "text": "The Federal Reserve's monitoring focuses on identifying and assessing potential risks..." } ] } ] } ``` -------------------------------- ### PageIndex Chat API Response Example Source: https://docs.pageindex.ai/cookbook/agentic-retrieval-pageindex Displays the structure of a response object returned by the PageIndex Chat API. ```python 'ensuring the reliable deployment of context-engineered systems ' 'in real-world applications [841, 1141].', 'page': 50}] ``` -------------------------------- ### Agentic Document Query Interaction Source: https://docs.pageindex.ai/cookbook/agentic-retrieval-pageindex Example of an agentic system querying a document structure and extracting content based on specific page ranges. ```json {"doc_name": "2507.13334_19.pdf"} ``` ```json {"doc_name": "2507.13334_19.pdf", "pages": "45-50"} ``` -------------------------------- ### Initialize Agent and MCP configuration Source: https://docs.pageindex.ai/cookbook/mcp/claude-agent-sdk Set up the PageIndex client and define the asynchronous agent query function with MCP server configuration. ```python from claude_agent_sdk import query, ClaudeAgentOptions, StreamEvent, UserMessage, ToolResultBlock from pageindex import PageIndexClient # Get your PageIndex API key from https://dash.pageindex.ai/api-keys PAGEINDEX_API_KEY = "YOUR_PAGEINDEX_API_KEY" # Get your Anthropic API key from https://platform.claude.com/settings/keys ANTHROPIC_API_KEY = "YOUR_ANTHROPIC_API_KEY" MODEL = "claude-sonnet-4-6" pi = PageIndexClient(api_key=PAGEINDEX_API_KEY) async def ask(question, show_tool_results=False): options = ClaudeAgentOptions( model=MODEL, thinking={"type": "enabled", "budget_tokens": 10000}, mcp_servers={"pageindex": {"type": "http", "url": "https://api.pageindex.ai/mcp", "headers": {"Authorization": f"Bearer {PAGEINDEX_API_KEY}"}, "alwaysLoad": True}}, tools=[], permission_mode="bypassPermissions", env={"ANTHROPIC_API_KEY": ANTHROPIC_API_KEY}, include_partial_messages=True, ) async for message in query(prompt=question, options=options): if isinstance(message, StreamEvent): event = message.event if event["type"] == "content_block_start": block = event["content_block"] header = "\n" if block["type"] == "thinking": header = f"\n[{block['type']}] " elif block["type"] == "tool_use": header = f"\n[{block['type']}] {block['name'].replace('mcp__pageindex__', '')} " print(header, end="", flush=True) elif event["type"] == "content_block_delta": delta = event["delta"] chunk = delta.get("thinking", "") or delta.get("text", "") or delta.get("partial_json", "") print(chunk, end="", flush=True) elif event["type"] == "content_block_stop" and header: print() elif isinstance(message, UserMessage) and show_tool_results: for block in message.content: if isinstance(block, ToolResultBlock): print(f"\n[tool_result] {block.content}") ``` -------------------------------- ### Initialize PageIndex and OpenRouter Client Source: https://docs.pageindex.ai/cookbook/mcp/openrouter Configure the PageIndex client and the AsyncOpenAI client pointing to OpenRouter. Ensure you have valid API keys for both services. ```python from openai import AsyncOpenAI from agents import Agent, Runner, ModelSettings, set_tracing_disabled from agents.models.openai_chatcompletions import OpenAIChatCompletionsModel from agents.mcp import MCPServerStreamableHttp from pageindex import PageIndexClient set_tracing_disabled(True) # Get your PageIndex API key from https://dash.pageindex.ai/api-keys PAGEINDEX_API_KEY = "YOUR_PAGEINDEX_API_KEY" # Get your OpenRouter API key from https://openrouter.ai/keys OPENROUTER_API_KEY = "YOUR_OPENROUTER_API_KEY" # Pick a model on OpenRouter MODEL = "moonshotai/kimi-k2.6" # MODEL = "deepseek/deepseek-v4-pro" # MODEL = "z-ai/glm-5.1" # MODEL = "minimax/minimax-m2.7" # MODEL = "qwen/qwen3.6-max-preview" pi = PageIndexClient(api_key=PAGEINDEX_API_KEY) client = AsyncOpenAI(base_url="https://openrouter.ai/api/v1", api_key=OPENROUTER_API_KEY) async def ask(question, show_tool_results=False): async with MCPServerStreamableHttp( name="pageindex", params={"url": "https://api.pageindex.ai/mcp", "headers": {"Authorization": f"Bearer {PAGEINDEX_API_KEY}"}}, cache_tools_list=True, ) as server: agent = Agent( name="PageIndex RAG Agent", model=OpenAIChatCompletionsModel(model=MODEL, openai_client=client), instructions="Use the PageIndex MCP tools to answer questions about the user's documents.", mcp_servers=[server], model_settings=ModelSettings(extra_body={"reasoning": {"max_tokens": 10000}}), ) result = Runner.run_streamed(agent, question) async for event in result.stream_events(): if event.type == "raw_response_event": data = event.data if data.type == "response.output_item.added": item = data.item if item.type == "reasoning": print(f"\n[{item.type}] ", end="", flush=True) elif item.type == "function_call": print(f"\n[{item.type}] {item.name} ", end="", flush=True) elif data.type in ("response.reasoning_summary_text.delta", "response.reasoning_text.delta", "response.output_text.delta", "response.function_call_arguments.delta"): print(data.delta, end="", flush=True) elif data.type == "response.output_item.done" and data.item.type == "function_call": print() elif event.type == "run_item_stream_event" and event.item.type == "tool_call_output_item" and show_tool_results: print(f"\n[tool_result] {event.item.output}") ``` -------------------------------- ### Initialize clients and define ask function Source: https://docs.pageindex.ai/cookbook/mcp/openai-api Sets up the PageIndex and OpenAI clients and defines an asynchronous function to stream responses from the OpenAI API using an MCP tool. ```python from openai import AsyncOpenAI from pageindex import PageIndexClient # Get your PageIndex API key from https://dash.pageindex.ai/api-keys PAGEINDEX_API_KEY = "YOUR_PAGEINDEX_API_KEY" # Get your OpenAI API key from https://platform.openai.com/api-keys OPENAI_API_KEY = "YOUR_OPENAI_API_KEY" MODEL = "gpt-5.5" pi = PageIndexClient(api_key=PAGEINDEX_API_KEY) client = AsyncOpenAI(api_key=OPENAI_API_KEY) async def ask(question, show_tool_results=False): stream = await client.responses.create( model=MODEL, stream=True, reasoning={"effort": "medium", "summary": "auto"}, instructions="You are a document analysis assistant. Always use the available tools to search and retrieve information from the user's documents.", tools=[{"type": "mcp", "server_label": "pageindex", "server_url": "https://api.pageindex.ai/mcp", "headers": {"Authorization": f"Bearer {PAGEINDEX_API_KEY}"}, "require_approval": "never"}], input=question, ) async for event in stream: if event.type == "response.output_item.added": item = event.item if item.type == "reasoning": print(f"\n[{item.type}] ", end="", flush=True) elif item.type == "message": print("\n", end="", flush=True) elif event.type in ("response.reasoning_summary_text.delta", "response.output_text.delta"): print(event.delta, end="", flush=True) elif event.type == "response.output_item.done": item = event.item if item.type == "mcp_call": print(f"\n[{item.type}] {item.name} {item.arguments}") if show_tool_results: print(f"\n[mcp_result] {item.output}") elif item.type in ("reasoning", "message"): print() ``` -------------------------------- ### Initialize Local Mode Client Source: https://docs.pageindex.ai/quickstart Configure the client for local indexing and chat using your own OpenAI key. Local indexing is synchronous. ```python import os from pageindex import PageIndexClient os.environ["OPENAI_API_KEY"] = "your-openai-key" client = PageIndexClient( index="gpt-5.6-luna", # model that builds the tree index chat="gpt-5.6-sol", # model that searches the tree ) doc_id = client.submit_document("./2023-annual-report.pdf")["doc_id"] answer = client.chat( "What was the 2023 operating margin, and where is it stated?", doc_id=doc_id, ) print(answer) ``` -------------------------------- ### Initialize Agent and PageIndex Client Source: https://docs.pageindex.ai/cookbook/mcp/openai-agents-sdk Configure the PageIndex client and the OpenAI agent with MCP server support for document retrieval. ```python from openai import AsyncOpenAI from agents import Agent, Runner, ModelSettings, set_tracing_disabled from agents.models.openai_responses import OpenAIResponsesModel from agents.mcp import MCPServerStreamableHttp from pageindex import PageIndexClient set_tracing_disabled(True) # Get your PageIndex API key from https://dash.pageindex.ai/api-keys PAGEINDEX_API_KEY = "YOUR_PAGEINDEX_API_KEY" # Get your OpenAI API key from https://platform.openai.com/api-keys OPENAI_API_KEY = "YOUR_OPENAI_API_KEY" MODEL = "gpt-5.5" pi = PageIndexClient(api_key=PAGEINDEX_API_KEY) client = AsyncOpenAI(api_key=OPENAI_API_KEY) async def ask(question, show_tool_results=False): async with MCPServerStreamableHttp( name="pageindex", params={"url": "https://api.pageindex.ai/mcp", "headers": {"Authorization": f"Bearer {PAGEINDEX_API_KEY}"}}, cache_tools_list=True, ) as server: agent = Agent( name="PageIndex RAG Agent", model=OpenAIResponsesModel(model=MODEL, openai_client=client), instructions="Use the PageIndex MCP tools to answer questions about the user's documents.", mcp_servers=[server], model_settings=ModelSettings(reasoning={"effort": "medium", "summary": "auto"}), ) result = Runner.run_streamed(agent, question) async for event in result.stream_events(): if event.type == "raw_response_event": data = event.data if data.type == "response.output_item.added": item = data.item header = "" if item.type == "reasoning": header = f"\n[{item.type}] " elif item.type == "message": header = "\n" elif item.type == "function_call": header = f"\n[{item.type}] {item.name} " print(header, end="", flush=True) elif data.type in ("response.reasoning_summary_text.delta", "response.output_text.delta", "response.function_call_arguments.delta"): print(data.delta, end="", flush=True) elif data.type == "response.output_item.done" and header: print() elif event.type == "run_item_stream_event" and event.item.type == "tool_call_output_item" and show_tool_results: print(f"\n[tool_result] {event.item.output}") ``` -------------------------------- ### Initialize Cloud Mode Client Source: https://docs.pageindex.ai/quickstart Configure the client for PageIndex Cloud processing. Cloud indexing is asynchronous, so use wait=True to block until ready. ```python import os from pageindex import PageIndexClient os.environ["PAGEINDEX_API_KEY"] = "your-pageindex-key" os.environ["OPENAI_API_KEY"] = "your-openai-key" client = PageIndexClient( index="cloud", # index and store in PageIndex Cloud chat="gpt-5.6-sol", # your own model answers ) # Cloud indexing is asynchronous — wait=True blocks until the document is ready doc_id = client.submit_document("./2023-annual-report.pdf", wait=True)["doc_id"] print(client.chat("What was the 2023 operating margin?", doc_id=doc_id)) ``` -------------------------------- ### Get page content Source: https://docs.pageindex.ai/sdk/documents Reads markdown content from specific pages of a document. ```python pages = client.get_page_content(doc_id, "5-7") for page in pages: print(page["page_index"], page["markdown"][:200]) ``` -------------------------------- ### Example chat completion response Source: https://docs.pageindex.ai/sdk/chat The structure of a standard non-streaming response object. ```json { "id": "chatcmpl-xyz789", "object": "chat.completion", "created": 1234567890, "choices": [{ "index": 0, "message": { "role": "assistant", "content": "Based on the document, the key findings are..." }, "finish_reason": "stop" }], "usage": { "prompt_tokens": 1234, "completion_tokens": 567, "total_tokens": 1801 } } ``` -------------------------------- ### Initialize clients and define query function Source: https://docs.pageindex.ai/cookbook/mcp/gemini-api Configure the PageIndex and Gemini clients and define an asynchronous function to interact with the Gemini model using MCP tools. ```python from google import genai from pageindex import PageIndexClient # Get your PageIndex API key from https://dash.pageindex.ai/api-keys PAGEINDEX_API_KEY = "YOUR_PAGEINDEX_API_KEY" # Get your Gemini API key from https://aistudio.google.com/apikey GEMINI_API_KEY = "YOUR_GEMINI_API_KEY" MODEL = "gemini-2.5-pro" pi = PageIndexClient(api_key=PAGEINDEX_API_KEY) client = genai.Client(api_key=GEMINI_API_KEY) async def ask(question, show_tool_results=False): stream = await client.aio.interactions.create( model=MODEL, stream=True, system_instruction="You are a document analysis assistant. Always use the available MCP tools to search and retrieve information from the user's documents.", input=question, tools=[{"type": "mcp_server", "name": "pageindex", "url": "https://api.pageindex.ai/mcp", "headers": {"Authorization": f"Bearer {PAGEINDEX_API_KEY}"}}], generation_config={"thinking_summaries": "auto"}, ) async for event in stream: if event.event_type == "content.start" and event.content: content = event.content header = "" if content.type == "thought": header = "[thinking] " elif content.type == "text": header = "" print(header, end="", flush=True) elif event.event_type == "content.delta" and event.delta: delta = event.delta if delta.type == "thought_summary": text = (delta.content.text if delta.content and hasattr(delta.content, "text") else "") or "" print(text, end="", flush=True) elif delta.type == "text": print(delta.text or "", end="", flush=True) elif delta.type == "mcp_server_tool_call": print(f"[{delta.type}] {delta.name} {delta.arguments}") elif delta.type == "mcp_server_tool_result" and show_tool_results: print(f"[{delta.type}] {delta.result}") ``` -------------------------------- ### OCR Submission Response Source: https://docs.pageindex.ai/sdk/legacy/ocr Example JSON response received after submitting a document. ```json { "doc_id": "pi-abc123def456" } ``` -------------------------------- ### Get Document Metadata Source: https://docs.pageindex.ai/sdk/documents Retrieve metadata for a document, which includes the associated folder ID. ```python meta = client.get_document("pi-abc123def456") print(meta["folderId"]) ``` -------------------------------- ### Initialize PageIndex Client Source: https://docs.pageindex.ai/js-sdk Create a new client instance using your API key. ```javascript import { PageIndexClient } from "@pageindex/sdk"; const client = new PageIndexClient({ apiKey: "YOUR_API_KEY" }); ``` -------------------------------- ### Get Folder Structure Response Format Source: https://docs.pageindex.ai/js-sdk/mcp-tools The JSON structure returned by the getFolderStructure tool. ```json { "tree": { "name": "root", "file_count": 12, "children_count": 3, "children": [ { "id": "folder-abc123", "name": "Research Papers", "path": "/Research Papers", "file_count": 5, "children_count": 2, "children": [ { "id": "folder-def456", "name": "Q1 Reports", "path": "/Research Papers/Q1 Reports", "file_count": 3, "children_count": 0, "children": [] } ] } ] }, "total_folders": 4, "depth": 3, "truncated": false, "next_steps": { "summary": "...", "options": ["..."] } } ``` -------------------------------- ### agent_instructions(doc_id, include_management) Source: https://docs.pageindex.ai/sdk/agents Retrieves the orchestration guidance for the agent, which can be used as a system prompt. ```APIDOC ## agent_instructions ### Description Returns the orchestration guidance PageIndex's own agent runs on. This should be passed as the agent's system prompt. ### Parameters - **doc_id** (string or List[string]) - Optional - Appends target documents' names and metadata to the instructions. - **include_management** (boolean) - Optional - Fetch guidance for the full tool set. Default: False. ``` -------------------------------- ### Get Document Structure Source: https://docs.pageindex.ai/sdk/documents Retrieves the hierarchical structure of an indexed document using its ID. ```python structure = client.get_document_structure(doc_id) ``` -------------------------------- ### Get Document Metadata Source: https://docs.pageindex.ai/js-sdk/folders Retrieve metadata for a document, which includes the associated folder ID. ```javascript const doc = await client.api.getDocument("pi-abc123def456"); console.log(doc.folderId); // "folder-abc123" ``` -------------------------------- ### Initialize and Run Document QA Agent Source: https://docs.pageindex.ai/cookbook/agentic-vectorless-rag-pageindex Configures an agent with PageIndex tools and streams responses, including reasoning and tool call outputs. ```python """ Agentic Vectorless RAG with PageIndex - Demo A simple example of building a document QA agent with the PageIndex SDK in local mode and the OpenAI Agents SDK. Instead of vector similarity search and chunking, PageIndex builds a hierarchical tree index and uses agentic LLM reasoning for human-like, context-aware retrieval. The agent tools come straight from the SDK — ``client.as_openai_tools()`` exposes the PageIndex tool contract (browse_documents, get_document, get_document_structure, get_page_content) and ``client.agent_instructions()`` provides the retrieval playbook, so the whole agent is a few lines. Swap ``PageIndexLocalClient()`` for ``PageIndexCloudClient(api_key=...)`` and the same code runs against the cloud. Steps: 1 — Index a PDF locally and view its tree structure index 2 — View document metadata 3 — Ask a question (agent reasons over the index and auto-calls tools) Requirements: pip install pageindex; OPENAI_API_KEY in the environment. """ import sys import asyncio import concurrent.futures from pathlib import Path import requests sys.path.insert(0, str(Path(__file__).parent.parent)) from agents import Agent, Runner, set_tracing_disabled from agents.stream_events import RawResponsesStreamEvent, RunItemStreamEvent from openai.types.responses import ResponseTextDeltaEvent, ResponseReasoningSummaryTextDeltaEvent from pageindex import PageIndexLocalClient import pageindex.utils as utils PDF_URL = "https://arxiv.org/pdf/2603.15031" _EXAMPLES_DIR = Path(__file__).parent PDF_PATH = _EXAMPLES_DIR / "documents" / "attention-residuals.pdf" STORAGE_PATH = _EXAMPLES_DIR / ".pageindex" def query_agent(client: PageIndexLocalClient, doc_id: str, prompt: str, verbose: bool = False) -> str: """Run a document QA agent using the OpenAI Agents SDK. Streams text output token-by-token and returns the full answer string. Tool calls are always printed; verbose=True also prints arguments and output previews. """ agent = Agent( **client.openai_agent_config( doc_id=doc_id, # model_settings=ModelSettings(reasoning={"effort": "low", "summary": "auto"}), # from agents.model_settings import ModelSettings ), ) async def _run(): streamed_run = Runner.run_streamed(agent, prompt) current_stream_kind = None async for event in streamed_run.stream_events(): if isinstance(event, RawResponsesStreamEvent): if isinstance(event.data, ResponseReasoningSummaryTextDeltaEvent): if current_stream_kind != "reasoning": if current_stream_kind is not None: print() print("\n[reasoning]: ", end="", flush=True) delta = event.data.delta print(delta, end="", flush=True) current_stream_kind = "reasoning" elif isinstance(event.data, ResponseTextDeltaEvent): if current_stream_kind != "text": if current_stream_kind is not None: print() print("\n[text]: ", end="", flush=True) delta = event.data.delta print(delta, end="", flush=True) current_stream_kind = "text" elif isinstance(event, RunItemStreamEvent): item = event.item if item.type == "tool_call_item": if current_stream_kind is not None: print() raw = item.raw_item args = getattr(raw, "arguments", "{}") args_str = f"({args})" if verbose else "" print(f"\n[tool call]: {raw.name}{args_str}", flush=True) current_stream_kind = None elif item.type == "tool_call_output_item" and verbose: if current_stream_kind is not None: print() output = str(item.output) preview = output[:200] + "..." if len(output) > 200 else output print(f"\n[tool call output]: {preview}", flush=True) current_stream_kind = None if current_stream_kind is not None: print() return "" if not streamed_run.final_output else str(streamed_run.final_output) try: asyncio.get_running_loop() with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool: return pool.submit(asyncio.run, _run()).result() except RuntimeError: return asyncio.run(_run()) if __name__ == "__main__": set_tracing_disabled(True) ``` -------------------------------- ### Retrieval Request Response Source: https://docs.pageindex.ai/sdk/legacy/retrieval Example JSON response received after submitting a retrieval query. ```json { "retrieval_id": "xyz789ghi012" } ``` -------------------------------- ### Initialize PageIndex and Deep Agent Source: https://docs.pageindex.ai/cookbook/mcp/deepagents Configure the PageIndex client, Anthropic LLM, and MCP client to enable agentic retrieval. ```python from langchain_mcp_adapters.client import MultiServerMCPClient from deepagents import create_deep_agent from langchain_anthropic import ChatAnthropic from pageindex import PageIndexClient # Get your PageIndex API key from https://dash.pageindex.ai/api-keys PAGEINDEX_API_KEY = "YOUR_PAGEINDEX_API_KEY" # Get your Anthropic API key from https://platform.claude.com/settings/keys ANTHROPIC_API_KEY = "YOUR_ANTHROPIC_API_KEY" MODEL = "claude-sonnet-4-6" pi = PageIndexClient(api_key=PAGEINDEX_API_KEY) llm = ChatAnthropic( model=MODEL, api_key=ANTHROPIC_API_KEY, thinking={"type": "enabled", "budget_tokens": 10000}, max_tokens=16000, ) mcp_client = MultiServerMCPClient({"pageindex": {"transport": "http", "url": "https://api.pageindex.ai/mcp", "headers": {"Authorization": f"Bearer {PAGEINDEX_API_KEY}"}}}) async def ask(question, show_tool_results=False): tools = await mcp_client.get_tools() agent = create_deep_agent(model=llm, tools=tools) current = None async for event in agent.astream_events({"messages": question}, version="v2"): kind = event["event"] data = event["data"] if kind == "on_chat_model_stream": for block in (data["chunk"].content if isinstance(data["chunk"].content, list) else []): btype = block.get("type") if btype != current: if btype == "thinking": print("\n[thinking] ", end="", flush=True) elif btype == "text": print("\n", end="", flush=True) current = btype if btype == "thinking": print(block.get("thinking", ""), end="", flush=True) elif btype == "text": print(block.get("text", ""), end="", flush=True) elif kind == "on_tool_start": current = None print(f"\n[tool_use] {event['name']} {data['input']}") elif kind == "on_tool_end" and show_tool_results: print(f"\n[tool_result] {data['output']}") ``` -------------------------------- ### Initialize PageIndex and Google ADK agent Source: https://docs.pageindex.ai/cookbook/mcp/google-adk Configure API keys and define the asynchronous ask function to manage the agent lifecycle, toolset connection, and event streaming. ```python import os from google.adk.agents import LlmAgent from google.adk.planners import BuiltInPlanner from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from google.adk.tools.mcp_tool import McpToolset from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams from google.genai import types from pageindex import PageIndexClient # Get your PageIndex API key from https://dash.pageindex.ai/api-keys PAGEINDEX_API_KEY = "YOUR_PAGEINDEX_API_KEY" # Get your Gemini API key from https://aistudio.google.com/apikey GOOGLE_API_KEY = "YOUR_GOOGLE_API_KEY" os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY MODEL = "gemini-3.1-pro-preview" pi = PageIndexClient(api_key=PAGEINDEX_API_KEY) async def ask(question, show_tool_results=False): toolset = McpToolset( connection_params=StreamableHTTPConnectionParams( url="https://api.pageindex.ai/mcp", headers={"Authorization": f"Bearer {PAGEINDEX_API_KEY}"}, ), ) agent = LlmAgent( name="pageindex_rag_agent", model=MODEL, instruction="Use the PageIndex MCP tools to answer questions about the user's documents.", tools=[toolset], planner=BuiltInPlanner(thinking_config=types.ThinkingConfig(include_thoughts=True, thinking_budget=2048)), ) session_service = InMemorySessionService() session = await session_service.create_session(app_name="pageindex_app", user_id="user") runner = Runner(app_name="pageindex_app", agent=agent, session_service=session_service) message = types.Content(role="user", parts=[types.Part(text=question)]) try: async for event in runner.run_async(user_id="user", session_id=session.id, new_message=message): calls = event.get_function_calls() responses = event.get_function_responses() if calls: for call in calls: print(f"\n[tool_call] {call.name} {dict(call.args)}") elif responses and show_tool_results: for resp in responses: print(f"\n[tool_result] {resp.response}") elif event.content and event.content.parts: for part in event.content.parts: if part.thought and part.text: print(f"\n[thinking] {part.text}") elif part.text and event.is_final_response(): print(f"\n{part.text}") finally: await toolset.close() ``` -------------------------------- ### OCR Status Response (Completed) Source: https://docs.pageindex.ai/sdk/legacy/ocr Example JSON response when the document processing is finished. ```json { "doc_id": "pi-abc123def456", "status": "completed", "result": [ { "page_index": 1, "markdown": "Content from page 1 in markdown format", "images": [ "iVBORw0KGgoAAAANSUhEUgAA...", // Base64-encoded image(s) "iVBORw0KGgoAAAANSUhEUgAB..." // More images if present ] }, { "page_index": 2, "markdown": "Content from page 2 in markdown format", "images": [] } ] } ``` -------------------------------- ### OCR Status Response (Processing) Source: https://docs.pageindex.ai/sdk/legacy/ocr Example JSON response when the document is still being processed. ```json { "doc_id": "pi-abc123def456", "status": "processing" } ``` -------------------------------- ### Upload, Process, and Chat with Documents Source: https://docs.pageindex.ai/js-sdk Demonstrates the full workflow of uploading a file, checking its processing status, and performing both standard and streaming chat completions. ```javascript import { PageIndexClient } from "@pageindex/sdk"; import { readFileSync } from "fs"; const client = new PageIndexClient({ apiKey: "YOUR_API_KEY" }); // 1. Upload a document const file = readFileSync("./2023-annual-report.pdf"); const { doc_id } = await client.api.submitDocument(file, "2023-annual-report.pdf"); console.log("Document ID:", doc_id); // 2. Get tree structure (includes processing status) const tree = await client.api.getTree(doc_id); if (tree.status === "completed") { console.log("Tree:", tree.result); } // 3. Chat with the document const response = await client.api.chatCompletions({ messages: [{ role: "user", content: "What are the key findings?" }], doc_id, }); console.log(response.choices[0].message.content); // 4. Stream a response const stream = await client.api.chatCompletions({ messages: [{ role: "user", content: "Summarize this document" }], doc_id, stream: true, }); for await (const chunk of stream) { process.stdout.write(chunk.choices[0]?.delta?.content ?? ""); } ``` -------------------------------- ### GET https://api.pageindex.ai/doc/{doc_id}/ Source: https://docs.pageindex.ai/api-reference Check processing status and retrieve results for a submitted document. ```APIDOC ## GET https://api.pageindex.ai/doc/{doc_id}/ ### Description Check processing status and (when complete) get the results for a submitted document. ### Method GET ### Endpoint https://api.pageindex.ai/doc/{doc_id}/ ### Parameters #### Path Parameters - **doc_id** (string) - Required - Document ID. #### Query Parameters - **type** (string) - Optional - Result type. Use "tree" for tree structure or "ocr" for OCR results. - **format** (string) - Optional - For OCR results, specify output format. Use "page" (default), "node", or "raw". - **summary** (boolean) - Optional - For tree results, include node summary for each node in response. Default is false. ### Response #### Success Response (200) - **doc_id** (string) - Document identifier. - **status** (string) - Processing status. - **retrieval_ready** (boolean) - Indicates if results are ready. - **result** (array) - The processed document data. ### Response Example { "doc_id": "pi-abc123def456", "status": "completed", "retrieval_ready": true, "result": [] } ``` -------------------------------- ### Response Formats Source: https://docs.pageindex.ai/api-reference Examples of non-streaming JSON responses and streaming Server-Sent Events (SSE) responses. ```json { "id": "chat_completion_id", "choices": [ { "message": { "role": "assistant", "content": "The key findings are..." }, "finish_reason": "end_turn" } ], "usage": { "prompt_tokens": 1234, "completion_tokens": 567, "total_tokens": 1801 } } ``` ```text data: {"choices":[{"delta":{"content":"The"}}]} data: {"choices":[{"delta":{"content":" key"}}]} data: {"choices":[{"delta":{"content":" findings"}}]} ... data: [DONE] ``` -------------------------------- ### GET https://api.pageindex.ai/docs Source: https://docs.pageindex.ai/api-reference Retrieve a paginated list of all documents, ordered by creation date (newest first). ```APIDOC ## GET https://api.pageindex.ai/docs ### Description Retrieve a paginated list of all documents, ordered by creation date (newest first). ### Method GET ### Endpoint https://api.pageindex.ai/docs ### Parameters #### Query Parameters - **limit** (int) - Optional - Maximum number of documents to return (1-100). Default: 50. - **offset** (int) - Optional - Number of documents to skip for pagination. Default: 0. ### Response #### Success Response (200) - **documents** (array) - List of document objects - **total** (int) - Total count of documents - **limit** (int) - Limit applied - **offset** (int) - Offset applied #### Response Example { "documents": [ { "id": "pi-abc123def456", "name": "research_paper.pdf", "description": "Machine Learning Research Paper", "status": "completed", "createdAt": "2024-01-15T10:30:00.000Z", "pageNum": 42 } ], "total": 25, "limit": 10, "offset": 0 } ``` -------------------------------- ### Download PDF and Initialize PageIndex Client Source: https://docs.pageindex.ai/cookbook/agentic-vectorless-rag-pageindex Downloads a PDF file if it does not exist locally and initializes the PageIndexLocalClient for vectorless RAG. ```python # Download PDF if needed if not PDF_PATH.exists(): print(f"Downloading {PDF_URL} ...") PDF_PATH.parent.mkdir(parents=True, exist_ok=True) with requests.get(PDF_URL, stream=True, timeout=30) as r: r.raise_for_status() with open(PDF_PATH, "wb") as f: for chunk in r.iter_content(chunk_size=8192): if chunk: f.write(chunk) print("Download complete.\n") # Setup: local mode — no PageIndex API key needed, your LLM key does the work client = PageIndexLocalClient(storage_path=str(STORAGE_PATH)) ``` -------------------------------- ### Get document tree structure Source: https://docs.pageindex.ai/sdk/documents Retrieves the document tree, checking for completion status before accessing the result. ```python tree_result = client.get_tree(doc_id) if tree_result.get("status") == "completed": print("PageIndex Tree Structure:", tree_result.get("result")) ``` -------------------------------- ### Initialize PageIndex Client Source: https://docs.pageindex.ai/cookbook/vectorless-rag-pageindex Configure the PageIndex client with your API key. ```python from pageindex import PageIndexClient import pageindex.utils as utils # Get your PageIndex API key from https://dash.pageindex.ai/api-keys PAGEINDEX_API_KEY = "YOUR_PAGEINDEX_API_KEY" pi_client = PageIndexClient(api_key=PAGEINDEX_API_KEY) ```