danielballance/ragtime
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.
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
- Install Python 3.12+ and uv.
- Clone the repository and install dependencies:
uv sync
- 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
- Launch the MCP server (choose one transport):
The HTTP transport defaults to
uv run ragtime-mcp-stdio uv run ragtime-mcp-http -- --host 0.0.0.0 --port 9000
127.0.0.1:9000/mcp
; override the host, port, or path with the CLI flags shown above when exposing it to other machines. - 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 undertools/ragtime/data/
(not your host repo root):- Databases:
tools/ragtime/data/databases/<NAME>/
- Artifacts:
tools/ragtime/data/{extractions,chunks,embeddings}
- Databases:
- If you already have databases under your repo root
./data/databases/
, either move them into./tools/ragtime/data/databases/
or adjust your wrapper tochdir
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 siblingragtime-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:Restart Claude Desktop so it loads the configuration.{ "mcpServers": { "ragtime": { "command": "uv", "args": ["--directory", "/path/to/ragtime", "run", "ragtime-mcp-stdio"] } } }
- 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:If your build lacks{ "mcpServers": { "ragtime-http": { "url": "http://127.0.0.1:9000" } } }
url
support, use stdio or run the HTTP server through a router likemcp-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 theurl
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 viamcp_servers
. To use the HTTP endpoint, run a bridge such asmcp-router
or@modelcontextprotocol/inspector
that connects tohttp://127.0.0.1:9000
and exposes a stdio endpoint back to Codex.
CLI Overview
Command | Description |
---|---|
ragtime add PATH | Ingest a file or directory into a Chroma database; supports --database , --split-by-subdir , and embedding options. |
ragtime ask QUERY | Run 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 status | Report detected databases and counts of extraction, chunk, and embedding artifacts. |
ragtime reset | Delete 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 asGRANITEDOCLING_TRANSFORMERS
orSMOLDOCLING_TRANSFORMERS
before runningragtime 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 tolocal
(i.e.,data/databases/local/
). - Federated queries span all subdirectories under
data/databases/
unless you restrict with--database
onragtime ask
.
Development Tasks
- Format and lint:
uv run ruff format src
anduv 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.