Metadata-Version: 2.5
Name: mcp-dharmamitra
Version: 0.1.0
Summary: MCP server for Dharmamitra OCR (Tibetan/Sanskrit/Devanagari)
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp[cli]>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# mcp-dharmamitra

<!-- mcp-name: io.github.alex-deus/mcp-dharmamitra -->

MCP server that runs OCR on an image via the public
[Dharmamitra](https://dharmamitra.org) OCR endpoint and writes the extracted
text to a local file. Optimised for Tibetan / Sanskrit / Devanagari input.

## Tool

### `ocr_image`

| Argument | Type | Default | Notes |
| --- | --- | --- | --- |
| `image_path` | `str` | — | Absolute path to a local image (png/jpg/…). |
| `output_path` | `str` | — | File to write UTF-8 text into. Parent dirs are created. |
| `transliterate_devanagari_to_iast` | `bool` | `false` | Passed to the API. |
| `transliterate_tibetan_to_wylie` | `bool` | `false` | Passed to the API. |
| `instruction` | `str` | `""` | Optional model instruction. |
| `model` | `str` | `"auto"` | OCR model id. |
| `poll_interval_seconds` | `float` | `2.0` | Delay between status polls. |
| `timeout_seconds` | `float` | `300.0` | Overall polling deadline. |

Returns a small JSON summary — the extracted text is written to `output_path`,
not returned to the client.

```json
{
  "job_id": "b8b26984b3ca49199c28303cad6a144d",
  "output_path": "/abs/path/out.txt",
  "pages": 1,
  "processing_time_seconds": 3.957,
  "chars": 1234
}
```

## Install

```bash
uv sync                           # or: pip install -e '.[dev]'
```

Run locally with the MCP inspector:

```bash
uv run mcp dev src/mcp_dharmamitra/server.py
```

Run tests:

```bash
uv run pytest
```

## Wire into Claude Desktop / Claude Code

`~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
    "mcpServers": {
      "dharmamitra": {
        "command": "uv",
        "args": ["--directory", "/path/mcp-dharmamitra", "run", "mcp-dharmamitra"],
        "env": {"DHARMAMITRA_COOKIE": ""}
      }
    }
  }
```

## Docker

Build the image:

```bash
docker build -t mcp-dharmamitra:latest .
```

MCP talks over stdio, so the container must be run with `-i` (no `-t`). Mount
a host directory that holds the input images — the tool arguments
(`image_path`, `output_path`) are paths **inside the container**.

Smoke-test the entrypoint:

```bash
docker run --rm --entrypoint python mcp-dharmamitra:latest \
  -c "from mcp_dharmamitra.server import mcp; print(mcp.name)"
```

### Wire the container into Claude Desktop / Claude Code

Replace `/Users/aleksei/projects/ai/mcp-dharmamitra/tmp` with any host
directory you want the tool to be able to read/write. Files inside it will be
visible under `/data` in the container.

```json
{
  "mcpServers": {
    "dharmamitra": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-v", "/Users/aleksei/projects/ai/mcp-dharmamitra/tmp:/data",
        "-e", "DHARMAMITRA_COOKIE",
        "mcp-dharmamitra:latest"
      ],
      "env": {
        "DHARMAMITRA_COOKIE": ""
      }
    }
  }
}
```

Or the same via CLI:

```bash
claude mcp add dharmamitra \
  --scope project \
  -e DHARMAMITRA_COOKIE="" \
  -- docker run -i --rm \
       -v /Users/aleksei/projects/ai/mcp-dharmamitra/tmp:/data \
       -e DHARMAMITRA_COOKIE \
       mcp-dharmamitra:latest
```

When calling the tool, pass container paths. Example — image at
`<host>/tmp/text.png` → `/data/text.png`:

```json
{
  "image_path": "/data/text.png",
  "output_path": "/data/text.txt"
}
```

The resulting `text.txt` appears in the mounted host directory.

## Cloudflare / `cf_clearance`

The endpoint sits behind Cloudflare. Most requests go through without any
cookie. If you start getting `403`, grab a fresh `cf_clearance` value from a
logged-in browser session on `dharmamitra.org` and export it:

```bash
export DHARMAMITRA_COOKIE='cf_clearance value here'
```

The server will attach it as a cookie on every request. Do not hardcode it —
Cloudflare rotates the value.
