Metadata-Version: 2.4
Name: xlmcp
Version: 0.5.1
Summary: MCP server for JupyterHub/Jupyter/Qubx integration with Claude Code
Project-URL: Homepage, https://github.com/xLydianSoftware/aix
Project-URL: Repository, https://github.com/xLydianSoftware/aix
Project-URL: Documentation, https://github.com/xLydianSoftware/aix#readme
Project-URL: Issues, https://github.com/xLydianSoftware/aix/issues
Author-email: Dmitry Marienko <dmitry.ema@gmail.com>
License: MIT
License-File: LICENSE
Keywords: ai,anthropic,claude,jupyter,jupyterhub,mcp,notebook,qubx,xlydian
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: <4.0,>=3.10
Requires-Dist: click>=8.0.0
Requires-Dist: fastmcp>=2.13.0
Requires-Dist: httpx>=0.25.0
Requires-Dist: jupyter-client>=8.0.0
Requires-Dist: nbformat>=5.9.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: ruff<0.15.0,>=0.14.8
Requires-Dist: rust-just<2.0.0,>=1.44.0
Requires-Dist: uv<0.10.0,>=0.9.16
Requires-Dist: websockets>=12.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Description-Content-Type: text/markdown

# AIX - AI eXtensions for quantitative development

Collection of MCP servers, agents, and extensions for quantitative development/research with Qubx.

## XLMCP - Jupyter MCP Server

XLMCP gives Claude Code tools to interact with Jupyter notebooks running on JupyterHub or a standalone Jupyter Server — read/edit cells, manage kernels, and execute code.

> **Note:** knowledge/RAG search and project-management tools were moved out of xlmcp (to the `crtx-server` project) as of v0.5.0. xlmcp is now a focused Jupyter server.

**Total Tools: 17** (Jupyter notebook, kernel, and execution operations)

## Quick Reference

### Jupyter Tools (17)

```python
# - Notebook operations
await jupyter_list_notebooks(directory="")
await jupyter_find_notebook(filename)
await jupyter_get_notebook_info(notebook_path)
await jupyter_read_cell(notebook_path, cell_index)
await jupyter_read_all_cells(notebook_path)
await jupyter_append_cell(notebook_path, source, cell_type="code")
await jupyter_insert_cell(notebook_path, cell_index, source, cell_type="code")
await jupyter_update_cell(notebook_path, cell_index, source)
await jupyter_delete_cell(notebook_path, cell_index)

# - Kernel operations
await jupyter_list_kernels()
await jupyter_start_kernel(kernel_name="python3")
await jupyter_stop_kernel(kernel_id)
await jupyter_restart_kernel(kernel_id)
await jupyter_interrupt_kernel(kernel_id)

# - Execution
await jupyter_execute_code(kernel_id, code, timeout=None)
await jupyter_connect_notebook(notebook_path)
await jupyter_execute_cell(notebook_path, cell_index, timeout=None)
```

### Connecting to a notebook's kernel

`jupyter_connect_notebook` resolves the kernel for a notebook by **normalised path match** (absolute /
server-relative / VS Code `-jvsc-<uuid>` synthetic paths all map to the same notebook), so it reuses the
live kernel instead of spawning duplicates. Its `status`:

- `existing` — one live kernel matched; use its `kernel_id`.
- `ambiguous` — several matched; pick a `kernel_id` from `candidates` (or stop the extras).
- `created` — none matched, a new session was made.

Every response includes `attach_url` — paste it into **VS Code → Select Kernel → Existing Jupyter
Server** to join the same kernel from the editor (the token authenticates directly to the single-user
server, bypassing the Hub login dialog).

## Installation

### From PyPI (Recommended)

```bash
pip install xlmcp
# - or using uv
uv pip install xlmcp
```

### From Source

```bash
cd ~/devs/aix
uv pip install -e .
```

## Configuration

### Environment Setup

1. Copy `env.example` to `.env`:
```bash
cp env.example .env
```

2. Edit `.env` and configure:

**Jupyter Server (Required):**
```bash
JUPYTER_SERVER_URL=http://localhost:8888
JUPYTER_API_TOKEN=your-token-here
JUPYTER_NOTEBOOK_DIR=~/
JUPYTER_ALLOWED_DIRS=~/projects,~/devs,~/research
```

**MCP Server (Optional, defaults provided):**
```bash
MCP_TRANSPORT=stdio
MCP_HTTP_PORT=8765
MCP_MAX_OUTPUT_TOKENS=25000
```

### Get a Jupyter API Token
- **JupyterHub**: Admin panel → User → New API Token
- **Jupyter Server**: `jupyter server list` shows the token

## Global Setup (Multi-Project Environments)

**For users with multiple projects and virtual environments:**

### 1. Install xlmcp Globally

```bash
# Install in system Python (not in project venvs)
pip install xlmcp
# or: /usr/bin/python -m pip install xlmcp
```

### 2. Create Central Configuration

```bash
mkdir -p ~/.aix/xlmcp
cp env.example ~/.aix/xlmcp/.env
nano ~/.aix/xlmcp/.env   # Add your JUPYTER_API_TOKEN
```

**xlmcp finds config in this order:**
1. `.env` in the current directory (project-specific override)
2. `~/.aix/xlmcp/.env` (global default) ← **Recommended**
3. Environment variables

### 3. Register with Claude Code

```bash
cd /path/to/project
source .venv/bin/activate            # if using a venv
claude mcp add --transport stdio xlmcp -- /usr/bin/python -m xlmcp.server
```

Replace `/usr/bin/python` with your system Python (`which python` outside any venv).

**Verify:**
```bash
claude mcp list
# Should show: xlmcp: /usr/bin/python -m xlmcp.server - ✓ Connected
```

## Simple Setup (Single Project / Quick Start)

```bash
pip install xlmcp
cp env.example .env
nano .env                            # Add JUPYTER_API_TOKEN
claude mcp add --transport stdio xlmcp -- python -m xlmcp.server
```

**Or with environment variables (no .env file needed):**

```bash
claude mcp add \
  -e JUPYTER_SERVER_URL=http://localhost:8888 \
  -e JUPYTER_API_TOKEN=your-token \
  --transport stdio \
  xlmcp \
  -- python -m xlmcp.server
```

The `--` before `python` separates MCP options from the server command.

## XLMCP CLI

```bash
xlmcp start      # Start server in background
xlmcp status     # Show server status
xlmcp ls         # List available tools
xlmcp kernels    # List active Jupyter kernels
xlmcp restart    # Restart server
xlmcp stop       # Stop server
```

## Usage Examples

```
> Connect to my notebook and execute the first cell
> List all notebooks in research/momentum/
> Execute code: print("Hello from Jupyter!")
> Restart the kernel for research/analysis.ipynb
```

## Transport Modes

**stdio (default)** — for local Claude Code:
```bash
MCP_TRANSPORT=stdio
```

**http** — for remote access:
```bash
MCP_TRANSPORT=http
MCP_HTTP_PORT=8765
claude mcp add xlmcp --transport http http://your-server:8765
```

## Security

- Path validation: only allows access to configured directories
- Token authentication: uses Jupyter API tokens
- Timeout limits: prevents runaway executions

## Documentation

- **[Usage Guide](docs/USAGE.md)** — installation, configuration, CLI, usage examples
- **[Implementation](docs/IMPLEMENTATION.md)** — technical architecture and design details

## License

MIT
