Extend transforms PDFs, images, Office files, and spreadsheets into structured data by extracting fields, tables, and line items; classifying document types; splitting document bundles; and filling PDF forms. Build reusable processors and workflows, evaluate extraction accuracy, and run document-processing jobs at scale.
Encrypted at rest, isolated from the model
Resolved from an AES-256-GCM vault at the moment of the call and attached to the request — the model never sees the secrets.
Try asking
Extract specific structured values (totals, line items, dates, names, tables) from a document (extract group) using a saved extractor, an inline JSON Schema, or schema-less inference. If the user says "OCR" but wants specific values out, use this tool; for the raw text/markdown of the pages use parse_document instead. Provide exactly one of extractor or config, or omit both for schema-less inference (guided by config.extractionRules when config has no schema; not usable with package). If a saved extractor turns out not to exist, rerun THIS tool without the extractor (schema-less) — do not fall back to parse_document for value extraction. For one merged result across 2-50 related documents, pass package instead of file. detail: "full" returns per-field source citations and confidence — the only way to prove where a value came from (provenance); parsing cannot cite. Async: a status: "running" result with a runId is not an error — resume with get_extract_run passing that runId, the same workspaceId and environment, and wait: true, repeating until the status is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Output shape (output.value, per-field metadata, confidence, citations) is documented at https://docs.extend.ai/extraction/response-format.md (get_documentation).
Create a saved, reusable extractor (extract group). Three starting points, mutually exclusive: config (inline schema — call get_documentation with https://docs.extend.ai/extraction/schema.md BEFORE writing one by hand), cloneExtractorId (copy another extractor's draft config), or generate (Extend writes the schema from 1-5 sample documents plus optional instructions; no docs needed); name alone creates an empty draft. The draft is the only mutable surface — edit it with update_extractor, freeze it with publish_extractor_version, run it with extract_data.
Update an extractor's mutable draft (extract group): rename it and/or replace the draft config (hand-editing the schema? call get_documentation with https://docs.extend.ai/extraction/schema.md first). Published versions are immutable and unaffected — runs pinned to them keep working.
Get an extractor with its draft config, or one specific version's config via version (extract group). Use list_extractors to discover IDs.
List the workspace's extractors, newest first (extract group). Fetch a specific one's config with get_extractor. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
List an extractor's published (immutable) versions (extract group). Fetch one version's config with get_extractor. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Publish the extractor's current draft config as a new immutable semver version ("1.2"-style) that runs and evaluations can pin (extract group). releaseType picks the major or minor bump; pass config to publish that config instead of the draft. Published versions never change — keep iterating on the draft.
Get the state and output of an extract run (extract group) — resume a status: "running" run or inspect a failed one. wait: true blocks until terminal or wait-budget expiry. While status is "running", call again with wait: true (same workspaceId and environment) until it is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Output shape is documented at https://docs.extend.ai/extraction/response-format.md (get_documentation).
List recent extract runs, newest first (extract group). Filter rather than paginate: status, extractorId, batchId, fileNameContains. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Cancel a queued or in-flight extract run (extract group). Best-effort: a run already finishing may still complete.
Permanently delete an extract run and its stored outputs (extract group). Cannot be undone.
Submit up to 1,000 documents as one batch of extract runs (extract group) against a saved processor. Returns a batchId immediately; runs execute async — poll aggregate status with get_extract_batch (wait: true), and fetch individual results with the extract-run list tool filtered by batchId.
Get the aggregate status of an extract batch (extract group) submitted by run_extract_batch. wait: true polls until terminal. Statuses: PENDING, PROCESSING, PROCESSED, FAILED, CANCELLED. While non-terminal, call again with wait: true; do not re-submit the batch. Individual results: list_extract_runs filtered by batchId (status: "FAILED" for per-run failure reasons). Batch semantics: https://docs.extend.ai/general/batch-processing.md (get_documentation).
Categorize a document into one of a set of types, e.g. MSA vs SOW vs NDA (classify group), using a saved classifier or an inline list of classifications. Provide exactly one of classifier or config. Inline config.classifications must include one entry with type: "other" as the fallback and unique ids per entry. Returns the winning type with a confidence score. Async: a status: "running" result with a runId is not an error — resume with get_classify_run passing that runId, the same workspaceId and environment, and wait: true, repeating until the status is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Output shape is documented at https://docs.extend.ai/classification/response-format.md (get_documentation).
Create a saved, reusable classifier (classify group). Start from config (inline classifications list — call get_documentation with https://docs.extend.ai/classification/configuration.md before hand-authoring one) or cloneClassifierId (copy another classifier's draft config) — mutually exclusive; name alone creates an empty draft. There is no generate mode (extractors only). The draft is the only mutable surface — edit it with update_classifier, freeze it with publish_classifier_version, run it with classify_document.
Update a classifier's mutable draft (classify group): rename it and/or replace the draft config (hand-editing it? call get_documentation with https://docs.extend.ai/classification/configuration.md first). Published versions are immutable and unaffected — runs pinned to them keep working.
Get a classifier with its draft config, or one specific version's config via version (classify group). Use list_classifiers to discover IDs.
List the workspace's classifiers, newest first (classify group). Fetch a specific one's config with get_classifier. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
List a classifier's published (immutable) versions (classify group). Fetch one version's config with get_classifier. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Publish the classifier's current draft config as a new immutable semver version ("1.2"-style) that runs and evaluations can pin (classify group). releaseType picks the major or minor bump; pass config to publish that config instead of the draft. Published versions never change — keep iterating on the draft.
Get the state and output of a classify run (classify group) — resume a status: "running" run or inspect a failed one. wait: true blocks until terminal or wait-budget expiry. While status is "running", call again with wait: true (same workspaceId and environment) until it is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Output shape is documented at https://docs.extend.ai/classification/response-format.md (get_documentation).
List recent classify runs, newest first (classify group). Filter rather than paginate: status, classifierId, batchId, fileNameContains. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Cancel a queued or in-flight classify run (classify group). Best-effort: a run already finishing may still complete.
Permanently delete a classify run and its stored outputs (classify group). Cannot be undone.
Submit up to 1,000 documents as one batch of classify runs (classify group) against a saved processor. Returns a batchId immediately; runs execute async — poll aggregate status with get_classify_batch (wait: true), and fetch individual results with the classify-run list tool filtered by batchId.
Get the aggregate status of a classify batch (classify group) submitted by run_classify_batch. wait: true polls until terminal. Statuses: PENDING, PROCESSING, PROCESSED, FAILED, CANCELLED. While non-terminal, call again with wait: true; do not re-submit the batch. Individual results: list_classify_runs filtered by batchId (status: "FAILED" for per-run failure reasons). Batch semantics: https://docs.extend.ai/general/batch-processing.md (get_documentation).
Divide a combined file, e.g. a scanned bundle of invoices or a merged PDF of statements, into typed segments with page ranges (split group), using a saved splitter or inline split classifications. Also the right FIRST step to locate one document or section inside a larger bundle — split, then parse/extract only the relevant segment instead of processing the whole file. Provide exactly one of splitter or config; inline config.splitClassifications needs a type: "other" entry. Each split includes startPage/endPage and, when Extend materializes child files, a fileId usable directly in other tools. Raw text input is not supported — splitting is page-based. Async: a status: "running" result with a runId is not an error — resume with get_split_run passing that runId, the same workspaceId and environment, and wait: true, repeating until the status is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Output shape is documented at https://docs.extend.ai/splitting/response-format.md (get_documentation).
Create a saved, reusable splitter (split group). Start from config (inline split classifications — call get_documentation with https://docs.extend.ai/splitting/configuration.md before hand-authoring one) or cloneSplitterId (copy another splitter's draft config) — mutually exclusive; name alone creates an empty draft. The draft is the only mutable surface — edit it with update_splitter, freeze it with publish_splitter_version, run it with split_document.
Update a splitter's mutable draft (split group): rename it and/or replace the draft config (hand-editing it? call get_documentation with https://docs.extend.ai/splitting/configuration.md first). Published versions are immutable and unaffected — runs pinned to them keep working.
Get a splitter with its draft config, or one specific version's config via version (split group). Use list_splitters to discover IDs.
List the workspace's splitters, newest first (split group). Fetch a specific one's config with get_splitter. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
List a splitter's published (immutable) versions (split group). Fetch one version's config with get_splitter. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Publish the splitter's current draft config as a new immutable semver version ("1.2"-style) that runs and evaluations can pin (split group). releaseType picks the major or minor bump; pass config to publish that config instead of the draft. Published versions never change — keep iterating on the draft.
Get the state and output of a split run (split group) — resume a status: "running" run or inspect a failed one. wait: true blocks until terminal or wait-budget expiry. While status is "running", call again with wait: true (same workspaceId and environment) until it is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Output shape is documented at https://docs.extend.ai/splitting/response-format.md (get_documentation).
List recent split runs, newest first (split group). Filter rather than paginate: status, splitterId, batchId, fileNameContains. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Cancel a queued or in-flight split run (split group). Best-effort: a run already finishing may still complete.
Permanently delete a split run and its stored outputs (split group). Cannot be undone.
Submit up to 1,000 documents as one batch of split runs (split group) against a saved processor. Returns a batchId immediately; runs execute async — poll aggregate status with get_split_batch (wait: true), and fetch individual results with the split-run list tool filtered by batchId.
Get the aggregate status of a split batch (split group) submitted by run_split_batch. wait: true polls until terminal. Statuses: PENDING, PROCESSING, PROCESSED, FAILED, CANCELLED. While non-terminal, call again with wait: true; do not re-submit the batch. Individual results: list_split_runs filtered by batchId (status: "FAILED" for per-run failure reasons). Batch semantics: https://docs.extend.ai/general/batch-processing.md (get_documentation).
Convert a document (PDF, image, Office doc, spreadsheet) into clean structured text — markdown by default (parse group). Right when the user wants the content of the pages ("OCR this", "what does this document say", feed text to another step); for specific field values — or when values need source citations/provenance — use extract_data instead. No saved resource needed. Use pageRange to return only the pages of interest; full output of a long document is large, and maxChars caps it. To work on one section of a bundle, split_document it first and parse the relevant segment's fileId. rawBlocks returns block-level structure (tables, figures, coordinates). Async: a status: "running" result with a runId is not an error — resume with get_parse_run passing that runId, the same workspaceId and environment, and wait: true, repeating until the status is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Parse runs cannot be cancelled. truncated: true means the markdown was cut at maxChars — re-call with pageRange for the pages you need, or rawBlocks: true for block-level output. pageRange/maxChars/rawBlocks are not remembered between calls; pass them again when resuming with get_parse_run. Output shape is documented at https://docs.extend.ai/parsing/response-format.md (get_documentation).
Get the state and output of a parse run (parse group) — resume a status: "running" run or inspect a failed one. wait: true blocks until terminal or wait-budget expiry. Supports pageRange/maxChars/rawBlocks output slicing as in parse_document. While status is "running", call again with wait: true (same workspaceId and environment) until it is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. truncated: true means the markdown was cut at maxChars — re-call with pageRange for the pages you need, or rawBlocks: true for block-level output. pageRange/maxChars/rawBlocks are not remembered between calls; pass them again when resuming with get_parse_run. Output shape is documented at https://docs.extend.ai/parsing/response-format.md (get_documentation).
List recent parse runs, newest first (parse group). Filter rather than paginate: status, batchId, fileNameContains. Results come back in the upstream default order — this endpoint does not support sorting. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Permanently delete a parse run and its stored outputs (parse group). Cannot be undone.
Submit up to 1,000 documents as one batch of parse runs (parse group); no saved processor needed — an optional inline config applies to every run. Returns a batchId immediately; poll aggregate status with get_parse_batch and fetch individual results with list_parse_runs filtered by batchId.
Get the aggregate status of a parse batch (parse group) submitted by run_parse_batch. wait: true polls until terminal. Statuses: PENDING, PROCESSING, PROCESSED, FAILED, CANCELLED. While non-terminal, call again with wait: true; do not re-submit the batch. Individual results: list_parse_runs filtered by batchId (status: "FAILED" for per-run failure reasons). Batch semantics: https://docs.extend.ai/general/batch-processing.md (get_documentation).
Start a run of a deployed multi-step workflow on a document (workflows group; not runnable until a version is deployed, or pass version "draft"). Workflow runs commonly take minutes to hours. Async: a status: "running" result with a runId is not an error — resume with get_workflow_run passing that runId, the same workspaceId and environment, and wait: true, repeating until the status is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Statuses: PROCESSED; FAILED (retryable: true means the failureReason is usually transient and one retry is reasonable); NEEDS_REVIEW (paused for a human reviewer in the dashboard — share dashboardUrl with the user and re-check the run after they finish; do not retry or re-submit); REJECTED (a reviewer rejected the run in the dashboard — final; dashboardUrl has their reasoning); CANCELLED. For one merged run over 2-50 related files, pass package instead of file. outputs injects pre-computed results for specific extractors/classifiers/splitters so the workflow skips recomputing them (not allowed with package).
Create a workflow — a multi-step document pipeline (workflows group): parse → extract/classify/split → validations → human review. name alone creates an empty draft; steps builds the graph up front (call get_documentation with https://docs.extend.ai/workflows/configuring-workflows.md before hand-authoring a step graph). The draft is the only mutable surface — edit with update_workflow, freeze with deploy_workflow_version, run with run_workflow.
Update a workflow's mutable draft (workflows group): rename it and/or replace the entire draft step graph (hand-editing steps? call get_documentation with https://docs.extend.ai/workflows/configuring-workflows.md first). Deployed versions are immutable and unaffected — runs pinned to them keep working.
Get a workflow with its draft step graph, or one specific deployed version's steps via version (workflows group). Use list_workflows to discover IDs.
List the workspace's workflows, newest first (workflows group). Fetch a specific one's step graph with get_workflow. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
List a workflow's deployed (immutable) versions — integer deploy numbers with optional names (workflows group). Fetch one version's steps with get_workflow. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Deploy the workflow's current draft as a new immutable version (workflows group). Unlike extractor/classifier/splitter publishing there is NO releaseType — workflow versions are integer deploy numbers ("1", "2", ...) with an optional display name referenced at run time. Pass steps to deploy that graph instead of the draft. Deployed versions never change — keep iterating on the draft.
Get the state and output of a workflow run (workflows group) — resume a status: "running" run or inspect a failed one. wait: true blocks until terminal or wait-budget expiry. Workflow runs commonly take minutes to hours — repeated running responses are normal. While status is "running", call again with wait: true (same workspaceId and environment) until it is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Statuses: PROCESSED; FAILED (retryable: true means the failureReason is usually transient and one retry is reasonable); NEEDS_REVIEW (paused for a human reviewer in the dashboard — share dashboardUrl with the user and re-check the run after they finish; do not retry or re-submit); REJECTED (a reviewer rejected the run in the dashboard — final; dashboardUrl has their reasoning); CANCELLED.
List recent workflow runs, newest first (workflows group). Filter rather than paginate: status, workflowId, batchId, fileNameContains. Workflow batches have no batch-get endpoint — track them here via batchId. NEEDS_REVIEW runs are paused for human review. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Cancel a queued or in-flight workflow run (workflows group). Best-effort: a run already finishing may still complete.
Permanently delete a workflow run and its stored outputs (workflows group). Cannot be undone.
Submit up to 1,000 documents as one batch of workflow runs (workflows group). Returns a batchId immediately; workflow batches have NO batch-get endpoint — track progress with list_workflow_runs filtered by batchId; do not re-submit the documents.
Fill form fields in a PDF and return the edited file (edit group). Values come from instructions (free-form prose, e.g. "name is Acme Corp; date is 2026-04-15") and/or schema (an edit schema from detect_form_fields with extend_edit:value set per field; extend_edit:image with an image_url for signature images). The document passed here must be the TARGET form, not the source you read values from — parse or extract the source first, then fill. Before authoring a schema fill by hand, call get_documentation with https://docs.extend.ai/editing/configuration.md and follow it. templateId runs a saved edit template instead of file; its stored schema/instructions apply unless overridden below. Output is a pointer { id, presignedUrl } to the filled PDF; the URL expires in ~15 minutes (re-fetch with get_file). Async: a status: "running" result with a runId is not an error — resume with get_edit_run passing that runId, the same workspaceId and environment, and wait: true, repeating until the status is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Output shape is documented at https://docs.extend.ai/editing/response-format.md (get_documentation).
Detect the fillable fields in a PDF form and return an edit schema (edit group): each property is a detected field with its type (text/checkbox/radio/dropdown/signature/table), page index, and bounding box. Use it to see what a form asks for, or as the scaffold for a structured fill — set extend_edit:value on each field and pass the populated schema to edit_pdf. Pass inputSchema to re-run detection against an existing schema (mapping mode) — for the edit-schema rules, call get_documentation with https://docs.extend.ai/editing/configuration.md first. Async: a status: "running" result with a runId is not an error — resume with get_form_detection_run passing that runId, the same workspaceId and environment, and wait: true, repeating until the status is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Output shape is documented at https://docs.extend.ai/editing/response-format.md (get_documentation).
Get the state and output of an edit run (edit group) — resume a status: "running" run or inspect a failed one. wait: true blocks until terminal or wait-budget expiry. Edit runs have no list endpoint — keep the run ID. While status is "running", call again with wait: true (same workspaceId and environment) until it is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. output.editedFile.presignedUrl expires in ~15 minutes (re-fetch with get_file). Output shape is documented at https://docs.extend.ai/editing/response-format.md (get_documentation).
Get the state and output of a form detection run (edit group) — resume a status: "running" run or inspect a failed one. wait: true blocks until terminal or wait-budget expiry. Form detection runs have no list endpoint — keep the run ID. While status is "running", call again with wait: true (same workspaceId and environment) until it is terminal; never re-submit the document. On UNAUTHORIZED or NOT_FOUND, re-call get_me for the granted targets. Output shape is documented at https://docs.extend.ai/editing/response-format.md (get_documentation).
Permanently delete an edit run and its stored outputs (edit group). Cannot be undone.
Upload a file from the user's computer (files group). Returns a dashboard upload link; uploaded file IDs only become available after the user completes the upload in their browser, so the link should be surfaced to the user before calling get_file_upload with the returned uploadId. The link expires at expiresAt and cannot be re-fetched — call this tool again for a fresh one. Documents already at a public https:// URL can be passed to tools directly without uploading.
Get the status and uploaded file ids of an upload link created by upload_file (files group). Default is one instant status check; wait: true blocks until the user finishes or the wait budget runs out. Statuses: pending (the user has not completed the upload — call again with wait: true once they say they are done); completed (files lists the uploaded file ids, usable as { "id": "file_..." } inputs in any file-accepting tool); expired or cancelled (the link is no longer usable — call upload_file for a fresh one).
Get a file's metadata and a fresh presigned download URL — expires in ~15 minutes, re-call to refresh (files group). Set contents to also return parsed text; contents: null means "not parsed yet", not an error (run parse_document first). Split-produced child files carry parentSplit (source file, page range) in metadata.
List files in the workspace, newest first (files group). Filter with nameContains rather than paginating broadly. Use get_file for a download URL or parsed contents. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Permanently delete an uploaded file from Extend (files group). Runs that already processed the file keep their outputs, but the file's bytes and parsed contents are gone. This cannot be undone.
Register an HTTPS URL to receive Extend events (webhooks group). CRITICAL: the response's signingSecret is shown ONLY on this call — store it immediately; it cannot be retrieved later. Receivers verify HMAC-SHA256 of "v0:{timestamp}:{body}" against it (reject timestamps older than 5 minutes). enabledEvents here are workspace-global and NOT every event type is valid globally: resource-run events such as workflow_run.completed are rejected here and must instead be scoped to a specific resource via create_webhook_subscription (create the endpoint with enabledEvents [], then subscribe it to the workflow/extractor/etc.). Setting up webhooks by hand? Call get_documentation with https://docs.extend.ai/webhooks/configuration.md first.
List the workspace's webhook endpoints with their global event lists (webhooks group). Signing secrets are never returned here — they are shown once at creation only. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Update a webhook endpoint's URL, name, status (enable/disable deliveries), global event list, or advanced options (webhooks group). The signing secret never changes and is not returned.
Permanently delete a webhook endpoint (webhooks group). This ALSO deletes every subscription attached to it, and deliveries stop immediately. This cannot be undone.
Subscribe an existing webhook endpoint to events from ONE specific extractor, classifier, splitter, or workflow (webhooks group) — deliveries for other resources are unaffected. Use this instead of global enabledEvents when only some resources matter. Configuration rules: call get_documentation with https://docs.extend.ai/webhooks/configuration.md first (event catalog: https://docs.extend.ai/webhooks/events.md).
List resource-scoped webhook subscriptions, filterable by endpoint or by the watched resource (webhooks group). hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Replace a webhook subscription's event list (webhooks group). The endpoint and watched resource cannot change — delete and recreate the subscription for that.
Permanently delete a webhook subscription (webhooks group). The endpoint and its global events are unaffected. This cannot be undone.
Create an evaluation set — a named collection of ground-truth examples scoped to ONE extractor, classifier, or splitter via entityId (evaluations group). The iteration loop: create a set → add items with add_evaluation_items → publish a new version of the resource → run_evaluation against that version → read accuracy metrics with get_evaluation_run. New to evaluations? Call get_documentation with https://docs.extend.ai/evaluation/overview.md first (set authoring in detail: https://docs.extend.ai/evaluation/creating-evaluation-sets.md).
List evaluation sets, optionally scoped to one extractor/classifier/splitter via entityId (evaluations group). There is no get-by-id tool — this list returns full set objects. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Bulk-add ground-truth examples (1-100 per call) to an evaluation set (evaluations group). Each item pairs an already-uploaded file with the output the resource SHOULD produce for it.
List an evaluation set's items — file pairings only; expected outputs are not included in summaries (evaluations group). Item IDs feed update_evaluation_item / delete_evaluation_item and subset runs. hasMore: true means more items exist — prefer narrowing filters over paginating, and pass nextPageToken only when every item is needed.
Replace one evaluation item's expected output (evaluations group). The file pairing cannot change — delete and re-add for that.
Permanently remove one ground-truth item from an evaluation set (evaluations group). Past run metrics are unaffected. This cannot be undone.
Run an evaluation set against a version of its resource and score the results against the ground truth (evaluations group). Async: returns immediately with a bpr_... run ID — poll it with get_evaluation_run (evaluationRunId, wait: true; NOT a get-batch tool, even though the ID looks like a batch), and do not re-submit while it runs. Defaults to the set's resource at its latest published version; pass entity to pin { id, version: "1.2" | "latest" | "draft" }.
Get an evaluation run's status and accuracy metrics — this is the ONLY tool that returns them, not a get-batch tool (evaluations group). An evaluation is an async job: a fresh run reports PROCESSING, so pass wait: true to block until it finishes; if it is still non-terminal afterward, call again with wait: true rather than re-submitting. Metrics by resource type: extractors { accuracy, fieldMetrics per field path — each field has countExpected/countAccurate, and accuracy is aggregated across items, not per-item }; classifiers { accuracy, classificationMetrics with precision/recall/f1 per type }; splitters { precision, recall, f1, split counts }. Terminal statuses: PROCESSED, FAILED, CANCELLED.
Return the connected organization, the credential in use, and the granted workspace + environment ("TEST" or "PRODUCTION") targets — exactly the values the required workspaceId/environment arguments on targeted tools accept. Always available; call this first, and again whenever a tool returns UNAUTHORIZED or NOT_FOUND unexpectedly, or after this connection's access changes — resources live per-workspace.
Fetch an Extend docs page as markdown, live from docs.extend.ai. Pass a URL from a tool description, an error's docUrl, or a search_documentation result. truncated: true means the page was cut at a section boundary to fit the response budget; the returned url has the full page. Always available, no workspace targeting.
Search the Extend documentation. Returns matching pages with URLs — results are pointers, not content: fetch the most relevant with get_documentation. An empty results list means nothing matched; different domain terms (feature names, API field names, product vocabulary) usually do. Always available, no workspace targeting.
One endpoint, the same key, whichever client you use.
~/Library/Application Support/Claude/claude_desktop_config.json (Mac) · %APPDATA%\Claude\claude_desktop_config.json (Windows)
Replace API_KEY with your own key.
Already have an "mcpServers" section in your config? Just add the server entry inside it.
Discovery, routing, credentials, tool scoping and execution logs all happen at the gateway→connections stay ACTIVE with no work from you
Extend MCP runs through a gateway that holds the credentials, scopes the access and records every call.
Managed auth, hosted MCP servers, and every Extend MCP tool your agent needs.
Free to start.