Preview — The sandbox API is under active development. Method signatures may change.
For production use, prefer generate(), stream(), and query() directly.
Overview
The sandbox() method creates a scoped tool set for AI agents. Documents are accessed through defined capabilities — agents can only read, query, or ask questions about documents you explicitly allow.
Compatible with MCP (Model Context Protocol) and any agent framework that accepts tool definitions.
Quick start
import { createOkra } from '@okrapdf/runtime';
const okra = createOkra({ apiKey: process.env.OKRA_API_KEY });
const sandbox = okra.sandbox({
docs: ['ocr-abc123', 'ocr-def456'],
capabilities: ['read', 'query', 'complete'],
});
// MCP-compatible tool definitions
const tools = sandbox.asMcp();
Capabilities
| Capability | Tools Created | What It Allows |
|---|
read | get_pages, get_entities | Read page content and extracted entities |
query | query_sql | Run read-only SQL against document data |
complete | ask_document | Ask natural-language questions |
// Read-only agent (most restrictive)
const readOnly = okra.sandbox({
docs: [docId],
capabilities: ['read'],
});
// Tools: get_pages, get_entities
// Full access agent
const full = okra.sandbox({
docs: [docId],
capabilities: ['read', 'query', 'complete'],
});
// Tools: get_pages, get_entities, query_sql, ask_document
const sandbox = okra.sandbox({
docs: [docId],
capabilities: ['read', 'query'],
});
// Read pages
const readTool = sandbox.tools.find(t => t.name === 'get_pages')!;
const pages = await readTool.execute({ document_id: docId });
// SQL query
const sqlTool = sandbox.tools.find(t => t.name === 'query_sql')!;
const result = await sqlTool.execute({
document_id: docId,
sql: 'SELECT type, COUNT(*) as count FROM nodes GROUP BY type',
});
// Get entities
const entTool = sandbox.tools.find(t => t.name === 'get_entities')!;
const tables = await entTool.execute({
document_id: docId,
type: 'table',
});
Scope enforcement
Agents can only access documents in the docs array. Attempts to access other documents throw:
const sandbox = okra.sandbox({
docs: ['ocr-abc123'],
capabilities: ['read'],
});
const tool = sandbox.tools.find(t => t.name === 'get_pages')!;
// OK
await tool.execute({ document_id: 'ocr-abc123' });
// Throws: "Document ocr-other not in sandbox scope"
await tool.execute({ document_id: 'ocr-other' });
Use with Claude / LangChain / any agent
The asMcp() output follows the MCP tool definition spec. Pass it to any framework:
const tools = okra.sandbox({
docs: [docId],
capabilities: ['read', 'query', 'complete'],
}).asMcp();
// Each tool has: name, description, parameters (JSON Schema), execute
for (const tool of tools) {
console.log(`${tool.name}: ${tool.description}`);
}