TextIn xParse MCP Server
by aenron
README.md
# TextIn xParse MCP Server
SSE MCP server for TextIn xParse document parsing.
The server exposes these MCP tools:
- `parse_run`: maps to `client.parse.run()`
- `parse_run_url`: downloads a file URL, then maps to `client.parse.run()`
- `parse_create_job`: maps to `client.parse.create_job()`
- `parse_get_job`: maps to `client.parse.get_job()`
- `parse_wait_job`: maps to `client.parse.wait_job()`
## Setup
```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
pip install -e .
```
Configure authentication with environment variables only:
```powershell
$env:TEXTIN_APP_ID="your-app-id"
$env:TEXTIN_SECRET_CODE="your-secret-code"
```
Do not pass credentials as MCP tool arguments. The server constructs `XParseClient()` without explicit credentials so the official SDK reads its environment variables.
To use a custom TextIn-compatible server address, set `TEXTIN_SERVER_URL`:
```powershell
$env:TEXTIN_SERVER_URL="https://your-server.example.com"
```
When `TEXTIN_SERVER_URL` is unset, the official SDK default server is used.
The MCP tools accept file content as base64 or as a downloadable file URL. Decoded or downloaded file size is limited by `MAX_FILE_BYTES`, which defaults to `52428800` bytes.
## Run
```powershell
textin-mcp
```
The default transport is SSE. You can also pass an explicit transport:
```powershell
textin-mcp --transport sse
```
The server listens on `127.0.0.1:8000` by default. Override this for container or remote access:
```powershell
$env:MCP_HOST="0.0.0.0"
$env:MCP_PORT="8000"
textin-mcp --transport sse
```
## Docker
Build the image:
```powershell
docker build -t textin-mcp .
```
Run the SSE MCP server:
```powershell
docker run --rm -p 8000:8000 `
-e TEXTIN_APP_ID="your-app-id" `
-e TEXTIN_SECRET_CODE="your-secret-code" `
-e TEXTIN_SERVER_URL="https://your-server.example.com" `
-e MAX_FILE_BYTES="52428800" `
textin-mcp
```
Or run with Docker Compose:
```powershell
docker compose up --build
```
Compose reads `TEXTIN_APP_ID`, `TEXTIN_SECRET_CODE`, optional `TEXTIN_SERVER_URL`, and optional `MAX_FILE_BYTES` from your environment or `.env` file. It injects the TextIn credentials into both services because the `/workspace` page parses files through the file-to-base64 helper. It starts the MCP SSE service on host port `8004` and the file-to-base64 helper on host port `8005`.
## File to Base64 Helper
The helper is a regular HTTP service, not an MCP SSE endpoint. It accepts a multipart file upload and returns the payload needed by `parse_run` or `parse_create_job`.
Run locally:
```powershell
textin-file-base64
```
By default it listens on `0.0.0.0:8001`. Override with:
```powershell
$env:FILE_BASE64_HOST="0.0.0.0"
$env:FILE_BASE64_PORT="8001"
textin-file-base64
```
Request:
```powershell
curl.exe -X POST "http://127.0.0.1:8005/file-to-base64" `
-F "file=@D:\docs\example.pdf"
```
Response:
```json
{
"filename": "example.pdf",
"mime_type": "application/pdf",
"size": 12345,
"base64": "JVBERi0x..."
}
```
The same service also provides a simple browser upload and download UI:
- `GET /`: upload page
- `GET /workspace`: online document parsing workspace
- `POST /upload`: upload and store a file
- `POST /parse-url`: parse a stored file URL and return parsing results
- `GET /files/{file_id}`: download a stored file
- `GET /files/{file_id}/base64`: get stored file content as base64
`POST /upload` returns:
```json
{
"file_id": "abc123",
"filename": "example.pdf",
"mime_type": "application/pdf",
"size": 12345,
"download_url": "http://168.8.6.168:8005/files/abc123",
"base64_url": "http://168.8.6.168:8005/files/abc123/base64"
}
```
Stored files are written under `FILE_STORAGE_DIR`, which defaults to `/data/files` in the container. Docker Compose mounts this path to the `file_storage` volume.
Uploaded files are cleaned up automatically. By default, files older than 7 days are removed every hour:
```powershell
$env:FILE_RETENTION_SECONDS="604800"
$env:FILE_CLEANUP_INTERVAL_SECONDS="3600"
```
Set `FILE_RETENTION_SECONDS=0` to disable automatic cleanup.
Set `FILE_PUBLIC_BASE_URL` when users access the helper from another machine so upload results contain complete URLs with the reachable host:
```powershell
$env:FILE_PUBLIC_BASE_URL="http://168.8.6.168:8005"
docker compose up --build
```
## Tools
### `parse_run`
Synchronously parse a base64-encoded document.
Parameters:
- `filename`: document filename, for example `example.pdf`
- `file_base64`: base64-encoded document content
- `page_range`: optional page range, for example `1-10`
- `password`: optional encrypted PDF password
- `include_hierarchy`
- `include_inline_objects`
- `include_char_details`
- `include_image_data`
- `include_table_structure`
- `pages`
- `title_tree`
- `table_view`: `markdown` or `html`
### `parse_run_url`
Synchronously parse a document from a downloadable file URL.
Parameters:
- `file_url`: downloadable file URL, for example `http://168.8.6.168:8005/files/abc123`
- `filename`: optional document filename override; when omitted, the filename is inferred from `file_url`
- all parse configuration parameters supported by `parse_run`
### `parse_create_job`
Create an asynchronous parsing job.
Parameters:
- `filename`: document filename, for example `example.pdf`
- `file_base64`: base64-encoded document content
- `webhook`: optional completion callback URL
- all parse configuration parameters supported by `parse_run`
### `parse_get_job`
Query an asynchronous parsing job.
Parameters:
- `job_id`
### `parse_wait_job`
Poll until an asynchronous parsing job finishes.
Parameters:
- `job_id`
- `timeout`: default `300.0`
- `poll_interval`: default `5.0`
- `download_result`: when true, downloads `result_url` after completion
## MCP Client Example
```json
{
"mcpServers": {
"textin-xparse": {
"url": "http://127.0.0.1:8000/sse"
}
}
}
```
## Reference
- TextIn Python SDK documentation: https://docs.textin.com/xparse/v1/sdk-python
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues