Handley Lab
Comprehensive MCP framework for Handley Research Group - productivity tools, scientific computing, and lab administration
Installation
npx mcp-handley-labAsk AI about Handley Lab
Powered by Claude ยท Grounded in docs
I know everything about Handley Lab. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
MCP Handley Lab Toolkit
โ ๏ธ BETA SOFTWARE: This toolkit is in active development. While functional, APIs may change and some features may have rough edges. Issues and pull requests are welcome!
A toolkit that bridges AI assistants with command-line tools and services. Built on the Model Context Protocol (MCP), it enables AI models like Claude, Gemini, or GPT to interact with your local development environment, manage calendars, analyze code, and automate workflows through a standardized interface.
Requirements
- Python: 3.10 or higher
- MCP CLI:
pip install mcp[cli](for Claude Desktop integration) - Package Manager: Either standard
pip/venvorpipx
System Dependencies (Optional)
Some tools require additional system packages:
- code2prompt tool:
cargo install code2prompt - email tools:
mutt,notmuch,offlineimapfor email management - repl tool:
tmuxfor session management - screenshot tool:
maim,wmctrlfor X11 window capture - messenger:
claudeCLI (Claude Code) for WhatsApp/Telegram bridge
Quick Start
Installation with uv tool (Recommended)
uv tool installs Python CLI applications in isolated environments while making them globally available. (Note: uvx is an alias for uv tool run if you've seen that elsewhere.)
git clone git@github.com:handley-lab/mcp-handley-lab.git
cd mcp-handley-lab
uv tool install .
Then continue to Configuration to set up API keys and register tools with Claude.
Alternative: pipx
pipx provides similar functionality if you don't have uv:
git clone git@github.com:handley-lab/mcp-handley-lab.git
cd mcp-handley-lab
pipx install .
Arch Linux
A PKGBUILD is included in the repository for native package manager integration:
git clone git@github.com:handley-lab/mcp-handley-lab.git
cd mcp-handley-lab
makepkg -si
This installs to /usr/bin/ and is managed by pacman. Note that uv and pipx are also available in the official Arch repos (pacman -S uv or pacman -S python-pipx).
Development Installation
For contributors who want to modify the code:
# Clone and enter the project
git clone git@github.com:handley-lab/mcp-handley-lab.git
cd mcp-handley-lab
# Install editable and globally available
uv tool install -e .
Alternatively:
uv syncfor a local venv (run tools withuv run mcp-llmorsource .venv/bin/activate)- Traditional pip:
python3 -m venv venv && source venv/bin/activate && pip install -e .
Configuration
After installing, set up API keys and register tools with Claude.
API Keys
Export in your .bashrc/.zshrc, a .env file, or the current session:
export OPENAI_API_KEY="sk-..."
export GEMINI_API_KEY="AIza..."
export ANTHROPIC_API_KEY="sk-ant-..."
export GROQ_API_KEY="gsk_..."
export GROK_API_KEY="grok-..."
export GOOGLE_MAPS_API_KEY="AIza..."
# Note: Google Calendar requires OAuth setup (see tool description below)
Register Tools with Claude
Register only the tools you need to avoid context bloat:
# Unified LLM tools (one tool handles all providers via model inference)
claude mcp add llm --scope user mcp-llm # Chat, vision, image gen, transcribe, OCR, models
# Other essential tools
claude mcp add arxiv --scope user mcp-arxiv
claude mcp add google-maps --scope user mcp-google-maps
# Add additional tools as needed:
# claude mcp add llm-embeddings --scope user mcp-llm-embeddings
# claude mcp add code2prompt --scope user mcp-code2prompt
# claude mcp add google-calendar --scope user mcp-google-calendar
# claude mcp add email --scope user mcp-email
# claude mcp add word --scope user mcp-word # Word document editing
# claude mcp add excel --scope user mcp-excel # Excel spreadsheet editing
# claude mcp add mathematica --scope user mcp-mathematica
# claude mcp add loop --scope user mcp-loop
# claude mcp add otter --scope user mcp-otter # Otter.ai transcripts
# claude mcp add screenshot --scope user mcp-screenshot
# claude mcp add search --scope user mcp-search # Transcript search
Verify tools are working with the /mcp command in Claude.
Available Tools
๐ค Unified LLM Tools (llm, llm-embeddings)
Connect with multiple AI providers through unified interfaces
- llm: Chat, vision, image generation, transcription, OCR, model discovery - all in one tool
- llm-embeddings: Semantic embeddings for text (OpenAI, Gemini, Mistral)
- Provider inferred from model name (e.g.,
gpt-5.2โ OpenAI,gemini-2.5-flashโ Gemini) - Persistent conversations with memory via
agent_nameparameter - Supported providers: OpenAI, Gemini, Claude, Mistral, Grok, Groq
- Claude example:
> ask gpt-5.2 to review the changes you just made
๐ ArXiv (arxiv)
Search and download academic papers from ArXiv
- Search by author, title, or topic
- Download source code, PDFs, or LaTeX files
- Claude example:
> find all papers by Harry Bevins on arxiv
๐ Code Flattening (code2prompt)
Convert codebases into structured, AI-readable text
- Flatten project structure and code into markdown format
- Include git diffs for review workflows
- Claude example:
> use code2prompt and gemini to look for refactoring opportunities in my codebase - Requires: code2prompt CLI tool (
cargo install code2prompt)
๐
Google Calendar (google-calendar)
Manage your calendar programmatically
- Create, update, and search events
- Find free time slots for meetings
- Claude example:
> when did I last meet with Jiamin Hou?, and when would be a good slot to meet with her again this week? - Requires: OAuth2 setup
๐บ๏ธ Google Maps (google-maps)
Get directions and routing information
- Multi-modal directions (driving, walking, cycling, transit)
- Real-time traffic awareness with departure times
- Alternative routes and waypoint support
- Claude example:
> what time train do I need to get from Cambridge North to get to Euston in time for 10:30 on Sunday? - Requires: Google Maps API key (
GOOGLE_MAPS_API_KEY)
๐ Excel Spreadsheets (excel)
Comprehensive Excel spreadsheet manipulation via openpyxl
- Reading: Sheet list, cell data (grid/markdown/json), named ranges, tables
- Editing: Set cells, formulas, formatting, add/delete rows/columns/sheets
- Tables: Create structured tables, sort, filter
- Claude example:
> read the sales figures from Sheet1 and add a total row
๐งฎ Mathematica (mathematica)
Execute Mathematica code and computations
- Run WolframScript commands and notebooks
- Perform symbolic and numerical calculations
- Generate plots and visualizations
- Export results in various formats
- Claude example:
> use Mathematica to solve this differential equation and plot the solution - Requires: WolframScript installed and licensed
๐ง Email Management (email)
Comprehensive email workflow integration
- Compose, reply, and forward with Mutt (interactive sign-off before sending)
- Search and manage emails with Notmuch
- Sync mailboxes with offlineimap
- Contact management
- Claude example:
> compose an email to the team about the project update - Requires:
mutt,notmuch, andofflineimapinstalled and configured - Microsoft 365 accounts: OAuth2 setup guide
๐ Word Documents (word)
Comprehensive Word document manipulation via pure OOXML
- Reading: Progressive disclosure (outline โ blocks โ full), search, metadata
- Content: Paragraphs, headings, tables, images (inline + floating), text boxes
- Formatting: Styles (create/edit/delete), runs, paragraph formatting, tab stops
- Tables: Add/delete rows/columns, merge cells, borders, shading, alignment
- Track Changes: Read revisions, accept/reject individual or all changes
- References: Bookmarks, captions, cross-references, TOC, footnotes/endnotes
- Bibliography: Add sources, insert citations, generate bibliography
- Comments: Add, reply, resolve/unresolve threaded comments
- Page Setup: Margins, orientation, columns, borders, sections, headers/footers
- Lists: Numbered/bulleted lists, promote/demote, restart numbering
- Other: Content controls, equations, hyperlinks, custom properties
- Claude example:
> read the outline of my thesis, then add a citation to Smith2020 in the introduction
๐ฅ๏ธ Loop Sessions (loop)
Manage persistent REPL and LLM sessions via a background daemon
- Terminal REPLs: bash, python, ipython, julia, R, clojure, apl, maple, mathematica (via tmux)
- LLM backends: claude, gemini, openai (via CLI subprocesses with subscription auth)
- Execute code or chat and retrieve output with cell indexing
- Pass extra arguments to interpreters (e.g.,
--matplotlibfor ipython) - Claude example:
> start an ipython session with matplotlib, create a plot, and show me the figure - Requires:
tmuxfor terminal REPLs;claude,gemini,codexCLIs for LLM backends
๐ฌ Messenger (messenger)
Bridge WhatsApp and Telegram to Claude via persistent loop sessions
- One Claude session per conversation, with automatic session resume across restarts
- WhatsApp support via webhook (requires Meta Business API setup)
- Telegram support via long-polling (requires Bot API token from @BotFather)
- Commands:
/resetor/newto start a fresh session - Sessions stored in
~/messenger/{platform}/{id}/ - Not an MCP tool โ runs as a standalone server:
messenger [port](default: 8080) - Requires:
claudeCLI (Claude Code) installed and authenticated
Setup:
- Install this package (provides the
messengercommand) - Install and authenticate the
claudeCLI - Set environment variables (see
src/mcp_handley_lab/messenger/.env.example):# Telegram (easiest โ just need a bot token) export TELEGRAM_BOT_TOKEN="123456:ABC..." export TELEGRAM_ALLOWED_CHAT_IDS="12345,67890" # comma-separated, optional allowlist # WhatsApp (requires Meta Business API app + webhook) export WHATSAPP_VERIFY_TOKEN="your-verify-token" export WHATSAPP_ACCESS_TOKEN="your-access-token" export WHATSAPP_PHONE_NUMBER_ID="your-phone-number-id" export WHATSAPP_APP_SECRET="your-app-secret" # Optional export CLAUDE_PERMISSION_MODE="acceptEdits" # default export CLAUDE_SYSTEM_PROMPT="You are a personal assistant." # default - Run
messenger(ormessenger 9090for a custom port) - For WhatsApp: point your webhook URL to
http://your-server:8080/webhook
๐๏ธ Otter.ai Transcripts (otter)
Access live and recent Otter.ai meeting transcripts
- List live meetings and fetch real-time transcripts
- Browse and search recent meetings by title
- Refresh session cookies via headless Playwright
- Claude example:
> what's being said in my current meeting? - Requires: Otter.ai account logged in via Chrome;
pip install -e '.[otter]'for session refresh
๐ธ Screenshot Capture (screenshot)
Capture screenshots of windows or the full screen
- List all windows with ID, class, desktop, and name
- Capture specific window by name or hex ID
- Capture full screen
- Save to file or return image directly
- Claude example:
> show me the matplotlib Figure 1 window - Requires:
maimandwmctrl(X11)
๐ Transcript Search (search)
Search and slice across past AI conversation transcripts
- Full-text search (FTS5) across Claude Code, Codex, Gemini, and MCP memory conversations
- Slice conversation segments by position for context retrieval
- List and browse available sessions
- Sync and index conversation files into a searchable database
- Claude example:
> search my past conversations for discussions about authentication
Recommended External MCPs
These MCP servers from other projects complement this toolkit:
| MCP | Description | Installation |
|---|---|---|
| Playwright | Browser automation for web scraping and testing | npx @playwright/mcp@latest |
See awesome-mcp-servers for a comprehensive list of available MCP servers.
Using AI Tools Together
You can use AI tools to analyze outputs from other tools. For example:
# 1. Use code2prompt to summarize your codebase
# Claude will run: mcp__code2prompt__generate_prompt path="/your/project" output_file="/tmp/summary.md"
# 2. Then ask any LLM to review it (provider inferred from model name)
# Claude will run: mcp__llm-chat__ask model="gemini-2.5-flash" prompt="Review this codebase" files=["/tmp/summary.md"]
This pattern works because:
code2promptcreates a structured markdown file with your code- The unified
llm-chattool can read files as context - The provider is automatically inferred from the model name
Direct LLM Access in Python
For advanced workflows, you can use the llm module directly from Python without going through MCP:
from mcp_handley_lab import llm
# Stateless query (branch="" disables memory)
result = llm.chat("What is 2+2?", branch="")
print(result.content) # "The answer is 4."
# With conversation memory (default branch="session")
result = llm.chat("What is 2+2?")
result = llm.chat("Double that") # Knows context, returns 8
# With different provider
result = llm.chat("Hello", model="openai", branch="")
# With provider-specific options
result = llm.chat("Search for Python tutorials", model="gemini", branch="", options={"grounding": True})
# Access token usage
print(f"Input: {result.usage.input_tokens}, Output: {result.usage.output_tokens}")
Recursive LLM Pattern for Large Documents
For documents too large to fit in context (>100K tokens), use the Recursive LLM pattern inspired by the RLM paper. This approach processes documents in chunks using sub-LLM calls from within a REPL session:
# In a Python REPL session (mcp__repl__session)
from mcp_handley_lab import llm
from pathlib import Path
# Process a large file in chunks
context_path = Path("/path/to/large/document.txt")
results = []
chunk_size = 100_000 # ~25K tokens
with open(context_path, 'rb') as f:
offset = 0
while chunk := f.read(chunk_size):
text = chunk.decode('utf-8', errors='replace')
result = llm.chat(f'''Extract key facts from this chunk.
<document_chunk offset="{offset}">
{text}
</document_chunk>''', branch="") # Stateless sub-calls
results.append({"offset": offset, "summary": result.content})
offset += len(chunk)
# Aggregate results
summaries = "\n".join(f"[{r['offset']}]: {r['summary']}" for r in results)
final = llm.chat(f"Synthesize these summaries:\n{summaries}", branch="")
print(final.content)
The /recursive-llm skill (in .claude/skills/recursive-llm/SKILL.md) provides detailed guidance on when and how to use this pattern.
Testing
This project uses pytest for testing. The tests are divided into unit and integration categories.
-
Install development dependencies:
pip install -e ".[dev]" -
Run all tests:
pytest -
Run only unit or integration tests:
# Run unit tests (do not require network access or API keys) pytest -m unit # Run integration tests (require API keys and network access) pytest -m integration
Contributing
We welcome contributions! See CONTRIBUTING.md for detailed guidelines.
Quick start for contributors:
- Fork and clone the repository
- Create a feature branch
- Make your changes following existing patterns
- Run tests and linting:
pytest && ruff check . - Bump version:
python scripts/bump_version.py - Submit a pull request
License
MIT License - see LICENSE for details.
