pairtools-mcp
LocalA Model Context Protocol (MCP) server that exposes pairtools tools for use with Claude or any MCP-compatible client.
Add to your MCP Client
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
| Tool | Description |
|---|---|
check_pairtools_installed | Check whether pairtools is on PATH and return its version |
install_pairtools | Install pairtools via pip on macOS and Linux |
install_pairtools_windows | Install pairtools on Windows via WSL |
pairtools_parse | Parse BWA-MEM SAM output into .pairs format (background) |
pairtools_sort | Sort a .pairs file by chromosome and position (background) |
pairtools_dedup | Remove PCR duplicates from a sorted .pairs file (background) |
pairtools_stats | Calculate QC statistics for a .pairs file (background) |
pairtools_merge | Merge multiple sorted .pairs files (background) |
pairtools_select | Filter pairs by a Python expression (background) |
check_job_status | Poll the status of any background pairtools job |
list_jobs | List 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. Callcheck_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 --installin 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--directoryflag tells uv to use the project's own persistent.venvand install all dependencies frompyproject.toml(includingpairtools) automatically on first launch. Usinguv run --with mcp main.pycreates 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:
- Open PowerShell or Command Prompt as Administrator
- Run:
wsl --install - Restart your computer when prompted
- After restart, complete the WSL setup (username + password)
- 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_statusin 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
| Platform | Status |
|---|---|
| macOS | Tested — installs via pip with htslib from Homebrew |
| Linux | Supported (same pip install steps as macOS) |
| Windows | Supported via WSL — tested on Windows 10/11 with WSL2 |