# Suparse MCP Server MCP stdio server for the [Suparse](https://suparse.com) Document Processing API. Use it from local MCP clients such as Claude Code and Codex to extract structured data from documents into JSON, CSV, XLSX, or Google Sheets; process single files or folders, including encrypted PDFs; let Suparse auto-detect extraction schemas or apply your team templates; create schemas automatically; split mixed multi-page documents; and download or clean up results by document ID. ## Security Boundary This is a local stdio MCP server. Connected MCP clients can ask it to read local document paths and write export files wherever the server process has permission. Only connect it to MCP clients and workspaces you trust. ## Requirements - A Suparse API key - Node.js 20+ ## Authentication The MCP server reads credentials from: 1. `SUPARSE_API_KEY` 2. `~/.config/suparse/config.json` Prefer passing `SUPARSE_API_KEY` through your client's environment or secret-input support. The fallback file is implemented by Suparse and contains `{ "apiKey": "your_api_key" }`. Protect it as a credential file. Replace `your_api_key` in the examples below. Client `env` settings and CLI `--env` options can save the key in client configuration; keep files containing real keys out of Git and shared workspaces. CLI commands containing a key may also appear in shell history. Use scoped API keys where available. ## Local Installation Install your chosen client first and ensure Node.js 20+ and `npx` are available to it. These setups launch `@suparse/mcp` as a local stdio process: - [Claude Code](#claude-code) - [Claude Desktop](#claude-desktop) - [Codex CLI / IDE](#codex) - [Cursor](#cursor) - [VS Code / GitHub Copilot](#vs-code--github-copilot) - [Gemini CLI](#gemini-cli) - [Windsurf / Cascade](#windsurf--cascade) Merge JSON examples into existing configuration rather than replacing other servers. After connecting, use the [template-listing check](#verify-your-installation) to verify Suparse authentication. ### Claude Code Install for all your projects with user scope: ```bash claude mcp add --scope user --transport stdio suparse \ --env SUPARSE_API_KEY=your_api_key \ -- npx -y @suparse/mcp ``` Keep the server name (`suparse`) before `--env`; Claude Code can otherwise parse it as another environment variable and report `Invalid environment variable format`. To change an existing registration (for example, its API key or launch command), remove it before running the add command again: ```bash claude mcp remove --scope user suparse ``` Use the name and scope from your original installation. For a user-scoped local test registered as `suparse-local`, run `claude mcp remove --scope user suparse-local`. After adding the updated registration, fully exit Claude Code and start a fresh session to load the new configuration. Check the configuration and connection: ```bash claude mcp list claude mcp get suparse ``` Inside Claude Code, use `/mcp` to inspect status and tools, then run the [template-listing check](#verify-your-installation). See the [Claude Code MCP documentation](https://code.claude.com/docs/en/mcp). ### Claude Desktop Open your config file at `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS or `%APPDATA%\Claude\claude_desktop_config.json` on Windows. Add Suparse to the `mcpServers` section: ```json { "mcpServers": { "suparse": { "command": "npx", "args": ["-y", "@suparse/mcp"], "env": { "SUPARSE_API_KEY": "your_api_key" } } } } ``` Fully quit and reopen Claude Desktop, confirm Suparse appears among the available tools, then run the [template-listing check](#verify-your-installation). If Windows reports a process-start error for `npx`, replace the server's `command` and `args` with: ```json { "command": "cmd", "args": ["/c", "npx", "-y", "@suparse/mcp"] } ``` Keep the existing `env` block. This workaround is only needed for clients that cannot launch `npx.cmd` directly. ### Codex The preferred installation is through the CLI: ```bash codex mcp add suparse \ --env SUPARSE_API_KEY=your_api_key \ -- npx -y @suparse/mcp ``` After installation, add `tool_timeout_sec = 300` inside the existing `[mcp_servers.suparse]` table in `~/.codex/config.toml`. The CLI command does not set this timeout. Alternatively, configure the server manually in `~/.codex/config.toml` or a project-scoped `.codex/config.toml`: ```toml [mcp_servers.suparse] command = "npx" args = ["-y", "@suparse/mcp"] tool_timeout_sec = 300 [mcp_servers.suparse.env] SUPARSE_API_KEY = "your_api_key" ``` `tool_timeout_sec` gives Suparse extraction tools up to five minutes to finish; Codex defaults to 60 seconds. The CLI and IDE extension share this configuration. See the [Codex MCP documentation](https://developers.openai.com/codex/mcp). Verify the configured server: ```bash codex mcp list ``` In an interactive Codex session, use `/mcp` to inspect active servers, then run the [template-listing check](#verify-your-installation). ### Cursor Add this to `~/.cursor/mcp.json` for all projects, or `.cursor/mcp.json` for the current project: ```json { "mcpServers": { "suparse": { "type": "stdio", "command": "npx", "args": ["-y", "@suparse/mcp"], "env": { "SUPARSE_API_KEY": "${env:SUPARSE_API_KEY}" } } } } ``` Set `SUPARSE_API_KEY` in Cursor's environment before launching it; the `${env:SUPARSE_API_KEY}` reference keeps the key out of the JSON file. Restart Cursor after changing its environment. Alternatively, put the key in an untracked personal configuration. Open Cursor's MCP settings, confirm Suparse is enabled and its tools are available, then run the [template-listing check](#verify-your-installation) in Agent chat. See the [Cursor MCP documentation](https://cursor.com/docs/mcp). ### VS Code / GitHub Copilot For Copilot CLI, install and verify with: ```bash copilot mcp add suparse \ --env SUPARSE_API_KEY=your_api_key \ --timeout 300000 \ -- npx -y @suparse/mcp copilot mcp list ``` The timeout is in milliseconds and allows up to five minutes for tool discovery and calls. Then run the [template-listing check](#verify-your-installation) in Copilot CLI. See the [Copilot CLI command reference](https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-command-reference). For a portable Copilot setup, create `.mcp.json` in the workspace root. For a personal installation, use `~/.copilot/mcp-config.json` (or `$COPILOT_HOME/mcp-config.json` if configured): ```json { "mcpServers": { "suparse": { "type": "stdio", "command": "npx", "args": ["-y", "@suparse/mcp"], "env": { "SUPARSE_API_KEY": "your_api_key" }, "tools": ["*"] } } } ``` Keep any file with a real key untracked. For a workspace configuration using VS Code's password input, use `.vscode/mcp.json` instead: ```json { "inputs": [ { "id": "suparse-api-key", "type": "promptString", "description": "Suparse API key", "password": true } ], "servers": { "suparse": { "type": "stdio", "command": "npx", "args": ["-y", "@suparse/mcp"], "env": { "SUPARSE_API_KEY": "${input:suparse-api-key}" } } } } ``` The VS Code format uses `servers`; the portable format uses `mcpServers`. Choose one setup to avoid duplicate servers. Interactive inputs are not forwarded to Copilot harness sessions; use the portable setup for those sessions. Run **MCP: List Servers** from the Command Palette, select Suparse and start it, then run the [template-listing check](#verify-your-installation) in agent chat. See the [VS Code MCP configuration reference](https://code.visualstudio.com/docs/agents/reference/mcp-configuration). ### Gemini CLI Install for your user account: ```bash gemini mcp add --scope user \ --env SUPARSE_API_KEY=your_api_key \ suparse npx -y @suparse/mcp ``` This writes the server configuration to `~/.gemini/settings.json`. Check connection status with: ```bash gemini mcp list ``` In an interactive session, use `/mcp list` to inspect tools, then run the [template-listing check](#verify-your-installation). See the [Gemini CLI MCP documentation](https://geminicli.com/docs/tools/mcp-server/). ### Windsurf / Cascade These instructions target the legacy **Cascade** agent. For the newer default **Devin Local** agent, follow the [Devin CLI MCP configuration documentation](https://docs.devin.ai/cli/extensibility/mcp/configuration); its configuration locations and migration behavior depend on the installed version, even where paths overlap with Cascade. Open the MCP configuration from Cascade's MCP controls. Windsurf installations use `~/.codeium/windsurf/mcp_config.json` (`%USERPROFILE%\.codeium\windsurf\mcp_config.json` on Windows). Cascade in current Devin Desktop releases uses `~/.config/devin/mcp_config.json` (or `$XDG_CONFIG_HOME/devin/mcp_config.json`) on macOS/Linux and `%APPDATA%\devin\mcp_config.json` on Windows. Opening the file from Cascade selects the path for your installed version. Add Suparse under `mcpServers`: ```json { "mcpServers": { "suparse": { "command": "npx", "args": ["-y", "@suparse/mcp"], "env": { "SUPARSE_API_KEY": "your_api_key" } } } } ``` Save the file, refresh the MCP list or restart the client, and confirm Suparse and its tools are enabled in Cascade. Run the [template-listing check](#verify-your-installation). See the [Cascade MCP documentation](https://docs.windsurf.com/windsurf/cascade/mcp). ### Verify Your Installation In your client's agent chat, ask: > Use Suparse's `list_templates` tool to list my team's available extraction templates. Approve the tool call if prompted. A successful response confirms both the MCP connection and Suparse API authentication; an empty `team_templates` list is valid if your team has no templates. This check does not upload or process a document. If the server fails to start, check that Node.js 20+ and `npx` are on the client's `PATH`, and inspect its MCP logs. For authentication errors, check the key passed to the server or the Suparse fallback file. Desktop applications may not inherit environment variables set in a terminal. #### Verify Document Processing (Optional) Processing may consume Suparse credits. Use a small sample invoice or receipt containing data you are comfortable uploading to Suparse. 1. Put the sample PDF somewhere accessible to the MCP server and use its absolute path (see [local paths](#local-paths)). 2. Ask your client: "Use Suparse's `start_file_extraction` to extract structured data from `/absolute/path/to/sample.pdf`. Return the task ID and any document IDs or processing status provided. Do not delete the uploaded document." 3. Call `wait_for_task_extraction` with the returned task ID. If processing is still running, retain the ID and poll again; do not upload the file again. 4. Once processing completes, use a returned document ID to call `fetch_document_result`. If necessary, use `get_task_results` with the task ID to discover document IDs. This checks local file access, authentication, upload, processing, and result retrieval. Keep the uploaded document unless you explicitly want to delete it later. ## Tools | Goal | Recommended tool | | --- | --- | | Process a document, then obtain task/document IDs | `extract_file` with the default `result_mode: "defer"` | | Start processing and return after upload confirmation | `start_file_extraction` | | Get JSON directly in the MCP response | `extract_file` with `result_mode: "return_json"` | | Start processing many documents | `start_folder_extraction` | | Inspect intermediate results | `get_task_results` | | Save a CSV/XLSX/JSON file | `download_results` | | Download a completed export after reconnecting | `download_export_job` | `defer` uploads and polls until processing reaches a terminal state or polling fails; it defers the result export, not the processing wait. The start-only tools return task IDs after upload confirmation without polling for processing completion. Use them when you need an ID promptly, especially for long jobs or human review. `return_json` returns full results in both text and structured content. Large documents or batches can consume substantial assistant context; prefer `download_results` to save exports for those jobs. ### Local Paths Input and output paths must be accessible to the machine and operating-system process running Suparse MCP. Relative paths such as `./invoice.pdf` resolve against the server process's current working directory, which the MCP client chooses at launch; this may differ from your open project or chat's directory. File paths pass directly to the Node SDK's filesystem operations, and folder paths are normalized with `path.resolve` against that same working directory. Relative export paths also use the process's working directory; omitted output paths default there. The server does not expand `~` in tool path arguments. Prefer absolute paths when the working directory is uncertain. Use paths for the server's operating system: for example, `C:\Users\you\invoice.pdf` for a Windows process or `/mnt/c/Users/you/invoice.pdf` for a WSL2 process with that drive mounted. A path on another machine or outside the server's accessible filesystem cannot be read just because it appears in chat. ### Credits, Deletion, and Retries Document processing and automatic schema creation may consume Suparse credits. Uploading the same file again can create another processing submission. If a request times out, recover using the retained task ID, export job ID, or idempotency key before submitting new work. `delete_documents` deletes documents from Suparse remotely; it does not just remove local temporary files. The `cleanup` option on combined extraction tools can also delete remote documents after a verified export. Request deletion only after confirming that the results you need are safely saved. The server already supplies MCP annotations: status, template, and result inspection tools are read-only; upload/schema-creation tools are mutating and non-idempotent; combined extraction is marked potentially destructive because it can clean up; and `delete_documents` is marked destructive. Export submission tools are not advertised as universally idempotent: safe replay requires the same key and identical request options. Disk export tools can also write or overwrite local files. These hints help clients assess tool calls, but do not enforce permissions or make arbitrary retries safe. ### Tool Reference - `extract_file`, `extract_folder`: Combined upload and processing. `defer` is the default and returns task/document IDs after polling; a task can be `partially_completed`. `return_json` returns exported groups with per-input task status and document IDs; partial tasks and empty exports are reported as incomplete. `cleanup` is best-effort and valid only with `return_json`. - `start_file_extraction`, `start_folder_extraction`: Upload and return task IDs immediately, without polling or exporting. Folder scans are sorted, nonrecursive, and limited to 10 concurrent uploads. - `wait_for_task_extraction`: Poll a remote task. Defaults to 2 seconds between polls and 3 attempts; retries and SDK backoff mean this is not a strict wall-clock deadline. - `get_task_results`: Read one bounded page of partial task documents. The opaque cursor ends a snapshot, not task processing; a fresh call may show more documents. - `list_templates`: List summary or full template records, grouped into directly usable `team_templates` and discovery-only `system_templates`. - `start_quick_schema_creation`, `get_quick_schema_creation`, `wait_for_quick_schema_creation`: Start and inspect automatic schema creation. The run ID is separate from task, document, and export job IDs. - `fetch_json_results`: Return validated `TaskExport[]` JSON by document ID. It does not unpack ZIP artifacts or accept arbitrary JSON schemas. - `fetch_document_result`: Fetch one document's structured JSON result through the direct single-document endpoint. - `download_results`: Export documents and save the response to a local path. Supports JSON, CSV, XLSX, and immediate Google Sheets. Existing output paths follow the SDK overwrite behavior. - `get_export_job`, `wait_for_export_job`, `download_export_job`: Inspect, wait for, and download a known remote export job across MCP restarts. Downloads preserve original bytes, including ZIP, and verify the artifact before atomic publication. `download_export_job` defaults to `overwrite: false`. - `delete_documents`: Delete remote documents by ID. Use after confirming a successful export/download when cleanup is requested. ### Export Formats `fetch_json_results` accepts: | Input | Values | Default | | ------------- | --------------------- | --------- | | `export_type` | `original`, `unified` | `unified` | JSON exports are returned as structured `results`. `fetch_json_results` and `download_results` accept `wait_timeout_ms` (positive integer milliseconds, default 60000) and an optional UUID `idempotency_key`. The wait value bounds completion waiting, including polling retries; submission and transfer are separate phases, so MCP clients still need enough total tool time. If a response is lost, replay the same document IDs, format, export type, layout, and key. `download_results` accepts `json`, `csv`, `xlsx`, and `google_sheets`, plus an optional `output_path` local file path or existing directory. XLSX exports additionally accept `xlsx_layout: "standard" | "flat"` and default to `standard`. It writes the export directly to disk and returns the saved `output_path`. Immediate Google Sheets responses work; background Google Sheets is unsupported. The disk tool saves the Sheets response metadata, including URLs, rather than a spreadsheet binary. MCP clients should use `download_results` for CSV, XLSX, Google Sheets, and saved JSON files; they should not fetch base64 data and decode it with shell or Python. A known-job download preserves raw artifact bytes and is the path for ZIP or exact JSON artifacts. CSV/XLSX exports can return a ZIP containing several files (for example, invoices and bank statements). Both download tools report `requested_format`, `artifact_format`, and `content_type`, and correct the saved extension to match the artifact. An explicit `results.xlsx` path therefore becomes `results.zip` when the API returns an archive; check the returned `output_path`. For separate local files, call `download_results` with `unpack: true`: ```json {"document_ids":["invoice-id","statement-id"],"format":"xlsx","output_path":"/absolute/path/results.xlsx","unpack":true} ``` The ZIP is retained, and `output_paths` lists the extracted files in a fresh `results_files-*` folder next to it. Existing extracted files are never replaced. A single workbook stays `.xlsx` and appears directly in `output_paths`. Unpacking defaults to false, applies only to CSV/XLSX, and rejects unsafe archive paths, links, duplicate destinations, more than 1000 entries, or more than 512 MiB of uncompressed data. Failed extraction removes partial files; error recovery includes `saved_artifact_path` if the archive was already saved. `download_export_job` always preserves the original artifact without unpacking. CSV/XLSX `download_results` buffers the artifact through the SDK's raw-download API; known-job recovery streams and verifies the artifact before publication. `result_mode` controls whether extraction results in JSON format are returned directly. Use `return_json` only when you need the full JSON extraction in the MCP response. In all other cases you can retrieve the results in the format of your choice using `download_results`. Explicit `return_json` requests return complete JSON in both text and structured content, including when cleanup is enabled. Its `tasks` records preserve each polled input’s task ID, status, and document IDs. Partial completion and empty exports increase `failed_count` while preserving any exported data; their parent tasks are retained during cleanup. Combined extraction accepts `wait_timeout_ms` for each JSON export, defaulting to 60000 milliseconds; it is ignored in `defer` mode. Its optional `exports` records associate generated idempotency keys and accepted job IDs with each local input. Combined extraction does not accept caller-supplied idempotency keys. Cancelled folder responses account for all scanned files. Inputs that never started appear in `failed` with `cancelled: true`, `unstarted: true`, and code `OPERATION_NOT_STARTED`; `failed_count` includes them. These entries remain in source order and distinguish inputs safe to start from submitted tasks needing recovery. A known export job takes recovery priority, followed by replaying an identical export with its retained key, then task polling. Important: `cleanup` on `extract_file` and `extract_folder` is only valid with `result_mode: "return_json"`. Cleanup is best-effort and requires a fully completed task and a JSON export covering every requested document ID. Missing or unverifiable coverage produces an `INCOMPLETE_EXPORT` failure and retains the parent. It retains partial tasks, empty exports, and inputs whose backend work is uncertain. Folder cleanup waits for all extraction workers to settle and is skipped after cancellation. For CSV/XLSX/Google Sheets or saved JSON files, use start or combined extraction, wait for the task, download the result, then call `delete_documents` if requested. A local artifact write failure alone does not prove backend work is still running. When cleanup is requested, `cleanup` reports its status and deleted or retained document IDs in both text and structured results. Retained IDs include deletions that could not be confirmed. Combined extraction progress counts settled input files and increases with every notification. `extract_file`, `extract_folder`, `start_file_extraction`, and `start_folder_extraction` accept `template_id`, `split`, `pdf_password`, `folder_id`, and `auto_approve`. Approval defaults to true. Set `auto_approve: false` only when human review is requested, and use the start-only tools so the task ID is returned before processing waits. MCP cannot perform human review or approve documents; retain the task ID and resume polling after review is complete. This does not create or report a backend `awaiting_approval` status. Treat `pdf_password` as sensitive input. MCP redacts it from returned errors, metadata, partial results, and progress, while an MCP client may retain submitted tool arguments according to its own behavior. ### Google Sheets Requirements and Results - Connect Google Sheets in Suparse before requesting `format: "google_sheets"`; the SDK requires a working Google integration. - The [Suparse integration](https://www.suparse.com/key-features) supports creating a spreadsheet or appending to an existing one. This MCP tool exposes no target spreadsheet ID or append option, and the SDK does not specify which destination behavior its export endpoint chooses. Selecting a destination or explicitly appending rows is not supported through this MCP server. - Only immediate Google Sheets export responses are supported here; background Google Sheets jobs cannot be downloaded through this workflow. - `download_results` saves a JSON metadata file and returns `output_path` plus available `google_sheets_metadata`, which may include spreadsheet or folder URLs. It does not save a local `.xlsx` file. Use `format: "xlsx"` for that. ### Recovery guide | Known information | Next action | | --- | --- | | Export job ID | `get_export_job`, then `wait_for_export_job` if queued/processing, then `download_export_job` when completed. | | Task ID | `wait_for_task_extraction`, then `get_task_results` or export known document IDs. | | Lost export response and retained UUID key | Replay the identical request with the same IDs, format, type, layout, and key. | | Unknown upload confirmation with an upload reference | Retain the reference and investigate. Do not submit a fresh upload. The MCP has no upload recovery endpoint. | ### Typical workflows Ordinary extraction and download: ```text extract_file(file_path="./invoice.pdf") download_results(document_ids=[""], format="csv", output_path="./exports") ``` Long-running work and partial inspection: ```text start_file_extraction(file_path="./invoice.pdf") wait_for_task_extraction(task_id="", poll_interval=2, max_poll_attempts=3) get_task_results(task_id="", limit=25, cursor=null) ``` `poll_interval` is seconds. Export `wait_timeout_ms` is milliseconds. A task may be `partially_completed`; retain its completed document IDs and inspect later pages. When a page returns `next_cursor: null`, that snapshot is exhausted but the task may still produce documents. Start a fresh page request later and track IDs to avoid duplicates. Human review: ```text start_file_extraction(file_path="./contract.pdf", auto_approve=false) ``` The returned `task_id` is a remote task ID, `document_ids` identify remote documents, `run_id` belongs to quick-schema creation, `export_job_id` identifies a remote export job, and `output_path` is a local filesystem path. Recover an accepted export after a timeout or lost response: ```text get_export_job(export_job_id="") wait_for_export_job(export_job_id="", wait_timeout_ms=60000) download_export_job(export_job_id="", output_path="./exports/result.zip") ``` The 60000 millisecond SDK wait bound includes polling retries, but not submission or artifact transfer. Set a suitable timeout in the MCP client for the full operation. Parsed JSON tools return validated `TaskExport[]`; known-job downloads keep the raw artifact bytes, which may be ZIP or exact JSON. Do not expose base64/raw buffers to chat or decode artifacts with shell commands. ## Automatic Schema Creation Call `start_quick_schema_creation` with a local file, then pass its normalized `run_id` to `get_quick_schema_creation` or `wait_for_quick_schema_creation`. Terminal results preserve generated template IDs, saved documents, failed-document details, and retryability. The start tool also accepts `pdf_password` and `folder_id`. `upload_batch_id` and `source_upload_id` are supported only for advanced workflows that obtain those IDs elsewhere; the MCP server does not create upload batches. ## Template Selection for MCP Agents MCP agents should use only `team_templates` when passing `template_id` to an extraction tool. Use the default summary view for normal selection and request `view: "full"` only when schema, prompt, validation, or creator metadata is needed. When a user asks to process a document type such as a receipt: 1. Check `team_templates` first and use the matching team template if present. 2. If no matching team template exists, call `list_templates` with `include_system: true` and check `system_templates`. 3. System templates are discovery-only. MCP cannot add them to the team or use their IDs directly for extraction. 4. If no matching team template exists, omit `template_id` for auto-detection, or use `start_quick_schema_creation` and follow its `run_id` when the user authorized schema creation. Custom template editing and manual configuration are not exposed through MCP; explain that limitation if requested. ## Development Build the package: ```bash pnpm build ``` Test with MCP Inspector: ```bash npx @modelcontextprotocol/inspector node dist/index.mjs ``` The MCP server uses stdout for JSON-RPC protocol messages. Do not add `console.log` output to the server path; use stderr or MCP tool responses.