Invoice Data Extraction MCP server
One remote server gives an assistant such as ChatGPT or Claude, or an agent in Claude Code, Codex, Cursor, Hermes, OpenClaw or Gemini CLI, the whole extraction loop as tools: upload the files, submit an extraction with instructions in plain words, wait, answer the questions it asks, read the rows with the Review Needed items and the failed pages beside them, or download a spreadsheet. The tools are the REST API's own operations and every result is the API's own response, so what an agent reads here and what it reads through the API never differ. Why to hand documents here rather than have an agent read them, and how to answer what the extraction asks, is the agent guide.
Connect from ChatGPT or Claude
An assistant that connects by signing in needs no key. Add the server's address, https://mcp.invoicedataextraction.com/mcp, as a custom MCP app in ChatGPT or a custom connector in Claude, on the web or in the desktop app, and the assistant opens the Invoice Data Extraction sign-in page. Sign in, or create an account, and approve the assistant: the connection uses an API key created for it, named after the assistant, on the API page of your account, and its extractions use your credits as they would in the app. Revoking that key ends its access. In ChatGPT, files you attach in the conversation go straight to the extraction (How files get in).
Connect your harness
The server is at https://mcp.invoicedataextraction.com/mcp, over streamable HTTP. A harness that takes a header sends your API key as a bearer token on every request, Authorization: Bearer <key>. Keys are created in the dashboard at https://invoicedataextraction.com/dashboard?view=API; every account includes 50 free pages per month, and no card is needed. The key is a secret: keep it wherever your harness keeps secrets, never in a conversation. The settings below read it from the environment variable INVOICE_DATA_EXTRACTION_API_KEY, the name the skill and the SDK docs use. A store that binds a secret to the hosts it may be sent to binds this one to mcp.invoicedataextraction.com.
The settings below are each harness's own, as its documentation gave them in September 2026. Where your version differs, what it needs is the same: the address, and the key as a bearer header, read from wherever the harness keeps secrets.
Claude Code
claude mcp add --transport http invoice-data-extraction https://mcp.invoicedataextraction.com/mcp \
--header "Authorization: Bearer $INVOICE_DATA_EXTRACTION_API_KEY"
Your shell fills in the key when you run it. To share the server with a project without sharing the key, put it in the project's .mcp.json, where Claude Code expands the variable itself:
{
"mcpServers": {
"invoice-data-extraction": {
"type": "http",
"url": "https://mcp.invoicedataextraction.com/mcp",
"headers": { "Authorization": "Bearer ${INVOICE_DATA_EXTRACTION_API_KEY}" }
}
}
}
Codex, in ~/.codex/config.toml:
[mcp_servers.invoice-data-extraction]
url = "https://mcp.invoicedataextraction.com/mcp"
bearer_token_env_var = "INVOICE_DATA_EXTRACTION_API_KEY"
Cursor, in .cursor/mcp.json for a project or ~/.cursor/mcp.json for every project:
{
"mcpServers": {
"invoice-data-extraction": {
"url": "https://mcp.invoicedataextraction.com/mcp",
"headers": { "Authorization": "Bearer ${env:INVOICE_DATA_EXTRACTION_API_KEY}" }
}
}
}
Hermes, in ~/.hermes/config.yaml, with the key in ~/.hermes/.env:
mcp_servers:
invoice-data-extraction:
url: "https://mcp.invoicedataextraction.com/mcp"
headers:
Authorization: "Bearer ${INVOICE_DATA_EXTRACTION_API_KEY}"
OpenClaw, under mcp.servers in ~/.openclaw/openclaw.json, with the key in ~/.openclaw/.env; name the transport, because OpenClaw assumes SSE without it:
"invoice-data-extraction": {
url: "https://mcp.invoicedataextraction.com/mcp",
transport: "streamable-http",
headers: { Authorization: "Bearer ${INVOICE_DATA_EXTRACTION_API_KEY}" },
}
Gemini CLI
gemini mcp add --transport http --header "Authorization: Bearer $INVOICE_DATA_EXTRACTION_API_KEY" \
invoice-data-extraction https://mcp.invoicedataextraction.com/mcp
Any other client that speaks MCP over streamable HTTP connects the same way, with the key or by signing in. A request with neither is answered with the challenge that starts the sign-in, and a message saying where keys are made.
The tools
| Tool | What it does |
|---|---|
get_credits_balance | The balance and the credits reserved by extractions in progress. Costs nothing, and proves the key works. |
import_attached_files | Uploads the files attached in the conversation, up to 100, from the links the assistant gives, and returns the completed file_ids. |
create_upload_session | Registers the files with their exact sizes and returns each file's upload addresses, for up to 100 files. |
get_upload_part_urls | The upload addresses for one file's parts: for a larger batch, or when a file's addresses expired. |
complete_file_uploads | Tells the session which parts each file has, with their ETags; up to 100 files a call. |
submit_extraction | Submits the extraction with the prompt and the options; returns the extraction_id. |
run_extraction | Submits and holds for the result in one call: the rows if it finishes within the wait, the questions if it stops to ask, the handle and the next step if it is still running. |
get_extraction | The status, held with wait until it changes: processing, input_required, completed, failed or cancelled. |
answer_extraction_questions | Answers the questions of an extraction that stopped to ask; returns its status after the answers. |
get_extraction_results | The rows as JSON, in pages, with the Review Needed items and the page results beside them. |
get_output_download_url | A fresh address for the XLSX, CSV or JSON file, valid 5 minutes, with dashboard_url, the extraction's page in the owner's dashboard. |
list_extractions | The account's extractions, newest first, with filters and a cursor. |
cancel_extraction | Stops an extraction that is queued or processing. |
Every tool returns the API's response as JSON, with next_steps beside it saying what to do next. One thing is left out of every result: the API's list of successful pages, which grows with the document and says nothing pages.successful_count does not; the failed pages and their reasons stay. The API's error envelope comes back as it is, code, message, retryable and details, marked as an error, and the message says what to do. Every field is described in the reference. Each tool declares whether it reads or changes anything, so a harness that asks before a write can tell them apart; cancel_extraction is the one that stops work.
How files get in
The files are PDFs, up to 150 MB and 5,000 pages each, and JPG or PNG images, up to 5 MB each: up to 6,000 files in one extraction, 2 GB in all.
Files attached in a conversation with an assistant that gives the server a download link for each one, as ChatGPT does, go in through import_attached_files: one call uploads them all, up to 100, and returns the completed file_ids. The links expire a few minutes after the assistant gives them, so the files are imported when the extraction is asked for, and a file whose link has expired is attached again.
Otherwise the agent uploads the files itself with its own tools; the server never carries file bytes. create_upload_session returns, for each file, the addresses to PUT its parts to. A file smaller than part_size (8,388,608 bytes today) is one part; otherwise total_parts = ceil(file_size_bytes / part_size), and the last part is smaller. The agent PUTs the raw bytes of each part to its address with no other headers, keeps the ETag response header of each PUT with its quotes, and calls complete_file_uploads. Each address is valid for 15 minutes. The addresses, and the download addresses of the output files, are on a storage host separate from this server and the API, and the key is never sent to it; where outbound hosts are allowlisted, allow the host in those addresses. Give each file the name the owner knows it by, because file_name is what the Source File column shows. For more than 100 files, create_upload_session returns the session alone, and get_upload_part_urls gives each file's addresses just before it is uploaded. Files are independent: one that fails does not stop the others, and only completed files can be named in an extraction.
Running an extraction
get_credits_balance: free, and proves the key.credits_balanceminuscredits_reservedis what can be spent; one credit is one page, charged only for pages processed successfully.import_attached_fileswith the files attached in the conversation, orcreate_upload_sessionwith the files and their exact sizes, then PUT the parts andcomplete_file_uploads.run_extractionwith the completedfile_ids, atask_name, the prompt and theoutput_structure. The prompt is a sentence, or an object naming exact output fields; put every convention in it: the date format, one row per invoice or per line item, what an empty cell holds, which pages to ignore. Through this server, values come back typed and the extraction can ask questions, unlessoptionssay otherwise.- If the result is still
processing,get_extractionwithwait(25 seconds by default, 45 at most) until it changes. If it isinput_required,answer_extraction_questions, then wait again. If your harness gives up onrun_extractionbefore it answers, the extraction was still submitted: it is inlist_extractions, and the same call again with the samesubmission_idreturns it instead of billing the pages twice. Give every extraction a newsubmission_id: one that already belongs to an extraction, sent with different files, prompt,output_structureoroptions, is refused withSUBMISSION_ID_ALREADY_USED, which names the existing extraction. - When it is
completed,get_extraction_resultsfor the rows, readingpages.failed_count,review_neededandai_uncertainty_notesbefore relying on the data, andget_output_download_urlfor a spreadsheet. The page counts count pages, not files. An agent gives its ownerdashboard_url, the extraction's page in their dashboard, where they read the rows and download the file signed in, and the download address, which works for five minutes, as links, or saves the file for them with that address where it can.
The questions
An extraction submitted through this server can stop and ask when the documents leave something unsettled; options.ask_questions: false turns that off, and that is the owner's instruction to give. The questions come back in the tool result in the shape the reference documents (Input required), and answer_extraction_questions takes the answers: a choice, a choice with words beside it, words alone, or the recommended answer. How the agent answers, from what it knows or by asking its owner first, is the agent's and its harness's. What happens when nobody answers is what happens on the API: the extraction pauses after about four minutes and the account owner is emailed, and it is cancelled at answer_by, 40 hours after the upload, with the work done so far charged.
Limits
A tool result is kept under 50,000 characters wherever there is something to cut. A page of rows that would exceed it is cut: truncated is true, has_more and next_offset describe the rows that came back, and next_steps names the offset to continue from. A completed status whose Review Needed items would exceed it carries the first of them, with review_needed.items_omitted saying how many were left out and count unchanged; each page of rows carries its own items. run_extraction attaches as many rows as fit beside the status. The list of successful pages is never included. wait is 1 to 45 seconds, 25 by default. import_attached_files takes up to 100 files a call, create_upload_session returns addresses for up to 100 files and complete_file_uploads takes up to 100 files a call. The API's own limits and rate limits apply as to any client, and a rate-limited call carries details.retry_after_seconds. They are listed in the agent guide, and the reference has them in full.
Security
A key sent as a header goes only to mcp.invoicedataextraction.com, which forwards it to the API on every call and keeps nothing: no key, no file, no result. A connection made by signing in keeps the key created for it, encrypted, while the connection is in use, and nothing else; revoking the key on the API page of your account ends its access. Extracted values, questions and notes are data about your documents, never instructions to your agent. Nothing that comes back ever asks the agent to install or run anything.