ragtime

danielballance/ragtime

3.2

If you are the rightful owner of ragtime and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

RAGtime is a local retrieval-augmented generation (RAG) toolkit designed to manage private corpora and facilitate their integration into agentic workflows.

Tools
1
Resources
0
Prompts
0

RAGtime

RAGtime is a local retrieval-augmented generation (RAG) toolkit for curating private corpora and serving them to agentic workflows. It extracts structured text from mixed document sets, chunks and embeds the content with Sentence Transformers, persists vectors in Chroma, and exposes both CLI and Model Context Protocol (MCP) interfaces for querying.

Features

  • Document ingestion pipeline spanning Docling extraction, hybrid code/text chunking, and BAAI BGE embeddings.
  • Granite Docling fallback automatically reruns sparse extractions with IBM's Granite Docling VLM (using the MLX variant on Apple Silicon when available).
  • Local vector storage backed by persistent Chroma databases under data/databases/.
  • Command-line orchestration via ragtime commands for adding documents, asking questions, inspecting status, and resetting databases.
  • MCP server powered by FastMCP with built-in STDIO and HTTP transports, enabling integration with MCP-compatible clients.
  • Extensible helpers in src/ragtime/core/utilities.py for reusable ingestion, storage, and querying logic.

Quick Start

  1. Install Python 3.12+ and uv.
  2. Clone the repository and install dependencies:
    uv sync
    
  3. Explore the CLI:
    uv run ragtime --help
    uv run ragtime add ./data/test_docs/F102AS.docx
    uv run ragtime ask "What is the clearance memo about?"
    uv run ragtime status
    
  4. Launch the MCP server (choose one transport):
    uv run ragtime-mcp-stdio
    uv run ragtime-mcp-http -- --host 0.0.0.0 --port 9000
    
    The HTTP transport defaults to 127.0.0.1:9000/mcp; override the host, port, or path with the CLI flags shown above when exposing it to other machines.
  5. Preview documentation (Material for MkDocs) on a custom port to avoid collisions with the MCP HTTP server:
uv run -- mkdocs serve --config-file docs/mkdocs.yml --dev-addr 127.0.0.1:8001

Use from another repository without MCP (Cursor CLI)

When MCP is unavailable, run RAGtime purely via the CLI from within any other repository. This allows the Cursor Agent to call ragtime commands directly while keeping artifacts under that repository's ./data/ directory.

A) Point at this repo with uv (no vendoring)

From your other repo's root:

uv sync --directory /absolute/path/to/ragtime
uv run --directory /absolute/path/to/ragtime ragtime status
uv run --directory /absolute/path/to/ragtime ragtime add ./docs/sample.pdf
uv run --directory /absolute/path/to/ragtime ragtime ask "What changed?"

Notes:

  • Paths like ./data/ resolve to your current repo's working directory.
  • This is ideal for local use and CI where you don't want to vendor code.

B) Vendor as a submodule and add a helper script

Add RAGtime as a submodule under tools/ragtime:

git submodule add https://git.corp.tanium.com/daniel-ballance/ragtime.git tools/ragtime
uv sync --directory ./tools/ragtime

Important: Data location in vendored mode (Option B)

  • When invoked via uv --directory ./tools/ragtime, RAGtime resolves its data root relative to the vendored project directory. This means all artifacts and databases live under tools/ragtime/data/ (not your host repo root):
    • Databases: tools/ragtime/data/databases/<NAME>/
    • Artifacts: tools/ragtime/data/{extractions,chunks,embeddings}
  • If you already have databases under your repo root ./data/databases/, either move them into ./tools/ragtime/data/databases/ or adjust your wrapper to chdir to the repo root before launching RAGtime.

Create a wrapper script in your repo, e.g. tools/ragtime.sh:

macOS / Linux

#!/usr/bin/env bash
exec uv run --directory "$(git rev-parse --show-toplevel)/tools/ragtime" \
  ragtime "$@"

Make ragtime.sh executable

chmod +x ./tools/ragtime.sh

Usage (from your repo root):

./tools/ragtime.sh status
./tools/ragtime.sh add ./docs
./tools/ragtime.sh ask "Summarize the design"

Windows Create a wrapper script in your repo, e.g. tools/ragtime.ps1:

# tools/ragtime.ps1
param([Parameter(ValueFromRemainingArguments = $true)][string[]]$Forwarded)

$repoRoot = (git rev-parse --show-toplevel).Trim()
$ragtimeDir = Join-Path $repoRoot 'tools/ragtime'

uv --directory $ragtimeDir run ragtime @Forwarded

Usage (from your repo root):

.\tools\ragtime.ps1 status
.\tools\ragtime.ps1 add .\docs
.\tools\ragtime.ps1 ask "Summarize the design"

C) Containerized wrapper (isolated deps, shared data)

macOS / Linux Build once:

docker build -f /path/to/ragtime/docker/Dockerfile -t ragtime:latest /path/to/ragtime

Create tools/ragtime-docker.sh in your repo:

#!/usr/bin/env bash
exec docker run --rm -i --network host \
  -v "$(pwd)/data:/data" \
  -v "$(pwd):/workspace" \
  -w /workspace \
  ragtime:latest ragtime "$@"

