pairtools-mcp

Local

A Model Context Protocol (MCP) server that exposes pairtools tools for use with Claude or any MCP-compatible client.

Add to your MCP Client

LocalLinuxmacOSWindows

Add the following to your claude_desktop_config.json (or equivalent MCP config file):

{
  "mcpServers": {
    "pairtools-mcp": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/absolute/path/to/pairtools-mcp",
        "main.py"
      ]
    }
  }
}

Pairtools MCP Server

A Model Context Protocol (MCP) server that exposes pairtools tools for use with Claude or any MCP-compatible client.

pairtools is a command-line toolkit for processing sequencing reads from Hi-C and other proximity ligation experiments. It converts BWA-MEM alignments into the .pairs format, sorts, deduplicates, and filters them for downstream contact-matrix generation.


Tools

ToolDescription
check_pairtools_installedCheck whether pairtools is on PATH and return its version
install_pairtoolsInstall pairtools via pip on macOS and Linux
install_pairtools_windowsInstall pairtools on Windows via WSL
pairtools_parseParse BWA-MEM SAM output into .pairs format (background)
pairtools_sortSort a .pairs file by chromosome and position (background)
pairtools_dedupRemove PCR duplicates from a sorted .pairs file (background)
pairtools_statsCalculate QC statistics for a .pairs file (background)
pairtools_mergeMerge multiple sorted .pairs files (background)
pairtools_selectFilter pairs by a Python expression (background)
check_job_statusPoll the status of any background pairtools job
list_jobsList all background jobs submitted in the current session

Background execution: all pairtools operations return immediately with a job_id. Long-running jobs will not time out the MCP connection. Call check_job_status(job_id) to poll until the job is "completed" or "failed".


Requirements

  • Python 3.12+
  • uv
  • macOS: Homebrew — brew install htslib (required by pairtools)
  • Linux: sudo apt-get install libhts-dev zlib1g-dev
  • Windows: WSL — run wsl --install in PowerShell as Administrator, then restart

Local Setup

1. Clone the repository

git clone https://github.com/JesKwek/pairtools-mcp.git
cd pairtools-mcp

2. Add to Claude Desktop

Open your Claude Desktop config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add the following — replace the path with the actual location where you cloned the repo:

{
  "mcpServers": {
    "pairtools-mcp": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/absolute/path/to/pairtools-mcp",
        "main.py"
      ]
    }
  }
}

Important — use --directory, not --with. The --directory flag tells uv to use the project's own persistent .venv and install all dependencies from pyproject.toml (including pairtools) automatically on first launch. Using uv run --with mcp main.py creates a throwaway environment that is discarded on every restart, so pairtools would never be available.

Save the file and restart Claude Desktop. On the very first launch uv will download and install pairtools into .venv — this takes 1–3 minutes. Subsequent starts are instant.


Typical Hi-C Pipeline

BWA-MEM (bwa-mcp)
      │  SAM output
      ▼
pairtools_parse   ← convert alignments to .pairs format
      │
      ▼
pairtools_sort    ← sort by chrom + position
      │
      ▼
pairtools_dedup   ← remove PCR duplicates
      │
      ▼
pairtools_stats   ← QC summary

Tip: use bwa-mcp for the alignment step.


Usage Examples

1. Check if pairtools is installed

"Is pairtools installed on my system?"

Claude will tell you whether pairtools is found, where it lives, and which version is installed.

See JSON output

Found:

{
  "installed": true,
  "path": "/usr/local/bin/pairtools",
  "version": "pairtools, version 1.0.3",
  "via_wsl": false,
  "error": null
}

Not found:

{
  "installed": false,
  "path": null,
  "version": null,
  "via_wsl": false,
  "error": null
}

2. Install pairtools on macOS or Linux

"Install pairtools on my Mac."

Claude will locate pip, run pip install pairtools, and confirm the binary path. If htslib is missing it will provide the exact command to install it.

See JSON output

Success:

{
  "success": true,
  "message": "pairtools installed successfully at /usr/local/bin/pairtools.",
  "binary_path": "/usr/local/bin/pairtools",
  "error": null
}

Needs system library first:

{
  "success": false,
  "message": "pip install failed. If the error mentions a missing library, install htslib first:\n  brew install htslib\n\nAlternatively, install via conda:\n  conda install -c conda-forge -c bioconda pairtools",
  "binary_path": null,
  "error": "..."
}

3. Install pairtools on Windows

"Install pairtools on Windows."

pairtools is installed through WSL (Windows Subsystem for Linux). Claude checks if WSL is set up and, if so, installs pairtools and its dependencies automatically.

If WSL is not installed

Claude will return the following steps:

  1. Open PowerShell or Command Prompt as Administrator
  2. Run: wsl --install
  3. Restart your computer when prompted
  4. After restart, complete the WSL setup (username + password)
  5. Ask Claude to install pairtools again
See JSON output

Success:

{
  "success": true,
  "message": "pairtools installed successfully inside WSL.",
  "error": null
}

4. Parse BWA-MEM alignments into .pairs format

"Parse the BWA-MEM output at /data/output.sam using the hg38 chromsizes file at /data/hg38.chrom.sizes and save to /data/sample.pairs"

pairtools_parse launches in the background and returns immediately with a job_id.

See JSON output

Job started:

{
  "job_id": "b1c4a72e",
  "pid": 51200,
  "status": "running",
  "message": "pairtools parse started in the background. Call check_job_status('b1c4a72e') to monitor progress.",
  "output_pairs": "/data/sample.pairs",
  "via_wsl": false,
  "error": null
}

