OkraPDF
Upload a PDF, get an API. Extract tables, ask questions, get structured JSON — via MCP, CLI, or HTTP.
Designed for subagents. Every document is its own stateless endpoint. Fire off parallel queries to different documents — no shared state, no locks, no ordering issues. Ideal as a tool inside agent loops (Claude, GPT, custom orchestrators).
Setup
MCP (Claude Code, Cursor, OpenCode)
Add to ~/.claude/mcp.json or .cursor/mcp.json:
CODEBLOCK0
CLI
CODEBLOCK1
HTTP
All endpoints use https://api.okrapdf.com with header Authorization: Bearer $OKRA_API_KEY.
Get a free API key at okrapdf.com (Settings > API Keys).
Upload a PDF
CLI
CODEBLOCK2
Options: -o json|markdown|table, --processor, --tables-only, --text-only, -d <dir> (agentic workspace), -q (quiet, for piping)
MCP
CODEBLOCK3
Parameters: url (required), wait (default: true), document_id (optional), page_images (none/cover/lazy), INLINECODE17
HTTP
CODEBLOCK4
Response: {"document_id": "doc-abc123", "phase": "extracting", "pages_total": 42}
Check Status
CLI
CODEBLOCK5
MCP
CODEBLOCK6
HTTP
CODEBLOCK7
Response: INLINECODE19
Documents must reach phase: "complete" before reading/asking. Use wait: true on upload (MCP) or poll status.
Read Content
CLI
CODEBLOCK8
MCP
CODEBLOCK9
INLINECODE22 accepts: doc-abc123, arxiv:2307.09288, or https://arxiv.org/pdf/2307.09288.
HTTP
# Full markdown
curl https://api.okrapdf.com/v1/documents/doc-abc123/full.md \
-H "Authorization: Bearer $OKRA_API_KEY"
# Specific page
curl "https://api.okrapdf.com/v1/documents/doc-abc123/pages/3" \
-H "Authorization: Bearer $OKRA_API_KEY"
# All pages as JSON
curl https://api.okrapdf.com/v1/documents/doc-abc123/pages \
-H "Authorization: Bearer $OKRA_API_KEY"
Ask Questions
CLI
CODEBLOCK11
MCP
CODEBLOCK12
Returns answer with page citations (page number + supporting snippet).
HTTP (OpenAI-compatible)
CODEBLOCK13
Supports "stream": true for SSE streaming.
Extract Structured Data
CLI
CODEBLOCK14
MCP
CODEBLOCK15
HTTP
curl -X POST https://api.okrapdf.com/document/doc-abc123/chat/completions \
-H "Authorization: Bearer $OKRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "Extract all line items"}],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "invoice",
"schema": {
"type": "object",
"properties": {
"line_items": {"type": "array", "items": {"type": "object", "properties": {"description": {"type": "string"}, "amount": {"type": "number"}}}},
"total": {"type": "number"}
}
},
"strict": true
}
},
"stream": false
}'
Tables and Entities
CLI
CODEBLOCK17
HTTP
curl https://api.okrapdf.com/v1/documents/doc-abc123/entities/tables \
-H "Authorization: Bearer $OKRA_API_KEY"
curl https://api.okrapdf.com/v1/documents/doc-abc123/entities \
-H "Authorization: Bearer $OKRA_API_KEY"
Collections
Group documents and query across all of them at once.
Create and manage
CLI:
CODEBLOCK19
HTTP:
CODEBLOCK20
Query across documents
Two modes:
| Mode | Behavior | Best for |
|---|
| INLINECODE27 (default) | Separate completion per document, NDJSON stream | Per-document answers |
| INLINECODE28 |
Single LLM with grep/Python over all docs | Cross-doc search, comparisons |
CLI:
CODEBLOCK21
HTTP (fanout):
CODEBLOCK22
Response (NDJSON):
CODEBLOCK23
HTTP (sandbox):
CODEBLOCK24
Export
# NDJSON stream
curl -N "https://api.okrapdf.com/v1/collections/col-xxx/export?format=markdown" \
-H "Authorization: Bearer $OKRA_API_KEY"
# Zip archive
curl -L "https://api.okrapdf.com/v1/collections/col-xxx/export?format=zip" \
-H "Authorization: Bearer $OKRA_API_KEY" -o collection.zip
Exports
CODEBLOCK26
Page Images
Deterministic, CDN-cached URLs:
CODEBLOCK27
Document Management
CLI
CODEBLOCK28
HTTP
curl "https://api.okrapdf.com/v1/documents?limit=20" -H "Authorization: Bearer $OKRA_API_KEY"
Subagent & Parallel Patterns
OkraPDF is built for agent-to-agent use. Each document is an isolated Durable Object with its own SQLite — queries to different documents never contend. Run them in parallel freely.
As tools inside an agent loop
Map each document to a callable tool. The orchestrating agent picks which docs to query:
CODEBLOCK30
Fan-out: same question across N documents
CODEBLOCK31
CODEBLOCK32
CODEBLOCK33
MCP subagent pattern (Claude Code)
When Claude Code spawns subagents, each can independently call OkraPDF MCP tools:
CODEBLOCK34
When to use which pattern
| Pattern | Best for |
|---|
| MCP tools | Agent picks which docs to query dynamically |
SDK Promise.all |
You know the doc set upfront, want max parallelism |
|
Collections query | Same question across a predefined group, server handles fan-out |
|
okra chat --doc | Quick CLI comparison of 2-5 docs |
Piping and Scripting
CODEBLOCK35
Available Processors
| Processor | Best For | Speed |
|---|
| textlayer | Native PDFs with selectable text | Fast |
| llamaparse |
Complex layouts, mixed content | Medium |
| unstructured | General purpose | Medium |
| azure-di | Forms, invoices, receipts | Medium |
| docai | High-accuracy OCR | Slow |
| gemini | Vision-based extraction | Medium |
| qwen | Open-source VLM extraction | Medium |
Error Codes
| Status | Meaning |
|---|
| 202 | Accepted, processing async |
| 400 |
Bad request |
| 401 | Missing or invalid API key |
| 404 | Document not found |
| 409 | Conflict (document exists) |
| 429 | Rate limited |
Links
OkraPDF
上传PDF,获取API。提取表格、提问、获取结构化JSON——通过MCP、CLI或HTTP实现。
专为子代理设计。 每个文档都是独立无状态端点。可并行向不同文档发起查询——无共享状态、无锁、无顺序问题。非常适合作为代理循环(Claude、GPT、自定义编排器)中的工具。
设置
MCP(Claude Code、Cursor、OpenCode)
添加到 ~/.claude/mcp.json 或 .cursor/mcp.json:
json
{
mcpServers: {
okra-pdf: {
type: url,
url: https://api.okrapdf.com/mcp,
headers: { Authorization: Bearer YOURAPIKEY }
}
}
}
CLI
bash
npm install -g okrapdf
okra auth set-key YOURAPIKEY
HTTP
所有端点均使用 https://api.okrapdf.com,并携带请求头 Authorization: Bearer $OKRAAPIKEY。
在 okrapdf.com 获取免费API密钥(设置 > API密钥)。
上传PDF
CLI
bash
okra extract invoice.pdf
okra extract https://arxiv.org/pdf/2307.09288
okra extract report.pdf --processor llamaparse
okra run report.pdf What was total revenue? # 上传+提问一步完成
选项:-o json|markdown|table、--processor、--tables-only、--text-only、-d
(代理工作区)、-q(静默模式,用于管道传输)
MCP
upload_document(url: https://example.com/report.pdf)
upload_document(url: https://arxiv.org/pdf/2307.09288, wait: true)
uploaddocument(url: https://example.com/invoice.pdf, pageimages: lazy)
参数:url(必填)、wait(默认:true)、documentid(可选)、pageimages(none/cover/lazy)、processor
HTTP
bash
从URL上传
curl -X POST https://api.okrapdf.com/v1/documents \
-H Authorization: Bearer $OKRAAPIKEY \
-H Content-Type: application/json \
-d {url: https://arxiv.org/pdf/2307.09288}
从文件上传
curl -X POST https://api.okrapdf.com/v1/documents \
-H Authorization: Bearer $OKRAAPIKEY \
-F file=@report.pdf -F page_images=cover
响应:{documentid: doc-abc123, phase: extracting, pagestotal: 42}
检查状态
CLI
bash
okra status doc-abc123
MCP
getdocumentstatus(document_id: doc-abc123)
HTTP
bash
curl https://api.okrapdf.com/v1/documents/doc-abc123/status \
-H Authorization: Bearer $OKRAAPIKEY
响应:{phase: complete, pagecount: 42, totalnodes: 318}
文档必须达到 phase: complete 状态后才能读取或提问。上传时使用 wait: true(MCP)或轮询状态。
读取内容
CLI
bash
okra read doc-abc123
okra page get doc-abc123 1
okra toc doc-abc123
okra tree doc-abc123
okra search doc-abc123 revenue
MCP
readdocument(documentid: doc-abc123)
readdocument(documentid: doc-abc123, pages: 1-5)
readdocument(documentid: arxiv:2307.09288)
document_id 接受:doc-abc123、arxiv:2307.09288 或 https://arxiv.org/pdf/2307.09288。
HTTP
bash
完整Markdown
curl https://api.okrapdf.com/v1/documents/doc-abc123/full.md \
-H Authorization: Bearer $OKRAAPIKEY
指定页面
curl https://api.okrapdf.com/v1/documents/doc-abc123/pages/3 \
-H Authorization: Bearer $OKRAAPIKEY
所有页面(JSON格式)
curl https://api.okrapdf.com/v1/documents/doc-abc123/pages \
-H Authorization: Bearer $OKRAAPIKEY
提问
CLI
bash
okra chat doc-abc123
okra chat send doc-abc123 -m What are the key findings?
MCP
askdocument(documentid: doc-abc123, question: What was total revenue in 2024?)
返回带页面引用的答案(页码+支持片段)。
HTTP(兼容OpenAI)
bash
curl -X POST https://api.okrapdf.com/document/doc-abc123/chat/completions \
-H Authorization: Bearer $OKRAAPIKEY \
-H Content-Type: application/json \
-d {
messages: [{role: user, content: What was total revenue in 2024?}],
stream: false
}
支持 stream: true 实现SSE流式传输。
提取结构化数据
CLI
bash
okra extract report.pdf -o json -q | jq .entities[] | select(.type == table)
MCP
extract_data(
document_id: doc-abc123,
prompt: Extract all line items from this invoice,
json_schema: {
type: object,
properties: {
line_items: {
type: array,
items: {
type: object,
properties: {
description: {type: string},
quantity: {type: number},
unit_price: {type: number},
total: {type: number}
}
}
},
grand_total: {type: number}
}
}
)
HTTP
bash
curl -X POST https://api.okrapdf.com/document/doc-abc123/chat/completions \
-H Authorization: Bearer $OKRAAPIKEY \
-H Content-Type: application/json \
-d {
messages: [{role: user, content: Extract all line items}],
response_format: {
type: json_schema,
json_schema: {
name: invoice,
schema: {
type: object,
properties: {
line_items: {type: array, items: {type: object, properties: {description: {type: string}, amount: {type: number}}}},
total: {type: number}
}
},
strict: true
}
},
stream: false
}
表格与实体
CLI
bash
okra tables doc-abc123
okra tables get doc-abc123 table-0
okra entities list doc-abc123
okra entities images doc-abc123
okra query doc-abc123 table:has(revenue)
HTTP
bash
curl https://api.okrapdf.com/v1/documents/doc-abc123/entities/tables \
-H Authorization: Bearer $OKRAAPIKEY
curl https://api.okrapdf.com/v1/documents/doc-abc123/entities \
-H Authorization: Bearer $OKRAAPIKEY
集合
将文档分组并一次性跨所有文档查询。
创建与管理
CLI:
bash
okra collections create Q4 Earnings -d Quarterly filings --docs doc-abc123,doc-def456
okra collections list # 或:okra col ls
okra collections show Q4 Earnings
okra collections add Q4 Earnings doc-ghi789
okra collections remove Q4 Earnings doc-abc123
okra collections delete Q4 Earnings
HTTP:
bash
创建时包含种子文档
curl -X POST https://api.okrapdf.com/v1/collections \
-H Authorization: Bearer $OKRAAPIKEY \
-H Content-Type: application/json \
-d {name: Q4 Earnings, document_ids: [doc-abc123, doc-def456]}
添加文档
curl