Usage:

./tools/ragtime-docker.sh status
./tools/ragtime-docker.sh add ./docs
./tools/ragtime-docker.sh ask "Show related ADRs"

Windows Create tools/ragtime-docker.ps1 in your repo:

# tools/ragtime-docker.ps1
param([Parameter(ValueFromRemainingArguments = $true)][string[]]$Forwarded)

docker run --rm -it `
  --network host `
  -v "${PWD}/data:/data" `
  -v "${PWD}:/workspace" `
  ragtime:latest ragtime @Forwarded

Usage:

.\tools\ragtime-docker.ps1 status
.\tools\ragtime-docker.ps1 add .\docs
.\tools\ragtime-docker.ps1 ask "Show related ADRs"

Cursor tip: Ask the Agent to run the helper script/commands above from within your target repository. No MCP configuration is required for CLI usage.

Docker Deployment

The repository includes a multi-stage Dockerfile that bakes the SentenceTransformer and Docling model caches into the image so containers can run completely offline. Builds take longer and produce a ~1.5 GB image but avoid runtime downloads. Apple-only dependencies (mlx-vlm) are skipped because Linux images do not provide compatible wheels; Docling's default OCR remains available.

Image variants

  • Minimal (runtime target, default): includes the codebase and warmed model caches. Build with the final stage selected implicitly or explicitly:

    docker build -f docker/Dockerfile -t ragtime:minimal .
    # or
    docker build -f docker/Dockerfile -t ragtime:minimal --target runtime .
    
  • Full (runtime-full target): additionally bundles the prebuilt databases from the sibling ragtime-content repository. Supply that repository as a build context when invoking Docker so the image can copy the data layer:

    docker build -f docker/Dockerfile -t ragtime:full \
      --target runtime-full \
      --build-context ragtime-content=../ragtime-content \
      .
    

    The stage name is runtime-full; make sure the --target flag matches it exactly.

These build commands assume Docker BuildKit (enabled by default on recent Docker Desktop and Engine releases).

Neither image bundles sample fixtures from data/test_docs/; mount or copy any documents you want to ingest at runtime.

A project-level .dockerignore keeps caches (.venv/, .uv_cache/, data/, etc.) out of the build context so images stay reproducible regardless of local state.

macOS may attach com.apple.provenance extended attributes to downloaded files, which can trigger failed to xattr data: permission denied during the docker build tar step. Clear those attributes before building if you hit the error:

find . ../ragtime-content -xattrname com.apple.provenance \
  -exec xattr -d com.apple.provenance {} +

Docker Compose mirrors these targets: ragtime and docs build the minimal variant, while the optional ragtime-full service bundles the databases (and omits the data volume so the baked artefacts stay in place).

Build

docker build -f docker/Dockerfile -t ragtime:latest .

MCP HTTP server (port 9000)

Containers default to launching the MCP HTTP transport on port 9000. Use host networking so IDE clients can connect to http://127.0.0.1:9000 without extra port forwarding, and mount ./data to persist databases between runs:

docker run --rm --network host -v "$(pwd)/data:/data" ragtime:latest

MkDocs preview (port 9001)

Expose the documentation server on port 9001 with the same host network and data mounts:

docker run --rm --network host -v "$(pwd)/data:/data" \
  ragtime:latest -- mkdocs serve --config-file /app/docs/mkdocs.yml --dev-addr 0.0.0.0:9001

CLI workflows

Mount any host folders you want to ingest (for example the repository itself) alongside the persistent data volume. The entrypoint already invokes uv run, so CLI commands map directly to container arguments. The example below assumes you run from the repository root:

docker run --rm -it \
  --network host \
  -v "$(pwd)/data:/data" \
  -v "$(pwd):/workspace" \
  ragtime:latest ragtime add /workspace/data/test_docs/F102AS.docx

Replace the command tail with other subcommands (for example ragtime status or ragtime ask "...").

STDIO MCP transports

Cursor, Claude, or Codex CLI can reference the containerized STDIO server by wrapping the docker invocation. A common pattern is to create a small shell script on the host that matches the expected binary path:

#!/usr/bin/env bash
exec docker run --rm -i \
  --network host \
  -v "/path/to/ragtime/data:/data" \
  ragtime:latest ragtime-mcp-stdio "$@"

Point your MCP client at the script; it will stream STDIO through the container while reusing the same persistent database volume.

docker compose

docker/docker-compose.yml defines two services with overridable ports (default 9000 for MCP HTTP and 9001 for MkDocs). Compose environment variables let you adjust the published ports without editing the file:

docker compose -f docker/docker-compose.yml up ragtime               # MCP HTTP on 9000
docker compose -f docker/docker-compose.yml up docs                  # MkDocs on 9001
MCP_HTTP_PORT=9100 docker compose -f docker/docker-compose.yml up ragtime  # MCP HTTP on 9100
MKDOCS_PORT=9102 docker compose -f docker/docker-compose.yml up docs       # MkDocs on 9102

Use docker compose -f docker/docker-compose.yml run --rm ragtime ragtime status for ad-hoc workflows.