Polling — complete:

{
  "job_id": "b1c4a72e",
  "status": "completed",
  "pid": 51200,
  "operation": "pairtools_parse",
  "started_at": "2024-06-01T12:10:00",
  "output_pairs": "/data/sample.pairs",
  "via_wsl": false,
  "stderr": "...",
  "error": null
}

5. Sort a .pairs file

"Sort /data/sample.pairs and save to /data/sample.sorted.pairs"

See JSON output

Job started:

{
  "job_id": "c3d82f91",
  "pid": 51350,
  "status": "running",
  "message": "pairtools sort started in the background. Call check_job_status('c3d82f91') to monitor progress.",
  "output_pairs": "/data/sample.sorted.pairs",
  "via_wsl": false,
  "error": null
}

6. Deduplicate a sorted .pairs file

"Deduplicate /data/sample.sorted.pairs, write the output to /data/sample.dedup.pairs and the stats to /data/dedup.stats"

See JSON output

Job started:

{
  "job_id": "e9f03b44",
  "pid": 51480,
  "status": "running",
  "message": "pairtools dedup started in the background. Call check_job_status('e9f03b44') to monitor progress.",
  "output_pairs": "/data/sample.dedup.pairs",
  "output_stats": "/data/dedup.stats",
  "via_wsl": false,
  "error": null
}

7. Calculate statistics

"Calculate statistics for /data/sample.dedup.pairs and write to /data/sample.stats"

See JSON output

Job started:

{
  "job_id": "f2a17c55",
  "pid": 51600,
  "status": "running",
  "message": "pairtools stats started in the background. Call check_job_status('f2a17c55') to monitor progress.",
  "output_stats": "/data/sample.stats",
  "via_wsl": false,
  "error": null
}

8. Merge replicates

"Merge /data/rep1.sorted.pairs and /data/rep2.sorted.pairs into /data/merged.pairs"

See JSON output

Job started:

{
  "job_id": "a8b29d66",
  "pid": 51720,
  "status": "running",
  "message": "pairtools merge started in the background. Call check_job_status('a8b29d66') to monitor progress.",
  "output_pairs": "/data/merged.pairs",
  "input_count": 2,
  "via_wsl": false,
  "error": null
}

9. Filter pairs by condition

"Select only cis pairs (same chromosome) from /data/sample.dedup.pairs and write to /data/cis.pairs"

"Select long-range cis pairs (> 1 kb) from /data/sample.dedup.pairs"

See JSON output

Job started (cis pairs):

{
  "job_id": "d7e38f77",
  "pid": 51840,
  "status": "running",
  "message": "pairtools select started in the background. Call check_job_status('d7e38f77') to monitor progress.",
  "output_pairs": "/data/cis.pairs",
  "condition": "(chrom1 == chrom2)",
  "via_wsl": false,
  "error": null
}

10. List all background jobs

"Show me all pairtools jobs."

See JSON output
{
  "jobs": [
    {
      "job_id": "e9f03b44",
      "status": "running",
      "operation": "pairtools_dedup",
      "pid": 51480,
      "started_at": "2024-06-01T12:20:00",
      "output_pairs": "/data/sample.dedup.pairs",
      "via_wsl": false
    },
    {
      "job_id": "c3d82f91",
      "status": "completed",
      "operation": "pairtools_sort",
      "pid": 51350,
      "started_at": "2024-06-01T12:15:00",
      "output_pairs": "/data/sample.sorted.pairs",
      "via_wsl": false
    }
  ],
  "total": 2
}

Background Job Workflow

pairtools_parse / pairtools_sort / pairtools_dedup / …
        │
        ▼
   returns job_id   ←── no timeout risk
        │
        ▼
check_job_status(job_id)
        │
   status = "running"?  ──► poll again later
        │
   status = "completed"  ──► result is ready
   status = "failed"     ──► check stderr field

Note: The job registry is in-memory. Jobs are lost if the MCP server process restarts. Always call check_job_status in the same session that launched the job.


Troubleshooting

pairtools not found in the MCP server's Python environment

This means the server was launched with --with mcp (ephemeral env) instead of --directory. Fix it by updating your Claude Desktop config:

"args": ["run", "--directory", "/absolute/path/to/pairtools-mcp", "main.py"]

Then restart Claude Desktop. uv will install pairtools automatically.


libctabixproxies.cpython-3xx-darwin.so (no such file)

This error comes from a conda-managed pairtools that is missing a shared library. The MCP server is designed to never touch the conda PATH — it only uses the binary inside its own .venv. If you see this error it means the server was launched with the wrong config (see above).


Server fails to spawn — No such file or directory

Check the path in your Claude Desktop config. The correct directory name is pairtools-mcp — not pairsamtools-mcp (pairsamtools was the old name of the tool before it was renamed to pairtools).


install_pairtools times out

The first install compiles C extensions and can exceed the MCP client's 4-minute request timeout. The install continues running in the background. Wait 1–2 minutes and call check_pairtools_installed() to confirm it finished.

You can also pre-install by running in your terminal:

cd /path/to/pairtools-mcp
uv sync

Platform Support

PlatformStatus
macOSTested — installs via pip with htslib from Homebrew
LinuxSupported (same pip install steps as macOS)
WindowsSupported via WSL — tested on Windows 10/11 with WSL2