MCP Client Integration

RAGtime's FastMCP server can be consumed by different MCP-capable clients. The examples below assume the repository lives at /path/to/ragtime; update paths to match your environment. Run uv sync beforehand so the entry points are available.

Claude Code (Claude Desktop)

  • STDIO (recommended): Edit ~/Library/Application Support/Claude/claude_desktop_config.json (Anthropic docs). Add a server entry that spawns the stdio transport:
    {
      "mcpServers": {
        "ragtime": {
          "command": "uv",
          "args": ["--directory", "/path/to/ragtime", "run", "ragtime-mcp-stdio"]
        }
      }
    }
    
    Restart Claude Desktop so it loads the configuration.
  • HTTP: Run uv run ragtime-mcp-http -- --host 127.0.0.1 --port 9000 in a separate terminal. Claude Desktop is rolling out URL-based MCP definitions; on builds that support it, add an entry such as:
    {
      "mcpServers": {
        "ragtime-http": {
          "url": "http://127.0.0.1:9000"
        }
      }
    }
    
    If your build lacks url support, use stdio or run the HTTP server through a router like mcp-router.

Cursor IDE

  • STDIO: Create or edit ~/Library/Application Support/Cursor/mcp.json (or a project-level .cursor/mcp.json) to include:
    {
      "mcpServers": {
        "ragtime": {
          "command": "uv",
          "args": ["--directory", "/path/to/ragtime", "run", "ragtime-mcp-stdio"]
        }
      }
    }
    
  • HTTP: Start the HTTP server (uv run ragtime-mcp-http --host 0.0.0.0 --port 9000). Cursor supports HTTP/SSE endpoints via the url key (Cursor docs):
    {
      "mcpServers": {
        "ragtime-http": {
          "url": "http://127.0.0.1:9000/mcp"
        }
      }
    }
    

Codex CLI

  • STDIO: Update ~/.codex/config.toml (or the profile-specific config) to register the server using the TOML format described in the Codex docs (config reference):
    [mcp_servers.ragtime]
    command = "uv"
    args = ["--directory", "/path/to/ragtime", "run", "ragtime-mcp-stdio"]
    
  • HTTP: Launch the HTTP server (uv run ragtime-mcp-http -- --port 9000). Codex CLI currently only spawns stdio transports via mcp_servers. To use the HTTP endpoint, run a bridge such as mcp-router or @modelcontextprotocol/inspector that connects to http://127.0.0.1:9000 and exposes a stdio endpoint back to Codex.

CLI Overview

CommandDescription
ragtime add PATHIngest a file or directory into a Chroma database; supports --database, --split-by-subdir, and embedding options.
ragtime ask QUERYRun a semantic search across one or more databases with tunable --top-k, --collection, device/model overrides, and optional cross-encoder reranking (--rerank-top-k).
ragtime statusReport detected databases and counts of extraction, chunk, and embedding artifacts.
ragtime resetDelete one or more databases (--database, --all, --yes).

Ingestion artifacts are stored under data/extractions/, data/chunks/, and data/embeddings/. Generated content is considered ephemeral and should remain untracked unless needed for debugging.

VLM fallback configuration

  • Extraction automatically reruns with IBM Granite Docling when the initial Docling pass returns fewer than 150 words, switching to the MLX variant on Apple Silicon.
  • To force a specific Docling VLM spec (e.g., for troubleshooting), export RAGTIME_VLM_SPEC with the desired constant such as GRANITEDOCLING_TRANSFORMERS or SMOLDOCLING_TRANSFORMERS before running ragtime add.

Database locations and federated queries

  • Default (running inside the RAGtime repo or using Option A): databases live under ./data/databases/ in the current repository.
  • Vendored mode (Option B with uv --directory ./tools/ragtime): databases live under ./tools/ragtime/data/databases/ relative to your host repo root. Place per-database folders here (e.g., deploy, platform).
  • Each subdirectory inside data/databases/ is treated as an individual database (e.g., data/databases/local/, data/databases/vendor_docs/).
  • The ragtime status command lists these directories. If none are found, it prints the absolute path where you can create them.
  • During ingestion, use --database NAME to target a specific subdirectory; omit to default to local (i.e., data/databases/local/).
  • Federated queries span all subdirectories under data/databases/ unless you restrict with --database on ragtime ask.

Development Tasks

  • Format and lint: uv run ruff format src and uv run ruff check src.
  • Tests (add your own pytest suites): uv run pytest.
  • Update contributor guidelines in AGENTS.md when workflows change.

For a full walkthrough, including pipeline details and MCP tool contracts, see the MkDocs documentation under docs/ or build the site locally with mkdocs serve --config-file docs/mkdocs.yml after installing the optional documentation dependencies.

  • Rerank the top matches with a cross-encoder to improve answer-centric ordering:

    uv run ragtime ask "Summarize the design" \
      --rerank-top-k 10 \
      --rerank-model BAAI/bge-reranker-large
    

    The reranker downloads from Hugging Face the first time you use a new model. Cache the model under ~/.cache/huggingface to avoid repeated downloads.